efl

Форк
0
/
ecore_x.c 
2614 строк · 75.8 Кб
1
#ifdef HAVE_CONFIG_H
2
# include <config.h>
3
#endif /* ifdef HAVE_CONFIG_H */
4

5
#ifdef STDC_HEADERS
6
# include <stdlib.h>
7
# include <stddef.h>
8
#else
9
# ifdef HAVE_STDLIB_H
10
#  include <stdlib.h>
11
# endif
12
#endif
13

14
#include <stdlib.h>
15
#include <string.h>
16
#include <unistd.h>
17

18
//#define LOGRT 1
19

20
#ifdef LOGRT
21
#include <dlfcn.h>
22
#endif /* ifdef LOGRT */
23

24
#include "Ecore.h"
25
#include "ecore_private.h"
26
#include "ecore_x_private.h"
27
#include "Ecore_X.h"
28
#include "Ecore_X_Atoms.h"
29
#include "Ecore_Input.h"
30

31
static Ecore_X_Version _version = { VMAJ, VMIN, VMIC, VREV };
32
EAPI Ecore_X_Version *ecore_x_version = &_version;
33

34
static Eina_Bool _ecore_x_fd_handler(void *data,
35
                                     Ecore_Fd_Handler *fd_handler);
36
static Eina_Bool _ecore_x_fd_handler_buf(void *data,
37
                                         Ecore_Fd_Handler *fd_handler);
38
static int       _ecore_x_key_mask_get(XModifierKeymap *mod, KeySym sym);
39
static int       _ecore_x_event_modifier(unsigned int state);
40

41
static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL;
42

43
static const int AnyXEvent = 0; /* 0 can be used as there are no event types
44
                                 * with index 0 and 1 as they are used for
45
                                 * errors
46
                                 */
47

48
static int _ecore_x_event_shape_id = 0;
49
static int _ecore_x_event_screensaver_id = 0;
50
static int _ecore_x_event_sync_id = 0;
51
int _ecore_xlib_log_dom = -1;
52

53
Eina_Bool _ecore_xlib_sync = EINA_FALSE;
54

55
#ifdef ECORE_XRANDR
56
static int _ecore_x_event_randr_id = 0;
57
#endif /* ifdef ECORE_XRANDR */
58
#ifdef ECORE_XFIXES
59
static int _ecore_x_event_fixes_selection_id = 0;
60
#endif /* ifdef ECORE_XFIXES */
61
#ifdef ECORE_XDAMAGE
62
static int _ecore_x_event_damage_id = 0;
63
#endif /* ifdef ECORE_XDAMAGE */
64
#ifdef ECORE_XKB
65
static int _ecore_x_event_xkb_id = 0;
66
#endif /* ifdef ECORE_XKB */
67
static int _ecore_x_event_handlers_num = 0;
68
typedef void (*Ecore_X_Event_Handler) (XEvent *event);
69
static Ecore_X_Event_Handler *_ecore_x_event_handlers = NULL;
70

71
static int _ecore_x_init_count = 0;
72
static int _ecore_x_grab_count = 0;
73

74
Display *_ecore_x_disp = NULL;
75
double _ecore_x_double_click_time = 0.25;
76
Time _ecore_x_event_last_time = 0;
77
Window _ecore_x_event_last_win = 0;
78
int _ecore_x_event_last_root_x = 0;
79
int _ecore_x_event_last_root_y = 0;
80
Eina_Bool _ecore_x_xcursor = EINA_FALSE;
81

82
Ecore_X_Window _ecore_x_private_win = 0;
83

84
Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
85

86
EAPI int ECORE_X_EVENT_ANY = 0;
87
EAPI int ECORE_X_EVENT_MOUSE_IN = 0;
88
EAPI int ECORE_X_EVENT_MOUSE_OUT = 0;
89
EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0;
90
EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0;
91
EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0;
92
EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0;
93
EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0;
94
EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0;
95
EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0;
96
EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0;
97
EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0;
98
EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0;
99
EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0;
100
EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0;
101
EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0;
102
EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0;
103
EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0;
104
EAPI int ECORE_X_EVENT_WINDOW_STACK = 0;
105
EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0;
106
EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0;
107
EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0;
108
EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0;
109
EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0;
110
EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
111
EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
112
EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
113
EAPI int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = 0;
114
EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
115
EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
116
EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
117
EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_FLICK;
118
EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN;
119
EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION;
120
EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP;
121
EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD;
122
EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD;
123
EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP;
124
EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0;
125
EAPI int ECORE_X_EVENT_SYNC_ALARM = 0;
126
EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0;
127
EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0;
128
EAPI int ECORE_X_EVENT_RANDR_CRTC_CHANGE = 0;
129
EAPI int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = 0;
130
EAPI int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = 0;
131
EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
132
EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0;
133
EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0;
134
EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0;
135
EAPI int ECORE_X_EVENT_PING = 0;
136
EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0;
137

138
EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0;
139
EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0;
140
EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0;
141

142
EAPI int ECORE_X_EVENT_XKB_STATE_NOTIFY = 0;
143
EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0;
144

145

146
EAPI int ECORE_X_EVENT_GENERIC = 0;
147

148
EAPI int ECORE_X_EVENT_PRESENT_CONFIGURE = 0;
149
EAPI int ECORE_X_EVENT_PRESENT_COMPLETE = 0;
150
EAPI int ECORE_X_EVENT_PRESENT_IDLE = 0;
151

152
EAPI int ECORE_X_MODIFIER_SHIFT = 0;
153
EAPI int ECORE_X_MODIFIER_CTRL = 0;
154
EAPI int ECORE_X_MODIFIER_ALT = 0;
155
EAPI int ECORE_X_MODIFIER_WIN = 0;
156
EAPI int ECORE_X_MODIFIER_ALTGR = 0;
157

158
EAPI int ECORE_X_LOCK_SCROLL = 0;
159
EAPI int ECORE_X_LOCK_NUM = 0;
160
EAPI int ECORE_X_LOCK_CAPS = 0;
161
EAPI int ECORE_X_LOCK_SHIFT = 0;
162

163
EAPI int ECORE_X_RAW_BUTTON_PRESS = 0;
164
EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0;
165
EAPI int ECORE_X_RAW_MOTION = 0;
166

167
EAPI int ECORE_X_DEVICES_CHANGE = 0;
168

169
#ifdef LOGRT
170
static double t0 = 0.0;
171
static Status (*_logrt_real_reply)(Display *disp,
172
                                   void *rep,
173
                                   int extra,
174
                                   Bool discard) = NULL;
175
static void
176
_logrt_init(void)
177
{
178
   void *lib;
179

180
   lib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
181
   if (!lib)
182
     lib = dlopen("libX11.so.6", RTLD_GLOBAL | RTLD_LAZY);
183

184
   if (!lib)
185
     lib = dlopen("libX11.so.6.3", RTLD_GLOBAL | RTLD_LAZY);
186

187
   if (!lib)
188
     lib = dlopen("libX11.so.6.3.0", RTLD_GLOBAL | RTLD_LAZY);
189

190
   _logrt_real_reply = dlsym(lib, "_XReply");
191
   t0 = ecore_time_get();
192
}
193

194
Status
195
_XReply(Display *disp,
196
        void *rep,
197
        int extra,
198
        Bool discard)
199
{
200
   void *bt[128];
201
   int i, n;
202
   char **sym;
203

204
   n = backtrace(bt, 128);
205
   if (n > 0)
206
     {
207
        sym = backtrace_symbols(bt, n);
208
        printf("ROUNDTRIP: %4.4f :", ecore_time_get() - t0);
209
        if (sym)
210
          {
211
             for (i = n - 1; i > 0; i--)
212
               {
213
                  char *fname = strchr(sym[i], '(');
214
                  if (fname)
215
                    {
216
                       char *tsym = alloca(strlen(fname) + 1);
217
                       char *end;
218
                       strcpy(tsym, fname + 1);
219
                       end = strchr(tsym, '+');
220
                       if (end)
221
                         {
222
                            *end = 0;
223
                            printf("%s", tsym);
224
                         }
225
                       else
226
                         printf("???");
227
                    }
228
                  else
229
                    printf("???");
230

231
                  if (i > 1)
232
                    printf(" > ");
233
               }
234
             printf("\n");
235
          }
236
     }
237

238
   // fixme: logme
239
   return _logrt_real_reply(disp, rep, extra, discard);
240
}
241

242
#endif /* ifdef LOGRT */
243

244
/* wrapper to use XkbKeycodeToKeysym when possible */
245
KeySym
246
_ecore_x_XKeycodeToKeysym(Display *display, KeyCode keycode, int idx)
247
{
248
#ifdef ECORE_XKB
249
   return XkbKeycodeToKeysym(display, keycode, 0, idx);
250
#else
251
   return XKeycodeToKeysym(display, keycode, idx);
252
#endif
253
}
254

255
void
256
_ecore_x_modifiers_get(void)
257
{
258
   XModifierKeymap *mod;
259
   ECORE_X_MODIFIER_SHIFT = 0;
260
   ECORE_X_MODIFIER_CTRL = 0;
261
   ECORE_X_MODIFIER_ALT = 0;
262
   ECORE_X_MODIFIER_WIN = 0;
263
   ECORE_X_MODIFIER_ALTGR = 0;
264
   ECORE_X_LOCK_SCROLL = 0;
265
   ECORE_X_LOCK_NUM = 0;
266
   ECORE_X_LOCK_CAPS = 0;
267
   ECORE_X_LOCK_SHIFT = 0;
268

269
   mod = XGetModifierMapping(_ecore_x_disp);
270
   if ((!mod) || (mod->max_keypermod <= 0)) goto clean_up;
271

272
   /* everything has these... unless its like a pda... :) */
273
   ECORE_X_MODIFIER_SHIFT = _ecore_x_key_mask_get(mod, XK_Shift_L);
274
   ECORE_X_MODIFIER_CTRL = _ecore_x_key_mask_get(mod, XK_Control_L);
275

276
   /* apple's xdarwin has no alt!!!! */
277
   ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(mod, XK_Alt_L);
278
   if (!ECORE_X_MODIFIER_ALT)
279
     ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(mod, XK_Meta_L);
280

281
   if (!ECORE_X_MODIFIER_ALT)
282
     ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(mod, XK_Super_L);
283

284
   /* the windows key... a valid modifier :) */
285
   ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(mod, XK_Super_L);
286
   if (!ECORE_X_MODIFIER_WIN)
287
     ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(mod, XK_Meta_L);
288

289
   ECORE_X_MODIFIER_ALTGR = _ecore_x_key_mask_get(mod, XK_Mode_switch);
290

291
   if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT)
292
     ECORE_X_MODIFIER_WIN = 0;
293

294
   if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL)
295
     ECORE_X_MODIFIER_ALT = 0;
296

297
   if (ECORE_X_MODIFIER_ALTGR)
298
     {
299
        if ((ECORE_X_MODIFIER_ALTGR == ECORE_X_MODIFIER_SHIFT) ||
300
            (ECORE_X_MODIFIER_ALTGR == ECORE_X_MODIFIER_CTRL) ||
301
            (ECORE_X_MODIFIER_ALTGR == ECORE_X_MODIFIER_ALT) ||
302
            (ECORE_X_MODIFIER_ALTGR == ECORE_X_MODIFIER_WIN))
303
          {
304
             ERR("ALTGR conflicts with other modifiers. IGNORE ALTGR");
305
             ECORE_X_MODIFIER_ALTGR = 0;
306
          }
307
     }
308

309
   if (ECORE_X_MODIFIER_ALT)
310
     {
311
        if ((ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_SHIFT) ||
312
            (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL) ||
313
            (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_WIN))
314
          {
315
             ERR("ALT conflicts with other modifiers. IGNORE ALT");
316
             ECORE_X_MODIFIER_ALT = 0;
317
          }
318
     }
319

320
   if (ECORE_X_MODIFIER_WIN)
321
     {
322
        if ((ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_SHIFT) ||
323
            (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_CTRL))
324
          {
325
             ERR("WIN conflicts with other modifiers. IGNORE WIN");
326
             ECORE_X_MODIFIER_WIN = 0;
327
          }
328
     }
329

330
   if (ECORE_X_MODIFIER_SHIFT)
331
     {
332
        if (ECORE_X_MODIFIER_SHIFT == ECORE_X_MODIFIER_CTRL)
333
          {
334
             ERR("CTRL conflicts with other modifiers. IGNORE CTRL");
335
             ECORE_X_MODIFIER_CTRL = 0;
336
          }
337
     }
