summaryrefslogtreecommitdiff
path: root/ecore/src/e_x.c
diff options
context:
space:
mode:
Diffstat (limited to 'ecore/src/e_x.c')
-rw-r--r--ecore/src/e_x.c3610
1 files changed, 3610 insertions, 0 deletions
diff --git a/ecore/src/e_x.c b/ecore/src/e_x.c
new file mode 100644
index 0000000..b3d8069
--- /dev/null
+++ b/ecore/src/e_x.c
@@ -0,0 +1,3610 @@
+#include "Ecore.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#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
+
+typedef struct _window_list Window_List;
+
+struct _window_list
+{
+ Window win;
+ Window_List *next;
+};
+
+XContext xid_context = 0;
+
+static Display *disp;
+static Visual *default_vis;
+static Colormap default_cm;
+static int default_depth;
+static Window default_win;
+static Window default_root;
+
+static int lock_scroll = 0;
+static int lock_num = 0;
+static int lock_caps = 0;
+
+static Window focused_win = 0;
+
+static int mod_shift = 0;
+static int mod_ctrl = 0;
+static int mod_alt = 0;
+static int mod_win = 0;
+
+static Window grabkey_win = 0;
+
+static int mouse_x = 0, mouse_y = 0;
+
+static Window current_dnd_win = 0;
+static int current_dnd_target_ok = 0;
+static int dnd_await_target_status = 0;
+
+static int x_grabs = 0;
+
+static Window_List *ignore_wins = NULL;
+
+static Window grab_pointer_win = 0;
+
+static Window keyboard_grab_win = 0;
+
+static int dnd_copy = 0;
+static int dnd_link = 0;
+static int dnd_move = 1;
+
+static void ecore_handle_x_error(Display * d, XErrorEvent * ev);
+static void ecore_handle_x_io_error(Display * d);
+static Window ecore_window_at_xy_0(Window base, int bx, int by, int x,
+ int y);
+
+static void
+ecore_handle_x_error(Display * d, XErrorEvent * ev)
+{
+/*
+ char err[16384];
+
+ XGetErrorText(d, ev->error_code, err, 16000);
+ printf("X Error:\n"
+ "Error: %s\nrequest: %i\nminor: %i\n", err, ev->request_code, ev->minor_code);
+ */
+ /* ignore all X errors */
+ return;
+ d = NULL;
+ ev = NULL;
+}
+
+static void
+ecore_handle_x_io_error(Display * d)
+{
+ /* FIXME: call clean exit handler */
+ exit(1);
+ d = NULL;
+}
+
+void
+ecore_del_child(Window win, Window child)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ {
+ if (xid->children[i] == child)
+ {
+ int j;
+
+ for (j = i; j < xid->children_num - 1; j++)
+ xid->children[j] = xid->children[j + 1];
+ xid->children_num--;
+ REALLOC(xid->children, Window, xid->children_num);
+ return;
+ }
+ }
+ }
+}
+
+void
+ecore_add_child(Window win, Window child)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ {
+ if (xid->children[i] == child)
+ return;
+ }
+ xid->children_num++;
+ REALLOC(xid->children, Window, xid->children_num);
+ xid->children[xid->children_num - 1] = child;
+ }
+ xid = ecore_validate_xid(child);
+}
+
+void
+ecore_raise_child(Window win, Window child)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ {
+ if (xid->children[i] == child)
+ {
+ int j;
+
+ for (j = i; j < xid->children_num - 1; j++)
+ xid->children[j] = xid->children[j + 1];
+ xid->children[xid->children_num - 1] = child;
+ return;
+ }
+ }
+ }
+}
+
+void
+ecore_lower_child(Window win, Window child)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ {
+ if (xid->children[i] == child)
+ {
+ int j;
+
+ for (j = i; j > 0; j--)
+ xid->children[j] = xid->children[j - 1];
+ xid->children[0] = child;
+ return;
+ }
+ }
+ }
+}
+
+Ecore_XID *
+ecore_add_xid(Window win, int x, int y, int w, int h, int depth, Window parent)
+{
+ Ecore_XID *xid = NULL;
+
+ ecore_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE | XEV_VISIBILITY);
+ xid = NEW(Ecore_XID, 1);
+ xid->win = win;
+ xid->x = x;
+ xid->y = y;
+ xid->w = w;
+ xid->h = h;
+ xid->mapped = 0;
+ xid->depth = depth;
+ xid->mouse_in = 0;
+ xid->parent = parent;
+ xid->root = ecore_window_get_root(parent);
+ xid->children_num = 0;
+ xid->children = NULL;
+ xid->gravity = ecore_window_get_gravity(win);
+ xid->coords_invalid = 0;
+ xid->bw = 0;
+ xid->grab_button_auto_replay = NULL;
+ XSaveContext(disp, xid->win, xid_context, (XPointer) xid);
+ ecore_add_child(parent, win);
+ return xid;
+}
+
+Ecore_XID *
+ecore_validate_xid(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return NULL;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ {
+ XWindowAttributes att;
+ Window root_ret = 0, parent_ret = 0, *children_ret = NULL;
+ unsigned int children_ret_num = 0;
+
+ ecore_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE |
+ XEV_VISIBILITY | XEV_CHILD_CHANGE);
+ xid = NEW(Ecore_XID, 1);
+ xid->win = win;
+ if (!XGetWindowAttributes(disp, win, &att))
+ {
+ FREE(xid);
+ return NULL;
+ }
+ if (!XQueryTree(disp, win, &root_ret, &parent_ret, &children_ret,
+ &children_ret_num))
+ {
+ FREE(xid);
+ return NULL;
+ }
+ xid->parent = parent_ret;
+ if (xid->parent)
+ ecore_validate_xid(xid->parent);
+ if (children_ret)
+ {
+ xid->children_num = children_ret_num;
+ xid->children = NEW(Window, children_ret_num);
+ MEMCPY(children_ret, xid->children, Window, children_ret_num);
+ XFree(children_ret);
+ }
+ else
+ {
+ xid->children_num = 0;
+ xid->children = NULL;
+ }
+ xid->root = root_ret;
+ xid->x = att.x;
+ xid->y = att.y;
+ xid->w = att.width;
+ xid->h = att.height;
+ if (att.map_state == IsUnmapped)
+ xid->mapped = 0;
+ else
+ xid->mapped = 1;
+ xid->depth = att.depth;
+ xid->mouse_in = 0;
+ xid->gravity = att.win_gravity;
+ xid->bw = att.border_width;
+ xid->coords_invalid = 0;
+ xid->grab_button_auto_replay = NULL;
+ XSaveContext(disp, xid->win, xid_context, (XPointer) xid);
+ ecore_add_child(xid->parent, win);
+ }
+ return xid;
+}
+
+void
+ecore_unvalidate_xid(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ ecore_unvalidate_xid(xid->children[i]);
+ ecore_del_child(xid->parent, win);
+ IF_FREE(xid->children);
+ FREE(xid);
+ XDeleteContext(disp, win, xid_context);
+ }
+}
+
+void
+ecore_sync(void)
+{
+ if (!disp)
+ return;
+
+ XSync(disp, False);
+}
+
+void
+ecore_flush(void)
+{
+ if (!disp)
+ return;
+ XFlush(disp);
+}
+
+Window
+ecore_window_new(Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ if (!disp)
+ return 0;
+ if (!parent)
+ parent = default_root;
+ attr.backing_store = NotUseful;
+ attr.override_redirect = False;
+ attr.colormap = default_cm;
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = True;
+ win = XCreateWindow(disp, parent,
+ x, y, w, h, 0,
+ default_depth, InputOutput, default_vis,
+ CWOverrideRedirect | CWSaveUnder | CWBackingStore |
+ CWColormap | CWBackPixmap | CWBorderPixel |
+ CWDontPropagate, &attr);
+ ecore_add_xid(win, x, y, w, h, default_depth, parent);
+ ecore_add_child(parent, win);
+ ecore_validate_xid(parent);
+ return win;
+}
+
+Window
+ecore_window_override_new(Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ if (!disp)
+ return 0;
+ if (!parent)
+ parent = default_root;
+ attr.backing_store = NotUseful;
+ attr.override_redirect = True;
+ attr.colormap = default_cm;
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = True;
+ win = XCreateWindow(disp, parent,
+ x, y, w, h, 0,
+ default_depth, InputOutput, default_vis,
+ CWOverrideRedirect | CWSaveUnder | CWBackingStore |
+ CWColormap | CWBackPixmap | CWBorderPixel |
+ CWDontPropagate, &attr);
+ ecore_add_xid(win, x, y, w, h, default_depth, parent);
+ ecore_add_child(parent, win);
+ ecore_validate_xid(parent);
+ return win;
+}
+
+Window
+ecore_window_input_new(Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ if (!disp)
+ return 0;
+ if (!parent)
+ parent = default_root;
+ attr.override_redirect = True;
+ attr.do_not_propagate_mask = True;
+ win = XCreateWindow(disp, parent,
+ x, y, w, h, 0,
+ 0, InputOnly, default_vis,
+ CWOverrideRedirect | CWDontPropagate, &attr);
+ ecore_add_xid(win, x, y, w, h, 0, parent);
+ ecore_add_child(parent, win);
+ ecore_validate_xid(parent);
+ return win;
+}
+
+void
+ecore_window_set_events_propagate(Window win, int propagate)
+{
+ XSetWindowAttributes attr;
+
+ if (!disp)
+ return;
+ if (!win)
+ win = default_root;
+ if (!propagate)
+ attr.do_not_propagate_mask = True;
+ else
+ attr.do_not_propagate_mask = False;
+ XChangeWindowAttributes(disp, win, CWDontPropagate, &attr);
+}
+
+void
+ecore_window_show(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (xid->mapped)
+ return;
+ xid->mapped = 1;
+ XMapWindow(disp, win);
+ }
+}
+
+void
+ecore_window_hide(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (!xid->mapped)
+ return;
+ xid->mapped = 0;
+ XUnmapWindow(disp, win);
+ }
+}
+
+Pixmap
+ecore_pixmap_new(Window win, int w, int h, int dep)
+{
+ if (!disp)
+ return 0;
+ if (!win)
+ win = default_win;
+ if (dep == 0)
+ dep = default_depth;
+ return XCreatePixmap(disp, win, w, h, dep);
+}
+
+void
+ecore_pixmap_free(Pixmap pmap)
+{
+ if (!disp)
+ return;
+ if (!pmap)
+ return;
+ XFreePixmap(disp, pmap);
+}
+
+void
+ecore_window_set_background_pixmap(Window win, Pixmap pmap)
+{
+ if (!disp)
+ return;
+ if (win == 0)
+ win = default_root;
+ XSetWindowBackgroundPixmap(disp, win, pmap);
+}
+
+void
+ecore_window_set_shape_mask(Window win, Pixmap mask)
+{
+ if (!disp)
+ return;
+ XShapeCombineMask(disp, win, ShapeBounding, 0, 0, mask, ShapeSet);
+}
+
+void
+ecore_window_add_shape_mask(Window win, Pixmap mask)
+{
+ if (!disp)
+ return;
+ XShapeCombineMask(disp, win, ShapeBounding, 0, 0, mask, ShapeUnion);
+}
+
+void
+ecore_window_set_shape_window(Window win, Window src, int x, int y)
+{
+ if (!disp)
+ return;
+ XShapeCombineShape(disp, win, ShapeBounding, x, y, src, ShapeBounding,
+ ShapeSet);
+}
+
+void
+ecore_window_add_shape_window(Window win, Window src, int x, int y)
+{
+ if (!disp)
+ return;
+ XShapeCombineShape(disp, win, ShapeBounding, x, y, src, ShapeBounding,
+ ShapeUnion);
+}
+
+void
+ecore_window_set_shape_rectangle(Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ if (!disp)
+ return;
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeSet,
+ Unsorted);
+}
+
+void
+ecore_window_add_shape_rectangle(Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ if (!disp)
+ return;
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeUnion,
+ Unsorted);
+}
+
+void
+ecore_window_set_shape_rectangles(Window win, XRectangle * rect, int num)
+{
+ if (!disp)
+ return;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rect, num, ShapeSet,
+ Unsorted);
+}
+
+void
+ecore_window_add_shape_rectangles(Window win, XRectangle * rect, int num)
+{
+ if (!disp)
+ return;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rect, num, ShapeUnion,
+ Unsorted);
+}
+
+void
+ecore_window_clip_shape_by_rectangle(Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ if (!disp)
+ return;
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1,
+ ShapeIntersect, Unsorted);
+}
+
+XRectangle *
+ecore_window_get_shape_rectangles(Window win, int *num)
+{
+ int ord;
+
+ if (!disp)
+ return NULL;
+ return XShapeGetRectangles(disp, win, ShapeBounding, num, &ord);
+}
+
+void
+ecore_window_select_shape_events(Window win)
+{
+ if (!disp)
+ return;
+
+ XShapeSelectInput(disp, win, ShapeNotifyMask);
+}
+
+void
+ecore_window_unselect_shape_events(Window win)
+{
+ if (!disp)
+ return;
+
+ XShapeSelectInput(disp, win, 0);
+}
+
+void
+ecore_window_clear(Window win)
+{
+ if (!disp)
+ return;
+ if (win == 0)
+ win = default_root;
+ XClearWindow(disp, win);
+}
+
+void
+ecore_window_clear_area(Window win, int x, int y, int w, int h)
+{
+ if (!disp)
+ return;
+ if (win == 0)
+ win = default_root;
+ XClearArea(disp, win, x, y, w, h, False);
+}
+
+void
+ecore_pointer_xy(Window win, int *x, int *y)
+{
+ Window dw;
+ unsigned int dm;
+ int wx, wy;
+
+ if (!disp)
+ return;
+
+ if (win == 0)
+ win = default_root;
+
+ XQueryPointer(disp, win, &dw, &dw, &mouse_x, &mouse_y, &wx, &wy, &dm);
+
+ if (x)
+ *x = wx;
+ if (y)
+ *y = wy;
+}
+
+void
+ecore_pointer_xy_set(int x, int y)
+{
+ if (!disp) return;
+ mouse_x = x;
+ mouse_y = y;
+}
+
+void
+ecore_pointer_xy_get(int *x, int *y)
+{
+ if (!disp) return;
+ if (x)
+ *x = mouse_x;
+ if (y)
+ *y = mouse_y;
+}
+
+void
+ecore_window_set_events(Window win, long mask)
+{
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ XSelectInput(disp, win, mask);
+}
+
+void
+ecore_window_remove_events(Window win, long mask)
+{
+ XWindowAttributes att;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ mask = att.your_event_mask & (~mask);
+ ecore_window_set_events(win, mask);
+ }
+}
+
+void
+ecore_window_add_events(Window win, long mask)
+{
+ XWindowAttributes att;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ mask = att.your_event_mask | mask;
+ ecore_window_set_events(win, mask);
+ }
+}
+
+void
+ecore_window_move(Window win, int x, int y)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (!xid->coords_invalid)
+ {
+ if ((xid->x == x) && (xid->y == y))
+ return;
+ }
+ xid->x = x;
+ xid->y = y;
+ xid->coords_invalid = 0;
+ XMoveWindow(disp, win, x, y);
+ }
+}
+
+#define REGRAVITATE \
+if (xid->children) \
+{ \
+ int j; \
+\
+ for (j = 0; j < xid->children_num; j++) \
+ { \
+ Ecore_XID *xid2; \
+\
+ xid2 = ecore_validate_xid(xid->children[j]); \
+ if (xid2) \
+ { \
+ xid2->coords_invalid = 1; \
+ } \
+ } \
+}
+
+#if 0
+switch (xid2->gravity)
+ {
+ case UnmapGravity:
+ xid2->mapped = 0;
+ break;
+ case NorthWestGravity:
+ break;
+ case NorthGravity:
+ xid2->x += (w - xid->w) / 2;
+ break;
+ case NorthEastGravity:
+ xid2->x += (w - xid->w);
+ break;
+ case WestGravity:
+ xid2->h += (h - xid->h) / 2;
+ break;
+ case CenterGravity:
+ xid2->x += (w - xid->w) / 2;
+ xid2->h += (h - xid->h) / 2;
+ break;
+ case EastGravity:
+ xid2->x += (w - xid->w);
+ break;
+ case SouthWestGravity:
+ xid2->y += (h - xid->h);
+ break;
+ case SouthGravity:
+ xid2->x += (w - xid->w) / 2;
+ xid2->y += (h - xid->h);
+ break;
+ case SouthEastGravity:
+ xid2->x += (w - xid->w);
+ xid2->y += (h - xid->h);
+ break;
+ case StaticGravity:
+ xid2->coords_invalid = 1;
+ break;
+ default:
+ break;
+ }
+}
+}
+}
+#endif
+
+void
+ecore_window_resize(Window win, int w, int h)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (!xid->coords_invalid)
+ {
+ if ((xid->w == w) && (xid->h == h))
+ return;
+ }
+ REGRAVITATE;
+ xid->w = w;
+ xid->h = h;
+ xid->coords_invalid = 0;
+ XResizeWindow(disp, win, w, h);
+ }
+}
+
+void
+ecore_window_move_resize(Window win, int x, int y, int w, int h)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (!xid->coords_invalid)
+ {
+ if ((xid->x == x) && (xid->y == y) && (xid->w == w) && (xid->h == h))
+ return;
+ }
+ REGRAVITATE;
+ xid->x = x;
+ xid->y = y;
+ xid->w = w;
+ xid->h = h;
+ xid->coords_invalid = 0;
+ XMoveResizeWindow(disp, win, x, y, w, h);
+ }
+}
+
+int
+ecore_x_get_fd(void)
+{
+ if (!disp) return 0;
+ return ConnectionNumber(disp);
+}
+
+void
+ecore_set_error_handler(Ecore_Error_Function func)
+{
+ if (!disp) return;
+ XSetErrorHandler((XErrorHandler) func);
+}
+
+void
+ecore_reset_error_handler(void)
+{
+ if (!disp) return;
+ XSetErrorHandler((XErrorHandler) ecore_handle_x_error);
+}
+
+int
+ecore_display_init(char *display)
+{
+ int revert;
+
+ xid_context = XUniqueContext();
+ disp = XOpenDisplay(display);
+ if (!disp)
+ {
+ char *d;
+
+ d = getenv("DISPLAY");
+/* no need for this anymore
+ if (d)
+ fprintf(stderr,
+ "Fatal Error:\n"
+ "Cannot connect to the display nominated by your DISPLAY variable:\n"
+ "%s\n"
+ "Try changing your DISPLAY variable like:\n"
+ "DISPLAY=host:0 application_name\n", d);
+ else
+ fprintf(stderr,
+ "Fatal Error:\n"
+ "No DISPLAY variable set so cannot determine display to connect to.\n"
+ "Try setting your DISPLAY variable like:\n"
+ "DISPLAY=host:0 appication_name\n");
+*/
+ return 0;
+ }
+ XSetErrorHandler((XErrorHandler) ecore_handle_x_error);
+ XSetIOErrorHandler((XIOErrorHandler) ecore_handle_x_io_error);
+ default_vis = DefaultVisual(disp, DefaultScreen(disp));
+ default_depth = DefaultDepth(disp, DefaultScreen(disp));
+ default_cm = DefaultColormap(disp, DefaultScreen(disp));
+ default_win = DefaultRootWindow(disp);
+ default_root = DefaultRootWindow(disp);
+ mod_shift = ecore_mod_mask_shift_get();
+ mod_ctrl = ecore_mod_mask_ctrl_get();
+ mod_alt = ecore_mod_mask_alt_get();
+ mod_win = ecore_mod_mask_win_get();
+ XGetInputFocus(disp, &focused_win, &revert);
+ ecore_window_set_events(default_root, XEV_KEY | XEV_IN_OUT | XEV_MOUSE_MOVE |
+ XEV_CONFIGURE | XEV_CHILD_CHANGE | XEV_PROPERTY |
+ XEV_COLORMAP | XEV_VISIBILITY);
+ ecore_pointer_xy(0, NULL, NULL);
+ return 1;
+}
+
+int
+ecore_events_pending(void)
+{
+ if (!disp) return 0;
+ return XPending(disp);
+}
+
+void
+ecore_get_next_event(XEvent * event)
+{
+ if (!disp) return;
+ XNextEvent(disp, event);
+}
+
+int
+ecore_event_shape_get_id(void)
+{
+ int base = -1, err_base;
+
+ if (!disp) return 0;
+ XShapeQueryExtension(disp, &base, &err_base);
+ base += ShapeNotify;
+ return base;
+}
+
+KeySym
+ecore_key_get_keysym_from_keycode(KeyCode keycode)
+{
+ if (!disp) return 0;
+ return XKeycodeToKeysym(disp, keycode, 0);
+}
+
+char *
+ecore_key_get_string_from_keycode(KeyCode keycode)
+{
+ char *str;
+
+ if (!disp) return strdup("");
+ str = XKeysymToString(ecore_key_get_keysym_from_keycode(keycode));
+ if (!str)
+ return strdup("");
+ return strdup(str);
+}
+
+void
+ecore_event_allow(int mode, Time t)
+{
+ if (!disp) return;
+ XAllowEvents(disp, mode, t);
+}
+
+int
+ecore_lock_mask_scroll_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Scroll_Lock);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_lock_mask_num_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Num_Lock);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_lock_mask_caps_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Caps_Lock);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_mod_mask_shift_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Shift_L);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_mod_mask_ctrl_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Control_L);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_mod_mask_alt_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Alt_L);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_mod_mask_win_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Meta_L);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ if (mask == ecore_mod_mask_alt_get())
+ mask = 0;
+ if (mask == ecore_mod_mask_ctrl_get())
+ mask = 0;
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_lock_mask_get(void)
+{
+ static int mask = 0;
+ Window root_ret, child_ret;
+ int root_x_ret, root_y_ret, win_x_ret, win_y_ret;
+ unsigned int mask_ret;
+
+ if (!disp) return 0;
+ if (!mask)
+ mask = ecore_lock_mask_scroll_get() | ecore_lock_mask_num_get() |
+ ecore_lock_mask_caps_get();
+ XQueryPointer(disp, default_root, &root_ret, &child_ret, &root_x_ret,
+ &root_y_ret, &win_x_ret, &win_y_ret, &mask_ret);
+ return (mask_ret & mask);
+}
+
+int
+ecore_modifier_mask_get(void)
+{
+ Window root_ret, child_ret;
+ int root_x_ret, root_y_ret, win_x_ret, win_y_ret;
+ unsigned int mask_ret;
+
+ if (!disp) return 0;
+ XQueryPointer(disp, default_root, &root_ret, &child_ret, &root_x_ret,
+ &root_y_ret, &win_x_ret, &win_y_ret, &mask_ret);
+ return (mask_ret);
+}
+
+Window
+ecore_get_key_grab_win(void)
+{
+ if (!disp) return 0;
+ return grabkey_win;
+}
+
+void
+ecore_key_grab(char *key, Ecore_Event_Key_Modifiers mods, int anymod, int sync)
+{
+ KeyCode keycode;
+ int i, mod, mask_scroll, mask_num, mask_caps, masks[8], mode;
+
+ if (!disp) return;
+ keycode = ecore_key_get_keycode(key);
+ mod = 0;
+ mode = GrabModeAsync;
+ if (sync)
+ mode = GrabModeSync;
+ if (!grabkey_win)
+ grabkey_win = default_root;
+ if (mods & ECORE_EVENT_KEY_MODIFIER_SHIFT)
+ mod |= ecore_mod_mask_shift_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_CTRL)
+ mod |= ecore_mod_mask_ctrl_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_ALT)
+ mod |= ecore_mod_mask_alt_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_WIN)
+ mod |= ecore_mod_mask_win_get();
+ mask_scroll = ecore_lock_mask_scroll_get();
+ mask_num = ecore_lock_mask_num_get();
+ mask_caps = ecore_lock_mask_caps_get();
+ masks[0] = 0;
+ masks[1] = mask_scroll;
+ masks[2] = mask_num;
+ masks[3] = mask_caps;
+ masks[4] = mask_scroll | mask_num;
+ masks[5] = mask_scroll | mask_caps;
+ masks[6] = mask_num | mask_caps;
+ masks[7] = mask_scroll | mask_num | mask_caps;
+ if (anymod)
+ XGrabKey(disp, keycode, AnyModifier, grabkey_win, False, mode, mode);
+ else
+ {
+ for (i = 0; i < 8; i++)
+ XGrabKey(disp, keycode, masks[i] | mod, grabkey_win, False, mode, mode);
+ }
+}
+
+void
+ecore_key_ungrab(char *key, Ecore_Event_Key_Modifiers mods, int anymod)
+{
+ KeyCode keycode;
+
+ if (!disp) return;
+ keycode = ecore_key_get_keycode(key);
+ if (anymod)
+ XUngrabKey(disp, keycode, AnyModifier, default_root);
+ else
+ {
+ int i, mod, mask_scroll, mask_num, mask_caps, masks[8];
+
+ mod = 0;
+ if (mods & ECORE_EVENT_KEY_MODIFIER_SHIFT)
+ mod |= ecore_mod_mask_shift_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_CTRL)
+ mod |= ecore_mod_mask_ctrl_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_ALT)
+ mod |= ecore_mod_mask_alt_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_WIN)
+ mod |= ecore_mod_mask_win_get();
+ mask_scroll = ecore_lock_mask_scroll_get();
+ mask_num = ecore_lock_mask_num_get();
+ mask_caps = ecore_lock_mask_caps_get();
+ masks[0] = 0;
+ masks[1] = mask_scroll;
+ masks[2] = mask_num;
+ masks[3] = mask_caps;
+ masks[4] = mask_scroll | mask_num;
+ masks[5] = mask_scroll | mask_caps;
+ masks[6] = mask_num | mask_caps;
+ masks[7] = mask_scroll | mask_num | mask_caps;
+ for (i = 0; i < 8; i++)
+ XUngrabKey(disp, keycode, masks[i] | mod, grabkey_win);
+ }
+}
+
+KeyCode
+ecore_key_get_keycode(char *key)
+{
+ if (!disp) return 0;
+ return XKeysymToKeycode(disp, XStringToKeysym(key));
+}
+
+void
+ecore_window_destroy(Window win)
+{
+ if (!disp) return;
+ ecore_unvalidate_xid(win);
+ XDestroyWindow(disp, win);
+}
+
+void
+ecore_window_reparent(Window win, Window parent, int x, int y)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (parent == 0)
+ parent = default_root;
+ XReparentWindow(disp, win, parent, x, y);
+ ecore_del_child(xid->parent, win);
+ ecore_add_child(parent, win);
+ xid->parent = parent;
+ xid->x = x;
+ xid->y = y;
+ }
+}
+
+void
+ecore_window_raise(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ XRaiseWindow(disp, win);
+ ecore_raise_child(xid->parent, win);
+ }
+}
+
+void
+ecore_window_lower(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ XLowerWindow(disp, win);
+ ecore_lower_child(xid->parent, win);
+ }
+}
+
+void
+ecore_window_get_geometry(Window win, int *x, int *y, int *w, int *h)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if ((xid) && (xid->coords_invalid))
+ {
+ Window dw;
+ int rx, ry;
+ unsigned int rw, rh, di;
+
+ XGetGeometry(disp, win, &dw, &rx, &ry, &rw, &rh, &di, &di);
+ xid->x = rx;
+ xid->y = ry;
+ xid->w = (int)rw;
+ xid->h = (int)rh;
+ xid->coords_invalid = 0;
+ }
+ if (xid)
+ {
+ if (x)
+ *x = xid->x;
+ if (y)
+ *y = xid->y;
+ if (w)
+ *w = xid->w;
+ if (h)
+ *h = xid->h;
+ }
+ else
+ {
+ if (x)
+ *x = 0;
+ if (y)
+ *y = 0;
+ if (w)
+ *w = 0;
+ if (h)
+ *h = 0;
+ }
+}
+
+int
+ecore_window_get_depth(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return xid->depth;
+ return -1;
+}
+
+int
+ecore_window_exists(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return 1;
+ return 0;
+}
+
+Window
+ecore_window_get_parent(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return xid->parent;
+ return 0;
+}
+
+Window *
+ecore_window_get_children(Window win, int *num)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return NULL;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ Window *wlist = NULL;
+
+ *num = xid->children_num;
+ if (xid->children)
+ {
+ wlist = NEW(Window, xid->children_num);
+ MEMCPY(xid->children, wlist, Window, xid->children_num);
+ }
+ return wlist;
+ }
+ *num = 0;
+ return NULL;
+}
+
+int
+ecore_window_mouse_in(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return xid->mouse_in;
+ return 0;
+}
+
+void
+ecore_window_mouse_set_in(Window win, int in)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ xid->mouse_in = in;
+}
+
+Display *
+ecore_display_get(void)
+{
+ return disp;
+}
+
+Window
+ecore_window_get_root(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return xid->root;
+ return 0;
+}
+
+void
+ecore_lock_scroll_set(int onoff)
+{
+ lock_scroll = onoff;
+}
+
+int
+ecore_lock_scroll_get(void)
+{
+ return lock_scroll;
+}
+
+void
+ecore_lock_num_set(int onoff)
+{
+ lock_num = onoff;
+}
+
+int
+ecore_lock_num_get(void)
+{
+ return lock_num;
+}
+
+void
+ecore_lock_caps_set(int onoff)
+{
+ lock_caps = onoff;
+}
+
+int
+ecore_lock_caps_get(void)
+{
+ return lock_caps;
+}
+
+void
+ecore_mod_shift_set(int onoff)
+{
+ mod_shift = onoff;
+}
+
+int
+ecore_mod_shift_get(void)
+{
+ return mod_shift;
+}
+
+void
+ecore_mod_ctrl_set(int onoff)
+{
+ mod_ctrl = onoff;
+}
+
+int
+ecore_mod_ctrl_get(void)
+{
+ return mod_ctrl;
+}
+
+void
+ecore_mod_alt_set(int onoff)
+{
+ mod_alt = onoff;
+}
+
+int
+ecore_mod_alt_get(void)
+{
+ return mod_alt;
+}
+
+void
+ecore_mod_win_set(int onoff)
+{
+ mod_win = onoff;
+}
+
+int
+ecore_mod_win_get(void)
+{
+ return mod_win;
+}
+
+void
+ecore_focus_window_set(Window win)
+{
+ focused_win = win;
+}
+
+Window
+ecore_focus_window_get(void)
+{
+ return focused_win;
+}
+
+void
+ecore_focus_to_window(Window win)
+{
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ XSetInputFocus(disp, win, RevertToNone, CurrentTime);
+}
+
+void
+ecore_focus_mode_reset(void)
+{
+ if (!disp) return;
+ XSetInputFocus(disp, default_root, RevertToPointerRoot, CurrentTime);
+}
+
+Atom
+ecore_atom_get(char *name)
+{
+ if (!disp) return 0;
+ return XInternAtom(disp, name, False);
+}
+
+void
+ecore_window_set_delete_inform(Window win)
+{
+ static Atom protocols[1] = { 0 };
+
+ if (!disp) return;
+ ECORE_ATOM(protocols[0], "WM_DELETE_WINDOW");
+ XSetWMProtocols(disp, win, protocols, 1);
+}
+
+void
+ecore_window_property_set(Window win, Atom type, Atom format, int size,
+ void *data, int number)
+{
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ if (size != 32)
+ XChangeProperty(disp, win, type, format, size, PropModeReplace,
+ (unsigned char *)data, number);
+ else
+ {
+ long *dat;
+ int i, *ptr;
+
+ dat = NEW(long, number);
+
+ for (ptr = (int *)data, i = 0; i < number; i++)
+ dat[i] = ptr[i];
+ XChangeProperty(disp, win, type, format, size, PropModeReplace,
+ (unsigned char *)dat, number);
+ FREE(dat);
+ }
+}
+
+void *
+ecore_window_property_get(Window win, Atom type, Atom format, int *size)
+{
+ unsigned char *retval;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ void *data = NULL;
+
+ if (!disp)
+ return NULL;
+
+ retval = NULL;
+ if (win == 0)
+ win = default_root;
+ XGetWindowProperty(disp, win, type, 0, 0x7fffffffL, False, format,
+ &type_ret, &format_ret, &num_ret, &bytes_after, &retval);
+ if (retval)
+ {
+ if (format_ret == 32)
+ {
+ int i;
+
+ *size = num_ret * sizeof(unsigned int);
+
+ data = NEW(unsigned int, num_ret);
+
+ for (i = 0; i < (int)num_ret; i++)
+ ((unsigned int *)data)[i] = ((unsigned long *)retval)[i];
+ }
+ else if (format_ret == 16)
+ {
+ int i;
+
+ *size = num_ret * sizeof(unsigned short);
+
+ data = NEW(unsigned short, *size);
+
+ for (i = 0; i < (int)num_ret; i++)
+ ((unsigned short *)data)[i] = ((unsigned short *)retval)[i];
+ }
+ else if (format_ret == 8)
+ {
+ /* format_ret == 8 */
+ *size = num_ret;
+ data = NEW(char, num_ret);
+
+ if (data)
+ memcpy(data, retval, num_ret);
+ }
+ XFree(retval);
+ return data;
+ }
+ *size = 0;
+ return NULL;
+}
+
+void
+ecore_window_dnd_advertise(Window win)
+{
+ static Atom atom_xdndaware = 0;
+ int dnd_version = 3;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndaware, "XdndAware");
+ ecore_window_property_set(win, atom_xdndaware, XA_ATOM, 32, &dnd_version, 1);
+}
+
+void
+ecore_grab(void)
+{
+ if (!disp)
+ return;
+
+ x_grabs++;
+
+ if (x_grabs == 1)
+ XGrabServer(disp);
+}
+
+void
+ecore_ungrab(void)
+{
+ if (!disp)
+ return;
+
+ x_grabs--;
+
+ if (x_grabs == 0)
+ {
+ XUngrabServer(disp);
+ ecore_sync();
+ }
+}
+
+void
+ecore_window_ignore(Window win)
+{
+ Window_List *w;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ w = NEW(Window_List, 1);
+ w->win = win;
+ w->next = ignore_wins;
+ ignore_wins = w;
+}
+
+void
+ecore_window_no_ignore(Window win)
+{
+ Window_List *w, *pw;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ for (pw = NULL, w = ignore_wins; w; pw = w, w = w->next)
+ {
+ if (w->win == win)
+ {
+ if (pw)
+ pw->next = w->next;
+ else
+ ignore_wins = w->next;
+ FREE(w);
+ return;
+ }
+ }
+}
+
+int
+ecore_window_is_ignored(Window win)
+{
+ Window_List *w;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ for (w = ignore_wins; w; w = w->next)
+ {
+ if (w->win == win)
+ return 1;
+ }
+ return 0;
+}
+
+static Window
+ecore_window_at_xy_0(Window base, int bx, int by, int x, int y)
+{
+ Window *list = NULL;
+ XWindowAttributes att;
+ Window child = 0, parent_win = 0, root_win = 0;
+ int i;
+ unsigned int ww, wh, num;
+ int wx, wy;
+
+ if (!disp) return 0;
+ if ((!XGetWindowAttributes(disp, base, &att)) ||
+ (att.map_state != IsViewable))
+ return 0;
+
+ wx = att.x;
+ wy = att.y;
+ ww = att.width;
+ wh = att.height;
+
+ wx += bx;
+ wy += by;
+
+ if (!((x >= wx) && (y >= wy) && (x < (int)(wx + ww)) && (y < (int)(wy + wh))))
+ return 0;
+
+ if (!XQueryTree(disp, base, &root_win, &parent_win, &list, &num))
+ return base;
+ if (list)
+ {
+ for (i = num - 1;; i--)
+ {
+ if (!ecore_window_is_ignored(list[i]))
+ {
+ if ((child = ecore_window_at_xy_0(list[i], wx, wy, x, y)) != 0)
+ {
+ XFree(list);
+ return child;
+ }
+ }
+ if (!i)
+ break;
+ }
+ XFree(list);
+ }
+ return base;
+}
+
+Window
+ecore_window_get_at_xy(int x, int y)
+{
+ Window child;
+
+ if (!disp) return 0;
+ ecore_grab();
+ child = ecore_window_at_xy_0(default_root, 0, 0, x, y);
+ if (child)
+ {
+ ecore_ungrab();
+ return child;
+ }
+ ecore_ungrab();
+ return default_root;
+}
+
+int
+ecore_window_dnd_capable(Window win)
+{
+ static Atom atom_xdndaware = 0;
+ int dnd_version = 3;
+ int *atom_ret;
+ int size = 0;
+
+ if (!disp) return 0;
+ ECORE_ATOM(atom_xdndaware, "XdndAware");
+ atom_ret = ecore_window_property_get(win, atom_xdndaware, XA_ATOM, &size);
+ if ((atom_ret) && (size >= (int)sizeof(int)))
+ {
+ if (atom_ret[0] == dnd_version)
+ {
+ FREE(atom_ret);
+ return 1;
+ }
+ FREE(atom_ret);
+ }
+ return 0;
+}
+
+void
+ecore_window_dnd_handle_motion(Window source_win, int x, int y, int dragging)
+{
+ static Atom atom_xdndenter = 0;
+ static Atom atom_xdndleave = 0;
+ static Atom atom_xdnddrop = 0;
+ static Atom atom_xdndposition = 0;
+ static Atom atom_xdndactioncopy = 0;
+ static Atom atom_xdndactionmove = 0;
+ static Atom atom_xdndactionlink = 0;
+ static Atom atom_xdndactionask = 0;
+ static Atom atom_text_uri_list = 0;
+ static Atom atom_text_plain = 0;
+ static Atom atom_text_moz_url = 0;
+ static Atom atom_netscape_url = 0;
+ Window win;
+ XEvent xevent;
+
+ if (!disp) return;
+ win = ecore_window_get_at_xy(x, y);
+ while ((win) && (!ecore_window_dnd_capable(win)))
+ win = ecore_window_get_parent(win);
+ ECORE_ATOM(atom_xdndenter, "XdndEnter");
+ ECORE_ATOM(atom_xdndleave, "XdndLeave");
+ ECORE_ATOM(atom_xdnddrop, "XdndDrop");
+ ECORE_ATOM(atom_xdndposition, "XdndPosition");
+ ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy");
+ ECORE_ATOM(atom_xdndactionmove, "XdndActionMove");
+ ECORE_ATOM(atom_xdndactionlink, "XdndActionLink");
+ ECORE_ATOM(atom_xdndactionask, "XdndActionAsk");
+ ECORE_ATOM(atom_text_uri_list, "text/uri-list");
+ ECORE_ATOM(atom_text_plain, "text/plain");
+ ECORE_ATOM(atom_text_moz_url, "text/x-moz-url");
+ ECORE_ATOM(atom_netscape_url, "_NETSCAPE_URL");
+ if ((win != current_dnd_win) && (current_dnd_win))
+ {
+ /* send leave to old dnd win */
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.format = 32;
+ xevent.xclient.window = current_dnd_win;
+ xevent.xclient.message_type = atom_xdndleave;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 0;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, current_dnd_win, False, 0, &xevent);
+ }
+ if (win)
+ {
+ if (win != current_dnd_win)
+ {
+ /* send enter on new win */
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndenter;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = (3 << 24);
+ xevent.xclient.data.l[2] = atom_text_uri_list;
+ xevent.xclient.data.l[3] = atom_text_plain;
+ xevent.xclient.data.l[4] = atom_text_moz_url;
+ XSendEvent(disp, win, False, 0, &xevent);
+ ecore_clear_target_status();
+ }
+ /* kjb cep */
+ if(!dnd_await_target_status)
+ {
+ /* send position information */
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndposition;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = (3 << 24);
+ xevent.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+ xevent.xclient.data.l[3] = CurrentTime;
+ if (dnd_copy)
+ xevent.xclient.data.l[4] = atom_xdndactioncopy;
+ else if (dnd_link)
+ xevent.xclient.data.l[4] = atom_xdndactionlink;
+ else if (dnd_move)
+ xevent.xclient.data.l[4] = atom_xdndactionmove;
+ else
+ xevent.xclient.data.l[4] = atom_xdndactionask;
+ XSendEvent(disp, win, False, 0, &xevent);
+ dnd_await_target_status = 1;
+ }
+ }
+ if (!dragging)
+ {
+ if (win)
+ {
+ if (current_dnd_target_ok)
+ {
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdnddrop;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 0;
+ xevent.xclient.data.l[2] = CurrentTime;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, win, False, 0, &xevent);
+ }
+ else
+ {
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndleave;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 0;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, win, False, 0, &xevent);
+ }
+ }
+ current_dnd_target_ok = 0;
+ }
+ current_dnd_win = win;
+}
+
+
+void
+ecore_clear_target_status(void)
+{
+ dnd_await_target_status = 0;
+}
+
+
+int
+ecore_dnd_selection_convert(Window win, Window req, Atom type)
+{
+ static Atom atom_xdndselection = 0;
+ static Atom atom_jxselectionwindowproperty = 0;
+
+ if (!disp) return 0;
+ ECORE_ATOM(atom_xdndselection, "XdndSelection");
+ ECORE_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty");
+ if (win == XGetSelectionOwner(disp, atom_xdndselection))
+ {
+ XConvertSelection(disp, atom_xdndselection, type,
+ atom_jxselectionwindowproperty, req, CurrentTime);
+ return 1;
+ }
+ return 0;
+}
+
+void *
+ecore_dnd_selection_get(Window win, Window req, Atom type, int *size)
+{
+ unsigned char *data = NULL;
+ long bytes_read;
+ unsigned long remaining = 1;
+
+ if (!disp) return NULL;
+ *size = 0;
+ bytes_read = 0;
+ while (remaining)
+ {
+ unsigned char *s;
+ Atom actual;
+ int format;
+ unsigned long count;
+
+ s = NULL;
+ if (XGetWindowProperty(disp, win, type, bytes_read / 4, 0x10000, 1,
+ AnyPropertyType, &actual, &format, &count,
+ &remaining, &s) != Success)
+ {
+ /* error occured */
+ XFree(s);
+ IF_FREE(data);
+ *size = 0;
+ return NULL;
+ }
+ if (s)
+ {
+ /* got some mroe data - append it */
+ bytes_read += count;
+ if (!data)
+ data = NEW(char, bytes_read);
+
+ else
+ REALLOC(data, char, bytes_read);
+ MEMCPY(s, data + (bytes_read - count), char, count);
+
+ XFree(s);
+ }
+ }
+ *size = bytes_read;
+ return data;
+ req = 0;
+}
+
+void
+ecore_dnd_set_data(Window win)
+{
+ static Atom atom_xdndselection = 0;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndselection, "XdndSelection");
+ ecore_dnd_set_action(win);
+ XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime);
+}
+
+void
+ecore_dnd_set_action(Window win)
+{
+ static int atom_xdndactioncopy = 0;
+ static int atom_xdndactionmove = 0;
+ static int atom_xdndactionlink = 0;
+ static int atom_xdndactionask = 0;
+ static Atom atom_xdndactionlist = 0;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy");
+ ECORE_ATOM(atom_xdndactionmove, "XdndActionMove");
+ ECORE_ATOM(atom_xdndactionlink, "XdndActionLink");
+ ECORE_ATOM(atom_xdndactionask, "XdndActionAsk");
+ ECORE_ATOM(atom_xdndactionlist, "XdndActionList");
+ if (dnd_copy)
+ ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
+ &atom_xdndactioncopy, 1);
+ else if (dnd_link)
+ ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
+ &atom_xdndactionlink, 1);
+ else if (dnd_move)
+ ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
+ &atom_xdndactionmove, 1);
+ else
+ ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
+ &atom_xdndactionask, 1);
+}
+
+void
+ecore_dnd_send_data(Window win, Window source_win, void *data, int size,
+ Atom dest_atom, int type)
+{
+ XEvent xevent;
+ static Atom atom_text_plain = 0;
+ static Atom atom_text_uri_list = 0;
+ static Atom atom_text_moz_url = 0;
+ static Atom atom_netscape_url = 0;
+ static Atom atom_xdndselection = 0;
+ Atom target;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndselection, "XdndSelection");
+ ECORE_ATOM(atom_text_uri_list, "text/uri-list");
+ ECORE_ATOM(atom_text_plain, "text/plain");
+ ECORE_ATOM(atom_text_moz_url, "text/x-moz-url");
+ ECORE_ATOM(atom_text_moz_url, "_NETSCAPE_URL");
+ ECORE_ATOM(atom_text_plain, "text/plain");
+ if (type == DND_TYPE_URI_LIST) target = atom_text_uri_list;
+ else if (type == DND_TYPE_PLAIN_TEXT) target = atom_text_plain;
+ else if (type == DND_TYPE_MOZ_URL) target = atom_text_moz_url;
+ else if (type == DND_TYPE_NETSCAPE_URL) target = atom_netscape_url;
+ else target = 0;
+ ecore_window_property_set(win, dest_atom, target, 8, data, size);
+ xevent.xselection.type = SelectionNotify;
+ xevent.xselection.property = dest_atom;
+ xevent.xselection.display = disp;
+ xevent.xselection.requestor = win;
+ xevent.xselection.selection = atom_xdndselection;
+ xevent.xselection.target = target;
+ xevent.xselection.time = CurrentTime;
+ XSendEvent(disp, win, False, 0, &xevent);
+ return;
+ source_win = 0;
+}
+
+void
+ecore_dnd_set_mode_copy(void)
+{
+ dnd_copy = 1;
+ dnd_link = 0;
+ dnd_move = 0;
+}
+
+void
+ecore_dnd_set_mode_link(void)
+{
+ dnd_copy = 0;
+ dnd_link = 1;
+ dnd_move = 0;
+}
+
+void
+ecore_dnd_set_mode_move(void)
+{
+ dnd_copy = 0;
+ dnd_link = 0;
+ dnd_move = 1;
+}
+
+void
+ecore_dnd_set_mode_ask(void)
+{
+ dnd_copy = 0;
+ dnd_link = 0;
+ dnd_move = 0;
+}
+
+void
+ecore_dnd_own_selection(Window win)
+{
+ static Atom atom_xdndselection = 0;
+ static Atom atom_jxselectionwindowproperty = 0;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndselection, "XdndSelection");
+ ECORE_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty");
+
+ if (!XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime))
+ return;
+}
+
+void
+ecore_dnd_send_drop(Window win, Window source_win)
+{
+ static Atom atom_xdnddrop = 0;
+ XEvent xevent;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdnddrop, "XdndDrop");
+
+ ecore_dnd_own_selection(source_win);
+
+ memset(&xevent, 0, sizeof(xevent));
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdnddrop;
+ xevent.xclient.format = 32;
+
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = CurrentTime;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, win, False, 0, &xevent);
+}
+
+void
+ecore_window_dnd_send_status_ok(Window source_win, Window win, int x, int y,
+ int w, int h)
+{
+ static Atom atom_xdndstatus = 0;
+ static Atom atom_xdndactioncopy = 0;
+ static Atom atom_xdndactionmove = 0;
+ static Atom atom_xdndactionlink = 0;
+ static Atom atom_xdndactionask = 0;
+ XEvent xevent;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndstatus, "XdndStatus");
+ ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy");
+ ECORE_ATOM(atom_xdndactionmove, "XdndActionMove");
+ ECORE_ATOM(atom_xdndactionlink, "XdndActionLink");
+ ECORE_ATOM(atom_xdndactionask, "XdndActionAsk");
+ memset(&xevent, 0, sizeof(xevent));
+
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndstatus;
+ xevent.xclient.format = 32;
+
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 3;
+ xevent.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+ xevent.xclient.data.l[3] = ((h << 16) & 0xffff0000) | (w & 0xffff);
+ if (dnd_copy)
+ xevent.xclient.data.l[4] = atom_xdndactioncopy;
+ else if (dnd_link)
+ xevent.xclient.data.l[4] = atom_xdndactionlink;
+ else if (dnd_move)
+ xevent.xclient.data.l[4] = atom_xdndactionmove;
+ else
+ xevent.xclient.data.l[4] = atom_xdndactionask;
+ XSendEvent(disp, win, False, 0, &xevent);
+}
+
+void
+ecore_window_dnd_send_finished(Window source_win, Window win)
+{
+ static Atom atom_xdndfinished = 0;
+ XEvent xevent;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndfinished, "XdndFinished");
+ memset(&xevent, 0, sizeof(xevent));
+
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndfinished;
+ xevent.xclient.format = 32;
+
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 0;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, win, False, 0, &xevent);
+}
+
+void
+ecore_window_dnd_ok(int ok)
+{
+ current_dnd_target_ok = ok;
+}
+
+void
+ecore_window_dnd_finished(void)
+{
+ current_dnd_win = 0;
+}
+
+void
+ecore_window_set_title(Window win, char *title)
+{
+ if (!disp) return;
+ XStoreName(disp, win, title);
+}
+
+void
+ecore_window_set_name_class(Window win, char *name, char *class)
+{
+ XClassHint hint;
+
+ if (!disp) return;
+ hint.res_name = name;
+ hint.res_class = class;
+ XSetClassHint(disp, win, &hint);
+}
+
+void
+ecore_window_get_name_class(Window win, char **name, char **class)
+{
+ XClassHint xch;
+
+ if (!disp) return;
+ if (name)
+ *name = NULL;
+ if (class)
+ *class = NULL;
+ if (XGetClassHint(disp, win, &xch))
+ {
+ if (name)
+ {
+ if (xch.res_name)
+ *name = strdup(xch.res_name);
+ }
+ if (class)
+ {
+ if (xch.res_class)
+ *class = strdup(xch.res_class);
+ }
+ XFree(xch.res_name);
+ XFree(xch.res_class);
+ }
+}
+
+void
+ecore_window_get_hints(Window win, int *accepts_focus, int *initial_state,
+ Pixmap * icon_pixmap, Pixmap * icon_mask,
+ Window * icon_window, Window * window_group)
+{
+ XWMHints *hints;
+
+ if (!disp) return;
+ hints = XGetWMHints(disp, win);
+ if (hints)
+ {
+ if ((hints->flags & InputHint) && (accepts_focus))
+ {
+ if (hints->input)
+ *accepts_focus = 1;
+ else
+ *accepts_focus = 0;
+ }
+ if ((hints->flags & StateHint) && (initial_state))
+ {
+ *initial_state = hints->initial_state;
+ }
+ if ((hints->flags & IconPixmapHint) && (icon_pixmap))
+ {
+ *icon_pixmap = hints->icon_pixmap;
+ }
+ if ((hints->flags & IconMaskHint) && (icon_mask))
+ {
+ *icon_mask = hints->icon_pixmap;
+ }
+ if ((hints->flags & IconWindowHint) && (icon_window))
+ {
+ *icon_window = hints->icon_window;
+ }
+ if ((hints->flags & WindowGroupHint) && (window_group))
+ {
+ *window_group = hints->window_group;
+ }
+ XFree(hints);
+ }
+}
+
+char *
+ecore_window_get_machine(Window win)
+{
+ XTextProperty xtp;
+
+ if (!disp) return NULL;
+ if (XGetWMClientMachine(disp, win, &xtp))
+ {
+ char *s;
+
+ if (!xtp.value)
+ return NULL;
+ s = strdup(xtp.value);
+ XFree(xtp.value);
+ return s;
+ }
+ return NULL;
+}
+
+char *
+ecore_window_get_command(Window win)
+{
+ int cargc;
+ char **cargv;
+
+ if (!disp) return NULL;
+ if (XGetCommand(disp, win, &cargv, &cargc))
+ {
+ if (cargc > 0)
+ {
+ char *s;
+ int size, i;
+
+ size = 0;
+ for (i = 0; i < cargc; i++)
+ size += strlen(cargv[i]);
+ size += cargc - 1;
+ s = NEW(char, size + 1);
+ s[0] = 0;
+
+ strcpy(s, cargv[0]);
+ for (i = 1; i < cargc; i++)
+ {
+ strcat(s, " ");
+ strcat(s, cargv[i]);
+ }
+ XFreeStringList(cargv);
+ return s;
+ }
+ else
+ return NULL;
+ }
+ return NULL;
+}
+
+char *
+ecore_window_get_icon_name(Window win)
+{
+ XTextProperty xtp;
+
+ if (!disp) return NULL;
+ if (XGetWMIconName(disp, win, &xtp))
+ {
+ char *s;
+
+ if (!xtp.value)
+ return NULL;
+ s = strdup(xtp.value);
+ XFree(xtp.value);
+ return s;
+ }
+ return NULL;
+}
+
+void
+ecore_window_set_min_size(Window win, int w, int h)
+{
+ XSizeHints hints;
+ long ret;
+
+ if (!disp) return;
+ memset(&hints, 0, sizeof(XSizeHints));
+ XGetWMNormalHints(disp, win, &hints, &ret);
+ hints.flags |= PMinSize | PSize | USSize;
+ hints.min_width = w;
+ hints.min_height = h;
+ XSetWMNormalHints(disp, win, &hints);
+}
+
+void
+ecore_window_set_max_size(Window win, int w, int h)
+{
+ XSizeHints hints;
+ long ret;
+
+ if (!disp) return;
+ memset(&hints, 0, sizeof(XSizeHints));
+ XGetWMNormalHints(disp, win, &hints, &ret);
+ hints.flags |= PMaxSize | PSize | USSize;
+ hints.max_width = w;
+ hints.max_height = h;
+ XSetWMNormalHints(disp, win, &hints);
+}
+
+void
+ecore_window_set_xy_hints(Window win, int x, int y)
+{
+ XSizeHints hints;
+ long ret;
+
+ if (!disp) return;
+ memset(&hints, 0, sizeof(XSizeHints));
+ XGetWMNormalHints(disp, win, &hints, &ret);
+ hints.flags |= PPosition | USPosition | PSize | USSize;
+ hints.x = x;
+ hints.y = y;
+ XSetWMNormalHints(disp, win, &hints);
+}
+
+void
+ecore_window_get_frame_size(Window win, int *l, int *r, int *t, int *b)
+{
+ static Atom atom_e_frame_size = 0;
+ int *data, size;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_e_frame_size, "_E_FRAME_SIZE");
+ data = ecore_window_property_get(win, atom_e_frame_size, XA_CARDINAL, &size);
+ if (data)
+ {
+ if (size == (4 * sizeof(int)))
+ {
+ if (l)
+ *l = data[0];
+ if (r)
+ *r = data[1];
+ if (t)
+ *t = data[2];
+ if (b)
+ *b = data[3];
+ }
+ else
+ {
+ if (l)
+ *l = 0;
+ if (r)
+ *r = 0;
+ if (t)
+ *t = 0;
+ if (b)
+ *b = 0;
+ }
+ FREE(data);
+ }
+ else
+ {
+ if (l)
+ *l = 0;
+ if (r)
+ *r = 0;
+ if (t)
+ *t = 0;
+ if (b)
+ *b = 0;
+ }
+}
+
+int
+ecore_window_save_under(Window win)
+{
+ XSetWindowAttributes att;
+ XWindowAttributes gatt;
+
+ if (!disp) return 0;
+ att.save_under = True;
+ XChangeWindowAttributes(disp, win, CWSaveUnder, &att);
+ XGetWindowAttributes(disp, win, &gatt);
+ return (gatt.save_under == True) ? 1 : 0;
+}
+
+GC
+ecore_gc_new(Drawable d)
+{
+ XGCValues gcv;
+
+ if (!disp) return 0;
+ if (d == 0)
+ d = default_root;
+ return XCreateGC(disp, d, 0, &gcv);
+}
+
+void
+ecore_gc_free(GC gc)
+{
+ if (!disp) return;
+ XFreeGC(disp, gc);
+}
+
+void
+ecore_gc_set_fg(GC gc, int val)
+{
+ if (!disp) return;
+ XSetForeground(disp, gc, val);
+}
+
+void
+ecore_fill_rectangle(Drawable d, GC gc, int x, int y, int w, int h)
+{
+ if (!disp) return;
+ XFillRectangle(disp, d, gc, x, y, w, h);
+}
+
+void
+ecore_draw_rectangle(Drawable d, GC gc, int x, int y, int w, int h)
+{
+ if (!disp) return;
+ XDrawRectangle(disp, d, gc, x, y, w - 1, h - 1);
+}
+
+void
+ecore_draw_line(Drawable d, GC gc, int x1, int y1, int x2, int y2)
+{
+ if (!disp) return;
+ XDrawLine(disp, d, gc, x1, y1, x2, y2);
+}
+
+void
+ecore_draw_point(Drawable d, GC gc, int x, int y)
+{
+ if (!disp) return;
+ XDrawPoint(disp, d, gc, x, y);
+}
+
+void
+ecore_window_hint_set_layer(Window win, int layer)
+{
+ static Atom atom_win_layer = 0;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_win_layer, "_WIN_LAYER");
+ ecore_window_property_set(win, atom_win_layer, XA_CARDINAL, 32, &layer, 1);
+}
+
+void
+ecore_window_hint_set_sticky(Window win, int sticky)
+{
+ static Atom atom_win_state = 0;
+ static Atom atom_win_hints = 0;
+ int data;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_win_state, "_WIN_STATE");
+ ECORE_ATOM(atom_win_hints, "_WIN_HINTS");
+ if (sticky)
+ {
+ data = ((1 << 0) | (1 << 8) | (1 << 9));
+ ecore_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1);
+ data = ((1 << 0) | (1 << 1) | (1 << 2));
+ ecore_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1);
+ }
+ else
+ {
+ data = 0;
+ ecore_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1);
+ ecore_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1);
+ }
+}
+
+void
+ecore_window_hint_set_borderless(Window win)
+{
+ static Atom atom_motif_wm_hints = 0;
+ int data[5];
+
+ if (!disp) return;
+ ECORE_ATOM(atom_motif_wm_hints, "_MOTIF_WM_HINTS");
+ data[0] = 0x3;
+ data[1] = 0x0;
+ data[2] = 0x0;
+ data[3] = 0x2ada27b0;
+ data[4] = 0x2aabd6b0;
+ ecore_window_property_set(win, atom_motif_wm_hints, atom_motif_wm_hints, 32,
+ data, 5);
+}
+
+void
+ecore_grab_mouse(Window win, int confine, Cursor cursor)
+{
+ int ret;
+
+ if (!disp)
+ return;
+ if (confine)
+ ret = XGrabPointer(disp, win, False,
+ XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT,
+ GrabModeAsync, GrabModeAsync, win, cursor, CurrentTime);
+ else
+ ret = XGrabPointer(disp, win, False,
+ XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT,
+ GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime);
+ if (ret == GrabSuccess)
+ grab_pointer_win = win;
+}
+
+void
+ecore_ungrab_mouse(void)
+{
+ if (!disp) return;
+ XUngrabPointer(disp, CurrentTime);
+ grab_pointer_win = 0;
+}
+
+Window
+ecore_grab_window_get(void)
+{
+ return grab_pointer_win;
+}
+
+int
+ecore_window_get_gravity(Window win)
+{
+ XWindowAttributes att;
+
+ if (!disp)
+ return 0;
+
+ XGetWindowAttributes(disp, win, &att);
+ return att.win_gravity;
+}
+
+void
+ecore_window_gravity_reset(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ XSetWindowAttributes att;
+
+/* if (xid->gravity != NorthWestGravity)*/
+ {
+ att.win_gravity = NorthWestGravity;
+ XChangeWindowAttributes(disp, win, CWWinGravity, &att);
+ xid->gravity = NorthWestGravity;
+ xid->coords_invalid = 1;
+ }
+ }
+}
+
+void
+ecore_window_gravity_set(Window win, int gravity)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+/* if (xid->gravity != gravity)*/
+ {
+ XSetWindowAttributes att;
+
+ att.win_gravity = gravity;
+ XChangeWindowAttributes(disp, win, CWWinGravity, &att);
+ xid->gravity = gravity;
+ xid->coords_invalid = 1;
+ }
+ }
+}
+
+void
+ecore_window_bit_gravity_set(Window win, int gravity)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ XSetWindowAttributes att;
+
+ att.bit_gravity = gravity;
+ XChangeWindowAttributes(disp, win, CWBitGravity, &att);
+ }
+}
+
+void
+ecore_pointer_warp_by(int dx, int dy)
+{
+ if (!disp) return;
+ XWarpPointer(disp, None, None, 0, 0, 0, 0, dx, dy);
+}
+
+void
+ecore_pointer_warp_to(int x, int y)
+{
+ if (!disp) return;
+ XWarpPointer(disp, None, default_root, 0, 0, 0, 0, x, y);
+}
+
+void
+ecore_gc_set_include_inferiors(GC gc)
+{
+ XGCValues gcv;
+
+ if (!disp) return;
+ gcv.subwindow_mode = IncludeInferiors;
+ XChangeGC(disp, gc, GCSubwindowMode, &gcv);
+}
+
+void
+ecore_area_copy(Drawable src, Drawable dest, GC gc,
+ int sx, int sy, int sw, int sh, int dx, int dy)
+{
+ if (!disp) return;
+ if (src == 0)
+ src = default_root;
+ if (dest == 0)
+ dest = default_root;
+ XCopyArea(disp, src, dest, gc, sx, sy, sw, sh, dx, dy);
+}
+
+Window
+ecore_window_root(void)
+{
+ return default_root;
+}
+
+void
+ecore_window_get_virtual_area(Window win, int *area_x, int *area_y)
+{
+ static Atom atom_win_area = 0;
+ int *data, size;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_win_area, "_WIN_AREA");
+ data = ecore_window_property_get(win, atom_win_area, XA_CARDINAL, &size);
+ if (data)
+ {
+ if (size == (sizeof(int) * 2))
+ {
+ if (area_x)
+ *area_x = data[0];
+ if (area_y)
+ *area_y = data[1];
+ }
+ FREE(data);
+ }
+}
+
+void
+ecore_get_virtual_area(int *area_x, int *area_y)
+{
+ static Atom atom_win_area = 0;
+ int *data, size;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_win_area, "_WIN_AREA");
+ data = ecore_window_property_get(default_root, atom_win_area, XA_CARDINAL, &size);
+ if (data)
+ {
+ if (size == (sizeof(int) * 2))
+ {
+ if (area_x)
+ *area_x = data[0];
+ if (area_y)
+ *area_y = data[1];
+ }
+ FREE(data);
+ }
+}
+
+void
+ecore_window_get_root_relative_location(Window win, int *x, int *y)
+{
+ int dx, dy;
+ Window parent;
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ if (win == default_root)
+ {
+ if (x)
+ *x = 0;
+ if (y)
+ *y = 0;
+ return;
+ }
+ xid = ecore_validate_xid(win);
+ if (!xid)
+ {
+ if (x)
+ *x = 0;
+ if (y)
+ *y = 0;
+ return;
+ }
+ dx = 0;
+ dy = 0;
+ do
+ {
+ parent = xid->parent;
+ dx += xid->x;
+ dy += xid->y;
+ if (parent != default_root)
+ {
+ xid = ecore_validate_xid(parent);
+ if (!xid)
+ {
+ if (x)
+ *x = dx;
+ if (y)
+ *y = dy;
+ return;
+ }
+ }
+ }
+ while (parent != default_root);
+ if (x)
+ *x = dx;
+ if (y)
+ *y = dy;
+}
+
+void
+ecore_window_button_grab_auto_replay_set(Window win, int (*func) (Ecore_Event_Mouse_Down *ev))
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (!xid) return;
+ xid->grab_button_auto_replay = func;
+}
+
+void *
+ecore_window_button_grab_auto_replay_get(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return NULL;
+ xid = ecore_validate_xid(win);
+ if (!xid) return NULL;
+ return xid->grab_button_auto_replay;
+}
+
+void
+ecore_button_grab(Window win, int button, int events,
+ Ecore_Event_Key_Modifiers mod, int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ if (!disp) return;
+ b = button;
+ if (b == 0)
+ b = AnyButton;
+ m = 0;
+ if (any_mod)
+ m = AnyModifier;
+ else
+ {
+ if (mod & ECORE_EVENT_KEY_MODIFIER_SHIFT)
+ m |= ecore_mod_mask_shift_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_CTRL)
+ m |= ecore_mod_mask_ctrl_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_ALT)
+ m |= ecore_mod_mask_alt_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_WIN)
+ m |= ecore_mod_mask_win_get();
+ }
+ locks[0] = 0;
+ locks[1] = ecore_lock_mask_caps_get();
+ locks[2] = ecore_lock_mask_num_get();
+ locks[3] = ecore_lock_mask_scroll_get();
+ locks[4] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get();
+ locks[5] = ecore_lock_mask_caps_get() | ecore_lock_mask_scroll_get();
+ locks[6] = ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get();
+ locks[7] =
+ ecore_lock_mask_caps_get() | ecore_lock_mask_num_get() |
+ ecore_lock_mask_scroll_get();
+ for (i = 0; i < 8; i++)
+ XGrabButton(disp, b, m | locks[i],
+ win, False, events, GrabModeSync, GrabModeAsync, None, None);
+}
+
+void
+ecore_button_ungrab(Window win, int button, Ecore_Event_Key_Modifiers mod,
+ int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ if (!disp) return;
+ b = button;
+ if (b == 0)
+ b = AnyButton;
+ m = 0;
+ if (any_mod)
+ m = AnyModifier;
+ else
+ {
+ if (mod & ECORE_EVENT_KEY_MODIFIER_SHIFT)
+ m |= ecore_mod_mask_shift_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_CTRL)
+ m |= ecore_mod_mask_ctrl_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_ALT)
+ m |= ecore_mod_mask_alt_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_WIN)
+ m |= ecore_mod_mask_win_get();
+ }
+ locks[0] = 0;
+ locks[1] = ecore_lock_mask_caps_get();
+ locks[2] = ecore_lock_mask_num_get();
+ locks[3] = ecore_lock_mask_scroll_get();
+ locks[4] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get();
+ locks[5] = ecore_lock_mask_caps_get() | ecore_lock_mask_scroll_get();
+ locks[6] = ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get();
+ locks[7] =
+ ecore_lock_mask_caps_get() | ecore_lock_mask_num_get() |
+ ecore_lock_mask_scroll_get();
+ for (i = 0; i < 8; i++)
+ XUngrabButton(disp, b, m | locks[i], win);
+}
+
+void
+ecore_pointer_replay(Time t)
+{
+ if (!disp) return;
+ XSync(disp, False);
+ XAllowEvents(disp, ReplayPointer, t);
+ XSync(disp, False);
+}
+
+void
+ecore_pointer_grab(Window win, Time t)
+{
+ if (!disp) return;
+ XGrabPointer(disp, win, False, XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT,
+ GrabModeAsync, GrabModeAsync, None, None, t);
+}
+
+void
+ecore_pointer_ungrab(Time t)
+{
+ if (!disp) return;
+ XUngrabPointer(disp, t);
+}
+
+void
+ecore_window_send_event_move_resize(Window win, int x, int y, int w, int h)
+{
+ XEvent ev;
+
+ if (!disp) return;
+ ev.type = ConfigureNotify;
+ ev.xconfigure.display = disp;
+ ev.xconfigure.event = win;
+ ev.xconfigure.window = win;
+ ev.xconfigure.x = x;
+ ev.xconfigure.y = y;
+ ev.xconfigure.width = w;
+ ev.xconfigure.height = h;
+ ev.xconfigure.border_width = 0;
+ ev.xconfigure.above = win;
+ ev.xconfigure.override_redirect = False;
+ XSendEvent(disp, win, False, StructureNotifyMask, &ev);
+}
+
+void
+ecore_window_send_client_message(Window win, Atom type, int format, void *data)
+{
+ XClientMessageEvent ev;
+ int i;
+
+ if (!disp) return;
+ ev.type = ClientMessage;
+ ev.window = win;
+ ev.message_type = type;
+ ev.format = format;
+ if (format == 32)
+ {
+ for (i = 0; i < 5; i++)
+ ev.data.l[i] = ((unsigned int *)data)[i];
+ }
+ else if (format == 16)
+ {
+ for (i = 0; i < 10; i++)
+ ev.data.s[i] = ((unsigned short *)data)[i];
+ }
+ else if (format == 8)
+ {
+ for (i = 0; i < 20; i++)
+ ev.data.b[i] = ((unsigned char *)data)[i];
+ }
+ XSendEvent(disp, win, False, 0, (XEvent *) & ev);
+}
+
+void
+ecore_window_add_to_save_set(Window win)
+{
+ if (!disp) return;
+ XAddToSaveSet(disp, win);
+}
+
+void
+ecore_window_del_from_save_set(Window win)
+{
+ if (!disp) return;
+ XRemoveFromSaveSet(disp, win);
+}
+
+void
+ecore_window_kill_client(Window win)
+{
+ if (!disp) return;
+ XKillClient(disp, (XID) win);
+}
+
+void
+ecore_window_set_border_width(Window win, int bw)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ xid->bw = bw;
+ }
+ XSetWindowBorderWidth(disp, win, bw);
+}
+
+int
+ecore_window_get_border_width(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ return xid->bw;
+ }
+
+ return 0;
+}
+
+int
+ecore_window_get_wm_size_hints(Window win, XSizeHints * hints, int *mask)
+{
+ long sup_ret;
+ Status ok;
+
+ if (!disp) return 0;
+
+ ok = XGetWMNormalHints(disp, win, hints, &sup_ret);
+ *mask = (int)sup_ret;
+ return ok;
+}
+
+int
+ecore_window_is_visible(Window win)
+{
+ XWindowAttributes att;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ if (att.map_state == IsUnmapped)
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+int
+ecore_window_is_normal(Window win)
+{
+ XWindowAttributes att;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ if ((att.override_redirect) || (att.class == InputOnly))
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+int
+ecore_window_is_manageable(Window win)
+{
+ XWindowAttributes att;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ if ((att.map_state == IsUnmapped) || (att.override_redirect)
+ || (att.class == InputOnly))
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+void
+ecore_windows_restack(Window * wins, int num)
+{
+ if (!disp) return;
+ XRestackWindows(disp, wins, num);
+}
+
+void
+ecore_window_stack_above(Window win, Window above)
+{
+ XWindowChanges xwc;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ xwc.sibling = above;
+ xwc.stack_mode = Above;
+ XConfigureWindow(disp, win, CWSibling | CWStackMode, &xwc);
+}
+
+void
+ecore_window_stack_below(Window win, Window below)
+{
+ XWindowChanges xwc;
+
+ if (!disp) return;
+
+ if (win == 0)
+ win = default_root;
+ xwc.sibling = below;
+ xwc.stack_mode = Below;
+ XConfigureWindow(disp, win, CWSibling | CWStackMode, &xwc);
+}
+
+char *
+ecore_window_get_title(Window win)
+{
+ XTextProperty xtp;
+
+ if (!disp) return 0;
+
+ if (win == 0)
+ win = default_root;
+ if (XGetWMName(disp, win, &xtp))
+ {
+ int items;
+ char **list;
+ Status s;
+ char *title = NULL;
+
+ if (xtp.format == 8)
+ {
+ s = XmbTextPropertyToTextList(disp, &xtp, &list, &items);
+ if ((s == Success) && (items > 0))
+ {
+ title = strdup(*list);
+ XFreeStringList(list);
+ }
+ else
+ title = strdup((char *)xtp.value);
+ }
+ else
+ title = strdup((char *)xtp.value);
+ XFree(xtp.value);
+ return title;
+ }
+ return NULL;
+}
+
+void
+ecore_keyboard_grab(Window win)
+{
+ int status;
+
+ if (!disp) return;
+ if (keyboard_grab_win)
+ return;
+ if (win == 0)
+ win = default_root;
+ keyboard_grab_win = win;
+ status =
+ XGrabKeyboard(disp, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
+ if ((status == AlreadyGrabbed) || (status == GrabNotViewable)
+ || (status == GrabFrozen) || (status == GrabInvalidTime))
+ keyboard_grab_win = 0;
+}
+
+void
+ecore_keyboard_ungrab(void)
+{
+ if (!disp) return;
+ if (!keyboard_grab_win)
+ return;
+ keyboard_grab_win = 0;
+ XUngrabKeyboard(disp, CurrentTime);
+}
+
+Window
+ecore_keyboard_grab_window_get(void)
+{
+ if (!disp) return 0;
+ return keyboard_grab_win;
+}
+
+Window
+ecore_selection_set(char *string)
+{
+ Window target = 0;
+ static Atom dest = 0;
+ Atom selection;
+
+ if (!disp) return 0;
+ selection = X_CLIPBOARD_SELECTION;
+ ECORE_ATOM(dest, "TEXT_SELECTION");
+ target = ecore_window_new(0, 0, 0, 77, 7);
+ ecore_window_add_events(target, XEV_CONFIGURE | XEV_PROPERTY);
+ XSetSelectionOwner(disp, selection, target, CurrentTime);
+ if (XGetSelectionOwner(disp, XA_PRIMARY) != target)
+ {
+ ecore_window_destroy(target);
+ return 0;
+ }
+ XChangeProperty(disp, target, dest,
+ XA_STRING, 8, PropModeReplace, string, strlen(string));
+ return target;
+}
+
+Window
+ecore_selection_request(void)
+{
+ static Atom dest = 0;
+ Atom selection;
+ Window target = 0;
+
+ if (!disp) return 0;
+ selection = X_CLIPBOARD_SELECTION;
+ ECORE_ATOM(dest, "TEXT_SELECTION");
+ target = ecore_window_new(0, 0, 0, 7, 77);
+ ecore_window_add_events(target, XEV_CONFIGURE | XEV_PROPERTY);
+ XConvertSelection(disp, XA_PRIMARY, XA_STRING, dest, target, CurrentTime);
+ return target;
+}
+
+char *
+ecore_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 (!disp) return NULL;
+ 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;
+}
+
+void
+ecore_set_blank_pointer(Window w)
+{
+ Cursor c;
+ XColor cl;
+ Pixmap p, m;
+ GC gc;
+ XGCValues gcv;
+
+ if (!disp) return;
+ if (w == 0)
+ w = default_root;
+ p = XCreatePixmap(disp, w, 1, 1, 1);
+ m = XCreatePixmap(disp, w, 1, 1, 1);
+ gc = XCreateGC(disp, m, 0, &gcv);
+ XSetForeground(disp, gc, 0);
+ XDrawPoint(disp, m, gc, 0, 0);
+ XFreeGC(disp, gc);
+ c = XCreatePixmapCursor(disp, p, m, &cl, &cl, 0, 0);
+ XDefineCursor(disp, w, c);
+ XFreeCursor(disp, c);
+ XFreePixmap(disp, p);
+ XFreePixmap(disp, m);
+}
+
+Cursor
+ecore_cursor_new(Pixmap pmap, Pixmap mask, int x, int y, int fr, int fg, int fb,
+ int br, int bg, int bb)
+{
+ XColor cl1, cl2;
+
+ if (!disp) return 0;
+ cl1.pixel = 0;
+ cl1.red = fr << 8 | fr;
+ cl1.green = fg << 8 | fg;
+ cl1.blue = fb << 8 | fb;
+ cl1.flags = DoRed | DoGreen | DoBlue;
+ cl2.pixel = 0;
+ cl2.red = br << 8 | br;
+ cl2.green = bg << 8 | bg;
+ cl2.blue = bb << 8 | bb;
+ cl2.flags = DoRed | DoGreen | DoBlue;
+ return XCreatePixmapCursor(disp, pmap, mask, &cl1, &cl2, x, y);
+}
+
+void
+ecore_cursor_free(Cursor c)
+{
+ if (!disp) return;
+ XFreeCursor(disp, c);
+}
+
+void
+ecore_cursor_set(Window win, Cursor c)
+{
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ XDefineCursor(disp, win, c);
+}