diff options
Diffstat (limited to 'ecore/src/e_x.c')
-rw-r--r-- | ecore/src/e_x.c | 3610 |
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); +} |