338

339
   ECORE_X_LOCK_SCROLL = _ecore_x_key_mask_get(mod, XK_Scroll_Lock);
340
   ECORE_X_LOCK_NUM = _ecore_x_key_mask_get(mod, XK_Num_Lock);
341
   ECORE_X_LOCK_CAPS = _ecore_x_key_mask_get(mod, XK_Caps_Lock);
342
   ECORE_X_LOCK_SHIFT = _ecore_x_key_mask_get(mod, XK_Shift_Lock);
343

344
clean_up:
345
   if (mod)
346
     {
347
        if (mod->modifiermap) XFree(mod->modifiermap);
348
        XFree(mod);
349
     }
350
}
351

352
static Eina_Bool
353
_ecore_x_init1(void)
354
{
355
   LOGFN;
356
#ifdef LOGRT
357
   _logrt_init();
358
#endif /* ifdef LOGRT */
359

360
   eina_init();
361
   _ecore_xlib_log_dom = eina_log_domain_register
362
       ("ecore_x", ECORE_XLIB_DEFAULT_LOG_COLOR);
363
   if (_ecore_xlib_log_dom < 0)
364
     {
365
        EINA_LOG_ERR(
366
          "Impossible to create a log domain for the Ecore Xlib module.");
367
        return EINA_FALSE;
368
     }
369

370
   if (!ecore_init())
371
     goto shutdown_eina;
372
   if (!ecore_event_init())
373
     goto shutdown_ecore;
374

375
   return EINA_TRUE;
376
shutdown_ecore:
377
   ecore_shutdown();
378
shutdown_eina:
379
   eina_log_domain_unregister(_ecore_xlib_log_dom);
380
   _ecore_xlib_log_dom = -1;
381
   eina_shutdown();
382
   return EINA_FALSE;
383
}
384

385
static Eina_Bool
386
_ecore_x_init2(void)
387
{
388
   int shape_base = 0;
389
   int shape_err_base = 0;
390
#ifdef ECORE_XSS
391
   int screensaver_base = 0;
392
   int screensaver_err_base = 0;
393
#endif /* ifdef ECORE_XSS */
394
   int sync_base = 0;
395
   int sync_err_base = 0;
396
#ifdef ECORE_XRANDR
397
   int randr_base = 0;
398
   int randr_err_base = 0;
399
#endif /* ifdef ECORE_XRANDR */
400
#ifdef ECORE_XFIXES
401
   int fixes_base = 0;
402
   int fixes_err_base = 0;
403
#endif /* ifdef ECORE_XFIXES */
404
#ifdef ECORE_XDAMAGE
405
   int damage_base = 0;
406
   int damage_err_base = 0;
407
#endif /* ifdef ECORE_XDAMAGE */
408
#ifdef ECORE_XKB
409
   int xkb_base = 0;
410
#endif /* ifdef ECORE_XKB */
411

412
   _ecore_x_error_handler_init();
413
   _ecore_x_event_handlers_num = LASTEvent;
414

415
#define ECORE_X_EVENT_HANDLERS_GROW(ext_base, ext_num_events)            \
416
  do {                                                                   \
417
       if (_ecore_x_event_handlers_num < (ext_base + ext_num_events)) {  \
418
            _ecore_x_event_handlers_num = (ext_base + ext_num_events); } \
419
    } while (0)
420

421
   if (XShapeQueryExtension(_ecore_x_disp, &shape_base, &shape_err_base))
422
     _ecore_x_event_shape_id = shape_base;
423

424
   ECORE_X_EVENT_HANDLERS_GROW(shape_base, ShapeNumberEvents);
425

426
#ifdef ECORE_XSS
427
   if (XScreenSaverQueryExtension(_ecore_x_disp, &screensaver_base,
428
                                  &screensaver_err_base))
429
     _ecore_x_event_screensaver_id = screensaver_base;
430

431
   ECORE_X_EVENT_HANDLERS_GROW(screensaver_base, ScreenSaverNumberEvents);
432
#endif /* ifdef ECORE_XSS */
433

434
   if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base))
435
     {
436
        int major, minor;
437

438
        _ecore_x_event_sync_id = sync_base;
439
        if (!XSyncInitialize(_ecore_x_disp, &major, &minor))
440
          _ecore_x_event_sync_id = 0;
441
     }
442

443
   ECORE_X_EVENT_HANDLERS_GROW(sync_base, XSyncNumberEvents);
444

445
#ifdef ECORE_XRANDR
446
   if (XRRQueryExtension(_ecore_x_disp, &randr_base, &randr_err_base))
447
     _ecore_x_event_randr_id = randr_base;
448

449
   ECORE_X_EVENT_HANDLERS_GROW(randr_base, RRNumberEvents);
450
#endif /* ifdef ECORE_XRANDR */
451

452
#ifdef ECORE_XFIXES
453
   if (XFixesQueryExtension(_ecore_x_disp, &fixes_base, &fixes_err_base))
454
     _ecore_x_event_fixes_selection_id = fixes_base;
455

456
   ECORE_X_EVENT_HANDLERS_GROW(fixes_base, XFixesNumberEvents);
457
#endif /* ifdef ECORE_XFIXES */
458

459
#ifdef ECORE_XDAMAGE
460
   if (XDamageQueryExtension(_ecore_x_disp, &damage_base, &damage_err_base))
461
     _ecore_x_event_damage_id = damage_base;
462

463
   ECORE_X_EVENT_HANDLERS_GROW(damage_base, XDamageNumberEvents);
464
#endif /* ifdef ECORE_XDAMAGE */
465

466
#ifdef ECORE_XKB
467
     {
468
        int dummy;
469

470
        if (XkbQueryExtension(_ecore_x_disp, &dummy, &xkb_base,
471
                              &dummy, &dummy, &dummy))
472
          _ecore_x_event_xkb_id = xkb_base;
473
        XkbSelectEventDetails(_ecore_x_disp, XkbUseCoreKbd, XkbStateNotify,
474
                              XkbAllStateComponentsMask, XkbGroupStateMask);
475
        XkbSelectEventDetails(_ecore_x_disp, XkbUseCoreKbd, XkbNewKeyboardNotify,
476
                              XkbNewKeyboardNotifyMask, XkbNewKeyboardNotifyMask);
477
     }
478
   ECORE_X_EVENT_HANDLERS_GROW(xkb_base, XkbNumberEvents);
479
#endif
480

481
   _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(Ecore_X_Event_Handler));
482
   if (!_ecore_x_event_handlers)
483
     goto close_display;
484

485
#ifdef ECORE_XCURSOR
486
   _ecore_x_xcursor = XcursorSupportsARGB(_ecore_x_disp) ? EINA_TRUE : EINA_FALSE;
487
#endif /* ifdef ECORE_XCURSOR */
488
   _ecore_x_event_handlers[AnyXEvent] = _ecore_x_event_handle_any_event;
489
   _ecore_x_event_handlers[KeyPress] = _ecore_x_event_handle_key_press;
490
   _ecore_x_event_handlers[KeyRelease] = _ecore_x_event_handle_key_release;
491
   _ecore_x_event_handlers[ButtonPress] = _ecore_x_event_handle_button_press;
492
   _ecore_x_event_handlers[ButtonRelease] = _ecore_x_event_handle_button_release;
493
   _ecore_x_event_handlers[MotionNotify] = _ecore_x_event_handle_motion_notify;
494
   _ecore_x_event_handlers[EnterNotify] = _ecore_x_event_handle_enter_notify;
495
   _ecore_x_event_handlers[LeaveNotify] = _ecore_x_event_handle_leave_notify;
496
   _ecore_x_event_handlers[FocusIn] = _ecore_x_event_handle_focus_in;
497
   _ecore_x_event_handlers[FocusOut] = _ecore_x_event_handle_focus_out;
498
   _ecore_x_event_handlers[KeymapNotify] = _ecore_x_event_handle_keymap_notify;
499
   _ecore_x_event_handlers[Expose] = _ecore_x_event_handle_expose;
500
   _ecore_x_event_handlers[GraphicsExpose] = _ecore_x_event_handle_graphics_expose;
501
   _ecore_x_event_handlers[VisibilityNotify] = _ecore_x_event_handle_visibility_notify;
502
   _ecore_x_event_handlers[CreateNotify] = _ecore_x_event_handle_create_notify;
503
   _ecore_x_event_handlers[DestroyNotify] = _ecore_x_event_handle_destroy_notify;
504
   _ecore_x_event_handlers[UnmapNotify] = _ecore_x_event_handle_unmap_notify;
505
   _ecore_x_event_handlers[MapNotify] = _ecore_x_event_handle_map_notify;
506
   _ecore_x_event_handlers[MapRequest] = _ecore_x_event_handle_map_request;
507
   _ecore_x_event_handlers[ReparentNotify] = _ecore_x_event_handle_reparent_notify;
508
   _ecore_x_event_handlers[ConfigureNotify] = _ecore_x_event_handle_configure_notify;
509
   _ecore_x_event_handlers[ConfigureRequest] = _ecore_x_event_handle_configure_request;
510
   _ecore_x_event_handlers[GravityNotify] = _ecore_x_event_handle_gravity_notify;
511
   _ecore_x_event_handlers[ResizeRequest] = _ecore_x_event_handle_resize_request;
512
   _ecore_x_event_handlers[CirculateNotify] = _ecore_x_event_handle_circulate_notify;
513
   _ecore_x_event_handlers[CirculateRequest] = _ecore_x_event_handle_circulate_request;
514
   _ecore_x_event_handlers[PropertyNotify] = _ecore_x_event_handle_property_notify;
515
   _ecore_x_event_handlers[SelectionClear] = _ecore_x_event_handle_selection_clear;
516
   _ecore_x_event_handlers[SelectionRequest] = _ecore_x_event_handle_selection_request;
517
   _ecore_x_event_handlers[SelectionNotify] = _ecore_x_event_handle_selection_notify;
518
   _ecore_x_event_handlers[ColormapNotify] = _ecore_x_event_handle_colormap_notify;
519
   _ecore_x_event_handlers[ClientMessage] = _ecore_x_event_handle_client_message;
520
   _ecore_x_event_handlers[MappingNotify] = _ecore_x_event_handle_mapping_notify;
521
#ifdef GenericEvent
522
   _ecore_x_event_handlers[GenericEvent] = _ecore_x_event_handle_generic_event;
523
#endif /* ifdef GenericEvent */
524

525
   if (_ecore_x_event_shape_id)
526
     _ecore_x_event_handlers[_ecore_x_event_shape_id] = _ecore_x_event_handle_shape_change;
527
   if (_ecore_x_event_screensaver_id)
528
     _ecore_x_event_handlers[_ecore_x_event_screensaver_id] = _ecore_x_event_handle_screensaver_notify;
529
   if (_ecore_x_event_sync_id)
530
     {
531
        _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncCounterNotify] = _ecore_x_event_handle_sync_counter;
532
        _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncAlarmNotify] = _ecore_x_event_handle_sync_alarm;
533
     }
534

535
#ifdef ECORE_XRANDR
536
   if (_ecore_x_event_randr_id)
537
     {
538
        _ecore_x_event_handlers[_ecore_x_event_randr_id + RRScreenChangeNotify] = _ecore_x_event_handle_randr_change;
539
        _ecore_x_event_handlers[_ecore_x_event_randr_id + RRNotify] = _ecore_x_event_handle_randr_notify;
540
     }
541
#endif /* ifdef ECORE_XRANDR */
542
#ifdef ECORE_XFIXES
543
   if (_ecore_x_event_fixes_selection_id)
544
     _ecore_x_event_handlers[_ecore_x_event_fixes_selection_id] = _ecore_x_event_handle_fixes_selection_notify;
545

546
#endif /* ifdef ECORE_XFIXES */
547
#ifdef ECORE_XDAMAGE
548
   if (_ecore_x_event_damage_id)
549
     _ecore_x_event_handlers[_ecore_x_event_damage_id] = _ecore_x_event_handle_damage_notify;
550

551
#endif /* ifdef ECORE_XDAMAGE */
552
#ifdef ECORE_XKB
553
   // set x autorepeat detection to on. that means instead of
554
   //   press-release-press-release-press-release
555
   // you get
556
   //   press-press-press-press-press-release
557
   do
558
     {
559
        Bool works = 0;
560
        XkbSetDetectableAutoRepeat(_ecore_x_disp, 1, &works);
561
     }
562
     while (0);
563
   if (_ecore_x_event_xkb_id)
564
   _ecore_x_event_handlers[_ecore_x_event_xkb_id] = _ecore_x_event_handle_xkb;
565
#endif /* ifdef ECORE_XKB */
566

567
   ECORE_X_EVENT_ANY = ecore_event_type_new();
568
   ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new();
569
   ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new();
570
   ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
571
   ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
572
   ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new();
573
   ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
574
   ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new();
575
   ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new();
576
   ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new();
577
   ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new();
578
   ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new();
579
   ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new();
580
   ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new();
581
   ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
582
   ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new();
583
   ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new();
584
   ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new();
585
   ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new();
586
   ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new();
587
   ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new();
588
   ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new();
589
   ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new();
590
   ECORE_X_EVENT_MAPPING_CHANGE = ecore_event_type_new();
591
   ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new();
592
   ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new();
593
   ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new();
594
   ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new();
595
   ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new();
596
   ECORE_X_EVENT_SCREENSAVER_NOTIFY = ecore_event_type_new();
597
   ECORE_X_EVENT_GESTURE_NOTIFY_FLICK = ecore_event_type_new();
598
   ECORE_X_EVENT_GESTURE_NOTIFY_PAN = ecore_event_type_new();
599
   ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = ecore_event_type_new();
600
   ECORE_X_EVENT_GESTURE_NOTIFY_TAP = ecore_event_type_new();
601
   ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = ecore_event_type_new();
602
   ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = ecore_event_type_new();
603
   ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = ecore_event_type_new();
604
   ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new();
605
   ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new();
606
   ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new();
607
   ECORE_X_EVENT_RANDR_CRTC_CHANGE = ecore_event_type_new();
608
   ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = ecore_event_type_new();
609
   ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = ecore_event_type_new();
610
   ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new();
611

612
   ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
613

614
   ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new();
615
   ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new();
616
   ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new();
617
   ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new();
618
   ECORE_X_EVENT_PING = ecore_event_type_new();
619

620
   ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new();
621
   ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new();
622
   ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new();
623

624
   ECORE_X_EVENT_XKB_STATE_NOTIFY = ecore_event_type_new();
625
   ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new();
626

627
   ECORE_X_EVENT_GENERIC = ecore_event_type_new();
628

629
   ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new();
630
   ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new();
631
   ECORE_X_RAW_MOTION = ecore_event_type_new();
632

633
   ECORE_X_DEVICES_CHANGE = ecore_event_type_new();
634

635
   _ecore_x_modifiers_get();
636

637
   _ecore_x_atoms_init();
638

639
   /* Set up the ICCCM hints */
640
   ecore_x_icccm_init();
641

642
   /* Set up the _NET_... hints */
643
   ecore_x_netwm_init();
644

645
   /* old e hints init */
646
   ecore_x_e_init();
647

648
   /* This is just to be anal about naming conventions */
649

650
   _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] =
651
     ECORE_X_ATOM_WM_DELETE_WINDOW;
652
   _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] =
653
     ECORE_X_ATOM_WM_TAKE_FOCUS;
654
   _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] =
655
     ECORE_X_ATOM_NET_WM_PING;
656
   _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] =
657
     ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
658

659
   _ecore_x_selection_data_init();
660
   _ecore_x_dnd_init();
661
   _ecore_x_fixes_init();
662
   _ecore_x_damage_init();
663
   _ecore_x_composite_init();
664
   _ecore_x_present_init();
665
   _ecore_x_dpms_init();
666
   _ecore_x_randr_init();
667
   _ecore_x_input_init();
668
   _ecore_x_events_init();
669

670
   _ecore_x_fd_handler_handle =
671
     ecore_main_fd_handler_add(ConnectionNumber(_ecore_x_disp),
672
                               ECORE_FD_READ,
673
                               _ecore_x_fd_handler, _ecore_x_disp,
674
                               _ecore_x_fd_handler_buf, _ecore_x_disp);
675
   if (!_ecore_x_fd_handler_handle)
676
     goto free_event_handlers;
677

678
   _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456);
679
   _ecore_xlib_sync = !!getenv("ECORE_X_SYNC");
680

681
   return EINA_TRUE;
682

683
free_event_handlers:
684
   free(_ecore_x_event_handlers);
685
   _ecore_x_event_handlers = NULL;
686
close_display:
687
   XCloseDisplay(_ecore_x_disp);
688
   _ecore_x_fd_handler_handle = NULL;
689
   _ecore_x_disp = NULL;
690
   ecore_event_shutdown();
691
   ecore_shutdown();
692
   eina_log_domain_unregister(_ecore_xlib_log_dom);
693
   _ecore_xlib_log_dom = -1;
694
   eina_shutdown();
695
   return EINA_FALSE;
696
}
697

698
/**
699
 * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions
700
 *
701
 * Functions that start and shut down the Ecore X Library.
702
 */
703

704
/**
705
 * Initialize the X display connection to the given display.
706
 *
707
 * @param   name Display target name.  If @c NULL, the default display is
708
 *               assumed.
709
 * @return  The number of times the library has been initialized without
710
 *          being shut down.  0 is returned if an error occurs.
711
 * @ingroup Ecore_X_Init_Group
712
 */
713
EAPI int
714
ecore_x_init(const char *name)
715
{
716
   if (++_ecore_x_init_count != 1)
717
     return _ecore_x_init_count;
718

719
   if (!_ecore_x_init1())
720
     return --_ecore_x_init_count;
721

722
#ifdef EVAS_FRAME_QUEUING
723
   XInitThreads();
724
#endif /* ifdef EVAS_FRAME_QUEUING */
725
   _ecore_x_disp = XOpenDisplay((char *)name);
726
   if (!_ecore_x_disp)
727
     goto shutdown_ecore_event;
728
   if (_ecore_x_init2())
729
     return _ecore_x_init_count;
730
shutdown_ecore_event:
731
   ecore_event_shutdown();
732
   ecore_shutdown();
733
   eina_log_domain_unregister(_ecore_xlib_log_dom);
734
   _ecore_xlib_log_dom = -1;
735
   eina_shutdown();
736
   return --_ecore_x_init_count;
737
}
738

739
EAPI int
740
ecore_x_init_from_display(Ecore_X_Display *display)
741
{
742
   EINA_SAFETY_ON_NULL_RETURN_VAL(display, 0);
743
   if (++_ecore_x_init_count != 1)
744
     return _ecore_x_init_count;
745

746
   if (!_ecore_x_init1())
747
     return --_ecore_x_init_count;
748
   _ecore_x_disp = display;
749
   if (_ecore_x_init2())
750
     return _ecore_x_init_count;
751
   ecore_event_shutdown();
752
   ecore_shutdown();
753
   eina_log_domain_unregister(_ecore_xlib_log_dom);
754
   _ecore_xlib_log_dom = -1;
755
   eina_shutdown();
756
   return --_ecore_x_init_count;
757
}
758
static Eina_Bool _ecore_x_window_manage_succeeded = EINA_FALSE;
759
int
760
_ecore_x_shutdown(void)
761
{
762
   if (!_ecore_x_disp)
763
     return 0;
764

765
   LOGFN;
766

767
   ecore_event_type_flush(ECORE_X_EVENT_ANY,
768
                          ECORE_X_EVENT_MOUSE_IN,
769
                          ECORE_X_EVENT_MOUSE_OUT,
770
                          ECORE_X_EVENT_WINDOW_FOCUS_IN,
771
                          ECORE_X_EVENT_WINDOW_FOCUS_OUT,
772
                          ECORE_X_EVENT_WINDOW_KEYMAP,
773
                          ECORE_X_EVENT_WINDOW_DAMAGE,
774
                          ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE,
775
                          ECORE_X_EVENT_WINDOW_CREATE,
776
                          ECORE_X_EVENT_WINDOW_DESTROY,
777
                          ECORE_X_EVENT_WINDOW_HIDE,
778
                          ECORE_X_EVENT_WINDOW_SHOW,
779
                          ECORE_X_EVENT_WINDOW_SHOW_REQUEST,
780
                          ECORE_X_EVENT_WINDOW_REPARENT,
781
                          ECORE_X_EVENT_WINDOW_CONFIGURE,
782
                          ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST,
783
                          ECORE_X_EVENT_WINDOW_GRAVITY,
784
                          ECORE_X_EVENT_WINDOW_RESIZE_REQUEST,
785
                          ECORE_X_EVENT_WINDOW_STACK,
786
                          ECORE_X_EVENT_WINDOW_STACK_REQUEST,
787
                          ECORE_X_EVENT_WINDOW_PROPERTY,
788
                          ECORE_X_EVENT_WINDOW_COLORMAP,
789
                          ECORE_X_EVENT_WINDOW_MAPPING,
790
                          ECORE_X_EVENT_MAPPING_CHANGE,
791
                          ECORE_X_EVENT_SELECTION_CLEAR,
792
                          ECORE_X_EVENT_SELECTION_REQUEST,
793
                          ECORE_X_EVENT_SELECTION_NOTIFY,
794
                          ECORE_X_EVENT_CLIENT_MESSAGE,
795
                          ECORE_X_EVENT_WINDOW_SHAPE,
796
                          ECORE_X_EVENT_SCREENSAVER_NOTIFY,
797
                          ECORE_X_EVENT_GESTURE_NOTIFY_FLICK,
798
                          ECORE_X_EVENT_GESTURE_NOTIFY_PAN,
799
                          ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION,
800
                          ECORE_X_EVENT_GESTURE_NOTIFY_TAP,
801
                          ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD,
802
                          ECORE_X_EVENT_GESTURE_NOTIFY_HOLD,
803
                          ECORE_X_EVENT_GESTURE_NOTIFY_GROUP,
804
                          ECORE_X_EVENT_SYNC_COUNTER,
805
                          ECORE_X_EVENT_SYNC_ALARM,
806
                          ECORE_X_EVENT_SCREEN_CHANGE,
807
                          ECORE_X_EVENT_RANDR_CRTC_CHANGE,
808
                          ECORE_X_EVENT_RANDR_OUTPUT_CHANGE,
809
                          ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY,
810
                          ECORE_X_EVENT_DAMAGE_NOTIFY,
811
                          ECORE_X_EVENT_WINDOW_DELETE_REQUEST,
812
                          ECORE_X_EVENT_DESKTOP_CHANGE,
813
                          ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST,
814
                          ECORE_X_EVENT_WINDOW_STATE_REQUEST,
815
                          ECORE_X_EVENT_FRAME_EXTENTS_REQUEST,
816
                          ECORE_X_EVENT_PING,
817
                          ECORE_X_EVENT_STARTUP_SEQUENCE_NEW,
818
                          ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE,
819
                          ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE,
820
                          ECORE_X_EVENT_XKB_STATE_NOTIFY,
821
                          ECORE_X_EVENT_XKB_NEWKBD_NOTIFY,
822
                          ECORE_X_EVENT_GENERIC,
823
                          ECORE_X_RAW_BUTTON_PRESS,
824
                          ECORE_X_RAW_BUTTON_RELEASE,
825
                          ECORE_X_RAW_MOTION,
826
                          ECORE_X_EVENT_PRESENT_CONFIGURE,
827
                          ECORE_X_EVENT_PRESENT_COMPLETE,
828
                          ECORE_X_EVENT_PRESENT_IDLE);
829
   ecore_main_fd_handler_del(_ecore_x_fd_handler_handle);
830

831
   free(_ecore_x_event_handlers);
832
   _ecore_x_fd_handler_handle = NULL;
833
   _ecore_x_event_handlers = NULL;
834
   _ecore_x_window_manage_succeeded = EINA_FALSE;
835
   _ecore_x_events_shutdown();
836
   _ecore_x_input_shutdown();
837
   _ecore_x_selection_shutdown();
838
   _ecore_x_dnd_shutdown();
839
   _ecore_x_resource_shutdown();
840
   ecore_x_netwm_shutdown();
841

842
   return 0;
843
}
844

845
static void
846
_ecore_x_shutdown2(void)
847
{
848
   ecore_event_shutdown();
849
   ecore_shutdown();
850

851
   eina_log_domain_unregister(_ecore_xlib_log_dom);
852
   _ecore_xlib_log_dom = -1;
853
   eina_shutdown();
854
   _ecore_xlib_sync = EINA_FALSE;
855
}
856

857
/**
858
 * Shuts down the Ecore X library.
859
 *
860
 * In shutting down the library, the X display connection is terminated
861
 * and any event handlers for it are removed.
862
 *
863
 * @return  The number of times the library has been initialized without
864
 *          being shut down. 0 is returned if an error occurs.
865
 * @ingroup Ecore_X_Init_Group
866
 */
867
EAPI int
868
ecore_x_shutdown(void)
869
{
870
   if (!_ecore_x_init_count)
871
     {
872
        CRI("Calling ecore_x_shutdown without init! BUG!");
873
        return 0;
874
     }
875
   if (--_ecore_x_init_count != 0)
876
     return _ecore_x_init_count;
877
   if (_ecore_x_shutdown()) return _ecore_x_init_count;
878
   if (_ecore_x_disp)
879
     XCloseDisplay(_ecore_x_disp);
880
   _ecore_x_disp = NULL;
881
   _ecore_x_shutdown2();
882
   return 0;
883
}
884

885
/**
886
 * Shuts down the Ecore X library.
887
 *
888
 * As ecore_x_shutdown, except do not close Display, only connection.
889
 *
890
 * @ingroup Ecore_X_Init_Group
891
 */
892
EAPI int
893
ecore_x_disconnect(void)
894
{
895
   if (--_ecore_x_init_count != 0)
896
     return _ecore_x_init_count;
897
   if (_ecore_x_shutdown()) return _ecore_x_init_count;
898
   close(ConnectionNumber(_ecore_x_disp));
899
    // FIXME: may have to clean up x display internal here
900
// getting segv here? hmmm. odd. disable
901
//        XFree(_ecore_x_disp);
902
   _ecore_x_disp = NULL;
903
   _ecore_x_shutdown2();
904
   return 0;
905
}
906

907
/**
908
 * @defgroup Ecore_X_Display_Attr_Group X Display Attributes
909
 *
910
 * Functions that set and retrieve X display attributes.
911
 */
912

913
/**
914
 * Retrieves the Ecore_X_Display handle used for the current X connection.
915
 * @return  The current X display.
916
 * @ingroup Ecore_X_Display_Attr_Group
917
 */
918
EAPI Ecore_X_Display *
919
ecore_x_display_get(void)
920
{
921
   return (Ecore_X_Display *)_ecore_x_disp;
922
}
923

924
/**
925
 * Retrieves the X display file descriptor.
926
 * @return  The current X display file descriptor.
927
 * @ingroup Ecore_X_Display_Attr_Group
928
 */
929
EAPI int
930
ecore_x_fd_get(void)
931
{
932
   LOGFN;
933
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, 0);
934
   return ConnectionNumber(_ecore_x_disp);
935
}
936

937
/**
938
 * Retrieves the Ecore_X_Screen handle used for the current X connection.
939
 * @return  The current default screen.
940
 * @ingroup Ecore_X_Display_Attr_Group
941
 */
942
EAPI Ecore_X_Screen *
943
ecore_x_default_screen_get(void)
944
{
945
   LOGFN;
946
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, NULL);
947
   return (Ecore_X_Screen *)DefaultScreenOfDisplay(_ecore_x_disp);
948
}
949

950
/**
951
 * Retrieves the size of an Ecore_X_Screen.
952
 * @param screen the handle to the screen to query.
953
 * @param w where to return the width. May be NULL. Returns 0 on errors.
954
 * @param h where to return the height. May be NULL. Returns 0 on errors.
955
 * @ingroup Ecore_X_Display_Attr_Group
956
 * @see ecore_x_default_screen_get()
957
 *
958
 * @since 1.1
959
 */
960
EAPI void
961
ecore_x_screen_size_get(const Ecore_X_Screen *screen,
962
                        int *w,
963
                        int *h)
964
{
965
   Screen *s = (Screen *)screen;
966
   LOGFN;
967
   if (w) *w = 0;
968
   if (h) *h = 0;
969
   EINA_SAFETY_ON_NULL_RETURN(screen);
970
   if (w) *w = s->width;
971
   if (h) *h = s->height;
972
}
973

974
/**
975
 * Retrieves the number of screens.
976
 *
977
 * @return  The count of the number of screens.
978
 * @ingroup Ecore_X_Display_Attr_Group
979
 *
980
 * @since 1.1
981
 */
982
EAPI int
983
ecore_x_screen_count_get(void)
984
{
985
   LOGFN;
986
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, 0);
987
   return ScreenCount(_ecore_x_disp);
988
}
989

990
/**
991
 * Retrieves the index number of the given screen.
992
 *
993
 * @param screen The screen for which the index will be retrieved.
994
 * @return  The index number of the screen.
995
 * @ingroup Ecore_X_Display_Attr_Group
996
 *
997
 * @since 1.1
998
 */
999
EAPI int
1000
ecore_x_screen_index_get(const Ecore_X_Screen *screen)
1001
{
1002
   EINA_SAFETY_ON_NULL_RETURN_VAL(screen, -1);
1003
   return XScreenNumberOfScreen((Screen *)screen);
1004
}
1005

1006
/**
1007
 * Retrieves the screen based on index number.
1008
 *
1009
 * @param idx The index that will be used to retrieve the screen.
1010
 * @return  The Ecore_X_Screen at this index.
1011
 * @ingroup Ecore_X_Display_Attr_Group
1012
 *
1013
 * @since 1.1
1014
 */
1015
EAPI Ecore_X_Screen *
1016
ecore_x_screen_get(int idx)
1017
{
1018
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, NULL);
1019
   return XScreenOfDisplay(_ecore_x_disp, idx);
1020
}
1021

1022
/**
1023
 * Sets the timeout for a double and triple clicks to be flagged.
1024
 *
1025
 * This sets the time between clicks before the double_click flag is
1026
 * set in a button down event. If 3 clicks occur within double this
1027
 * time, the triple_click flag is also set.
1028
 *
1029
 * @param   t The time in seconds
1030
 * @ingroup Ecore_X_Display_Attr_Group
1031
 */
1032
EAPI void
1033
ecore_x_double_click_time_set(double t)
1034
{
1035
   if (t < 0.0)
1036
     t = 0.0;
1037

1038
   _ecore_x_double_click_time = t;
1039
}
1040

1041
/**
1042
 * Retrieves the double and triple click flag timeout.
1043
 *
1044
 * See @ref ecore_x_double_click_time_set for more information.
1045
 *
1046
 * @return  The timeout for double clicks in seconds.
1047
 * @ingroup Ecore_X_Display_Attr_Group
1048
 */
1049
EAPI double
1050
ecore_x_double_click_time_get(void)
1051
{
1052
   return _ecore_x_double_click_time;
1053
}
1054

1055
/**
1056
 * @defgroup Ecore_X_Flush_Group X Synchronization Functions
1057
 *
1058
 * Functions that ensure that all commands that have been issued by the
1059
 * Ecore X library have been sent to the server.
1060
 */
1061

1062
/**
1063
 * Sends all X commands in the X Display buffer.
1064
 * @ingroup Ecore_X_Flush_Group
1065
 */
1066
EAPI void
1067
ecore_x_flush(void)
1068
{
1069
   LOGFN;
1070
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1071
   XFlush(_ecore_x_disp);
1072
}
1073

1074
/**
1075
 * Flushes the command buffer and waits until all requests have been
1076
 * processed by the server.
1077
 * @ingroup Ecore_X_Flush_Group
1078
 */
1079
EAPI void
1080
ecore_x_sync(void)
1081
{
1082
   LOGFN;
1083
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1084
   XSync(_ecore_x_disp, False);
1085
}
1086

1087
/**
1088
 * Kill all clients with subwindows under a given window.
1089
 *
1090
 * You can kill all clients connected to the X server by using
1091
 * @ref ecore_x_window_root_list to get a list of root windows, and
1092
 * then passing each root window to this function.
1093
 *
1094
 * @param root The window whose children will be killed.
1095
 */
1096
EAPI void
1097
ecore_x_killall(Ecore_X_Window root)
1098
{
1099
   unsigned int j;
1100
   Window root_r;
1101
   Window parent_r;
1102
   Window *children_r = NULL;
1103
   unsigned int num_children = 0;
1104

1105
   LOGFN;
1106
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1107
   XGrabServer(_ecore_x_disp);
1108
   /* Tranverse window tree starting from root, and drag each
1109
    * before the firing squad */
1110
   while (XQueryTree(_ecore_x_disp, root, &root_r, &parent_r,
1111
                     &children_r, &num_children) && (num_children > 0))
1112
     {
1113
        for (j = 0; j < num_children; ++j)
1114
          {
1115
             XKillClient(_ecore_x_disp, children_r[j]);
1116
          }
1117

1118
        XFree(children_r);
1119
     }
1120
   XUngrabServer(_ecore_x_disp);
1121
   XSync(_ecore_x_disp, False);
1122
}
1123

1124
/**
1125
 * Kill a specific client
1126
 *
1127
 * You can kill a specific client owning window @p win
1128
 *
1129
 * @param win Window of the client to be killed
1130
 */
1131
EAPI void
1132
ecore_x_kill(Ecore_X_Window win)
1133
{
1134
   LOGFN;
1135
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1136
   XKillClient(_ecore_x_disp, win);
1137
   if (_ecore_xlib_sync) ecore_x_sync();
1138
}
1139

1140
/**
1141
 * Return the last event time
1142
 */
1143
EAPI Ecore_X_Time
1144
ecore_x_current_time_get(void)
1145
{
1146
   return _ecore_x_event_last_time;
1147
}
1148

1149
/**
1150
 * Return the screen DPI
1151
 *
1152
 * This is a simplistic call to get DPI. It does not account for differing
1153
 * DPI in the x amd y axes nor does it account for multihead or xinerama and
1154
 * xrander where different parts of the screen may have different DPI etc.
1155
 *
1156
 * @return the general screen DPI (dots/pixels per inch).
1157
 */
1158
EAPI int
1159
ecore_x_dpi_get(void)
1160
{
1161
   Screen *s;
1162

1163
   LOGFN;
1164
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, 0);
1165
   s = DefaultScreenOfDisplay(_ecore_x_disp);
1166
   if (s->mwidth <= 0)
1167
     return 75;
1168

1169
   return (((s->width * 254) / s->mwidth) + 5) / 10;
1170
}
1171

1172
/**
1173
 * Invoke the standard system beep to alert users
1174
 *
1175
 * @param percent The volume at which the bell rings. Must be in the range
1176
 * [-100,+100]. If percent >= 0, the final volume will be:
1177
 *       base - [(base * percent) / 100] + percent
1178
 * Otherwise, it's calculated as:
1179
 *       base + [(base * percent) / 100]
1180
 * where @c base is the bell's base volume as set by XChangeKeyboardControl(3).
1181
 *
1182
 * @returns @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1183
 */
1184
EAPI Eina_Bool
1185
ecore_x_bell(int percent)
1186
{
1187
   int ret;
1188

1189
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1190
   ret = XBell(_ecore_x_disp, percent);
1191
   if (ret == BadValue)
1192
     return EINA_FALSE;
1193

1194
   return EINA_TRUE;
1195
}
1196

1197
static Eina_Bool
1198
_ecore_x_fd_handler(void *data,
1199
                    Ecore_Fd_Handler *fd_handler EINA_UNUSED)
1200
{
1201
   Display *d;
1202

1203
   d = data;
1204
   while (XPending(d))
1205
     {
1206
        XEvent ev;
1207

1208
        XNextEvent(d, &ev);
1209
#ifdef BUILD_ECORE_IMF_XIM
1210
        /* Filter event for XIM */
1211
        if (XFilterEvent(&ev, ev.xkey.window))
1212
          continue;
1213

1214
#endif /* ifdef BUILD_ECORE_IMF_XIM */
1215
        if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num))
1216
          {
1217
             if (_ecore_x_event_handlers[AnyXEvent])
1218
               _ecore_x_event_handlers[AnyXEvent] (&ev);
1219

1220
             if (_ecore_x_event_handlers[ev.type])
1221
               _ecore_x_event_handlers[ev.type] (&ev);
1222
          }
1223
     }
1224
   return ECORE_CALLBACK_RENEW;
1225
}
1226

1227
static Eina_Bool
1228
_ecore_x_fd_handler_buf(void *data,
1229
                        Ecore_Fd_Handler *fd_handler EINA_UNUSED)
1230
{
1231
   Display *d;
1232

1233
   d = data;
1234
   if (XPending(d))
1235
     return ECORE_CALLBACK_RENEW;
1236

1237
   return ECORE_CALLBACK_CANCEL;
1238
}
1239

1240
static int
1241
_ecore_x_key_mask_get(XModifierKeymap *mod, KeySym sym)
1242
{
1243
   KeySym sym2;
1244
   int i, j, mask = 0;
1245
   const int masks[8] =
1246
     {
1247
        ShiftMask, LockMask, ControlMask,
1248
        Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
1249
     };
1250

1251
   for (i = 0; i < (8 * mod->max_keypermod); i++)
1252
     {
1253
        for (j = 0; j < 8; j++)
1254
          {
1255
             sym2 = _ecore_x_XKeycodeToKeysym(_ecore_x_disp,
1256
                                              mod->modifiermap[i], j);
1257
             if (sym2 != 0)
1258
             break;
1259
          }
1260
        if (sym2 == sym) mask = masks[i / mod->max_keypermod];
1261
     }
1262
   return mask;
1263
}
1264

1265
/*****************************************************************************/
1266
/*****************************************************************************/
1267
/*****************************************************************************/
1268
/* FIXME: these funcs need categorising */
1269
/*****************************************************************************/
1270

1271
/**
1272
 * Get a list of all the root windows on the server.
1273
 *
1274
 * @note   The returned array will need to be freed after use.
1275
 * @param  num_ret Pointer to integer to put number of windows returned in.
1276
 * @return An array of all the root windows.  @c NULL is returned if memory
1277
 *         could not be allocated for the list, or if @p num_ret is @c NULL.
1278
 */
1279
EAPI Ecore_X_Window *
1280
ecore_x_window_root_list(int *num_ret)
1281
{
1282
   int num, i;
1283
   Ecore_X_Window *roots;
1284

1285
   if (!num_ret)
1286
     return NULL;
1287

1288
   *num_ret = 0;
1289

1290
   LOGFN;
1291
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, NULL);
1292
   num = ScreenCount(_ecore_x_disp);
1293
   roots = malloc(num * sizeof(Ecore_X_Window));
1294
   if (!roots)
1295
     return NULL;
1296

1297
   *num_ret = num;
1298
   for (i = 0; i < num; i++)
1299
     roots[i] = RootWindow(_ecore_x_disp, i);
1300
   return roots;
1301
}
1302

1303
EAPI Ecore_X_Window
1304
ecore_x_window_root_first_get(void)
1305
{
1306
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, 0);
1307
   return RootWindow(_ecore_x_disp, 0);
1308
/*
1309
   int num;
1310
   Ecore_X_Window root, *roots = NULL;
1311

1312
   LOGFN;
1313
   roots = ecore_x_window_root_list(&num);
1314
   if (!(roots)) return 0;
1315

1316
   if (num > 0)
1317
     root = roots[0];
1318
   else
1319
     root = 0;
1320

1321
   free(roots);
1322
   return root;
1323
 */
1324
}
1325

1326
static void _ecore_x_window_manage_error(void *data);
1327

1328
static void
1329
_ecore_x_window_manage_error(void *data EINA_UNUSED)
1330
{
1331
   if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) &&
1332
       (ecore_x_error_code_get() == BadAccess))
1333
     _ecore_x_window_manage_succeeded = EINA_FALSE;
1334
}
1335

1336
EAPI Eina_Bool
1337
ecore_x_window_manage(Ecore_X_Window win)
1338
{
1339
   XWindowAttributes att;
1340

1341
   LOGFN;
1342
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1343
   if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True)
1344
     return EINA_FALSE;
1345

1346
   ecore_x_sync();
1347
   _ecore_x_window_manage_succeeded = EINA_TRUE;
1348
   ecore_x_error_handler_set(_ecore_x_window_manage_error, NULL);
1349
   XSelectInput(_ecore_x_disp, win,
1350
                EnterWindowMask |
1351
                LeaveWindowMask |
1352
                PropertyChangeMask |
1353
                ResizeRedirectMask |
1354
                SubstructureRedirectMask |
1355
                SubstructureNotifyMask |
1356
                StructureNotifyMask |
1357
                KeyPressMask |
1358
                KeyReleaseMask |
1359
                att.your_event_mask);
1360
   ecore_x_sync();
1361
   ecore_x_error_handler_set(NULL, NULL);
1362
   if (!_ecore_x_window_manage_succeeded)
1363
     {
1364
        return EINA_FALSE;
1365
     }
1366

1367
   return EINA_TRUE;
1368
}
1369

1370
EAPI void
1371
ecore_x_window_container_manage(Ecore_X_Window win)
1372
{
1373
   LOGFN;
1374
   if (_ecore_x_window_manage_succeeded && (win == ecore_x_window_root_first_get())) return;
1375
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1376
   XSelectInput(_ecore_x_disp, win,
1377
                SubstructureRedirectMask |
1378
                SubstructureNotifyMask);
1379
   if (_ecore_xlib_sync) ecore_x_sync();
1380
}
1381

1382
EAPI void
1383
ecore_x_window_client_manage(Ecore_X_Window win)
1384
{
1385
   LOGFN;
1386
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1387
   if (_ecore_x_window_manage_succeeded && (win == ecore_x_window_root_first_get())) return;
1388
   XSelectInput(_ecore_x_disp, win,
1389
                PropertyChangeMask |
1390
//		ResizeRedirectMask |
1391
                FocusChangeMask |
1392
                ColormapChangeMask |
1393
                VisibilityChangeMask |
1394
                StructureNotifyMask |
1395
                SubstructureNotifyMask
1396
                );
1397
   if (_ecore_xlib_sync) ecore_x_sync();
1398
   XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1399
   if (_ecore_xlib_sync) ecore_x_sync();
1400
}
1401

1402
EAPI void
1403
ecore_x_window_sniff(Ecore_X_Window win)
1404
{
1405
   LOGFN;
1406
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1407
   if (_ecore_x_window_manage_succeeded && (win == ecore_x_window_root_first_get())) return;
1408
   XSelectInput(_ecore_x_disp, win,
1409
                PropertyChangeMask |
1410
                SubstructureNotifyMask);
1411
   if (_ecore_xlib_sync) ecore_x_sync();
1412
}
1413

1414
/* this is internal-only for now */
1415
EAPI void
1416
ecore_x_window_root_properties_select(void)
1417
{
1418
   LOGFN;
1419
   if (_ecore_x_window_manage_succeeded) return;
1420
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1421
   XSelectInput(_ecore_x_disp, ecore_x_window_root_first_get(), PropertyChangeMask);
1422
   if (_ecore_xlib_sync) ecore_x_sync();
1423
}
1424

1425
EAPI void
1426
ecore_x_window_client_sniff(Ecore_X_Window win)
1427
{
1428
   LOGFN;
1429
   if (_ecore_x_window_manage_succeeded && (win == ecore_x_window_root_first_get())) return;
1430
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1431
   XSelectInput(_ecore_x_disp, win,
1432
                PropertyChangeMask |
1433
                FocusChangeMask |
1434
                ColormapChangeMask |
1435
                VisibilityChangeMask |
1436
                StructureNotifyMask |
1437
                SubstructureNotifyMask);
1438
   if (_ecore_xlib_sync) ecore_x_sync();
1439
   XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
1440
   if (_ecore_xlib_sync) ecore_x_sync();
1441
}
1442

1443
EAPI Eina_Bool
1444
ecore_x_window_attributes_get(Ecore_X_Window win,
1445
                              Ecore_X_Window_Attributes *att_ret)
1446
{
1447
   XWindowAttributes att;
1448
   Eina_Bool ret;
1449

1450
   LOGFN;
1451
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1452
   ret = XGetWindowAttributes(_ecore_x_disp, win, &att);
1453
   if (_ecore_xlib_sync) ecore_x_sync();
1454
   if (!ret) return EINA_FALSE;
1455

1456
   memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
1457
   att_ret->root = att.root;
1458
   att_ret->x = att.x;
1459
   att_ret->y = att.y;
1460
   att_ret->w = att.width;
1461
   att_ret->h = att.height;
1462
   att_ret->border = att.border_width;
1463
   att_ret->depth = att.depth;
1464
   if (att.map_state != IsUnmapped)
1465
     att_ret->visible = 1;
1466

1467
   if (att.map_state == IsViewable)
1468
     att_ret->viewable = 1;
1469

1470
   if (att.override_redirect)
1471
     att_ret->override = 1;
1472

1473
   if (att.class == InputOnly)
1474
     att_ret->input_only = 1;
1475

1476
   if (att.save_under)
1477
     att_ret->save_under = 1;
1478

1479
   att_ret->event_mask.mine = att.your_event_mask;
1480
   att_ret->event_mask.all = att.all_event_masks;
1481
   att_ret->event_mask.no_propagate = att.do_not_propagate_mask;
1482
   att_ret->window_gravity = att.win_gravity;
1483
   att_ret->pixel_gravity = att.bit_gravity;
1484
   att_ret->colormap = att.colormap;
1485
   att_ret->visual = att.visual;
1486
   return EINA_TRUE;
1487
}
1488

1489
EAPI void
1490
ecore_x_window_save_set_add(Ecore_X_Window win)
1491
{
1492
   LOGFN;
1493
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1494
   XAddToSaveSet(_ecore_x_disp, win);
1495
   if (_ecore_xlib_sync) ecore_x_sync();
1496
}
1497

1498
EAPI void
1499
ecore_x_window_save_set_del(Ecore_X_Window win)
1500
{
1501
   LOGFN;
1502
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1503
   XRemoveFromSaveSet(_ecore_x_disp, win);
1504
   if (_ecore_xlib_sync) ecore_x_sync();
1505
}
1506

1507
EAPI Ecore_X_Window *
1508
ecore_x_window_children_get(Ecore_X_Window win,
1509
                            int *num)
1510
{
1511
   Ecore_X_Window *windows = NULL;
1512
   Eina_Bool success;
1513
   Window root_ret = 0, parent_ret = 0, *children_ret = NULL;
1514
   unsigned int children_ret_num = 0;
1515

1516
   LOGFN;
1517
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, NULL);
1518
   success = XQueryTree(_ecore_x_disp, win, &root_ret, &parent_ret, &children_ret,
1519
                   &children_ret_num);
1520
   if (_ecore_xlib_sync) ecore_x_sync();
1521
   if (!success) return NULL;
1522

1523
   if (children_ret)
1524
     {
1525
        windows = malloc(children_ret_num * sizeof(Ecore_X_Window));
1526
        if (windows)
1527
          {
1528
             unsigned int i;
1529

1530
             for (i = 0; i < children_ret_num; i++)
1531
               windows[i] = children_ret[i];
1532
             *num = children_ret_num;
1533
          }
1534

1535
        XFree(children_ret);
1536
     }
1537

1538
   return windows;
1539
}
1540

1541
EAPI Eina_Bool
1542
ecore_x_pointer_control_set(int accel_num,
1543
                            int accel_denom,
1544
                            int threshold)
1545
{
1546
   Eina_Bool ret;
1547
   LOGFN;
1548
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1549
   ret = !!XChangePointerControl(_ecore_x_disp, 1, 1,
1550
                                accel_num, accel_denom, threshold);
1551
   if (_ecore_xlib_sync) ecore_x_sync();
1552
   return ret;
1553
}
1554

1555
EAPI Eina_Bool
1556
ecore_x_pointer_control_get(int *accel_num,
1557
                            int *accel_denom,
1558
                            int *threshold)
1559
{
1560
   Eina_Bool ret;
1561
   LOGFN;
1562
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1563
   ret = !!XGetPointerControl(_ecore_x_disp,
1564
                             accel_num, accel_denom, threshold);
1565
   if (_ecore_xlib_sync) ecore_x_sync();
1566
   return ret;
1567
}
1568

1569
EAPI Eina_Bool
1570
ecore_x_pointer_mapping_set(unsigned char *map,
1571
                            int nmap)
1572
{
1573
   Eina_Bool ret;
1574
   LOGFN;
1575
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1576
   ret = (XSetPointerMapping(_ecore_x_disp, map, nmap) == MappingSuccess);
1577
   if (_ecore_xlib_sync) ecore_x_sync();
1578
   return ret;
1579
}
1580

1581
EAPI Eina_Bool
1582
ecore_x_pointer_mapping_get(unsigned char *map,
1583
                            int nmap)
1584
{
1585
   Eina_Bool ret;
1586
   LOGFN;
1587
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1588
   ret = !!XGetPointerMapping(_ecore_x_disp, map, nmap);
1589
   if (_ecore_xlib_sync) ecore_x_sync();
1590
   return ret;
1591
}
1592

