summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsabetts <sabetts>2001-03-29 04:29:15 +0000
committersabetts <sabetts>2001-03-29 04:29:15 +0000
commiteb256cbcbed3431ec5a330fe6dcb12f75ec76c8a (patch)
treed57dd638f39dc32492f92ac86fd16c88929bc0a8
parent889c6fc041fe9af255f609ba434eceab74491e8c (diff)
downloadratpoison-eb256cbcbed3431ec5a330fe6dcb12f75ec76c8a.zip
better command functionality
-rw-r--r--ChangeLog22
-rw-r--r--src/actions.c9
-rw-r--r--src/actions.h1
-rw-r--r--src/communications.c64
-rw-r--r--src/data.h3
-rw-r--r--src/events.c63
-rw-r--r--src/main.c4
7 files changed, 156 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index d238ba3..b72a912 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2001-03-28 Shawn <sabetts@vcn.bc.ca>
+
+ * src/main.c (main): initialize rp_command_request and
+ rp_command_result.
+
+ * src/data.h (rp_command_request): new global
+ (rp_command_result): new global
+
+ * src/events.c (execute_remote_command): new function
+ (receive_command): loops through the list of command requests
+ calling execute_remote_command on each one.
+ (property_notify): better detection of command requests.
+
+ * src/communications.c (recieve_command_result): new function
+ (send_command): creates a new window to attach the command
+ to. Waits for confirmation that the command has been executed.
+
+ * src/actions.h (cmd_echo): new prototype
+
+ * src/actions.c (cmd_echo): new function
+ (user_commands): update "echo" entry
+
2001-03-22 Gergely Nagy <8@free.bsd.hu>
* debian/control: removed build-dependency on x-terminal-emulator,
diff --git a/src/actions.c b/src/actions.c
index debc821..44017fd 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -147,12 +147,12 @@ user_command user_commands[] =
{"bind", cmd_bind, arg_VOID},
{"source", cmd_source, arg_STRING},
{"escape", cmd_escape, arg_STRING},
+ {"echo", cmd_echo, arg_STRING},
/* the following screen commands may or may not be able to be
implemented. See the screen documentation for what should be
emulated with these commands */
- {"echo", cmd_unimplemented, arg_VOID},
{"stuff", cmd_unimplemented, arg_VOID},
{"number", cmd_unimplemented, arg_VOID},
{"hardcopy", cmd_unimplemented, arg_VOID},
@@ -754,3 +754,10 @@ cmd_escape (void *data)
message (" escape: could not parse key description ");
}
}
+
+/* User accessible call to display the passed in string. */
+void
+cmd_echo (void *data)
+{
+ if (data) message ((char *)data);
+}
diff --git a/src/actions.h b/src/actions.h
index b23fc59..7d0633e 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -62,6 +62,7 @@ void cmd_bind (void* data);
void cmd_source (void* data);
void cmd_maximize (void *data);
void cmd_escape (void *data);
+void cmd_echo (void *data);
/* void cmd_xterm (void *data); */
diff --git a/src/communications.c b/src/communications.c
index f87e115..0a0194d 100644
--- a/src/communications.c
+++ b/src/communications.c
@@ -67,9 +67,69 @@ send_kill ()
}
}
+/* Sending commands to ratpoison */
+
+static void
+recieve_command_result (Window w)
+{
+ Atom type_ret;
+ int format_ret;
+ unsigned long nitems;
+ unsigned long bytes_after;
+ unsigned char *result;
+
+
+ if (XGetWindowProperty (dpy, w, rp_command_result,
+ 0, 0, False, XA_STRING,
+ &type_ret, &format_ret, &nitems, &bytes_after,
+ &result) == Success
+ &&
+ XGetWindowProperty (dpy, w, rp_command_result,
+ 0, (bytes_after / 4) + (bytes_after % 4 ? 1 : 0),
+ True, XA_STRING, &type_ret, &format_ret, &nitems,
+ &bytes_after, &result) == Success)
+ {
+ if (result)
+ {
+ printf ("%s\n", result);
+ }
+ XFree (result);
+ }
+}
+
int
send_command (unsigned char *cmd)
{
- return XChangeProperty (dpy, DefaultRootWindow (dpy), rp_command, XA_STRING,
- 8, PropModeAppend, cmd, strlen (cmd) + 1);
+ Window w;
+ int done = 0;
+
+ w = XCreateSimpleWindow (dpy, DefaultRootWindow (dpy),
+ 0, 0, 1, 1, 0, 0, 0);
+
+ // Select first to avoid race condition
+ XSelectInput (dpy, w, PropertyChangeMask);
+
+ XChangeProperty (dpy, w, rp_command, XA_STRING,
+ 8, PropModeReplace, cmd, strlen (cmd) + 1);
+
+ XChangeProperty (dpy, DefaultRootWindow (dpy),
+ rp_command_request, XA_WINDOW,
+ 8, PropModeAppend, (unsigned char *)&w, sizeof (Window));
+
+ while (!done)
+ {
+ XEvent ev;
+
+ XMaskEvent (dpy, PropertyChangeMask, &ev);
+ if (ev.xproperty.atom == rp_command_result
+ && ev.xproperty.state == PropertyNewValue)
+ {
+ recieve_command_result(ev.xproperty.window);
+ done = 1;
+ }
+ }
+
+ XDestroyWindow (dpy, w);
+
+ return 1;
}
diff --git a/src/data.h b/src/data.h
index 34a006c..c968db9 100644
--- a/src/data.h
+++ b/src/data.h
@@ -124,6 +124,9 @@ extern Display *dpy;
extern Atom rp_restart;
extern Atom rp_kill;
extern Atom rp_command;
+extern Atom rp_command_request;
+extern Atom rp_command_result;
+
extern Atom wm_state;
extern Atom wm_change_state;
diff --git a/src/events.c b/src/events.c
index f32b4fa..9d8f140 100644
--- a/src/events.c
+++ b/src/events.c
@@ -286,7 +286,7 @@ configure_request (XConfigureRequestEvent *e)
static void
client_msg (XClientMessageEvent *ev)
{
- PRINT_DEBUG ("Recieved client message.\n");
+ PRINT_DEBUG ("Received client message.\n");
if (ev->message_type == rp_restart)
{
@@ -382,8 +382,12 @@ key_press (XEvent *ev)
}
}
-void
-receive_command()
+/* Read a command off the window and execute it. Some commands return
+ text. This text is passed back using the RP_COMMAND_RESULT
+ Atom. The client will wait for this property change so something
+ must be returned. */
+static void
+execute_remote_command (Window w)
{
Atom type_ret;
int format_ret;
@@ -391,12 +395,12 @@ receive_command()
unsigned long bytes_after;
unsigned char *req;
- if (XGetWindowProperty (dpy, DefaultRootWindow (dpy), rp_command,
+ if (XGetWindowProperty (dpy, w, rp_command,
0, 0, False, XA_STRING,
&type_ret, &format_ret, &nitems, &bytes_after,
&req) == Success
&&
- XGetWindowProperty (dpy, DefaultRootWindow (dpy), rp_command,
+ XGetWindowProperty (dpy, w, rp_command,
0, (bytes_after / 4) + (bytes_after % 4 ? 1 : 0),
True, XA_STRING, &type_ret, &format_ret, &nitems,
&bytes_after, &req) == Success)
@@ -414,6 +418,50 @@ receive_command()
}
}
+/* Command requests are posted as a property change using the
+ RP_COMMAND_REQUEST Atom on the root window. A Command request is a
+ Window that holds the actual command as a property using the
+ RP_COMMAND Atom. receive_command reads the list of Windows and
+ executes their associated command. */
+static void
+receive_command ()
+{
+ Atom type_ret;
+ int format_ret;
+ unsigned long nitems;
+ unsigned long bytes_after;
+ void *prop_return;
+
+ do
+ {
+ if (XGetWindowProperty (dpy, DefaultRootWindow (dpy),
+ rp_command_request, 0,
+ sizeof (Window) / 4 + (sizeof (Window) % 4 ?1:0),
+ True, XA_WINDOW, &type_ret, &format_ret, &nitems,
+ &bytes_after, (unsigned char **)&prop_return) == Success)
+ {
+ if (prop_return)
+ {
+ Window w;
+
+ w = *(Window *)prop_return;
+ XFree (prop_return);
+
+ execute_remote_command (w);
+ XChangeProperty (dpy, w, rp_command_result, XA_STRING,
+ 8, PropModeReplace, "Success", 8);
+ }
+ else
+ {
+ PRINT_DEBUG ("Couldn't get RP_COMMAND_REQUEST Property\n");
+ }
+
+ PRINT_DEBUG ("command requests: %ld\n", nitems);
+ }
+ } while (nitems > 0);
+
+}
+
void
property_notify (XEvent *ev)
{
@@ -421,8 +469,9 @@ property_notify (XEvent *ev)
PRINT_DEBUG ("atom: %ld\n", ev->xproperty.atom);
- if (ev->xproperty.atom == rp_command
- && ev->xproperty.window == DefaultRootWindow (dpy))
+ if (ev->xproperty.atom == rp_command_request
+ && ev->xproperty.window == DefaultRootWindow (dpy)
+ && ev->xproperty.state == PropertyNewValue)
{
PRINT_DEBUG ("ratpoison command\n");
receive_command();
diff --git a/src/main.c b/src/main.c
index 5cbf4c2..fc97004 100644
--- a/src/main.c
+++ b/src/main.c
@@ -51,6 +51,8 @@ Atom wm_colormaps;
Atom rp_restart;
Atom rp_kill;
Atom rp_command;
+Atom rp_command_request;
+Atom rp_command_result;
screen_info *screens;
int num_screens;
@@ -365,6 +367,8 @@ main (int argc, char *argv[])
rp_restart = XInternAtom (dpy, "RP_RESTART", False);
rp_kill = XInternAtom (dpy, "RP_KILL", False);
rp_command = XInternAtom (dpy, "RP_COMMAND", False);
+ rp_command_request = XInternAtom (dpy, "RP_COMMAND_REQUEST", False);
+ rp_command_result = XInternAtom (dpy, "RP_COMMAND_RESULT", False);
if (do_kill)
{