efl/legacy/ecore/src/lib/ecore_x/ecore_x_selection.c

463 lines
12 KiB
C
Raw Normal View History

#include <Ecore.h>
#include "ecore_x_private.h"
#include <Ecore_X.h>
#include <Ecore_Txt.h>
/* FIXME: Initialize! */
static Ecore_X_Selection_Data selections[3];
static Ecore_X_Selection_Data request_data[3];
static Ecore_X_Selection_Converter *converters;
static int _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret);
void
_ecore_x_selection_data_initialize(void)
{
memset(selections, 0, sizeof(selections));
memset(request_data, 0, sizeof(request_data));
/* Initialize converters */
converters = NULL;
ecore_x_selection_converter_atom_add(_ecore_x_atom_text,
_ecore_x_selection_converter_text);
ecore_x_selection_converter_atom_add(_ecore_x_atom_compound_text,
_ecore_x_selection_converter_text);
ecore_x_selection_converter_atom_add(_ecore_x_atom_string,
_ecore_x_selection_converter_text);
}
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)
{
return _ecore_x_selection_set(w, data, len, _ecore_x_atom_selection_primary);
}
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)
{
return _ecore_x_selection_set(w, data, len, _ecore_x_atom_selection_secondary);
}
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)
{
return _ecore_x_selection_set(w, data, len, _ecore_x_atom_selection_clipboard);
}
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)
{
Ecore_X_Atom target, prop;
switch (t) {
case ECORE_X_SELECTION_TARGET_FILENAME:
target = _ecore_x_atom_file_name;
break;
case ECORE_X_SELECTION_TARGET_STRING:
target = _ecore_x_atom_string;
break;
case ECORE_X_SELECTION_TARGET_UTF8_STRING:
target = _ecore_x_atom_utf8_string;
break;
case ECORE_X_SELECTION_TARGET_TEXT:
target = _ecore_x_atom_text;
break;
default:
target = _ecore_x_atom_text;
}
if (selection == _ecore_x_atom_selection_primary)
prop = _ecore_x_atom_selection_prop_primary;
else if (selection == _ecore_x_atom_selection_secondary)
prop = _ecore_x_atom_selection_prop_secondary;
else
prop = _ecore_x_atom_selection_prop_clipboard;
XConvertSelection(_ecore_x_disp, selection, target, prop,
w, _ecore_x_event_last_time);
}
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)
{
_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)
{
_ecore_x_selection_request(w, _ecore_x_atom_selection_clipboard, t);
}
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;
}
void
ecore_x_selection_converter_atom_add(Ecore_X_Atom target,
int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret))
{
Ecore_X_Selection_Converter *cnv;
cnv = converters;
if (converters)
{
while (1)
{
if (cnv->target == target)
{
cnv->convert = func;
return;
}
if (cnv->next)
cnv = cnv->next;
else
break;
}
cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter));
cnv = cnv->next;
} else {
converters = calloc(1, sizeof(Ecore_X_Selection_Converter));
cnv = converters;
}
cnv->target = target;
cnv->convert = func;
}
void
ecore_x_selection_converter_add(char *target,
int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret))
{
Ecore_X_Atom x_target;
char *atom_name;
if (!func || !target)
return;
/* FIXME: Some of these are just made up because I can't find
* standard "mime type" strings for them at the moment" */
if (!strcmp(target, "TEXT"))
x_target = _ecore_x_atom_text;
else if (!strcmp(target, "COMPOUND_TEXT"))
x_target = _ecore_x_atom_compound_text;
else if (!strcmp(target, "STRING"))
x_target = _ecore_x_atom_string;
else if (!strcmp(target, "UTF8_STRING"))
x_target = _ecore_x_atom_utf8_string;
else if (!strcmp(target, "FILENAME"))
x_target = _ecore_x_atom_file_name;
else
{
atom_name = malloc(strlen(target) + 4);
sprintf(atom_name, "_E_%s", target);
x_target = XInternAtom(_ecore_x_disp, atom_name, False);
}
ecore_x_selection_converter_atom_add(x_target, func);
}
void
ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
{
Ecore_X_Selection_Converter *cnv, *prev_cnv;
prev_cnv = NULL;
cnv = converters;
while (cnv)
{
if (cnv->target == target)
{
if (target == _ecore_x_atom_text ||
target == _ecore_x_atom_compound_text ||
target == _ecore_x_atom_string)
{
cnv->convert = _ecore_x_selection_converter_text;
}
else
{
if(prev_cnv)
prev_cnv->next = cnv->next;
else
converters = NULL; /* This was the only converter */
free(cnv);
}
return;
}
prev_cnv = cnv;
cnv = cnv->next;
}
}
void
ecore_x_selection_converter_del(char *target)
{
Ecore_X_Atom x_target;
char *atom_name;
if (!target)
return;
if (!strcmp(target, "TEXT"))
x_target = _ecore_x_atom_text;
else if (!strcmp(target, "COMPOUND_TEXT"))
x_target = _ecore_x_atom_compound_text;
else if (!strcmp(target, "STRING"))
x_target = _ecore_x_atom_string;
else if (!strcmp(target, "UTF8_STRING"))
x_target = _ecore_x_atom_utf8_string;
else if (!strcmp(target, "FILENAME"))
x_target = _ecore_x_atom_file_name;
else
{
atom_name = malloc(strlen(target) + 4);
sprintf(atom_name, "_E_%s", target);
x_target = XInternAtom(_ecore_x_disp, atom_name, False);
}
ecore_x_selection_converter_atom_del(x_target);
}
/* Locate and run conversion callback for specified selection target */
int
_ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret)
{
Ecore_X_Selection_Data *sel;
Ecore_X_Selection_Converter *cnv;
void *data;
int size;
char *tgt_str;
sel = _ecore_x_selection_get(selection);
/* COMPOUND_TEXT will be the default format for text requests */
if (target == _ecore_x_atom_text)
tgt_str = strdup("TEXT");
else if (target == _ecore_x_atom_compound_text)
tgt_str = strdup("COMPOUND_TEXT");
else if (target == _ecore_x_atom_string)
tgt_str = strdup("STRING");
else if (target == _ecore_x_atom_utf8_string)
tgt_str = strdup("UTF8_STRING");
else if (target == _ecore_x_atom_file_name)
tgt_str = strdup("FILENAME");
else
{
char *atom_name = XGetAtomName(_ecore_x_disp, target);
tgt_str = strdup(atom_name);
XFree(atom_name);
}
for (cnv = converters; cnv; cnv = cnv->next)
{
if (cnv->target == target)
{
int r;
r = cnv->convert(tgt_str, sel->data, sel->length, &data, &size);
if (r)
{
*data_ret = data;
return r;
}
else
return -1;
}
}
return -1;
}
/* Converter for standard non-utf8 text targets */
static int _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret)
{
XTextProperty text_prop;
char *mystr;
XICCEncodingStyle style;
if (!data || !size)
return 0;
if (!strcmp(target, "TEXT"))
style = XTextStyle;
else if (!strcmp(target, "COMPOUND_TEXT"))
style = XCompoundTextStyle;
else if (!strcmp(target, "STRING"))
style = XStringStyle;
else
return 0;
mystr = strdup(data);
if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success)
{
int bufsize = strlen(text_prop.value) + 1;
*data_ret = malloc(bufsize);
memcpy(*data_ret, text_prop.value, bufsize);
*size_ret = bufsize;
XFree(text_prop.value);
return 1;
}
else
return 0;
}