1593
EAPI Eina_Bool
1594
ecore_x_pointer_grab(Ecore_X_Window win)
1595
{
1596
   Eina_Bool ret;
1597
   LOGFN;
1598
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1599
   ret = (XGrabPointer(_ecore_x_disp, win, False,
1600
                    ButtonPressMask | ButtonReleaseMask |
1601
                    EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1602
                    GrabModeAsync, GrabModeAsync,
1603
                    None, None, CurrentTime) == GrabSuccess);
1604
   if (_ecore_xlib_sync) ecore_x_sync();
1605
   return ret;
1606
}
1607

1608
EAPI Eina_Bool
1609
ecore_x_pointer_confine_grab(Ecore_X_Window win)
1610
{
1611
   Eina_Bool ret;
1612
   LOGFN;
1613
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1614
   ret = (XGrabPointer(_ecore_x_disp, win, False,
1615
                    ButtonPressMask | ButtonReleaseMask |
1616
                    EnterWindowMask | LeaveWindowMask | PointerMotionMask,
1617
                    GrabModeAsync, GrabModeAsync,
1618
                    win, None, CurrentTime) == GrabSuccess);
1619
   if (_ecore_xlib_sync) ecore_x_sync();
1620
   return ret;
1621
}
1622

1623
EAPI void
1624
ecore_x_pointer_ungrab(void)
1625
{
1626
   LOGFN;
1627
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1628
   XUngrabPointer(_ecore_x_disp, CurrentTime);
1629
   if (_ecore_xlib_sync) ecore_x_sync();
1630
}
1631

1632
EAPI Eina_Bool
1633
ecore_x_pointer_warp(Ecore_X_Window win,
1634
                     int x,
1635
                     int y)
1636
{
1637
   Eina_Bool ret;
1638
   LOGFN;
1639
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1640
   ret = !!XWarpPointer(_ecore_x_disp, None, win, 0, 0, 0, 0, x, y);
1641
   if (_ecore_xlib_sync) ecore_x_sync();
1642
   return ret;
1643
}
1644

1645
EAPI Eina_Bool
1646
ecore_x_keyboard_grab(Ecore_X_Window win)
1647
{
1648
   Eina_Bool ret;
1649
   LOGFN;
1650
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
1651
   ret = (XGrabKeyboard(_ecore_x_disp, win, False,
1652
                     GrabModeAsync, GrabModeAsync,
1653
                     CurrentTime) == GrabSuccess);
1654
   if (_ecore_xlib_sync) ecore_x_sync();
1655
   return ret;
1656
}
1657

1658
EAPI void
1659
ecore_x_keyboard_ungrab(void)
1660
{
1661
   LOGFN;
1662
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1663
   XUngrabKeyboard(_ecore_x_disp, CurrentTime);
1664
}
1665

1666
EAPI void
1667
ecore_x_grab(void)
1668
{
1669
   LOGFN;
1670
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1671
   _ecore_x_grab_count++;
1672
   if (_ecore_x_grab_count == 1)
1673
     XGrabServer(_ecore_x_disp);
1674
}
1675

1676
EAPI void
1677
ecore_x_ungrab(void)
1678
{
1679
   LOGFN;
1680
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1681
   _ecore_x_grab_count--;
1682
   if (_ecore_x_grab_count < 0)
1683
     _ecore_x_grab_count = 0;
1684

1685
   if (_ecore_x_grab_count == 0)
1686
     XUngrabServer(_ecore_x_disp);
1687
}
1688

1689
Eina_Bool (*_ecore_window_grab_replay_func)(void *data,
1690
                                            int event_type,
1691
                                            void *event);
1692
void *_ecore_window_grab_replay_data;
1693

1694
EAPI void
1695
ecore_x_passive_grab_replay_func_set(Eina_Bool (*func)(void *data,
1696
                                                       int event_type,
1697
                                                       void *event),
1698
                                     void *data)
1699
{
1700
   LOGFN;
1701
   _ecore_window_grab_replay_func = func;
1702
   _ecore_window_grab_replay_data = data;
1703
}
1704

1705

1706

1707

1708

1709

1710
//////////////////////////////////////////////////////////////////////////////
1711
int _ecore_window_grabs_num = 0;
1712
Wingrab *_ecore_window_grabs = NULL;
1713

1714
static void
1715
_ecore_x_window_button_grab_internal(Ecore_X_Window win,
1716
                                     int button,
1717
                                     Ecore_X_Event_Mask event_mask,
1718
                                     int mod,
1719
                                     int any_mod)
1720
{
1721
   unsigned int b;
1722
   unsigned int m;
1723
   unsigned int locks[8];
1724
   int i, ev;
1725

1726
   LOGFN;
1727
   b = button;
1728
   if (b == 0)
1729
     b = AnyButton;
1730

1731
   m = _ecore_x_event_modifier(mod);
1732
   if (any_mod)
1733
     m = AnyModifier;
1734

1735
   locks[0] = 0;
1736
   locks[1] = ECORE_X_LOCK_CAPS;
1737
   locks[2] = ECORE_X_LOCK_NUM;
1738
   locks[3] = ECORE_X_LOCK_SCROLL;
1739
   locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1740
   locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1741
   locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1742
   locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1743
   ev = event_mask;
1744
   for (i = 0; i < 8; i++)
1745
     XGrabButton(_ecore_x_disp, b, m | locks[i],
1746
                 win, False, ev, GrabModeSync, GrabModeAsync, None, None);
1747
}
1748

1749
EAPI void
1750
ecore_x_window_button_grab(Ecore_X_Window win,
1751
                           int button,
1752
                           Ecore_X_Event_Mask event_mask,
1753
                           int mod,
1754
                           int any_mod)
1755
{
1756
   Wingrab *t;
1757

1758
   _ecore_x_window_button_grab_internal(win, button, event_mask, mod, any_mod);
1759
   _ecore_window_grabs_num++;
1760
   t = realloc(_ecore_window_grabs,
1761
               _ecore_window_grabs_num * sizeof(Wingrab));
1762
   if (!t) return;
1763
   _ecore_window_grabs = t;
1764
   _ecore_window_grabs[_ecore_window_grabs_num - 1].win = win;
1765
   _ecore_window_grabs[_ecore_window_grabs_num - 1].button = button;
1766
   _ecore_window_grabs[_ecore_window_grabs_num - 1].event_mask = event_mask;
1767
   _ecore_window_grabs[_ecore_window_grabs_num - 1].mod = mod;
1768
   _ecore_window_grabs[_ecore_window_grabs_num - 1].any_mod = any_mod;
1769
}
1770

1771
static void
1772
_ecore_x_sync_magic_send(int val, Ecore_X_Window swin, int b, int mod, int anymod)
1773
{
1774
   XEvent xev = { 0 };
1775

1776
   xev.xclient.type = ClientMessage;
1777
   xev.xclient.serial = 0;
1778
   xev.xclient.send_event = True;
1779
   xev.xclient.display = _ecore_x_disp;
1780
   xev.xclient.window = _ecore_x_private_win;
1781
   xev.xclient.format = 32;
1782
   xev.xclient.message_type = 27777;
1783
   xev.xclient.data.l[0] = 0x7162534;
1784
   xev.xclient.data.l[1] = val | (anymod << 8);
1785
   xev.xclient.data.l[2] = swin;
1786
   xev.xclient.data.l[3] = b;
1787
   xev.xclient.data.l[4] = mod;
1788
   XSendEvent(_ecore_x_disp, _ecore_x_private_win, False, NoEventMask, &xev);
1789
}
1790

1791
int
1792
_ecore_x_window_grab_remove(Ecore_X_Window win, int button, int mod, int any_mod)
1793
{
1794
   int i, shuffle = 0;
1795
   Wingrab *t;
1796

1797
   if (_ecore_window_grabs_num > 0)
1798
     {
1799
        for (i = 0; i < _ecore_window_grabs_num; i++)
1800
          {
1801
             if (shuffle)
1802
               _ecore_window_grabs[i - 1] = _ecore_window_grabs[i];
1803

1804
             if ((!shuffle) && (_ecore_window_grabs[i].win == win) &&
1805
                 (((button >= 0) && (_ecore_window_grabs[i].mod == mod) &&
1806
                   (_ecore_window_grabs[i].any_mod == any_mod)) ||
1807
                  (button < 0)))
1808
               shuffle = 1;
1809
          }
1810
        if (shuffle)
1811
          {
1812
             _ecore_window_grabs_num--;
1813
             if (_ecore_window_grabs_num <= 0)
1814
               {
1815
                  free(_ecore_window_grabs);
1816
                  _ecore_window_grabs = NULL;
1817
                  return shuffle;
1818
               }
1819
             t = realloc(_ecore_window_grabs,
1820
                         _ecore_window_grabs_num *
1821
                         sizeof(Wingrab));
1822
             if (!t) return shuffle;
1823
             _ecore_window_grabs = t;
1824
          }
1825
     }
1826
   return shuffle;
1827
}
1828

1829
static void
1830
_ecore_x_window_button_ungrab_internal(Ecore_X_Window win,
1831
                                       int button,
1832
                                       int mod,
1833
                                       int any_mod)
1834
{
1835
   unsigned int b;
1836
   unsigned int m;
1837
   unsigned int locks[8];
1838
   int i;
1839

1840
   LOGFN;
1841
   b = button;
1842
   if (b == 0)
1843
     b = AnyButton;
1844

1845
   m = _ecore_x_event_modifier(mod);
1846
   if (any_mod)
1847
     m = AnyModifier;
1848

1849
   locks[0] = 0;
1850
   locks[1] = ECORE_X_LOCK_CAPS;
1851
   locks[2] = ECORE_X_LOCK_NUM;
1852
   locks[3] = ECORE_X_LOCK_SCROLL;
1853
   locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1854
   locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1855
   locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1856
   locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1857
   for (i = 0; i < 8; i++)
1858
     {
1859
        XUngrabButton(_ecore_x_disp, b, m | locks[i], win);
1860
        if (_ecore_xlib_sync) ecore_x_sync();
1861
     }
1862
}
1863

1864
EAPI void
1865
ecore_x_window_button_ungrab(Ecore_X_Window win,
1866
                             int button,
1867
                             int mod,
1868
                             int any_mod)
1869
{
1870
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1871
   _ecore_x_window_button_ungrab_internal(win, button, mod, any_mod);
1872
   _ecore_x_sync_magic_send(1, win, button, mod, any_mod);
1873
//   _ecore_x_window_grab_remove(win, button, mod, any_mod);
1874
}
1875

1876
void _ecore_x_window_grab_suspend(void)
1877
{
1878
   int i;
1879

1880
   for (i = 0; i < _ecore_window_grabs_num; i++)
1881
     {
1882
        _ecore_x_window_button_ungrab_internal
1883
        (_ecore_window_grabs[i].win, _ecore_window_grabs[i].button,
1884
         _ecore_window_grabs[i].mod, _ecore_window_grabs[i].any_mod);
1885
     }
1886
}
1887

1888
void _ecore_x_window_grab_resume(void)
1889
{
1890
   int i;
1891

1892
   for (i = 0; i < _ecore_window_grabs_num; i++)
1893
     {
1894
        _ecore_x_window_button_grab_internal
1895
        (_ecore_window_grabs[i].win, _ecore_window_grabs[i].button,
1896
         _ecore_window_grabs[i].event_mask,
1897
         _ecore_window_grabs[i].mod, _ecore_window_grabs[i].any_mod);
1898
     }
1899
}
1900

1901

1902

1903

1904

1905

1906

1907

1908
//////////////////////////////////////////////////////////////////////////////
1909

1910
int _ecore_key_grabs_num = 0;
1911
typedef struct _Keygrab Keygrab;
1912
struct _Keygrab
1913
{
1914
   Window win;
1915
   char *key;
1916
   int mod, any_mod;
1917
};
1918
Keygrab *_ecore_key_grabs = NULL;
1919

1920
static KeyCode
1921
_ecore_x_window_key_grab_internal(Ecore_X_Window win,
1922
                                  const char *key,
1923
                                  int mod,
1924
                                  int any_mod)
