aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2014-05-17 23:27:38 -0400
committerJesse Luehrs <doy@tozt.net>2014-07-04 22:39:07 -0400
commit924c84ed4be18b41790d93218e7c56d223233446 (patch)
treeea134d130628b7fd6201ace4b63cd66fb299b6c4
parente6ca55231efac74945c4e90a7d27d9923071cd4a (diff)
downloadrunes-924c84ed4be18b41790d93218e7c56d223233446.tar.gz
runes-924c84ed4be18b41790d93218e7c56d223233446.zip
basic implementation of selections
still need to draw the selection, and look into how selections persist after the application is closed (cut buffers?)
-rw-r--r--src/window-xlib.c77
-rw-r--r--src/window-xlib.h1
2 files changed, 73 insertions, 5 deletions
diff --git a/src/window-xlib.c b/src/window-xlib.c
index 6f49715..e02db3d 100644
--- a/src/window-xlib.c
+++ b/src/window-xlib.c
@@ -102,7 +102,7 @@ static int runes_window_backend_handle_builtin_button_press(
static void runes_window_backend_start_selection(
RunesTerm *t, int xpixel, int ypixel);
static void runes_window_backend_stop_selection(
- RunesTerm *t, int xpixel, int ypixel);
+ RunesTerm *t, int xpixel, int ypixel, Time time);
static struct runes_loc runes_window_backend_get_mouse_position(
RunesTerm *t, int xpixel, int ypixel);
static void runes_window_backend_handle_expose_event(
@@ -113,6 +113,10 @@ static void runes_window_backend_handle_focus_event(
RunesTerm *t, XFocusChangeEvent *e);
static void runes_window_backend_handle_selection_notify_event(
RunesTerm *t, XSelectionEvent *e);
+static void runes_window_backend_handle_selection_clear_event(
+ RunesTerm *t, XSelectionClearEvent *e);
+static void runes_window_backend_handle_selection_request_event(
+ RunesTerm *t, XSelectionRequestEvent *e);
void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[])
{
@@ -385,6 +389,14 @@ static void runes_window_backend_process_event(uv_work_t *req, int status)
runes_window_backend_handle_selection_notify_event(
t, &e->xselection);
break;
+ case SelectionRequest:
+ runes_window_backend_handle_selection_request_event(
+ t, &e->xselectionrequest);
+ break;
+ case SelectionClear:
+ runes_window_backend_handle_selection_clear_event(
+ t, &e->xselectionclear);
+ break;
case ClientMessage: {
Atom a = e->xclient.data.l[0];
if (a == w->atoms[RUNES_ATOM_WM_DELETE_WINDOW]) {
@@ -796,7 +808,7 @@ static int runes_window_backend_handle_builtin_button_press(
if (e->type == ButtonRelease) {
switch (e->button) {
case Button1:
- runes_window_backend_stop_selection(t, e->x, e->y);
+ runes_window_backend_stop_selection(t, e->x, e->y, e->time);
return 1;
break;
default:
@@ -835,15 +847,24 @@ static void runes_window_backend_start_selection(
t->scr.grid->selection_start = runes_window_backend_get_mouse_position(
t, xpixel, ypixel);
t->scr.grid->selection_end = t->scr.grid->selection_start;
- runes_warn("started selection at (%d, %d)\n", t->scr.grid->selection_start.row, t->scr.grid->selection_start.col);
}
static void runes_window_backend_stop_selection(
- RunesTerm *t, int xpixel, int ypixel)
+ RunesTerm *t, int xpixel, int ypixel, Time time)
{
+ RunesWindowBackend *w = &t->w;
+
t->scr.grid->selection_end = runes_window_backend_get_mouse_position(
t, xpixel, ypixel);
- runes_warn("stopped selection at (%d, %d)\n", t->scr.grid->selection_end.row, t->scr.grid->selection_end.col);
+
+ if ((t->scr.grid->selection_start.row == t->scr.grid->selection_end.row) && (t->scr.grid->selection_start.col == t->scr.grid->selection_end.col)) {
+ XSetSelectionOwner(w->dpy, XA_PRIMARY, None, time);
+ w->has_selection = 0;
+ }
+ else {
+ XSetSelectionOwner(w->dpy, XA_PRIMARY, w->w, time);
+ w->has_selection = (XGetSelectionOwner(w->dpy, XA_PRIMARY) == w->w);
+ }
}
static struct runes_loc runes_window_backend_get_mouse_position(
@@ -946,3 +967,49 @@ static void runes_window_backend_handle_selection_notify_event(
XFree(buf);
}
}
+
+static void runes_window_backend_handle_selection_clear_event(
+ RunesTerm *t, XSelectionClearEvent *e)
+{
+ RunesWindowBackend *w = &t->w;
+
+ UNUSED(e);
+
+ w->has_selection = 0;
+}
+
+static void runes_window_backend_handle_selection_request_event(
+ RunesTerm *t, XSelectionRequestEvent *e)
+{
+ RunesWindowBackend *w = &t->w;
+ XSelectionEvent selection;
+
+ selection.type = SelectionNotify;
+ selection.serial = e->serial;
+ selection.send_event = e->send_event;
+ selection.display = e->display;
+ selection.requestor = e->requestor;
+ selection.selection = e->selection;
+ selection.target = e->target;
+ selection.property = e->property;
+ selection.time = e->time;
+
+ if (e->target == XA_STRING || e->target == w->atoms[RUNES_ATOM_UTF8_STRING]) {
+ char *contents;
+ size_t len;
+
+ runes_screen_get_string(
+ t, &t->scr.grid->selection_start, &t->scr.grid->selection_end,
+ &contents, &len);
+ XChangeProperty(
+ w->dpy, e->requestor, e->property,
+ e->target, 8, PropModeReplace,
+ (unsigned char *)contents, len);
+ free(contents);
+ }
+ else {
+ selection.property = None;
+ }
+
+ XSendEvent(w->dpy, e->requestor, False, NoEventMask, (XEvent *)&selection);
+}
diff --git a/src/window-xlib.h b/src/window-xlib.h
index 70f7516..10d3417 100644
--- a/src/window-xlib.h
+++ b/src/window-xlib.h
@@ -28,6 +28,7 @@ struct runes_window {
Atom atoms[RUNES_NUM_ATOMS];
char visual_bell_is_ringing: 1;
+ char has_selection: 1;
};
typedef struct {