efl/legacy/ecore/src/e_x.c

3611 lines
75 KiB
C

#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);
}