1925
{
1926
   KeyCode keycode = 0;
1927
   KeySym keysym;
1928
   unsigned int m;
1929
   unsigned int locks[8];
1930
   int i;
1931

1932
   LOGFN;
1933
   if (!strncmp(key, "Keycode-", 8))
1934
     keycode = atoi(key + 8);
1935
   else
1936
     {
1937
        keysym = XStringToKeysym(key);
1938
        if (keysym == NoSymbol)
1939
          return 0;
1940

1941
        keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
1942
     }
1943

1944
   if (keycode == 0)
1945
     return 0;
1946

1947
   m = _ecore_x_event_modifier(mod);
1948
   if (any_mod)
1949
     m = AnyModifier;
1950

1951
   locks[0] = 0;
1952
   locks[1] = ECORE_X_LOCK_CAPS;
1953
   locks[2] = ECORE_X_LOCK_NUM;
1954
   locks[3] = ECORE_X_LOCK_SCROLL;
1955
   locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1956
   locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1957
   locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1958
   locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1959
   for (i = 0; i < 8; i++)
1960
     {
1961
        XGrabKey(_ecore_x_disp, keycode, m | locks[i],
1962
                 win, False, GrabModeAsync, GrabModeAsync);
1963
        if (_ecore_xlib_sync) ecore_x_sync();
1964
     }
1965
   return keycode;
1966
}
1967

1968
EAPI void
1969
ecore_x_window_key_grab(Ecore_X_Window win,
1970
                        const char *key,
1971
                        int mod,
1972
                        int any_mod)
1973
{
1974
   Keygrab *t;
1975
   KeyCode keycode;
1976

1977
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
1978
   if (!(keycode = _ecore_x_window_key_grab_internal(win, key, mod, any_mod)))
1979
      return;
1980
   _ecore_key_grabs_num++;
1981
   t = realloc(_ecore_key_grabs,
1982
               _ecore_key_grabs_num * sizeof(Keygrab));
1983
   if (!t) return;
1984
   _ecore_key_grabs = t;
1985
   _ecore_key_grabs[_ecore_key_grabs_num - 1].win = win;
1986
   _ecore_key_grabs[_ecore_key_grabs_num - 1].key = strdup(key);
1987
   _ecore_key_grabs[_ecore_key_grabs_num - 1].mod = mod;
1988
   _ecore_key_grabs[_ecore_key_grabs_num - 1].any_mod = any_mod;
1989
}
1990

1991
int
1992
_ecore_x_key_grab_remove(Ecore_X_Window win,
1993
                         const char *key,
1994
                         int mod,
1995
                         int any_mod)
1996
{
1997
   int i, shuffle = 0;
1998
   Keygrab *t;
1999

2000
   if (_ecore_key_grabs_num > 0)
2001
     {
2002
        for (i = 0; i < _ecore_key_grabs_num; i++)
2003
          {
2004
             if (shuffle)
2005
               _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
2006

2007
             if ((!shuffle) && (_ecore_key_grabs[i].win == win) &&
2008
                 ((key && ((!strcmp(_ecore_key_grabs[i].key, key)) &&
2009
                           (_ecore_key_grabs[i].mod == mod) &&
2010
                           (_ecore_key_grabs[i].any_mod == any_mod))) ||
2011
                  (!key)))
2012
               {
2013
                  free(_ecore_key_grabs[i].key);
2014
                  _ecore_key_grabs[i].key = NULL;
2015
                  shuffle = 1;
2016
               }
2017
          }
2018
        if (shuffle)
2019
          {
2020
             _ecore_key_grabs_num--;
2021
             if (_ecore_key_grabs_num <= 0)
2022
               {
2023
                  free(_ecore_key_grabs);
2024
                  _ecore_key_grabs = NULL;
2025
                  return shuffle;
2026
               }
2027
             t = realloc(_ecore_key_grabs,
2028
                         _ecore_key_grabs_num * sizeof(Keygrab));
2029
             if (!t) return shuffle;
2030
             _ecore_key_grabs = t;
2031
          }
2032
     }
2033
   return shuffle;
2034
}
2035

2036
static KeyCode
2037
_ecore_x_window_key_ungrab_internal(Ecore_X_Window win,
2038
                                    const char *key,
2039
                                    int mod,
2040
                                    int any_mod)
2041
{
2042
   KeyCode keycode = 0;
2043
   KeySym keysym;
2044
   unsigned int m;
2045
   unsigned int locks[8];
2046
   int i;
2047

2048
   LOGFN;
2049
   if (!strncmp(key, "Keycode-", 8))
2050
     keycode = atoi(key + 8);
2051
   else
2052
     {
2053
        keysym = XStringToKeysym(key);
2054
        if (keysym == NoSymbol)
2055
          return 0;
2056

2057
        keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
2058
     }
2059

2060
   if (keycode == 0)
2061
     return 0;
2062

2063
   m = _ecore_x_event_modifier(mod);
2064
   if (any_mod)
2065
     m = AnyModifier;
2066

2067
   locks[0] = 0;
2068
   locks[1] = ECORE_X_LOCK_CAPS;
2069
   locks[2] = ECORE_X_LOCK_NUM;
2070
   locks[3] = ECORE_X_LOCK_SCROLL;
2071
   locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
2072
   locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
2073
   locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
2074
   locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
2075
   for (i = 0; i < 8; i++)
2076
     XUngrabKey(_ecore_x_disp, keycode, m | locks[i], win);
2077
   return keycode;
2078
}
2079

2080
EAPI void
2081
ecore_x_window_key_ungrab(Ecore_X_Window win,
2082
                          const char *key,
2083
                          int mod,
2084
                          int any_mod)
2085
{
2086
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
2087
   _ecore_x_window_key_ungrab_internal(win, key, mod, any_mod);
2088
   _ecore_x_sync_magic_send(2, win, XStringToKeysym(key), mod, any_mod);
2089
//   _ecore_x_key_grab_remove(win, key, mod, any_mod);
2090
}
2091

2092
void
2093
_ecore_x_key_grab_suspend(void)
2094
{
2095
   int i;
2096

2097
   for (i = 0; i < _ecore_key_grabs_num; i++)
2098
     {
2099
        _ecore_x_window_key_ungrab_internal
2100
        (_ecore_key_grabs[i].win, _ecore_key_grabs[i].key,
2101
         _ecore_key_grabs[i].mod, _ecore_key_grabs[i].any_mod);
2102
     }
2103
}
2104

2105
void
2106
_ecore_x_key_grab_resume(void)
2107
{
2108
   int i;
2109

2110
   for (i = 0; i < _ecore_key_grabs_num; i++)
2111
     {
2112
        _ecore_x_window_key_grab_internal
2113
        (_ecore_key_grabs[i].win, _ecore_key_grabs[i].key,
2114
         _ecore_key_grabs[i].mod, _ecore_key_grabs[i].any_mod);
2115
     }
2116
}
2117

2118

2119

2120

2121

2122

2123

2124

2125
/**
2126
 * Send client message with given type and format 32.
2127
 *
2128
 * @param win     The window the message is sent to.
2129
 * @param type    The client message type.
2130
 * @param mask    The mask of the message to be sent.
2131
 * @param d0      The client message data item 1
2132
 * @param d1      The client message data item 2
2133
 * @param d2      The client message data item 3
2134
 * @param d3      The client message data item 4
2135
 * @param d4      The client message data item 5
2136
 *
2137
 * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
2138
 */
2139
EAPI Eina_Bool
2140
ecore_x_client_message32_send(Ecore_X_Window win,
2141
                              Ecore_X_Atom type,
2142
                              Ecore_X_Event_Mask mask,
2143
                              long d0,
2144
                              long d1,
2145
                              long d2,
2146
                              long d3,
2147
                              long d4)
2148
{
2149
   XEvent xev = { 0 };
2150
   Eina_Bool ret;
2151

2152
   LOGFN;
2153
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
2154
   xev.xclient.window = win;
2155
   xev.xclient.type = ClientMessage;
2156
   xev.xclient.message_type = type;
2157
   xev.xclient.format = 32;
2158
   xev.xclient.data.l[0] = d0;
2159
   xev.xclient.data.l[1] = d1;
2160
   xev.xclient.data.l[2] = d2;
2161
   xev.xclient.data.l[3] = d3;
2162
   xev.xclient.data.l[4] = d4;
2163

2164
   ret = !!XSendEvent(_ecore_x_disp, win, False, mask, &xev);
2165
   if (_ecore_xlib_sync) ecore_x_sync();
2166
   return ret;
2167
}
2168

2169
/**
2170
 * Send client message with given type and format 8.
2171
 *
2172
 * @param win     The window the message is sent to.
2173
 * @param type    The client message type.
2174
 * @param data    Data to be sent.
2175
 * @param len     Number of data bytes, max @c 20.
2176
 *
2177
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2178
 */
2179
EAPI Eina_Bool
2180
ecore_x_client_message8_send(Ecore_X_Window win,
2181
                             Ecore_X_Atom type,
2182
                             const void *data,
2183
                             int len)
2184
{
2185
   XEvent xev = { 0 };
2186
   Eina_Bool ret;
2187

2188
   LOGFN;
2189
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
2190
   xev.xclient.window = win;
2191
   xev.xclient.type = ClientMessage;
2192
   xev.xclient.message_type = type;
2193
   xev.xclient.format = 8;
2194
   if (len > 20)
2195
     len = 20;
2196

2197
   if (data && len > 0)
2198
     memcpy(xev.xclient.data.b, data, len);
2199
   if (len < 20)
2200
     memset(xev.xclient.data.b + len, 0, 20 - len);
2201

2202
   ret = !!XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
2203
   if (_ecore_xlib_sync) ecore_x_sync();
2204
   return ret;
2205
}
2206

2207
EAPI Eina_Bool
2208
ecore_x_mouse_move_send(Ecore_X_Window win,
2209
                        int x,
2210
                        int y)
2211
{
2212
   XEvent xev = { 0 };
2213
   XWindowAttributes att;
2214
   Window tw;
2215
   int rx, ry;
2216
   Eina_Bool ret;
2217

2218
   LOGFN;
2219
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
2220
   XGetWindowAttributes(_ecore_x_disp, win, &att);
2221
   XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
2222
   xev.xmotion.type = MotionNotify;
2223
   xev.xmotion.window = win;
2224
   xev.xmotion.root = att.root;
2225
   xev.xmotion.subwindow = win;
2226
   xev.xmotion.time = _ecore_x_event_last_time;
2227
   xev.xmotion.x = x;
2228
   xev.xmotion.y = y;
2229
   xev.xmotion.x_root = rx;
2230
   xev.xmotion.y_root = ry;
2231
   xev.xmotion.state = 0;
2232
   xev.xmotion.is_hint = 0;
2233
   xev.xmotion.same_screen = 1;
2234
   ret = !!XSendEvent(_ecore_x_disp, win, True, PointerMotionMask, &xev);
2235
   if (_ecore_xlib_sync) ecore_x_sync();
2236
   return ret;
2237
}
2238

2239
EAPI Eina_Bool
2240
ecore_x_mouse_down_send(Ecore_X_Window win,
2241
                        int x,
2242
                        int y,
2243
                        int b)
2244
{
2245
   XEvent xev = { 0 };
2246
   XWindowAttributes att;
2247
   Window tw;
2248
   int rx, ry;
2249
   Eina_Bool ret;
2250

2251
   LOGFN;
2252
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
2253
   XGetWindowAttributes(_ecore_x_disp, win, &att);
2254
   XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
2255
   xev.xbutton.type = ButtonPress;
2256
   xev.xbutton.window = win;
2257
   xev.xbutton.root = att.root;
2258
   xev.xbutton.subwindow = win;
2259
   xev.xbutton.time = _ecore_x_event_last_time;
2260
   xev.xbutton.x = x;
2261
   xev.xbutton.y = y;
2262
   xev.xbutton.x_root = rx;
2263
   xev.xbutton.y_root = ry;
2264
   xev.xbutton.state = 1 << b;
2265
   xev.xbutton.button = b;
2266
   xev.xbutton.same_screen = 1;
2267
   ret = !!XSendEvent(_ecore_x_disp, win, True, ButtonPressMask, &xev);
2268
   if (_ecore_xlib_sync) ecore_x_sync();
2269
   return ret;
2270
}
2271

2272
EAPI Eina_Bool
2273
ecore_x_mouse_up_send(Ecore_X_Window win,
2274
                      int x,
2275
                      int y,
2276
                      int b)
2277
{
2278
   XEvent xev = { 0 };
2279
   XWindowAttributes att;
2280
   Window tw;
2281
   int rx, ry;
2282
   Eina_Bool ret;
2283

2284
   LOGFN;
2285
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
2286
   XGetWindowAttributes(_ecore_x_disp, win, &att);
2287
   XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
2288
   xev.xbutton.type = ButtonRelease;
2289
   xev.xbutton.window = win;
2290
   xev.xbutton.root = att.root;
2291
   xev.xbutton.subwindow = win;
2292
   xev.xbutton.time = _ecore_x_event_last_time;
2293
   xev.xbutton.x = x;
2294
   xev.xbutton.y = y;
2295
   xev.xbutton.x_root = rx;
2296
   xev.xbutton.y_root = ry;
2297
   xev.xbutton.state = 0;
2298
   xev.xbutton.button = b;
2299
   xev.xbutton.same_screen = 1;
2300
   ret = !!XSendEvent(_ecore_x_disp, win, True, ButtonReleaseMask, &xev);
2301
   if (_ecore_xlib_sync) ecore_x_sync();
2302
   return ret;
2303
}
2304

2305
EAPI Eina_Bool
2306
ecore_x_mouse_in_send(Ecore_X_Window win,
2307
                      int x,
2308
                      int y)
2309
{
2310
   XEvent xev = { 0 };
2311
   XWindowAttributes att;
2312
   Window tw;
2313
   int rx, ry;
2314
   Eina_Bool ret;
2315

2316
   LOGFN;
2317
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
2318
   XGetWindowAttributes(_ecore_x_disp, win, &att);
2319
   XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
2320
   xev.xcrossing.type = EnterNotify;
2321
   xev.xcrossing.window = win;
2322
   xev.xcrossing.root = att.root;
2323
   xev.xcrossing.subwindow = win;
2324
   xev.xcrossing.time = _ecore_x_event_last_time;
2325
   xev.xcrossing.x = x;
2326
   xev.xcrossing.y = y;
2327
   xev.xcrossing.x_root = rx;
2328
   xev.xcrossing.y_root = ry;
2329
   xev.xcrossing.mode = NotifyNormal;
2330
   xev.xcrossing.detail = NotifyNonlinear;
2331
   xev.xcrossing.same_screen = 1;
2332
   xev.xcrossing.focus = 0;
2333
   xev.xcrossing.state = 0;
2334
   ret = !!XSendEvent(_ecore_x_disp, win, True, EnterWindowMask, &xev);
2335
   if (_ecore_xlib_sync) ecore_x_sync();
2336
   return ret;
2337
}
2338

2339
EAPI Eina_Bool
2340
ecore_x_mouse_out_send(Ecore_X_Window win,
2341
                      int x,
2342
                      int y)
2343
{
2344
   XEvent xev = { 0 };
2345
   XWindowAttributes att;
2346
   Window tw;
2347
   int rx, ry;
2348
   Eina_Bool ret;
2349

2350
   LOGFN;
2351
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
2352
   XGetWindowAttributes(_ecore_x_disp, win, &att);
2353
   XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
2354
   xev.xcrossing.type = LeaveNotify;
2355
   xev.xcrossing.window = win;
2356
   xev.xcrossing.root = att.root;
2357
   xev.xcrossing.subwindow = win;
2358
   xev.xcrossing.time = _ecore_x_event_last_time;
2359
   xev.xcrossing.x = x;
2360
   xev.xcrossing.y = y;
2361
   xev.xcrossing.x_root = rx;
2362
   xev.xcrossing.y_root = ry;
2363
   xev.xcrossing.mode = NotifyNormal;
2364
   xev.xcrossing.detail = NotifyNonlinear;
2365
   xev.xcrossing.same_screen = 1;
2366
   xev.xcrossing.focus = 0;
2367
   xev.xcrossing.state = 0;
2368
   ret = !!XSendEvent(_ecore_x_disp, win, True, LeaveWindowMask, &xev);
2369
   if (_ecore_xlib_sync) ecore_x_sync();
2370
   return ret;
2371
}
2372

2373
EAPI void
2374
ecore_x_focus_reset(void)
2375
{
2376
   LOGFN;
2377
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
2378
   XSetInputFocus(_ecore_x_disp, PointerRoot, RevertToPointerRoot, CurrentTime);
2379
   if (_ecore_xlib_sync) ecore_x_sync();
2380
}
2381

2382
EAPI void
2383
ecore_x_events_allow_all(void)
2384
{
2385
   LOGFN;
2386
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
2387
   XAllowEvents(_ecore_x_disp, AsyncBoth, CurrentTime);
2388
   if (_ecore_xlib_sync) ecore_x_sync();
2389
}
2390

2391
EAPI void
2392
ecore_x_pointer_last_xy_get(int *x,
2393
                            int *y)
2394
{
2395
   if (x)
2396
     *x = _ecore_x_event_last_root_x;
2397

2398
   if (y)
2399
     *y = _ecore_x_event_last_root_y;
2400
}
2401

2402
EAPI void
2403
ecore_x_pointer_xy_get(Ecore_X_Window win,
2404
                       int *x,
2405
                       int *y)
2406
{
2407
   Window rwin, cwin;
2408
   int rx, ry, wx, wy, ret;
2409
   unsigned int mask;
2410

2411
   LOGFN;
2412
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
2413
   ret = XQueryPointer(_ecore_x_disp, win, &rwin, &cwin,
2414
                       &rx, &ry, &wx, &wy, &mask);
2415
   if (!ret)
2416
     wx = wy = -1;
2417

2418
   if (x) *x = wx;
2419
   if (y) *y = wy;
2420
   if (_ecore_xlib_sync) ecore_x_sync();
2421
}
2422

2423
EAPI void
2424
ecore_x_pointer_root_xy_get(int *x, int *y)
2425
{
2426
   Ecore_X_Window *root;
2427
   Window rwin, cwin;
2428
   int rx, ry, wx, wy, ret = 0;
2429
   int i, num;
2430
   unsigned int mask;
2431

2432
   LOGFN;
2433
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
2434
   root = ecore_x_window_root_list(&num);
2435
   for (i = 0; i < num; i++)
2436
     {
2437
        ret = XQueryPointer(_ecore_x_disp, root[i], &rwin, &cwin,
2438
                            &rx, &ry, &wx, &wy, &mask);
2439
        if (_ecore_xlib_sync) ecore_x_sync();
2440
        if (ret) break;
2441
     }
2442

2443
   if (!ret)
2444
     rx = ry = -1;
2445

2446
   if (x) *x = rx;
2447
   if (y) *y = ry;
2448
   free(root);
2449
}
2450

2451
/**
2452
 * Retrieve the Visual ID from a given Visual.
2453
 *
2454
 * @param visual  The Visual to get the ID for.
2455
 *
2456
 * @return The visual id.
2457
 * @since 1.1.0
2458
 */
2459
EAPI unsigned int
2460
ecore_x_visual_id_get(Ecore_X_Visual visual)
2461
{
2462
   unsigned int vis;
2463
   vis = XVisualIDFromVisual(visual);
2464
   if (_ecore_xlib_sync) ecore_x_sync();
2465
   return vis;
2466
}
2467

2468
/**
2469
 * Retrieve the default Visual.
2470
 *
2471
 * @param disp  The Display to get the Default Visual from
2472
 * @param screen The Screen.
2473
 *
2474
 * @return The default visual.
2475
 * @since 1.1.0
2476
 */
2477
EAPI Ecore_X_Visual
2478
ecore_x_default_visual_get(Ecore_X_Display *disp,
2479
                           Ecore_X_Screen *screen)
2480
{
2481
   Ecore_X_Visual vis = DefaultVisual(disp, ecore_x_screen_index_get(screen));
2482
   if (_ecore_xlib_sync) ecore_x_sync();
2483
   return vis;
2484
}
2485

2486
/**
2487
 * Retrieve the default Colormap.
2488
 *
2489
 * @param disp  The Display to get the Default Colormap from
2490
 * @param screen The Screen.
2491
 *
2492
 * @return The default colormap.
2493
 * @since 1.1.0
2494
 */
2495
EAPI Ecore_X_Colormap
2496
ecore_x_default_colormap_get(Ecore_X_Display *disp,
2497
                             Ecore_X_Screen *screen)
2498
{
2499
   Ecore_X_Colormap col = DefaultColormap(disp, ecore_x_screen_index_get(screen));
2500
   if (_ecore_xlib_sync) ecore_x_sync();
2501
   return col;
2502
}
2503

2504
/**
2505
 * Retrieve the default depth.
2506
 *
2507
 * @param disp  The Display to get the Default Depth from
2508
 * @param screen The Screen.
2509
 *
2510
 * @return The default depth.
2511
 * @since 1.1.0
2512
 */
2513
EAPI int
2514
ecore_x_default_depth_get(Ecore_X_Display *disp,
2515
                          Ecore_X_Screen *screen)
2516
{
2517
   int depth = DefaultDepth(disp, ecore_x_screen_index_get(screen));
2518
   if (_ecore_xlib_sync) ecore_x_sync();
2519
   return depth;
2520
}
2521

2522
EAPI Ecore_X_Connection *
2523
ecore_x_connection_get(void)
2524
{
2525
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, NULL);
2526
   return XGetXCBConnection(_ecore_x_disp);
2527
}
2528

2529
EAPI void
2530
ecore_x_xkb_select_group(int group)
2531
{
2532
#ifdef ECORE_XKB
2533
   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
2534
   XkbLockGroup(_ecore_x_disp, XkbUseCoreKbd, group);
2535
   if (_ecore_xlib_sync) ecore_x_sync();
2536
#endif
2537
}
2538

2539
EAPI Eina_Bool
2540
ecore_x_xkb_track_state(void)
2541
{
2542
   Eina_Bool ret = EINA_FALSE;
2543
#ifdef ECORE_XKB
2544
   unsigned mask = XkbNewKeyboardNotifyMask | XkbMapNotifyMask |
2545
     XkbStateNotifyMask | XkbCompatMapNotifyMask;
2546
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
2547
   ret = XkbSelectEvents(_ecore_x_disp, XkbUseCoreKbd, mask, mask);
2548
   if (_ecore_xlib_sync) ecore_x_sync();
2549
#endif
2550
   return ret;
2551
}
2552

2553
EAPI Eina_Bool
2554
ecore_x_xkb_state_get(Ecore_X_Xkb_State *state)
2555
{
2556
   Eina_Bool ret = EINA_FALSE;
2557
#ifdef ECORE_XKB
2558
   XkbStateRec xkbstate;
2559

2560
   EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, EINA_FALSE);
2561
   ret = XkbGetState(_ecore_x_disp, XkbUseCoreKbd, &xkbstate);
2562
   if (!ret) return ret;
2563

2564
   state->group = xkbstate.group;
2565
   state->base_group = xkbstate.base_group;
2566
   state->latched_group = xkbstate.latched_group;
2567
   state->locked_group = xkbstate.locked_group;
2568

2569
   state->mods = xkbstate.mods;
2570
   state->base_mods = xkbstate.base_mods;
2571
   state->latched_mods = xkbstate.latched_mods;
2572
   state->locked_mods = xkbstate.locked_mods;
2573
#endif
2574
   return ret;
2575
}
2576

2577
/*****************************************************************************/
2578
/*****************************************************************************/
2579
/*****************************************************************************/
2580

2581
static int
2582
_ecore_x_event_modifier(unsigned int state)
2583
{
2584
   int xmodifiers = 0;
2585

2586
   if (state & ECORE_EVENT_MODIFIER_SHIFT)
2587
     xmodifiers |= ECORE_X_MODIFIER_SHIFT;
2588

2589
   if (state & ECORE_EVENT_MODIFIER_CTRL)
2590
     xmodifiers |= ECORE_X_MODIFIER_CTRL;
2591

2592
   if (state & ECORE_EVENT_MODIFIER_ALT)
2593
     xmodifiers |= ECORE_X_MODIFIER_ALT;
2594

2595
   if (state & ECORE_EVENT_MODIFIER_WIN)
2596
     xmodifiers |= ECORE_X_MODIFIER_WIN;
2597

2598
   if (state & ECORE_EVENT_MODIFIER_ALTGR)
2599
     xmodifiers |= ECORE_X_MODIFIER_ALTGR;
2600

2601
   if (state & ECORE_EVENT_LOCK_SCROLL)
2602
     xmodifiers |= ECORE_X_LOCK_SCROLL;
2603

2604
   if (state & ECORE_EVENT_LOCK_NUM)
2605
     xmodifiers |= ECORE_X_LOCK_NUM;
2606

2607
   if (state & ECORE_EVENT_LOCK_CAPS)
2608
     xmodifiers |= ECORE_X_LOCK_CAPS;
2609

2610
   if (state & ECORE_EVENT_LOCK_SHIFT)
2611
     xmodifiers |= ECORE_X_LOCK_SHIFT;
2612

2613
   return xmodifiers;
2614
}
2615

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.