summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsabetts <sabetts>2001-08-18 21:54:21 +0000
committersabetts <sabetts>2001-08-18 21:54:21 +0000
commit0a1a6fbcfddf9f4857b1c95f32321bbd27968cea (patch)
treed7d799cffdbc3e27a37a8bbeac1393694def1c88
parentbd72362cf682c093fe84802b6c08b67f6f9d819e (diff)
downloadratpoison-0a1a6fbcfddf9f4857b1c95f32321bbd27968cea.zip
commands can be called interactively and non-interactively. commands return a result string
-rw-r--r--ChangeLog23
-rw-r--r--src/actions.c240
-rw-r--r--src/actions.h70
-rw-r--r--src/bar.c42
-rw-r--r--src/communications.c2
-rw-r--r--src/events.c30
-rw-r--r--src/list.c61
-rw-r--r--src/list.h3
-rw-r--r--src/main.c9
9 files changed, 315 insertions, 165 deletions
diff --git a/ChangeLog b/ChangeLog
index ffda688..f579043 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
2001-08-18 Shawn <sabetts@hotdog>
+ * src/main.c (read_rc_file): free the command's result string.
+
+ * src/list.h (get_window_list): new prototype
+
+ * src/list.c (get_window_list): new function
+
+ * src/events.c (handle_key): free the command's result string.
+ (receive_command): send the command's result string if there is
+ one, otherwise send NULL.
+
+ * src/communications.c (recieve_command_result): only print the
+ result if the string is not empty.
+
+ * src/bar.c (update_window_names): calls get_window_list.
+
+ * src/actions.c (cmd_windows): return a list of the windows when
+ called non-interactively.
+ (cmd_colon): free the command result.
+
+ * src/actions.c: command functions have been changed to return a
+ result string and take a parameter that tells the function if it
+ was called interactively or not. All callers updated.
+
* src/split.c (split_frame): unhide transient_for windows as well
as the active window.
(remove_all_splits): hide transient_for windows as well as the
diff --git a/src/actions.c b/src/actions.c
index 3e30693..043efac 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -290,8 +290,8 @@ parse_keydesc (char *keydesc)
return p;
}
-void
-cmd_bind (void *data)
+char *
+cmd_bind (int interactive, void *data)
{
char *keydesc;
char *cmd;
@@ -299,7 +299,7 @@ cmd_bind (void *data)
if (!data)
{
message (" bind: at least one argument required ");
- return;
+ return NULL;
}
keydesc = (char*) xmalloc (strlen (data + 1));
@@ -335,16 +335,20 @@ cmd_bind (void *data)
}
free (keydesc);
+
+ return NULL;
}
-void
-cmd_unimplemented (void *data)
+char *
+cmd_unimplemented (int interactive, void *data)
{
marked_message (" FIXME: unimplemented command ",0,8);
+
+ return NULL;
}
-void
-cmd_source (void *data)
+char *
+cmd_source (int interactive, void *data)
{
FILE *fileptr;
@@ -355,15 +359,17 @@ cmd_source (void *data)
read_rc_file (fileptr);
fclose (fileptr);
}
+
+ return NULL;
}
-void
-cmd_generate (void *data)
+char *
+cmd_generate (int interactive, void *data)
{
XEvent ev1, ev;
ev = rp_current_event;
- if (current_window() == NULL) return;
+ if (current_window() == NULL) return NULL;
PRINT_DEBUG ("type==%d\n", ev.xkey.type);
PRINT_DEBUG ("serial==%ld\n", ev.xkey.serial);
@@ -404,10 +410,12 @@ cmd_generate (void *data)
/* XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, 't'), True, 0); */
XSync (dpy, False);
+
+ return NULL;
}
-void
-cmd_prev (void *data)
+char *
+cmd_prev (int interactive, void *data)
{
rp_window *w;
@@ -419,7 +427,7 @@ cmd_prev (void *data)
if (!current_window())
message (MESSAGE_NO_MANAGED_WINDOWS);
- return;
+ return NULL;
}
else
{
@@ -430,10 +438,12 @@ cmd_prev (void *data)
else
set_active_window (w);
}
+
+ return NULL;
}
-void
-cmd_prev_frame (void *data)
+char *
+cmd_prev_frame (int interactive, void *data)
{
rp_window_frame *frame;
@@ -442,10 +452,12 @@ cmd_prev_frame (void *data)
message (MESSAGE_NO_OTHER_WINDOW);
else
set_active_frame (frame);
+
+ return NULL;
}
-void
-cmd_next (void *data)
+char *
+cmd_next (int interactive, void *data)
{
rp_window *w;
@@ -457,7 +469,7 @@ cmd_next (void *data)
if (!current_window())
message (MESSAGE_NO_MANAGED_WINDOWS);
- return;
+ return NULL;
}
else
{
@@ -468,10 +480,12 @@ cmd_next (void *data)
else
set_active_window (w);
}
+
+ return NULL;
}
-void
-cmd_next_frame (void *data)
+char *
+cmd_next_frame (int interactive, void *data)
{
rp_window_frame *frame;
@@ -481,10 +495,11 @@ cmd_next_frame (void *data)
else
set_active_frame (frame);
+ return NULL;
}
-void
-cmd_other (void *data)
+char *
+cmd_other (int interactive, void *data)
{
rp_window *w;
@@ -494,6 +509,8 @@ cmd_other (void *data)
message (MESSAGE_NO_OTHER_WINDOW);
else
set_active_window (w);
+
+ return NULL;
}
static int
@@ -513,8 +530,8 @@ string_to_window_number (char *str)
}
/* switch to window number or name */
-void
-cmd_select (void *data)
+char *
+cmd_select (int interactive, void *data)
{
char *str;
int n;
@@ -557,14 +574,16 @@ cmd_select (void *data)
}
free (str);
+
+ return NULL;
}
-void
-cmd_rename (void *data)
+char *
+cmd_rename (int interactive, void *data)
{
char *winname;
- if (current_window() == NULL) return;
+ if (current_window() == NULL) return NULL;
if (data == NULL)
winname = get_input (MESSAGE_PROMPT_NEW_WINDOW_NAME);
@@ -585,16 +604,18 @@ cmd_rename (void *data)
}
free (winname);
+
+ return NULL;
}
-void
-cmd_delete (void *data)
+char *
+cmd_delete (int interactive, void *data)
{
XEvent ev;
int status;
- if (current_window() == NULL) return;
+ if (current_window() == NULL) return NULL;
ev.xclient.type = ClientMessage;
ev.xclient.window = current_window()->w;
@@ -605,25 +626,31 @@ cmd_delete (void *data)
status = XSendEvent(dpy, current_window()->w, False, 0, &ev);
if (status == 0) fprintf(stderr, "ratpoison: delete window failed\n");
+
+ return NULL;
}
-void
-cmd_kill (void *data)
+char *
+cmd_kill (int interactive, void *data)
{
- if (current_window() == NULL) return;
+ if (current_window() == NULL) return NULL;
XKillClient(dpy, current_window()->w);
+
+ return NULL;
}
-void
-cmd_version (void *data)
+char *
+cmd_version (int interactive, void *data)
{
message (" " PACKAGE " " VERSION " ");
+ return NULL;
}
-void
-command (char *data)
+char *
+command (int interactive, char *data)
{
+ char *result = NULL;
char *cmd, *rest;
char *input;
@@ -631,7 +658,7 @@ command (char *data)
struct sbuf *buf = NULL;
if (data == NULL)
- return;
+ return NULL;
/* get a writable copy for strtok() */
input = strdup ((char *) data);
@@ -650,7 +677,7 @@ command (char *data)
{
if (!strcmp (cmd, uc->name))
{
- uc->func (rest);
+ result = uc->func (interactive, rest);
goto done;
}
}
@@ -668,11 +695,14 @@ command (char *data)
done:
free (input);
+
+ return result;
}
-void
-cmd_colon (void *data)
+char *
+cmd_colon (int interactive, void *data)
{
+ char *result;
char *input;
if (data == NULL)
@@ -680,13 +710,19 @@ cmd_colon (void *data)
else
input = get_more_input (MESSAGE_PROMPT_COMMAND, data);
- command (input);
+ result = command (1, input);
+
+ /* Gobble the result. */
+ if (result)
+ free (result);
free (input);
+
+ return NULL;
}
-void
-cmd_exec (void *data)
+char *
+cmd_exec (int interactive, void *data)
{
char *cmd;
@@ -698,6 +734,8 @@ cmd_exec (void *data)
spawn (cmd);
free (cmd);
+
+ return NULL;
}
@@ -727,8 +765,8 @@ spawn(void *data)
/* Switch to a different Window Manager. Thanks to
"Chr. v. Stuckrad" <stucki@math.fu-berlin.de> for the patch. */
-void
-cmd_newwm(void *data)
+char *
+cmd_newwm(int interactive, void *data)
{
char *prog;
@@ -746,23 +784,28 @@ cmd_newwm(void *data)
perror(" failed");
free (prog);
+
+ return NULL;
}
/* Quit ratpoison. Thanks to
"Chr. v. Stuckrad" <stucki@math.fu-berlin.de> for the patch. */
-void
-cmd_quit(void *data)
+char *
+cmd_quit(int interactive, void *data)
{
PRINT_DEBUG ("Exiting\n");
clean_up ();
exit (EXIT_SUCCESS);
+
+ /* Never gets here. */
+ return NULL;
}
/* Show the current time on the bar. Thanks to Martin Samuelsson
<cosis@lysator.liu.se> for the patch. Thanks to Jonathan Walther
<krooger@debian.org> for making it pretty. */
-void
-cmd_clock (void *data)
+char *
+cmd_clock (int interactive, void *data)
{
char *msg, *tmp;
time_t timep;
@@ -775,24 +818,26 @@ cmd_clock (void *data)
message (msg);
free (msg);
+
+ return NULL;
}
/* Assign a new number to a window ala screen's number command. Thanks
to Martin Samuelsson <cosis@lysator.liu.se> for the original
patch. */
-void
-cmd_number (void *data)
+char *
+cmd_number (int interactive, void *data)
{
int old_number, new_number;
rp_window *other_win;
char *str;
- if (current_window() == NULL) return;
+ if (current_window() == NULL) return NULL;
if (data == NULL)
{
print_window_information (current_window());
- return;
+ return NULL;
}
else
{
@@ -829,23 +874,41 @@ cmd_number (void *data)
}
free (str);
+
+ return NULL;
}
/* Toggle the display of the program bar */
-void
-cmd_windows (void *data)
+char *
+cmd_windows (int interactive, void *data)
{
+ struct sbuf *window_list = NULL;
+ char *tmp;
+ int dummy;
screen_info *s;
- s = current_screen ();
+ if (interactive)
+ {
+ s = current_screen ();
+ if (!hide_bar (s)) show_bar (s);
+
+ return NULL;
+ }
+ else
+ {
+ window_list = sbuf_new (0);
+ get_window_list ("\n", window_list, &dummy, &dummy);
+ tmp = sbuf_get (window_list);
+ free (window_list);
- if (!hide_bar (s)) show_bar (s);
+ return tmp;
+ }
}
-
-void
-cmd_abort (void *data)
+char *
+cmd_abort (int interactive, void *data)
{
+ return NULL;
}
/* Send the current window the prefix key event */
@@ -862,15 +925,17 @@ cmd_abort (void *data)
/* } */
/* Maximize the current window. */
-void
-cmd_maximize (void *data)
+char *
+cmd_maximize (int interactive, void *data)
{
force_maximize (current_window());
+
+ return NULL;
}
/* Reassign the prefix key. */
-void
-cmd_escape (void *data)
+char *
+cmd_escape (int interactive, void *data)
{
rp_window *cur;
struct rp_key *key;
@@ -920,36 +985,43 @@ cmd_escape (void *data)
{
message (" escape: could not parse key description ");
}
+
+ return NULL;
}
/* User accessible call to display the passed in string. */
-void
-cmd_echo (void *data)
+char *
+cmd_echo (int interactive, void *data)
{
if (data) message ((char *)data);
+ return NULL;
}
-void
-cmd_h_split (void *data)
+char *
+cmd_h_split (int interactive, void *data)
{
h_split_frame (rp_current_frame);
+ return NULL;
}
-void
-cmd_v_split (void *data)
+char *
+cmd_v_split (int interactive, void *data)
{
v_split_frame (rp_current_frame);
+ return NULL;
}
-void
-cmd_only (void *data)
+char *
+cmd_only (int interactive, void *data)
{
remove_all_splits();
maximize (current_window());
+
+ return NULL;
}
-void
-cmd_remove (void *data)
+char *
+cmd_remove (int interactive, void *data)
{
rp_window_frame *frame;
@@ -960,27 +1032,31 @@ cmd_remove (void *data)
remove_frame (rp_current_frame);
set_active_frame (frame);
}
+
+ return NULL;
}
/* banish the rat pointer */
-void
-cmd_banish (void *data)
+char *
+cmd_banish (int interactive, void *data)
{
screen_info *s;
s = current_screen ();
XWarpPointer (dpy, None, s->root, 0, 0, 0, 0, s->root_attr.width - 2, s->root_attr.height - 2);
+ return NULL;
}
-void
-cmd_curframe (void *data)
+char *
+cmd_curframe (int interactive, void *data)
{
show_frame_indicator();
+ return NULL;
}
-void
-cmd_help (void *data)
+char *
+cmd_help (int interactive, void *data)
{
screen_info *s = current_screen();
XEvent ev;
@@ -1049,4 +1125,6 @@ cmd_help (void *data)
XMaskEvent (dpy, KeyPressMask, &ev);
XUnmapWindow (dpy, s->help_window);
XSetInputFocus (dpy, fwin, revert, CurrentTime);
+
+ return NULL;
}
diff --git a/src/actions.h b/src/actions.h
index 19b5c02..f4933cc 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -33,46 +33,46 @@ struct
user_command
{
char *name;
- void (*func)(void *);
+ char * (*func)(int, void *);
int argtype;
};
void spawn(void *data);
-void command (char *data);
+char * command (int interactive, char *data);
-void cmd_newwm(void *which);
-void cmd_generate (void *data);
-void cmd_abort (void *data);
-void cmd_exec (void *data);
-void cmd_colon (void *data);
-void cmd_kill (void *data);
-void cmd_delete (void *data);
-void cmd_rename (void *data);
-void cmd_select (void *data);
-void cmd_last (void *data);
-void cmd_next (void *data);
-void cmd_next_frame (void *data);
-void cmd_prev (void *data);
-void cmd_prev_frame (void *data);
-void cmd_windows (void *data);
-void cmd_other (void *data);
-void cmd_clock (void *data);
-void cmd_version (void *data);
-void cmd_unimplemented (void *data);
-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_h_split (void *data);
-void cmd_v_split (void *data);
-void cmd_only (void *data);
-void cmd_remove (void *data);
-void cmd_banish (void *data);
-void cmd_curframe (void *data);
-void cmd_help (void *data);
-void cmd_quit(void *data);
-void cmd_number (void *data);
+char * cmd_newwm(int interactive, void *which);
+char * cmd_generate (int interactive, void *data);
+char * cmd_abort (int interactive, void *data);
+char * cmd_exec (int interactive, void *data);
+char * cmd_colon (int interactive, void *data);
+char * cmd_kill (int interactive, void *data);
+char * cmd_delete (int interactive, void *data);
+char * cmd_rename (int interactive, void *data);
+char * cmd_select (int interactive, void *data);
+char * cmd_last (int interactive, void *data);
+char * cmd_next (int interactive, void *data);
+char * cmd_next_frame (int interactive, void *data);
+char * cmd_prev (int interactive, void *data);
+char * cmd_prev_frame (int interactive, void *data);
+char * cmd_windows (int interactive, void *data);
+char * cmd_other (int interactive, void *data);
+char * cmd_clock (int interactive, void *data);
+char * cmd_version (int interactive, void *data);
+char * cmd_unimplemented (int interactive, void *data);
+char * cmd_bind (int interactive, void* data);
+char * cmd_source (int interactive, void* data);
+char * cmd_maximize (int interactive, void *data);
+char * cmd_escape (int interactive, void *data);
+char * cmd_echo (int interactive, void *data);
+char * cmd_h_split (int interactive, void *data);
+char * cmd_v_split (int interactive, void *data);
+char * cmd_only (int interactive, void *data);
+char * cmd_remove (int interactive, void *data);
+char * cmd_banish (int interactive, void *data);
+char * cmd_curframe (int interactive, void *data);
+char * cmd_help (int interactive, void *data);
+char * cmd_quit(int interactive, void *data);
+char * cmd_number (int interactive, void *data);
/* void cmd_xterm (void *data); */
diff --git a/src/bar.c b/src/bar.c
index 47c10f8..3208cac 100644
--- a/src/bar.c
+++ b/src/bar.c
@@ -91,10 +91,6 @@ void
update_window_names (screen_info *s)
{
static struct sbuf *bar_buffer = NULL;
- rp_window *w;
- rp_window *other_window;
-
- char dbuf[10];
int mark_start = 0;
int mark_end = 0;
@@ -104,43 +100,7 @@ update_window_names (screen_info *s)
if (bar_buffer == NULL)
bar_buffer = sbuf_new (0);
- sbuf_clear (bar_buffer);
-
- other_window = find_window_other ();
-
- for (w = rp_mapped_window_sentinel->next;
- w != rp_mapped_window_sentinel;
- w = w->next)
- {
- PRINT_DEBUG ("%d-%s\n", w->number, w->name);
-
- if (w == current_window())
- mark_start = strlen (sbuf_get (bar_buffer));
-
- sbuf_concat (bar_buffer, " ");
-
- sprintf (dbuf, "%d", w->number);
- sbuf_concat (bar_buffer, dbuf);
-
- if (w == current_window())
- sbuf_concat (bar_buffer, "*");
- else if (w == other_window)
- sbuf_concat (bar_buffer, "+");
- else
- sbuf_concat (bar_buffer, "-");
-
- sbuf_concat (bar_buffer, w->name);
-
- sbuf_concat (bar_buffer, " ");
-
- if (w == current_window())
- mark_end = strlen (sbuf_get (bar_buffer));
- }
-
- if (!strcmp (sbuf_get (bar_buffer), ""))
- {
- sbuf_copy (bar_buffer, MESSAGE_NO_MANAGED_WINDOWS);
- }
+ get_window_list (NULL, bar_buffer, &mark_start, &mark_end);
marked_message (sbuf_get (bar_buffer), mark_start, mark_end);
}
diff --git a/src/communications.c b/src/communications.c
index 0a0194d..8b6cd66 100644
--- a/src/communications.c
+++ b/src/communications.c
@@ -89,7 +89,7 @@ recieve_command_result (Window w)
True, XA_STRING, &type_ret, &format_ret, &nitems,
&bytes_after, &result) == Success)
{
- if (result)
+ if (result && strlen (result))
{
printf ("%s\n", result);
}
diff --git a/src/events.c b/src/events.c
index 0937b0b..7a6de8c 100644
--- a/src/events.c
+++ b/src/events.c
@@ -372,8 +372,13 @@ handle_key (screen_info *s)
if ((key_action = find_keybinding (keysym, mod)))
{
+ char *result;
XSetInputFocus (dpy, fwin, revert, CurrentTime);
- command (key_action->data);
+ result = command (1, key_action->data);
+
+ /* Gobble the result. */
+ if (result)
+ free (result);
}
else
{
@@ -436,9 +441,10 @@ key_press (XEvent *ev)
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
+static char *
execute_remote_command (Window w)
{
+ char *result = NULL;
Atom type_ret;
int format_ret;
unsigned long nitems;
@@ -458,7 +464,7 @@ execute_remote_command (Window w)
if (req)
{
PRINT_DEBUG ("command: %s\n", req);
- command (req);
+ result = command (0, req);
}
XFree (req);
}
@@ -466,6 +472,8 @@ execute_remote_command (Window w)
{
PRINT_DEBUG ("Couldn't get RP_COMMAND Property\n");
}
+
+ return result;
}
/* Command requests are posted as a property change using the
@@ -476,6 +484,7 @@ execute_remote_command (Window w)
static void
receive_command ()
{
+ char *result;
Atom type_ret;
int format_ret;
unsigned long nitems;
@@ -497,9 +506,18 @@ receive_command ()
w = *(Window *)prop_return;
XFree (prop_return);
- execute_remote_command (w);
- XChangeProperty (dpy, w, rp_command_result, XA_STRING,
- 8, PropModeReplace, "Success", 8);
+ result = execute_remote_command (w);
+ if (result)
+ {
+ XChangeProperty (dpy, w, rp_command_result, XA_STRING,
+ 8, PropModeReplace, result, strlen (result));
+ free (result);
+ }
+ else
+ {
+ XChangeProperty (dpy, w, rp_command_result, XA_STRING,
+ 8, PropModeReplace, NULL, 0);
+ }
}
else
{
diff --git a/src/list.c b/src/list.c
index e1f982d..348b1a1 100644
--- a/src/list.c
+++ b/src/list.c
@@ -579,3 +579,64 @@ print_window_information (rp_window *win)
return;
}
+
+/* get the window list and store it in buffer delimiting each window
+ with delim. mark_start and mark_end will be filled with the text
+ positions for the start and end of the current window. */
+void
+get_window_list (char *delim, struct sbuf *buffer, int *mark_start, int *mark_end)
+{
+ rp_window *w;
+ rp_window *other_window;
+ char dbuf[10];
+
+ if (buffer == NULL) return;
+
+ sbuf_clear (buffer);
+ other_window = find_window_other ();
+
+ for (w = rp_mapped_window_sentinel->next;
+ w != rp_mapped_window_sentinel;
+ w = w->next)
+ {
+ PRINT_DEBUG ("%d-%s\n", w->number, w->name);
+
+ if (w == current_window())
+ *mark_start = strlen (sbuf_get (buffer));
+
+ /* A hack, pad the window with a space at the beginning and end
+ if there is no delimiter. */
+ if (!delim)
+ sbuf_concat (buffer, " ");
+
+ sprintf (dbuf, "%d", w->number);
+ sbuf_concat (buffer, dbuf);
+
+ if (w == current_window())
+ sbuf_concat (buffer, "*");
+ else if (w == other_window)
+ sbuf_concat (buffer, "+");
+ else
+ sbuf_concat (buffer, "-");
+
+ sbuf_concat (buffer, w->name);
+
+ /* A hack, pad the window with a space at the beginning and end
+ if there is no delimiter. */
+ if (!delim)
+ sbuf_concat (buffer, " ");
+
+ /* Only put the delimiter between the windows, and not after the the last
+ window. */
+ if (delim && w->next != rp_mapped_window_sentinel)
+ sbuf_concat (buffer, delim);
+
+ if (w == current_window())
+ *mark_end = strlen (sbuf_get (buffer));
+ }
+
+ if (!strcmp (sbuf_get (buffer), ""))
+ {
+ sbuf_copy (buffer, MESSAGE_NO_MANAGED_WINDOWS);
+ }
+}
diff --git a/src/list.h b/src/list.h
index e216e9d..06913d1 100644
--- a/src/list.h
+++ b/src/list.h
@@ -22,6 +22,8 @@
#ifndef _RATPOISON_LIST_H
#define _RATPOISON_LIST_H 1
+#include "sbuf.h"
+
void free_window (rp_window *w);
rp_window *add_to_window_list (screen_info *s, Window w);
void init_window_list ();
@@ -55,5 +57,6 @@ void insert_into_list (rp_window *win, rp_window *sentinel);
void remove_from_list (rp_window *win);
void print_window_information (rp_window *win);
+void get_window_list (char *delim, struct sbuf *buffer, int *mark_start, int *mark_end);
#endif /* ! _RATPOISON_LIST_H */
diff --git a/src/main.c b/src/main.c
index c34436a..4fb0cf2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -243,7 +243,14 @@ read_rc_file (FILE *file)
/* do it */
if (*line != '#')
- command (line);
+ {
+ char *result;
+ result = command (0, line);
+
+ /* Gobble the result. */
+ if (result)
+ free (result);
+ }
*line = '\0';
}