summaryrefslogtreecommitdiff
path: root/src/globals.c
diff options
context:
space:
mode:
authorsabetts <sabetts>2004-12-13 01:04:15 +0000
committersabetts <sabetts>2004-12-13 01:04:15 +0000
commitf90ee8e9dfcb3ab286c5202e96a0715429f0e4e7 (patch)
tree43fd7965bcae0bf813f9609c4bf815cb6df09aff /src/globals.c
parentf6f24bd90f416993e1621266081bfc9419925495 (diff)
downloadratpoison-f90ee8e9dfcb3ab286c5202e96a0715429f0e4e7.zip
* src/sbuf.c (sbuf_concat): call sbuf_nconcat. move bulk of body
to sbuf_nconcat. (sbuf_nconcat): new function * src/globals.c (init_globals): new function * src/main.c (main): call init_globals. * src/globals.c: include unistd.h. (x_export_selection): new function (set_nselection): likewise (set_selection): call x_export_selection (get_cut_buffer): new function (get_primary_selection): likewise (get_selection): likewise * src/editor.c (editor_kill_word): add the deleted text to the X11 selection (editor_backward_kill_word): likewise (editor_kill_line): likewise (backward_kill_line): new fuction (editor_backward_kill_line): add the deleted text to the X11 selection. call backward_kill_line. (paste_cut_buffer): remove function (paste_primary_selection): likewise (editor_paste_selection): call get_selection to get the X11 selection. (editor_complete): call backward_kill_line instead of editor_backward_kill_line. * src/ratpoison.h: Include string.h. Include X11/XAtom.h. * src/globals.c (selection): new global (set_selection): new function * src/events.c: include X11/Xmd.h (selection_request): new function (selection_clear): new function (delegate_event): call selection_request and selection_clear for SelectionRequest and SelectionClear events. * src/actions.c (user_commands): remove duplicate focusprev entry. Add putsel. Add getsel. (cmd_putsel): new function (cmd_getsel): new function * contrib/genrpbindings: add a missing paren to the elisp bindings.
Diffstat (limited to 'src/globals.c')
-rw-r--r--src/globals.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/globals.c b/src/globals.c
index bc369ae..a76f220 100644
--- a/src/globals.c
+++ b/src/globals.c
@@ -20,6 +20,8 @@
#include "ratpoison.h"
+#include <unistd.h> /* for usleep(). */
+
int alarm_signalled = 0;
int kill_signalled = 0;
int hup_signalled = 0;
@@ -70,6 +72,143 @@ char *rp_error_msg = NULL;
/* Global frame numset */
struct numset *rp_frame_numset;
+/* The X11 selection globals */
+rp_xselection selection;
+
+static void
+x_export_selection ()
+{
+ /* Hang the selections off screen 0's key window. */
+ XSetSelectionOwner(dpy, XA_PRIMARY, screens[0].key_window, CurrentTime);
+ if (XGetSelectionOwner(dpy, XA_PRIMARY) != screens[0].key_window)
+ PRINT_ERROR(("can't get primary selection"));
+ XChangeProperty(dpy, screens[0].root, XA_CUT_BUFFER0, XA_STRING, 8,
+ PropModeReplace, selection.text, selection.len);
+}
+
+void
+set_nselection (char *txt, int len)
+{
+ int i;
+
+ /* Update the selection structure */
+ if (selection.text != NULL)
+ free(selection.text);
+
+ /* Copy the string by hand. */
+ selection.text = malloc(len+1);
+ selection.len = len + 1;
+ for (i=0; i<len; i++)
+ selection.text[i] = txt[i];
+ selection.text[len] = 0;
+
+ x_export_selection();
+}
+
+void
+set_selection (char *txt)
+{
+ /* Update the selection structure */
+ if (selection.text != NULL)
+ free(selection.text);
+ selection.text = xstrdup (txt);
+ selection.len = strlen (txt);
+
+ x_export_selection();
+}
+
+static char *
+get_cut_buffer ()
+{
+ int nbytes;
+ char *data;
+
+ PRINT_DEBUG (("trying the cut buffer\n"));
+
+ data = XFetchBytes (dpy, &nbytes);
+
+ if (data)
+ {
+ struct sbuf *s = sbuf_new (0);
+ sbuf_nconcat (s, data, nbytes);
+ XFree (data);
+ return sbuf_free_struct (s);
+ }
+ else
+ return NULL;
+}
+
+/* Lifted the code from rxvt. */
+static char *
+get_primary_selection()
+{
+ long nread;
+ unsigned long bytes_after;
+ XTextProperty ct;
+ struct sbuf *s = sbuf_new(0);
+
+ for (nread = 0, bytes_after = 1; bytes_after > 0; nread += ct.nitems) {
+ if ((XGetWindowProperty(dpy, current_screen()->input_window, rp_selection, (nread / 4), 4096,
+ True, AnyPropertyType, &ct.encoding,
+ &ct.format, &ct.nitems, &bytes_after,
+ &ct.value) != Success)) {
+ XFree(ct.value);
+ sbuf_free(s);
+ return NULL;
+ }
+ if (ct.value == NULL)
+ continue;
+ /* Accumulate the data. FIXME: ct.value may not be NULL
+ terminated. */
+ sbuf_nconcat (s, ct.value, ct.nitems);
+ XFree(ct.value);
+ }
+ return sbuf_free_struct (s);
+}
+
+char *
+get_selection ()
+{
+ Atom property;
+ XEvent ev;
+ rp_screen *s = current_screen ();
+ int loops = 1000;
+
+ /* Just insert our text, if we own the selection. */
+ if (selection.text)
+ {
+ return xstrdup (selection.text);
+ }
+ else
+ {
+ /* be a good icccm citizen */
+ XDeleteProperty (dpy, s->input_window, rp_selection);
+ /* TODO: we shouldn't use CurrentTime here, use the time of the XKeyEvent, should we fake it? */
+ XConvertSelection (dpy, XA_PRIMARY, XA_STRING, rp_selection, s->input_window, CurrentTime);
+
+ /* This seems like a hack. */
+ while (!XCheckTypedWindowEvent (dpy, s->input_window, SelectionNotify, &ev))
+ {
+ if (loops == 0)
+ {
+ PRINT_ERROR (("selection request timed out\n"));
+ return NULL;
+ }
+ usleep (10000);
+ loops--;
+ }
+
+ PRINT_DEBUG (("SelectionNotify event\n"));
+
+ property = ev.xselection.property;
+
+ if (property != None)
+ return get_primary_selection ();
+ else
+ return get_cut_buffer ();
+ }
+}
+
/* The hook dictionary globals. */
LIST_HEAD (rp_key_hook);
@@ -106,3 +245,10 @@ set_window_focus (Window window)
LIST_HEAD (rp_frame_undos);
int rp_num_frame_undos = 0;
+
+void
+init_globals ()
+{
+ selection.text = NULL;
+ selection.len = 0;
+}