diff --git a/legacy/ecore/src/Ecore.h b/legacy/ecore/src/Ecore.h index 409b81b019..7d89035875 100644 --- a/legacy/ecore/src/Ecore.h +++ b/legacy/ecore/src/Ecore.h @@ -182,6 +182,9 @@ void e_window_ignore(Window win); void e_window_no_ignore(Window win); int e_window_is_ignored(Window win); Window e_window_get_at_xy(int x, int y); + +char *e_selection_get_data(Window win, Atom prop); + int e_window_dnd_capable(Window win); void e_window_dnd_handle_motion(Window source_win, int x, int y, @@ -270,7 +273,9 @@ void e_window_stack_below(Window win, Window below); char *e_window_get_title(Window win); void e_keyboard_grab(Window win); void e_keyboard_ungrab(void); - + +Window e_selection_request(void); + typedef struct _eev Eevent; typedef struct _ev_fd_handler Ev_Fd_Handler; typedef struct _ev_pid_handler Ev_Pid_Handler; @@ -314,6 +319,7 @@ typedef struct _ev_dnd_drop_position Ev_Dnd_Drop_Position; typedef struct _ev_dnd_drop Ev_Dnd_Drop; typedef struct _ev_dnd_drop_status Ev_Dnd_Drop_Status; typedef struct _ev_dnd_data_request Ev_Dnd_Data_Request; +typedef struct _ev_paste_request Ev_Paste_Request; enum _eev_stack_detail { @@ -371,6 +377,7 @@ enum _eev_type EV_DND_DROP, EV_DND_DROP_STATUS, EV_DND_DATA_REQUEST, + EV_PASTE_REQUEST, EV_CHILD, EV_USER, @@ -622,6 +629,13 @@ struct _ev_window_delete Window win, root; }; +struct _ev_paste_request +{ + Window win, root, source_win; + char *string; +}; + + struct _ev_dnd_drop_request { Window win, root, source_win; diff --git a/legacy/ecore/src/e_ev_x.c b/legacy/ecore/src/e_ev_x.c index 6d76d73373..fdc4687030 100644 --- a/legacy/ecore/src/e_ev_x.c +++ b/legacy/ecore/src/e_ev_x.c @@ -11,6 +11,7 @@ static void e_ev_key_down_free(void *event); static void e_ev_key_up_free(void *event); static void e_ev_generic_free(void *event); static void e_ev_dnd_drop_request_free(void *event); +static void e_ev_paste_request_free(void *event); static void e_ev_x_handle_key_press(XEvent * xevent); static void e_ev_x_handle_key_release(XEvent * xevent); @@ -97,7 +98,6 @@ e_ev_x_init(void) event_translator[ClientMessage] = e_ev_x_handle_client_message; event_translator[SelectionNotify] = e_ev_x_handle_selection_notify; event_translator[SelectionRequest] = e_ev_x_handle_selection_request; - for (i = SelectionRequest + 1; i < shape_event_id; i++) event_translator[i] = NULL; event_translator[shape_event_id] = e_ev_x_handle_shape_change; lock_mask_scroll = e_lock_mask_scroll_get(); @@ -226,6 +226,16 @@ e_ev_dnd_drop_request_free(void *event) FREE(event); } +static void +e_ev_paste_request_free(void *event) +{ + Ev_Paste_Request *e; + + e = (Ev_Paste_Request *) event; + IF_FREE(e->string); + FREE(event); +} + static void e_ev_x_handle_key_press(XEvent * xevent) { @@ -780,7 +790,25 @@ e_ev_x_handle_selection_notify(XEvent * xevent) e = ev_drop_request_pending; if (!e) - return; + { + Ev_Paste_Request *e2; + + e2 = NEW(Ev_Paste_Request, 1); + e2->string = e_selection_get_data(xevent->xselection.requestor, + xevent->xselection.property); + if (e2->string) + { + e2->win = xevent->xselection.requestor; + e2->root = e_window_get_root(e2->win); + e2->source_win = xevent->xselection.requestor; + e_add_event(EV_PASTE_REQUEST, e2, e_ev_paste_request_free); + } + else + { + FREE(e2); + } + return; + } E_ATOM(atom_xdndactioncopy, "XdndActionCopy"); E_ATOM(atom_xdndactionmove, "XdndActionMove"); diff --git a/legacy/ecore/src/e_x.c b/legacy/ecore/src/e_x.c index 00be63031d..eff2da9c2b 100644 --- a/legacy/ecore/src/e_x.c +++ b/legacy/ecore/src/e_x.c @@ -1766,7 +1766,7 @@ e_window_dnd_capable(Window win) E_ATOM(atom_xdndaware, "XdndAware"); atom_ret = e_window_property_get(win, atom_xdndaware, XA_ATOM, &size); - if ((atom_ret) && (size >= sizeof(int))) + if ((atom_ret) && (size >= (int)sizeof(int))) { if (atom_ret[0] == dnd_version) { @@ -2890,3 +2890,110 @@ e_keyboard_ungrab(void) keyboard_grab_win = 0; XUngrabKeyboard(disp, CurrentTime); } + +#ifdef XA_CLIPBOARD +#define X_CLIPBOARD_SELECTION XA_CLIPBOARD(disp) +#define X_CLIPBOARD_PROP XA_CLIPBOARD(disp) +#else +#define X_CLIPBOARD_SELECTION XA_PRIMARY +#define X_CLIPBOARD_PROP XA_CUT_BUFFER0 +#endif + +Window +e_selection_request(void) +{ + Atom selection, dest = 0; + static Window target = 0; + + selection = X_CLIPBOARD_SELECTION; + E_ATOM(dest, "TEXT_SELECTION"); + target = e_window_new(0, 0, 0, 7, 77); + e_window_add_events(target, + XEV_CONFIGURE | XEV_PROPERTY); + XConvertSelection(disp, XA_PRIMARY, + XA_STRING, dest, + target, + CurrentTime); + return target; +} + +char * +e_selection_get_data(Window win, Atom prop) +{ + char *string = NULL; + long nread; + unsigned long bytes_after, nitems; + unsigned char *data; + Atom actual_type; + int actual_fmt; + + if (prop == None) + return NULL; + for (nread = 0, bytes_after = 1; bytes_after > 0;) + { + if ((XGetWindowProperty(disp, win, prop, nread / 4, + 0x10000, True, AnyPropertyType, + &actual_type, &actual_fmt, &nitems, + &bytes_after, &data) != Success)) + { + IF_FREE(string); + if (data) + { + XFree(data); + } + return NULL; + } + nread += nitems; + + if (actual_type == XA_STRING) + { + if (string) + string = realloc(string, strlen(string) + nitems + 1); + else + { + string = malloc(nitems + 1); + string[0] = 0; + } + string[strlen(string) + nitems] = 0; + strncat(string, data, nitems); + } + else + { + int size, i; + XTextProperty xtextp; + char **cl = NULL; + + xtextp.value = data; + xtextp.encoding = actual_type; + xtextp.format = actual_fmt; + xtextp.nitems = nitems; + XmbTextPropertyToTextList(disp, &xtextp, &cl, &size); + + if (cl) + { + for (i = 0 ; i < size ; i ++) + { + if (cl[i]) + { + if (string) + string = realloc(string, strlen(string) + strlen(cl[i]) + 1); + else + { + string = malloc(strlen(cl[i]) + 1); + string[0] = 0; + } + string[strlen(string) + strlen(cl[i])] = 0; + strcat(string, cl[i]); + } + } + XFreeStringList(cl); + } + } + if (data) + { + XFree(data); + } + } + return string; +} +