forked from enlightenment/efl
Lots of overdue selections code.
- Pasting works, but has a little data size-related bug that will be fixed soon. A work around would be to use the returned size (len) to determine the correct data length but this should be done within ecore itself. - Copy code isn't working yet SVN revision: 8332
This commit is contained in:
parent
814b888746
commit
8fcfc53754
|
@ -22,6 +22,19 @@ extern "C" {
|
|||
typedef void Ecore_X_Reply;
|
||||
#endif
|
||||
|
||||
typedef enum _Ecore_X_Selection_Target {
|
||||
ECORE_X_SELECTION_TARGET_FILENAME,
|
||||
ECORE_X_SELECTION_TARGET_STRING,
|
||||
ECORE_X_SELECTION_TARGET_UTF8_STRING,
|
||||
ECORE_X_SELECTION_TARGET_TEXT
|
||||
} Ecore_X_Selection_Target;
|
||||
|
||||
typedef enum _Ecore_X_Selection {
|
||||
ECORE_X_SELECTION_PRIMARY,
|
||||
ECORE_X_SELECTION_SECONDARY,
|
||||
ECORE_X_SELECTION_CLIPBOARD
|
||||
} Ecore_X_Selection;
|
||||
|
||||
typedef enum _Ecore_X_Event_Mode
|
||||
{
|
||||
ECORE_X_EVENT_MODE_NORMAL,
|
||||
|
@ -358,8 +371,10 @@ struct _Ecore_X_Event_Selection_Request
|
|||
|
||||
struct _Ecore_X_Event_Selection_Notify
|
||||
{
|
||||
Ecore_X_Window win;
|
||||
Ecore_X_Window time;
|
||||
Ecore_X_Window win;
|
||||
Ecore_X_Time time;
|
||||
Ecore_X_Selection selection;
|
||||
Ecore_X_Selection_Target target;
|
||||
};
|
||||
|
||||
struct _Ecore_X_Event_Client_Message
|
||||
|
@ -553,13 +568,6 @@ typedef enum _Ecore_X_Window_State {
|
|||
|
||||
} Ecore_X_Window_State;
|
||||
|
||||
typedef enum _Ecore_X_Selection_Target {
|
||||
ECORE_X_SELECTION_TARGET_FILENAME,
|
||||
ECORE_X_SELECTION_TARGET_STRING,
|
||||
ECORE_X_SELECTION_TARGET_UTF8_STRING,
|
||||
ECORE_X_SELECTION_TARGET_TEXT
|
||||
} Ecore_X_Selection_Target;
|
||||
|
||||
int ecore_x_init(const char *name);
|
||||
int ecore_x_shutdown(void);
|
||||
Ecore_X_Display *ecore_x_display_get(void);
|
||||
|
@ -581,6 +589,16 @@ int ecore_x_selection_secondary_set(Ecore_X_Window w, char *data, i
|
|||
int ecore_x_selection_secondary_clear(void);
|
||||
int ecore_x_selection_clipboard_set(Ecore_X_Window w, char *data, int len);
|
||||
int ecore_x_selection_clipboard_clear(void);
|
||||
void ecore_x_selection_primary_request(Ecore_X_Window w, Ecore_X_Selection_Target t);
|
||||
void ecore_x_selection_secondary_request(Ecore_X_Window w, Ecore_X_Selection_Target t);
|
||||
void ecore_x_selection_clipboard_request(Ecore_X_Window w, Ecore_X_Selection_Target t);
|
||||
void ecore_x_selection_primary_request_data_get(void **buf, int *len);
|
||||
void ecore_x_selection_secondary_request_data_get(void **buf, int *len);
|
||||
void ecore_x_selection_clipboard_request_data_get(void **buf, int *len);
|
||||
Ecore_X_Selection_Target
|
||||
ecore_x_selection_target_get(Ecore_X_Atom target);
|
||||
char * ecore_x_selection_convert_to_string(char *data);
|
||||
char * ecore_x_selection_convert_to_utf8_string(char *data);
|
||||
|
||||
Ecore_X_Window ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h);
|
||||
Ecore_X_Window ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h);
|
||||
|
|
|
@ -848,21 +848,108 @@ _ecore_x_event_handle_property_notify(XEvent *xevent)
|
|||
void
|
||||
_ecore_x_event_handle_selection_clear(XEvent *xevent)
|
||||
{
|
||||
/* FIXME: handle this event type */
|
||||
/* This should wrap all the netwm property changes as well as ICCCM, */
|
||||
/* the old gnomewm and kde hints, mwm hints and more */
|
||||
Ecore_X_Selection_Data *d;
|
||||
|
||||
if(!(d = _ecore_x_selection_get(xevent->xselectionclear.selection)))
|
||||
return;
|
||||
if (xevent->xselectionclear.time > d->time)
|
||||
{
|
||||
_ecore_x_selection_set(None, NULL, 0,
|
||||
xevent->xselectionclear.selection);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_x_event_handle_selection_request(XEvent *xevent)
|
||||
{
|
||||
/* FIXME: handle this event type */
|
||||
Ecore_X_Event_Selection_Request *e;
|
||||
Ecore_X_Selection_Data *sd;
|
||||
XSelectionEvent xnotify;
|
||||
XEvent *xev;
|
||||
char *data;
|
||||
|
||||
e = calloc(1, sizeof(Ecore_X_Event_Selection_Request));
|
||||
e->win = xevent->xselectionrequest.requestor;
|
||||
e->time = xevent->xselectionrequest.time;
|
||||
|
||||
xev = calloc(1, sizeof(XEvent));
|
||||
|
||||
xnotify.requestor = xevent->xselectionrequest.requestor;
|
||||
xnotify.selection = xevent->xselectionrequest.selection;
|
||||
xnotify.target = xevent->xselectionrequest.target;
|
||||
xnotify.time = CurrentTime;
|
||||
|
||||
if((sd = _ecore_x_selection_get(xnotify.selection))
|
||||
&& (sd->win == xevent->xselectionrequest.owner))
|
||||
{
|
||||
/* FIXME: Provide API for user-defined conversion functions */
|
||||
if (xnotify.target == _ecore_x_atom_string)
|
||||
data = ecore_x_selection_convert_to_string(sd->data);
|
||||
else if (xnotify.target == _ecore_x_atom_utf8_string)
|
||||
data = ecore_x_selection_convert_to_utf8_string(sd->data);
|
||||
else
|
||||
data = sd->data;
|
||||
|
||||
/* FIXME: This does not properly handle large data transfers */
|
||||
ecore_x_window_prop_property_set(e->win,
|
||||
xevent->xselectionrequest.property,
|
||||
xevent->xselectionrequest.target,
|
||||
8, data, sd->length);
|
||||
xnotify.property = xevent->xselectionrequest.property;
|
||||
}
|
||||
else
|
||||
{
|
||||
xnotify.property = None;
|
||||
return;
|
||||
}
|
||||
|
||||
xev->xselection = xnotify;
|
||||
XSendEvent(_ecore_x_disp, e->win, False, 0, xev);
|
||||
/* FIXME: We alloc e but we never actually add it to the event
|
||||
* queue -- should it be freed or is it still useful? */
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_x_event_handle_selection_notify(XEvent *xevent)
|
||||
{
|
||||
/* FIXME: handle this event type */
|
||||
Ecore_X_Event_Selection_Notify *e;
|
||||
unsigned char *data = NULL;
|
||||
Atom selection;
|
||||
int num_ret;
|
||||
Ecore_X_Selection_Data sel_data;
|
||||
|
||||
e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
|
||||
e->win = xevent->xselection.requestor;
|
||||
e->time = xevent->xselection.time;
|
||||
e->target = ecore_x_selection_target_get(xevent->xselection.target);
|
||||
selection = xevent->xselection.selection;
|
||||
if (selection == _ecore_x_atom_selection_primary)
|
||||
e->selection = ECORE_X_SELECTION_PRIMARY;
|
||||
else if (selection == _ecore_x_atom_selection_secondary)
|
||||
e->selection = ECORE_X_SELECTION_SECONDARY;
|
||||
else if (selection == _ecore_x_atom_selection_clipboard)
|
||||
e->selection = ECORE_X_SELECTION_CLIPBOARD;
|
||||
else
|
||||
{
|
||||
free(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ecore_x_window_prop_property_get(e->win, xevent->xselection.property,
|
||||
AnyPropertyType, 8, &data, &num_ret))
|
||||
{
|
||||
free(e);
|
||||
return;
|
||||
}
|
||||
|
||||
sel_data.win = e->win;
|
||||
sel_data.selection = selection;
|
||||
sel_data.data = data;
|
||||
sel_data.length = num_ret;
|
||||
_ecore_x_selection_request_data_set(sel_data);
|
||||
ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_generic, NULL);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -42,6 +42,7 @@ struct _Ecore_X_Selection_Data
|
|||
Atom selection;
|
||||
char *data;
|
||||
int length;
|
||||
Time time;
|
||||
};
|
||||
|
||||
typedef enum _Ecore_X_WM_Protocol {
|
||||
|
@ -169,4 +170,8 @@ void _ecore_x_event_handle_client_message(XEvent *xevent);
|
|||
void _ecore_x_event_handle_mapping_notify(XEvent *xevent);
|
||||
void _ecore_x_event_handle_shape_change(XEvent *xevent);
|
||||
|
||||
void _ecore_x_selection_request_data_set(Ecore_X_Selection_Data data);
|
||||
Ecore_X_Selection_Data * _ecore_x_selection_get(Atom selection);
|
||||
int _ecore_x_selection_set(Window w, char *data, int len, Atom selection);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,48 +1,170 @@
|
|||
#include <Ecore.h>
|
||||
#include "ecore_x_private.h"
|
||||
#include <Ecore_X.h>
|
||||
#include <Ecore_Txt.h>
|
||||
|
||||
static int _ecore_x_selection_set(Ecore_X_Window w, char *data, int len, Ecore_X_Atom selection)
|
||||
/* FIXME: Initialize! */
|
||||
static Ecore_X_Selection_Data selections[3];
|
||||
static Ecore_X_Selection_Data request_data[3];
|
||||
|
||||
static void
|
||||
_ecore_x_selection_request_data_get(Ecore_X_Atom selection, void **buf, int *len)
|
||||
{
|
||||
int i;
|
||||
char *data;
|
||||
if (selection == _ecore_x_atom_selection_primary)
|
||||
i = 0;
|
||||
else if (selection == _ecore_x_atom_selection_secondary)
|
||||
i = 1;
|
||||
else if (selection == _ecore_x_atom_selection_clipboard)
|
||||
i = 2;
|
||||
else
|
||||
return;
|
||||
|
||||
if (!request_data[i].data || !request_data[i].length)
|
||||
{
|
||||
*len = 0;
|
||||
*buf = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
data = malloc(request_data[i].length);
|
||||
memcpy(data, request_data[i].data, request_data[i].length);
|
||||
*len = request_data[i].length;
|
||||
*buf = data;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ecore_x_selection_primary_request_data_get(void **buf, int *len)
|
||||
{
|
||||
_ecore_x_selection_request_data_get(_ecore_x_atom_selection_primary,
|
||||
buf, len);
|
||||
}
|
||||
|
||||
void
|
||||
ecore_x_selection_secondary_request_data_get(void **buf, int *len)
|
||||
{
|
||||
_ecore_x_selection_request_data_get(_ecore_x_atom_selection_secondary,
|
||||
buf, len);
|
||||
}
|
||||
|
||||
void
|
||||
ecore_x_selection_clipboard_request_data_get(void **buf, int *len)
|
||||
{
|
||||
_ecore_x_selection_request_data_get(_ecore_x_atom_selection_clipboard,
|
||||
buf, len);
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_x_selection_request_data_set(Ecore_X_Selection_Data data)
|
||||
{
|
||||
int i;
|
||||
if (data.selection == _ecore_x_atom_selection_primary)
|
||||
i = 0;
|
||||
else if (data.selection == _ecore_x_atom_selection_secondary)
|
||||
i = 1;
|
||||
else if (data.selection == _ecore_x_atom_selection_clipboard)
|
||||
i = 2;
|
||||
else
|
||||
return;
|
||||
|
||||
request_data[i] = data;
|
||||
}
|
||||
|
||||
Ecore_X_Selection_Data *
|
||||
_ecore_x_selection_get(Atom selection)
|
||||
{
|
||||
if (selection == _ecore_x_atom_selection_primary)
|
||||
return &selections[0];
|
||||
else if (selection == _ecore_x_atom_selection_secondary)
|
||||
return &selections[1];
|
||||
else if (selection == _ecore_x_atom_selection_clipboard)
|
||||
return &selections[2];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
_ecore_x_selection_set(Window w, char *data, int len, Atom selection)
|
||||
{
|
||||
int in;
|
||||
char *buf = NULL;
|
||||
|
||||
XSetSelectionOwner(_ecore_x_disp, selection, w, _ecore_x_event_last_time);
|
||||
if (XGetSelectionOwner(_ecore_x_disp, selection) != w)
|
||||
return 0;
|
||||
|
||||
if (selection == _ecore_x_atom_selection_primary)
|
||||
in = 0;
|
||||
else if (selection == _ecore_x_atom_selection_secondary)
|
||||
in = 1;
|
||||
else
|
||||
in = 2;
|
||||
|
||||
if (data)
|
||||
{
|
||||
selections[in].win = w;
|
||||
selections[in].selection = selection;
|
||||
selections[in].length = len;
|
||||
selections[in].time = _ecore_x_event_last_time;
|
||||
|
||||
buf = malloc(sizeof(char) * len);
|
||||
memcpy(buf, data, sizeof(char) * len);
|
||||
selections[in].data = buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selections[in].data)
|
||||
{
|
||||
free(selections[in].data);
|
||||
memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data));
|
||||
}
|
||||
}
|
||||
|
||||
/* ecore_x_window_prop_property_set(_ecore_x_disp, w, selection,
|
||||
XA_STRING, 8, data, len); */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ecore_x_selection_primary_set(Ecore_X_Window w, char *data, int len)
|
||||
int
|
||||
ecore_x_selection_primary_set(Ecore_X_Window w, char *data, int len)
|
||||
{
|
||||
return _ecore_x_selection_set(w, data, len, _ecore_x_atom_selection_primary);
|
||||
}
|
||||
|
||||
int ecore_x_selection_primary_clear(void)
|
||||
int
|
||||
ecore_x_selection_primary_clear(void)
|
||||
{
|
||||
return _ecore_x_selection_set(None, NULL, 0, _ecore_x_atom_selection_primary);
|
||||
}
|
||||
|
||||
int ecore_x_selection_secondary_set(Ecore_X_Window w, char *data, int len)
|
||||
int
|
||||
ecore_x_selection_secondary_set(Ecore_X_Window w, char *data, int len)
|
||||
{
|
||||
return _ecore_x_selection_set(w, data, len, _ecore_x_atom_selection_secondary);
|
||||
}
|
||||
|
||||
int ecore_x_selection_secondary_clear(void)
|
||||
int
|
||||
ecore_x_selection_secondary_clear(void)
|
||||
{
|
||||
return _ecore_x_selection_set(None, NULL, 0, _ecore_x_atom_selection_secondary);
|
||||
}
|
||||
|
||||
int ecore_x_selection_clipboard_set(Ecore_X_Window w, char *data, int len)
|
||||
int
|
||||
ecore_x_selection_clipboard_set(Ecore_X_Window w, char *data, int len)
|
||||
{
|
||||
return _ecore_x_selection_set(w, data, len, _ecore_x_atom_selection_clipboard);
|
||||
}
|
||||
|
||||
int ecore_x_selection_clipboard_clear(void)
|
||||
int
|
||||
ecore_x_selection_clipboard_clear(void)
|
||||
{
|
||||
return _ecore_x_selection_set(None, NULL, 0, _ecore_x_atom_selection_clipboard);
|
||||
}
|
||||
|
||||
static void _ecore_x_selection_request(Ecore_X_Window w, Ecore_X_Atom selection, Ecore_X_Selection_Target t)
|
||||
static void
|
||||
_ecore_x_selection_request(Ecore_X_Window w, Ecore_X_Atom selection, Ecore_X_Selection_Target t)
|
||||
{
|
||||
Ecore_X_Atom target, prop;
|
||||
|
||||
|
@ -74,18 +196,50 @@ static void _ecore_x_selection_request(Ecore_X_Window w, Ecore_X_Atom selection,
|
|||
w, _ecore_x_event_last_time);
|
||||
}
|
||||
|
||||
void ecore_x_selection_primary_request(Ecore_X_Window w, Ecore_X_Selection_Target t)
|
||||
void
|
||||
ecore_x_selection_primary_request(Ecore_X_Window w, Ecore_X_Selection_Target t)
|
||||
{
|
||||
_ecore_x_selection_request(w, _ecore_x_atom_selection_primary, t);
|
||||
}
|
||||
|
||||
void ecore_x_selection_secondary_request(Ecore_X_Window w, Ecore_X_Selection_Target t)
|
||||
void
|
||||
ecore_x_selection_secondary_request(Ecore_X_Window w, Ecore_X_Selection_Target t)
|
||||
{
|
||||
_ecore_x_selection_request(w, _ecore_x_atom_selection_secondary, t);
|
||||
}
|
||||
|
||||
void ecore_x_selection_clipboard_request(Ecore_X_Window w, Ecore_X_Selection_Target t)
|
||||
void
|
||||
ecore_x_selection_clipboard_request(Ecore_X_Window w, Ecore_X_Selection_Target t)
|
||||
{
|
||||
_ecore_x_selection_request(w, _ecore_x_atom_selection_clipboard, t);
|
||||
}
|
||||
|
||||
char *
|
||||
ecore_x_selection_convert_to_string(char *data)
|
||||
{
|
||||
/* FIXME: Do something */
|
||||
return data;
|
||||
}
|
||||
|
||||
char *
|
||||
ecore_x_selection_convert_to_utf8_string(char *data)
|
||||
{
|
||||
/* FIXME: Do something */
|
||||
return data;
|
||||
}
|
||||
|
||||
Ecore_X_Selection_Target
|
||||
ecore_x_selection_target_get(Ecore_X_Atom target)
|
||||
{
|
||||
if (target == _ecore_x_atom_file_name)
|
||||
return ECORE_X_SELECTION_TARGET_FILENAME;
|
||||
else if (target == _ecore_x_atom_string)
|
||||
return ECORE_X_SELECTION_TARGET_STRING;
|
||||
else if (target == _ecore_x_atom_utf8_string)
|
||||
return ECORE_X_SELECTION_TARGET_UTF8_STRING;
|
||||
else if (target == _ecore_x_atom_text)
|
||||
return ECORE_X_SELECTION_TARGET_TEXT;
|
||||
else
|
||||
return ECORE_X_SELECTION_TARGET_TEXT;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue