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:
xcomputerman 2004-01-10 21:01:18 +00:00 committed by xcomputerman
parent 814b888746
commit 8fcfc53754
4 changed files with 289 additions and 25 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}