~cmiller/ubuntu/trusty/icewm/translations-cause-crash-lp447883

« back to all changes in this revision

Viewing changes to .pc/safe_get_argument/src/yxapp.cc

  • Committer: Package Import Robot
  • Author(s): Eduard Bloch
  • Date: 2013-06-29 17:59:17 UTC
  • mfrom: (14.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20130629175917-6bv5fgibwzfz8ke8
Tags: 1.3.7-5
* Fixing linking arguments (libm also for Gnome parts, closes: #713632)
* Using hardening flags now, working around null pointer dereferencing in
  option parsers

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "config.h"
 
2
 
 
3
#include "yxapp.h"
 
4
 
 
5
#include "yfull.h"
 
6
 
 
7
#include "wmprog.h"
 
8
#include "wmmgr.h"
 
9
#include "MwmUtil.h"
 
10
#include "prefs.h"
 
11
#include "yprefs.h"
 
12
#include "ypixbuf.h"
 
13
#include "yconfig.h"
 
14
 
 
15
#include <sys/resource.h>
 
16
#include <stdlib.h>
 
17
 
 
18
#include "intl.h"
 
19
 
 
20
YXApplication *xapp = 0;
 
21
 
 
22
YDesktop *desktop = 0;
 
23
XContext windowContext;
 
24
 
 
25
YCursor YXApplication::leftPointer;
 
26
YCursor YXApplication::rightPointer;
 
27
YCursor YXApplication::movePointer;
 
28
 
 
29
Atom _XA_WM_PROTOCOLS;
 
30
Atom _XA_WM_TAKE_FOCUS;
 
31
Atom _XA_WM_DELETE_WINDOW;
 
32
Atom _XA_WM_STATE;
 
33
Atom _XA_WM_CHANGE_STATE;
 
34
Atom _XATOM_MWM_HINTS;
 
35
//Atom _XA_MOTIF_WM_INFO;!!!
 
36
Atom _XA_WM_COLORMAP_WINDOWS;
 
37
Atom _XA_WM_CLIENT_LEADER;
 
38
Atom _XA_WM_WINDOW_ROLE;
 
39
Atom _XA_WINDOW_ROLE;
 
40
Atom _XA_SM_CLIENT_ID;
 
41
Atom _XA_ICEWM_ACTION;
 
42
Atom _XA_CLIPBOARD;
 
43
Atom _XA_TARGETS;
 
44
Atom _XA_XEMBED_INFO;
 
45
 
 
46
Atom _XA_WIN_PROTOCOLS;
 
47
Atom _XA_WIN_WORKSPACE;
 
48
Atom _XA_WIN_WORKSPACE_COUNT;
 
49
Atom _XA_WIN_WORKSPACE_NAMES;
 
50
Atom _XA_WIN_WORKAREA;
 
51
#ifdef CONFIG_TRAY
 
52
Atom _XA_WIN_TRAY;
 
53
#endif
 
54
Atom _XA_WIN_ICONS;
 
55
Atom _XA_WIN_STATE;
 
56
Atom _XA_WIN_LAYER;
 
57
Atom _XA_WIN_HINTS;
 
58
Atom _XA_WIN_SUPPORTING_WM_CHECK;
 
59
Atom _XA_WIN_CLIENT_LIST;
 
60
Atom _XA_WIN_DESKTOP_BUTTON_PROXY;
 
61
Atom _XA_WIN_AREA;
 
62
Atom _XA_WIN_AREA_COUNT;
 
63
 
 
64
Atom _XA_NET_SUPPORTED;
 
65
Atom _XA_NET_SUPPORTING_WM_CHECK;
 
66
Atom _XA_NET_CLIENT_LIST;
 
67
Atom _XA_NET_CLIENT_LIST_STACKING;
 
68
Atom _XA_NET_NUMBER_OF_DESKTOPS;
 
69
Atom _XA_NET_CURRENT_DESKTOP;
 
70
//Atom _XA_NET_WORKAREA;
 
71
Atom _XA_NET_WM_MOVERESIZE;
 
72
 
 
73
Atom _XA_NET_WM_STRUT;
 
74
Atom _XA_NET_WM_DESKTOP;
 
75
Atom _XA_NET_CLOSE_WINDOW;
 
76
Atom _XA_NET_ACTIVE_WINDOW;
 
77
Atom _XA_NET_WM_STATE;
 
78
 
 
79
Atom _XA_NET_WM_STATE_SHADED;
 
80
Atom _XA_NET_WM_STATE_MAXIMIZED_VERT;
 
81
Atom _XA_NET_WM_STATE_MAXIMIZED_HORZ;
 
82
Atom _XA_NET_WM_STATE_SKIP_TASKBAR;
 
83
Atom _XA_NET_WM_STATE_HIDDEN;
 
84
Atom _XA_NET_WM_STATE_FULLSCREEN;
 
85
Atom _XA_NET_WM_STATE_ABOVE;
 
86
Atom _XA_NET_WM_STATE_BELOW;
 
87
Atom _XA_NET_WM_STATE_MODAL;
 
88
Atom _XA_NET_WM_WINDOW_TYPE;
 
89
Atom _XA_NET_WM_WINDOW_TYPE_DOCK;
 
90
Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP;
 
91
Atom _XA_NET_WM_WINDOW_TYPE_SPLASH;
 
92
 
 
93
Atom _XA_NET_WM_NAME;
 
94
Atom _XA_NET_WM_ICON;
 
95
Atom _XA_NET_WM_PID;
 
96
 
 
97
Atom _XA_NET_WM_USER_TIME;
 
98
Atom _XA_NET_WM_STATE_DEMANDS_ATTENTION;
 
99
 
 
100
Atom _XA_KWM_WIN_ICON;
 
101
Atom _XA_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR = 0;
 
102
 
 
103
Atom XA_XdndAware;
 
104
Atom XA_XdndEnter;
 
105
Atom XA_XdndLeave;
 
106
Atom XA_XdndPosition;
 
107
Atom XA_XdndStatus;
 
108
Atom XA_XdndDrop;
 
109
Atom XA_XdndFinished;
 
110
 
 
111
YColor *YColor::black(NULL);
 
112
YColor *YColor::white(NULL);
 
113
 
 
114
ref<YPixmap> buttonIPixmap;
 
115
ref<YPixmap> buttonAPixmap;
 
116
 
 
117
ref<YPixmap> logoutPixmap;
 
118
ref<YPixmap> switchbackPixmap;
 
119
ref<YPixmap> listbackPixmap;
 
120
ref<YPixmap> dialogbackPixmap;
 
121
 
 
122
ref<YPixmap> menubackPixmap;
 
123
ref<YPixmap> menusepPixmap;
 
124
ref<YPixmap> menuselPixmap;
 
125
 
 
126
#ifdef CONFIG_GRADIENTS
 
127
ref<YImage> buttonIPixbuf;
 
128
ref<YImage> buttonAPixbuf;
 
129
 
 
130
ref<YImage> logoutPixbuf;
 
131
ref<YImage> switchbackPixbuf;
 
132
ref<YImage> listbackPixbuf;
 
133
ref<YImage> dialogbackPixbuf;
 
134
 
 
135
ref<YImage> menubackPixbuf;
 
136
ref<YImage> menuselPixbuf;
 
137
ref<YImage> menusepPixbuf;
 
138
#endif
 
139
 
 
140
//changed robc
 
141
ref<YPixmap> closePixmap[3];
 
142
ref<YPixmap> minimizePixmap[3];
 
143
ref<YPixmap> maximizePixmap[3];
 
144
ref<YPixmap> restorePixmap[3];
 
145
ref<YPixmap> hidePixmap[3];
 
146
ref<YPixmap> rollupPixmap[3];
 
147
ref<YPixmap> rolldownPixmap[3];
 
148
ref<YPixmap> depthPixmap[3];
 
149
 
 
150
#ifdef CONFIG_SHAPE
 
151
int shapesSupported;
 
152
int shapeEventBase, shapeErrorBase;
 
153
#endif
 
154
 
 
155
#ifdef CONFIG_XRANDR
 
156
int xrandrSupported;
 
157
bool xrandr12 = false;
 
158
int xrandrEventBase, xrandrErrorBase;
 
159
#endif
 
160
 
 
161
#ifdef DEBUG
 
162
int xeventcount = 0;
 
163
#endif
 
164
 
 
165
class YClipboard: public YWindow {
 
166
public:
 
167
    YClipboard(): YWindow() {
 
168
        fLen = 0;
 
169
        fData = 0;
 
170
    }
 
171
    ~YClipboard() {
 
172
        if (fData)
 
173
            delete [] fData;
 
174
        fData = 0;
 
175
        fLen = 0;
 
176
    }
 
177
 
 
178
    void setData(const char *data, int len) {
 
179
        if (fData)
 
180
            delete [] fData;
 
181
        fLen = len;
 
182
        fData = new char[len];
 
183
        if (fData)
 
184
            memcpy(fData, data, len);
 
185
        if (fLen == 0)
 
186
            clearSelection(false);
 
187
        else
 
188
            acquireSelection(false);
 
189
    }
 
190
    void handleSelectionClear(const XSelectionClearEvent &clear) {
 
191
        if (clear.selection == _XA_CLIPBOARD) {
 
192
            if (fData)
 
193
                delete [] fData;
 
194
            fLen = 0;
 
195
            fData = 0;
 
196
        }
 
197
    }
 
198
    void handleSelectionRequest(const XSelectionRequestEvent &request) {
 
199
        if (request.selection == _XA_CLIPBOARD) {
 
200
            XSelectionEvent notify;
 
201
 
 
202
            notify.type = SelectionNotify;
 
203
            notify.requestor = request.requestor;
 
204
            notify.selection = request.selection;
 
205
            notify.target = request.target;
 
206
            notify.time = request.time;
 
207
            notify.property = request.property;
 
208
 
 
209
            if (request.selection == _XA_CLIPBOARD &&
 
210
                request.target == XA_STRING &&
 
211
                fLen > 0)
 
212
            {
 
213
                XChangeProperty(xapp->display(),
 
214
                                request.requestor,
 
215
                                request.property,
 
216
                                request.target,
 
217
                                8, PropModeReplace,
 
218
                                (unsigned char *)(fData ? fData : ""),
 
219
                                fLen);
 
220
            } else if (request.selection == _XA_CLIPBOARD &&
 
221
                       request.target == _XA_TARGETS &&
 
222
                       fLen > 0)
 
223
            {
 
224
                Atom type = XA_STRING;
 
225
 
 
226
                XChangeProperty(xapp->display(),
 
227
                                request.requestor,
 
228
                                request.property,
 
229
                                request.target,
 
230
                                32, PropModeReplace,
 
231
                                (unsigned char *)&type, 1);
 
232
            } else {
 
233
                notify.property = None;
 
234
            }
 
235
 
 
236
            XSendEvent(xapp->display(), notify.requestor, False, 0L, (XEvent *)&notify);
 
237
        }
 
238
    }
 
239
 
 
240
private:
 
241
    int fLen;
 
242
    char *fData;
 
243
};
 
244
 
 
245
 
 
246
static void initAtoms() {
 
247
    struct {
 
248
        Atom *atom;
 
249
        const char *name;
 
250
    } atom_info[] = {
 
251
        { &_XA_WM_PROTOCOLS, "WM_PROTOCOLS" },
 
252
        { &_XA_WM_TAKE_FOCUS, "WM_TAKE_FOCUS" },
 
253
        { &_XA_WM_DELETE_WINDOW, "WM_DELETE_WINDOW" },
 
254
        { &_XA_WM_STATE, "WM_STATE" },
 
255
        { &_XA_WM_CHANGE_STATE, "WM_CHANGE_STATE" },
 
256
        { &_XA_WM_COLORMAP_WINDOWS, "WM_COLORMAP_WINDOWS" },
 
257
        { &_XA_WM_CLIENT_LEADER, "WM_CLIENT_LEADER" },
 
258
        { &_XA_WINDOW_ROLE, "WINDOW_ROLE" },
 
259
        { &_XA_WM_WINDOW_ROLE, "WM_WINDOW_ROLE" },
 
260
        { &_XA_SM_CLIENT_ID, "SM_CLIENT_ID" },
 
261
        { &_XA_ICEWM_ACTION, "_ICEWM_ACTION" },
 
262
        { &_XATOM_MWM_HINTS, _XA_MOTIF_WM_HINTS },
 
263
        { &_XA_KWM_WIN_ICON, "KWM_WIN_ICON" },
 
264
        { &_XA_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR" },
 
265
        { &_XA_WIN_WORKSPACE, XA_WIN_WORKSPACE },
 
266
        { &_XA_WIN_WORKSPACE_COUNT, XA_WIN_WORKSPACE_COUNT },
 
267
        { &_XA_WIN_WORKSPACE_NAMES, XA_WIN_WORKSPACE_NAMES },
 
268
        { &_XA_WIN_WORKAREA, XA_WIN_WORKAREA },
 
269
        { &_XA_WIN_ICONS, XA_WIN_ICONS },
 
270
        { &_XA_WIN_LAYER, XA_WIN_LAYER },
 
271
#ifdef CONFIG_TRAY
 
272
        { &_XA_WIN_TRAY, XA_WIN_TRAY },
 
273
#endif
 
274
        { &_XA_WIN_STATE, XA_WIN_STATE },
 
275
        { &_XA_WIN_HINTS, XA_WIN_HINTS },
 
276
        { &_XA_WIN_PROTOCOLS, XA_WIN_PROTOCOLS },
 
277
        { &_XA_WIN_SUPPORTING_WM_CHECK, XA_WIN_SUPPORTING_WM_CHECK },
 
278
        { &_XA_WIN_CLIENT_LIST, XA_WIN_CLIENT_LIST },
 
279
        { &_XA_WIN_DESKTOP_BUTTON_PROXY, XA_WIN_DESKTOP_BUTTON_PROXY },
 
280
        { &_XA_WIN_AREA, XA_WIN_AREA },
 
281
        { &_XA_WIN_AREA_COUNT, XA_WIN_AREA_COUNT },
 
282
 
 
283
        { &_XA_NET_SUPPORTED, "_NET_SUPPORTED" },
 
284
        { &_XA_NET_SUPPORTING_WM_CHECK, "_NET_SUPPORTING_WM_CHECK" },
 
285
        { &_XA_NET_CLIENT_LIST, "_NET_CLIENT_LIST" },
 
286
        { &_XA_NET_CLIENT_LIST_STACKING, "_NET_CLIENT_LIST_STACKING" },
 
287
        { &_XA_NET_NUMBER_OF_DESKTOPS, "_NET_NUMBER_OF_DESKTOPS" },
 
288
        { &_XA_NET_CURRENT_DESKTOP, "_NET_CURRENT_DESKTOP" },
 
289
//        { &_XA_NET_WORKAREA, "_NET_WORKAREA" },
 
290
        { &_XA_NET_WM_MOVERESIZE, "_NET_WM_MOVERESIZE" },
 
291
 
 
292
        { &_XA_NET_WM_STRUT, "_NET_WM_STRUT" },
 
293
        { &_XA_NET_WM_DESKTOP, "_NET_WM_DESKTOP" },
 
294
        { &_XA_NET_CLOSE_WINDOW, "_NET_CLOSE_WINDOW" },
 
295
        { &_XA_NET_ACTIVE_WINDOW, "_NET_ACTIVE_WINDOW" },
 
296
        { &_XA_NET_WM_STATE, "_NET_WM_STATE" },
 
297
 
 
298
        { &_XA_NET_WM_STATE_SHADED, "_NET_WM_STATE_SHADED" },
 
299
        { &_XA_NET_WM_STATE_MAXIMIZED_VERT, "_NET_WM_STATE_MAXIMIZED_VERT" },
 
300
        { &_XA_NET_WM_STATE_MAXIMIZED_HORZ, "_NET_WM_STATE_MAXIMIZED_HORZ" },
 
301
        { &_XA_NET_WM_STATE_SKIP_TASKBAR, "_NET_WM_STATE_SKIP_TASKBAR" },
 
302
        { &_XA_NET_WM_STATE_HIDDEN, "_NET_WM_STATE_HIDDEN" },
 
303
        { &_XA_NET_WM_STATE_FULLSCREEN, "_NET_WM_STATE_FULLSCREEN" },
 
304
        { &_XA_NET_WM_STATE_ABOVE, "_NET_WM_STATE_ABOVE" },
 
305
        { &_XA_NET_WM_STATE_BELOW, "_NET_WM_STATE_BELOW" },
 
306
        { &_XA_NET_WM_STATE_MODAL, "_NET_WM_STATE_MODAL" },
 
307
        { &_XA_NET_WM_WINDOW_TYPE, "_NET_WM_WINDOW_TYPE" },
 
308
        { &_XA_NET_WM_WINDOW_TYPE_DOCK, "_NET_WM_WINDOW_TYPE_DOCK" },
 
309
        { &_XA_NET_WM_WINDOW_TYPE_DESKTOP, "_NET_WM_WINDOW_TYPE_DESKTOP" },
 
310
        { &_XA_NET_WM_WINDOW_TYPE_SPLASH, "_NET_WM_WINDOW_TYPE_SPLASH" },
 
311
 
 
312
        { &_XA_NET_WM_NAME, "_NET_WM_NAME" },
 
313
        { &_XA_NET_WM_ICON, "_NET_WM_ICON" },
 
314
        { &_XA_NET_WM_PID, "_NET_WM_PID" },
 
315
        { &_XA_NET_WM_USER_TIME, "_NET_WM_USER_TIME" },
 
316
        { &_XA_NET_WM_STATE_DEMANDS_ATTENTION, "_NET_WM_STATE_DEMANDS_ATTENTION" },
 
317
 
 
318
        { &_XA_CLIPBOARD, "CLIPBOARD" },
 
319
        { &_XA_XEMBED_INFO, "_XEMBED_INFO" },
 
320
        { &_XA_TARGETS, "TARGETS" },
 
321
        { &XA_XdndAware, "XdndAware" },
 
322
        { &XA_XdndEnter, "XdndEnter" },
 
323
        { &XA_XdndLeave, "XdndLeave" },
 
324
        { &XA_XdndPosition, "XdndPosition" },
 
325
        { &XA_XdndStatus, "XdndStatus" },
 
326
        { &XA_XdndDrop, "XdndDrop" },
 
327
        { &XA_XdndFinished, "XdndFinished" }
 
328
    };
 
329
    unsigned int i;
 
330
 
 
331
#ifdef HAVE_XINTERNATOMS
 
332
    const char *names[ACOUNT(atom_info)];
 
333
    Atom atoms[ACOUNT(atom_info)];
 
334
 
 
335
    for (i = 0; i < ACOUNT(atom_info); i++)
 
336
        names[i] = atom_info[i].name;
 
337
 
 
338
    XInternAtoms(xapp->display(), (char **)names, ACOUNT(atom_info), False, atoms);
 
339
 
 
340
    for (i = 0; i < ACOUNT(atom_info); i++)
 
341
        *(atom_info[i].atom) = atoms[i];
 
342
#else
 
343
    for (i = 0; i < ACOUNT(atom_info); i++)
 
344
        *(atom_info[i].atom) = XInternAtom(xapp->display(),
 
345
                                           atom_info[i].name, False);
 
346
#endif
 
347
}
 
348
 
 
349
static void initPointers() {
 
350
    YXApplication::leftPointer.load("left.xpm",  XC_left_ptr);
 
351
    YXApplication::rightPointer.load("right.xpm", XC_right_ptr);
 
352
    YXApplication::movePointer.load("move.xpm",  XC_fleur);
 
353
}
 
354
 
 
355
static void initColors() {
 
356
    YColor::black = new YColor("rgb:00/00/00");
 
357
    YColor::white = new YColor("rgb:FF/FF/FF");
 
358
}
 
359
 
 
360
void YXApplication::initModifiers() {
 
361
    XModifierKeymap *xmk = XGetModifierMapping(xapp->display());
 
362
    AltMask = MetaMask = WinMask = SuperMask = HyperMask =
 
363
        NumLockMask = ScrollLockMask = ModeSwitchMask = 0;
 
364
    
 
365
    if (xmk) {
 
366
        KeyCode *c = xmk->modifiermap;
 
367
 
 
368
        for (int m = 0; m < 8; m++)
 
369
            for (int k = 0; k < xmk->max_keypermod; k++, c++) {
 
370
                if (*c == NoSymbol)
 
371
                    continue;
 
372
                KeySym kc = XKeycodeToKeysym(xapp->display(), *c, 0);
 
373
                if (kc == NoSymbol)
 
374
                    kc = XKeycodeToKeysym(xapp->display(), *c, 1);
 
375
                if (kc == XK_Num_Lock && NumLockMask == 0)
 
376
                    NumLockMask = (1 << m);
 
377
                if (kc == XK_Scroll_Lock && ScrollLockMask == 0)
 
378
                    ScrollLockMask = (1 << m);
 
379
                if ((kc == XK_Alt_L || kc == XK_Alt_R) && AltMask == 0)
 
380
                    AltMask = (1 << m);
 
381
                if ((kc == XK_Meta_L || kc == XK_Meta_R) && MetaMask == 0)
 
382
                    MetaMask = (1 << m);
 
383
                if ((kc == XK_Super_L || kc == XK_Super_R) && SuperMask == 0)
 
384
                    SuperMask = (1 << m);
 
385
                if ((kc == XK_Hyper_L || kc == XK_Hyper_R) && HyperMask == 0)
 
386
                    HyperMask = (1 << m);
 
387
                if ((kc == XK_Mode_switch || kc == XK_ISO_Level3_Shift) && ModeSwitchMask == 0)
 
388
                    ModeSwitchMask = (1 << m);
 
389
            }
 
390
 
 
391
        XFreeModifiermap(xmk);
 
392
    }
 
393
    if (MetaMask == AltMask)
 
394
        MetaMask = 0;
 
395
 
 
396
    MSG(("alt:%d meta:%d super:%d hyper:%d mode:%d num:%d scroll:%d",
 
397
         AltMask, MetaMask, SuperMask, HyperMask, ModeSwitchMask,
 
398
         NumLockMask, ScrollLockMask));
 
399
 
 
400
    // some hacks for "broken" modifier configurations
 
401
    if (HyperMask == SuperMask)
 
402
        HyperMask = 0;
 
403
 
 
404
    // this basically does what <0.9.13 versions did
 
405
    if (AltMask != 0 && MetaMask == Mod1Mask) {
 
406
        MetaMask = AltMask;
 
407
        AltMask = Mod1Mask;
 
408
    }
 
409
 
 
410
    if (AltMask == 0 && MetaMask != 0) {
 
411
        if (MetaMask != Mod1Mask) {
 
412
            AltMask = Mod1Mask;
 
413
        }
 
414
        else {
 
415
            AltMask = MetaMask;
 
416
            MetaMask = 0;
 
417
        }
 
418
    }
 
419
 
 
420
    if (AltMask == 0)
 
421
        AltMask = Mod1Mask;
 
422
 
 
423
    if (ModeSwitchMask & (AltMask | MetaMask | SuperMask | HyperMask))
 
424
        ModeSwitchMask = 0;
 
425
 
 
426
    PRECONDITION(xapp->AltMask != 0);
 
427
    PRECONDITION(xapp->AltMask != ShiftMask);
 
428
    PRECONDITION(xapp->AltMask != ControlMask);
 
429
    PRECONDITION(xapp->AltMask != xapp->MetaMask);
 
430
 
 
431
    KeyMask =
 
432
        ControlMask |
 
433
        ShiftMask |
 
434
        AltMask |
 
435
        MetaMask |
 
436
        SuperMask |
 
437
        HyperMask |
 
438
        ModeSwitchMask;
 
439
 
 
440
    ButtonMask =
 
441
        Button1Mask |
 
442
        Button2Mask |
 
443
        Button3Mask |
 
444
        Button4Mask |
 
445
        Button5Mask;
 
446
 
 
447
    ButtonKeyMask = KeyMask | ButtonMask;
 
448
 
 
449
#if 0
 
450
    KeySym wl = XKeycodeToKeysym(app->display(), 115, 0);
 
451
    KeySym wr = XKeycodeToKeysym(app->display(), 116, 0);
 
452
 
 
453
    if (wl == XK_Super_L) {
 
454
    } else if (wl == XK_Meta_L) {
 
455
    }
 
456
#endif
 
457
    // this will do for now, but we should actualy check the keycodes
 
458
    Win_L = Win_R = 0;
 
459
 
 
460
    if (SuperMask != 0) {
 
461
        WinMask = SuperMask;
 
462
 
 
463
        Win_L = XK_Super_L;
 
464
        Win_R = XK_Super_R;
 
465
    }
 
466
    MSG(("alt:%d meta:%d super:%d hyper:%d win:%d mode:%d num:%d scroll:%d",
 
467
         AltMask, MetaMask, SuperMask, HyperMask, WinMask, ModeSwitchMask,
 
468
         NumLockMask, ScrollLockMask));
 
469
 
 
470
}
 
471
 
 
472
void YXApplication::dispatchEvent(YWindow *win, XEvent &xev) {
 
473
    if (xev.type == KeyPress || xev.type == KeyRelease) {
 
474
        YWindow *w = win;
 
475
 
 
476
        if (!(fGrabWindow != 0 && !fGrabTree)) {
 
477
            if (w->toplevel())
 
478
                w = w->toplevel();
 
479
 
 
480
            if (w->getFocusWindow() != 0)
 
481
                w = w->getFocusWindow();
 
482
        }
 
483
 
 
484
        while (w && (w->handleKey(xev.xkey) == false)) {
 
485
            if (fGrabTree && w == fXGrabWindow)
 
486
                break;
 
487
            w = w->parent();
 
488
        }
 
489
    } else {
 
490
        Window child;
 
491
 
 
492
        if (xev.type == MotionNotify) {
 
493
            if (xev.xmotion.window != win->handle()) {
 
494
                if (XTranslateCoordinates(xapp->display(),
 
495
                                          xev.xany.window, win->handle(),
 
496
                                          xev.xmotion.x, xev.xmotion.y,
 
497
                                          &xev.xmotion.x, &xev.xmotion.y, &child) == True)
 
498
                    xev.xmotion.window = win->handle();
 
499
                else
 
500
                    return ;
 
501
            }
 
502
        } else if (xev.type == ButtonPress || xev.type == ButtonRelease ||
 
503
                   xev.type == EnterNotify || xev.type == LeaveNotify)
 
504
        {
 
505
            if (xev.xbutton.window != win->handle()) {
 
506
                if (XTranslateCoordinates(xapp->display(),
 
507
                                          xev.xany.window, win->handle(),
 
508
                                          xev.xbutton.x, xev.xbutton.y,
 
509
                                          &xev.xbutton.x, &xev.xbutton.y, &child) == True)
 
510
                    xev.xbutton.window = win->handle();
 
511
                else
 
512
                    return ;
 
513
            }
 
514
        } else if (xev.type == KeyPress || xev.type == KeyRelease) {
 
515
            if (xev.xkey.window != win->handle()) {
 
516
                if (XTranslateCoordinates(xapp->display(),
 
517
                                          xev.xany.window, win->handle(),
 
518
                                          xev.xkey.x, xev.xkey.y,
 
519
                                          &xev.xkey.x, &xev.xkey.y, &child) == True)
 
520
                    xev.xkey.window = win->handle();
 
521
                else
 
522
                    return ;
 
523
            }
 
524
        }
 
525
        win->handleEvent(xev);
 
526
    }
 
527
}
 
528
 
 
529
void YXApplication::handleGrabEvent(YWindow *winx, XEvent &xev) {
 
530
    union {
 
531
        YWindow *ptr;
 
532
        XPointer xptr;
 
533
    } win = { winx };
 
534
 
 
535
    PRECONDITION(win.ptr != 0);
 
536
    if (fGrabTree) {
 
537
        if (xev.xbutton.subwindow != None) {
 
538
            if (XFindContext(display(),
 
539
                         xev.xbutton.subwindow,
 
540
                         windowContext,
 
541
                             &(win.xptr)) != 0)
 
542
            {
 
543
                if (xev.type == EnterNotify || xev.type == LeaveNotify)
 
544
                    win.ptr = 0;
 
545
                else
 
546
                    win.ptr = fGrabWindow;
 
547
            }
 
548
        } else {
 
549
            if (XFindContext(display(),
 
550
                             xev.xbutton.window,
 
551
                             windowContext,
 
552
                             &(win.xptr)) != 0)
 
553
            {
 
554
                if (xev.type == EnterNotify || xev.type == LeaveNotify)
 
555
                    win.ptr = 0;
 
556
                else
 
557
                    win.ptr = fGrabWindow;
 
558
            }
 
559
        }
 
560
        if (win.ptr == 0)
 
561
            return ;
 
562
        {
 
563
            YWindow *p = win.ptr;
 
564
            while (p) {
 
565
                if (p == fXGrabWindow)
 
566
                    break;
 
567
                p = p->parent();
 
568
            }
 
569
            if (p == 0) {
 
570
                if (xev.type == EnterNotify || xev.type == LeaveNotify)
 
571
                    return ;
 
572
                else
 
573
                    win.ptr = fGrabWindow;
 
574
            }
 
575
        }
 
576
        if (xev.type == EnterNotify || xev.type == LeaveNotify)
 
577
            if (win.ptr != fGrabWindow)
 
578
                return ;
 
579
        if (fGrabWindow != fXGrabWindow)
 
580
            win.ptr = fGrabWindow;
 
581
    }
 
582
    dispatchEvent(win.ptr, xev);
 
583
}
 
584
 
 
585
void YXApplication::replayEvent() {
 
586
    if (!fReplayEvent) {
 
587
        fReplayEvent = true;
 
588
        XAllowEvents(xapp->display(), ReplayPointer, CurrentTime);
 
589
    }
 
590
}
 
591
 
 
592
void YXApplication::captureGrabEvents(YWindow *win) {
 
593
    if (fGrabWindow == fXGrabWindow && fGrabTree) {
 
594
        fGrabWindow = win;
 
595
    }
 
596
}
 
597
 
 
598
void YXApplication::releaseGrabEvents(YWindow *win) {
 
599
    if (win == fGrabWindow && fGrabTree) {
 
600
        fGrabWindow = fXGrabWindow;
 
601
    }
 
602
}
 
603
 
 
604
int YXApplication::grabEvents(YWindow *win, Cursor ptr, unsigned int eventMask, int grabMouse, int grabKeyboard, int grabTree) {
 
605
    int rc;
 
606
 
 
607
    if (fGrabWindow != 0)
 
608
        return 0;
 
609
    if (win == 0)
 
610
        return 0;
 
611
 
 
612
    XSync(display(), 0);
 
613
    fGrabTree = grabTree;
 
614
    if (grabMouse) {
 
615
        fGrabMouse = 1;
 
616
        rc = XGrabPointer(display(), win->handle(),
 
617
                          grabTree ? True : False,
 
618
                          eventMask,
 
619
                          GrabModeSync, GrabModeAsync,
 
620
                          None, ptr, CurrentTime);
 
621
 
 
622
        if (rc != Success) {
 
623
            MSG(("grab status = %d\x7", rc));
 
624
            return 0;
 
625
        }
 
626
    } else {
 
627
        fGrabMouse = 0;
 
628
 
 
629
        XChangeActivePointerGrab(display(),
 
630
                                 eventMask,
 
631
                                 ptr, CurrentTime);
 
632
    }
 
633
 
 
634
    if (grabKeyboard) {
 
635
        rc = XGrabKeyboard(display(), win->handle(),
 
636
                           ///False,
 
637
                           grabTree ? True : False,
 
638
                           GrabModeSync, GrabModeAsync, CurrentTime);
 
639
        if (rc != Success && grabMouse) {
 
640
            MSG(("grab status = %d\x7", rc));
 
641
            XUngrabPointer(display(), CurrentTime);
 
642
            return 0;
 
643
        }
 
644
    }
 
645
    XAllowEvents(xapp->display(), SyncPointer, CurrentTime);
 
646
 
 
647
    desktop->resetColormapFocus(false);
 
648
 
 
649
    fXGrabWindow = win;
 
650
    fGrabWindow = win;
 
651
    return 1;
 
652
}
 
653
 
 
654
int YXApplication::releaseEvents() {
 
655
    if (fGrabWindow == 0)
 
656
        return 0;
 
657
    fGrabWindow = 0;
 
658
    fXGrabWindow = 0;
 
659
    fGrabTree = 0;
 
660
    if (fGrabMouse) {
 
661
        XUngrabPointer(display(), CurrentTime);
 
662
        fGrabMouse = 0;
 
663
    }
 
664
    XUngrabKeyboard(display(), CurrentTime);
 
665
    desktop->resetColormapFocus(true);
 
666
    return 1;
 
667
}
 
668
 
 
669
void YXApplication::afterWindowEvent(XEvent & /*xev*/) {
 
670
}
 
671
 
 
672
bool YXApplication::filterEvent(const XEvent &xev) {
 
673
    if (xev.type == MappingNotify) {
 
674
        msg("MappingNotify");
 
675
        XMappingEvent xmapping = xev.xmapping;
 
676
        XRefreshKeyboardMapping(&xmapping);
 
677
 
 
678
        initModifiers();
 
679
 
 
680
        desktop->grabKeys();
 
681
        return true;
 
682
    }
 
683
    return false;
 
684
}
 
685
 
 
686
void YXApplication::saveEventTime(const XEvent &xev) {
 
687
    switch (xev.type) {
 
688
    case ButtonPress:
 
689
    case ButtonRelease:
 
690
        lastEventTime = xev.xbutton.time;
 
691
        break;
 
692
 
 
693
    case MotionNotify:
 
694
        lastEventTime = xev.xmotion.time;
 
695
        break;
 
696
 
 
697
    case KeyPress:
 
698
    case KeyRelease:
 
699
        lastEventTime = xev.xkey.time;
 
700
        break;
 
701
 
 
702
    case EnterNotify:
 
703
    case LeaveNotify:
 
704
        lastEventTime = xev.xcrossing.time;
 
705
        break;
 
706
 
 
707
    case PropertyNotify:
 
708
        lastEventTime = xev.xproperty.time;
 
709
        break;
 
710
 
 
711
    case SelectionClear:
 
712
        lastEventTime = xev.xselectionclear.time;
 
713
        break;
 
714
 
 
715
    case SelectionRequest:
 
716
        lastEventTime = xev.xselectionrequest.time;
 
717
        break;
 
718
 
 
719
    case SelectionNotify:
 
720
        lastEventTime = xev.xselection.time;
 
721
        break;
 
722
    }
 
723
}
 
724
 
 
725
Time YXApplication::getEventTime(const char */*debug*/) const {
 
726
    return lastEventTime;
 
727
}
 
728
 
 
729
 
 
730
extern void logEvent(const XEvent &xev);
 
731
 
 
732
 
 
733
bool YXApplication::hasColormap() {
 
734
    XVisualInfo pattern;
 
735
    pattern.screen = DefaultScreen(display());
 
736
 
 
737
    int nVisuals;
 
738
    bool rc = false;
 
739
 
 
740
    XVisualInfo *first_visual(XGetVisualInfo(display(), VisualScreenMask,
 
741
                                              &pattern, &nVisuals));
 
742
    XVisualInfo *visual = first_visual;
 
743
 
 
744
    while(visual && nVisuals--) {
 
745
        if (visual->c_class & 1)
 
746
            rc = true;
 
747
        visual++;
 
748
    }
 
749
 
 
750
    if (first_visual)
 
751
        XFree(first_visual);
 
752
 
 
753
    return rc;
 
754
}
 
755
 
 
756
 
 
757
void YXApplication::alert() {
 
758
    XBell(display(), 100);
 
759
}
 
760
 
 
761
void YXApplication::setClipboardText(const ustring &data) {
 
762
    if (fClip == 0)
 
763
        fClip = new YClipboard();
 
764
    if (!fClip)
 
765
        return ;
 
766
    cstring s(data);
 
767
    fClip->setData(s.c_str(), s.c_str_len());
 
768
}
 
769
 
 
770
YXApplication::YXApplication(int *argc, char ***argv, const char *displayName):
 
771
    YApplication(argc, argv)
 
772
{
 
773
    xapp = this;
 
774
    lastEventTime = CurrentTime;
 
775
    fGrabWindow = 0;
 
776
    fGrabTree = 0;
 
777
    fXGrabWindow = 0;
 
778
    fGrabMouse = 0;
 
779
    fPopup = 0;
 
780
    fClip = 0;
 
781
    fReplayEvent = false;
 
782
 
 
783
    bool runSynchronized(false);
 
784
 
 
785
    for (char ** arg = *argv + 1; arg < *argv + *argc; ++arg) {
 
786
        if (**arg == '-') {
 
787
            char *value;
 
788
 
 
789
            if ((value = GET_LONG_ARGUMENT("display")) != NULL)
 
790
                displayName = value;
 
791
            else if (IS_LONG_SWITCH("sync"))
 
792
                runSynchronized = true;
 
793
        }
 
794
    }
 
795
 
 
796
    if (displayName == 0)
 
797
        displayName = getenv("DISPLAY");
 
798
    else {
 
799
        static char disp[256] = "DISPLAY=";
 
800
        strcat(disp, displayName);
 
801
        putenv(disp);
 
802
    }
 
803
 
 
804
    if (!(fDisplay = XOpenDisplay(displayName)))
 
805
        die(1, _("Can't open display: %s. X must be running and $DISPLAY set."),
 
806
            displayName ? displayName : _("<none>"));
 
807
 
 
808
    if (runSynchronized)
 
809
        XSynchronize(display(), True);
 
810
 
 
811
    xfd.registerPoll(this, ConnectionNumber(display()));
 
812
 
 
813
    windowContext = XUniqueContext();
 
814
 
 
815
    new YDesktop(0, RootWindow(display(), DefaultScreen(display())));
 
816
    extern void image_init();
 
817
    image_init();
 
818
 
 
819
    initAtoms();
 
820
    initModifiers();
 
821
    initPointers();
 
822
    initColors();
 
823
 
 
824
#ifdef CONFIG_SHAPE
 
825
    shapesSupported = XShapeQueryExtension(display(),
 
826
                                           &shapeEventBase, &shapeErrorBase);
 
827
#endif
 
828
#ifdef CONFIG_XRANDR
 
829
    xrandrSupported = XRRQueryExtension(display(),
 
830
                                        &xrandrEventBase, &xrandrErrorBase);
 
831
    {
 
832
        int major = 0;
 
833
        int minor = 0;
 
834
        XRRQueryVersion(display(), &major, &minor);
 
835
            
 
836
        MSG(("XRRVersion: %d %d", major, minor)); 
 
837
        if (major > 1 || (major == 1 && minor >= 2)) {
 
838
            xrandrSupported = 1;
 
839
            xrandr12 = true;
 
840
        }
 
841
    }
 
842
#endif
 
843
}
 
844
 
 
845
YXApplication::~YXApplication() {
 
846
    xfd.unregisterPoll();
 
847
    XCloseDisplay(display());
 
848
    fDisplay = 0;
 
849
    xapp = 0;
 
850
}
 
851
 
 
852
bool YXApplication::handleXEvents() {
 
853
    if (XPending(display()) > 0) {
 
854
        XEvent xev;
 
855
 
 
856
        XNextEvent(display(), &xev);
 
857
#ifdef DEBUG
 
858
        xeventcount++;
 
859
#endif
 
860
        //msg("%d", xev.type);
 
861
 
 
862
        saveEventTime(xev);
 
863
 
 
864
#ifdef DEBUG
 
865
        DBG logEvent(xev);
 
866
#endif
 
867
        if (filterEvent(xev)) {
 
868
            ;
 
869
        } else {
 
870
            int ge = (xev.type == ButtonPress ||
 
871
                      xev.type == ButtonRelease ||
 
872
                      xev.type == MotionNotify ||
 
873
                      xev.type == KeyPress ||
 
874
                      xev.type == KeyRelease /*||
 
875
                      xev.type == EnterNotify ||
 
876
                      xev.type == LeaveNotify*/) ? 1 : 0;
 
877
 
 
878
            fReplayEvent = false;
 
879
 
 
880
            if (fPopup && ge) {
 
881
                handleGrabEvent(fPopup, xev);
 
882
            } else if (fGrabWindow && ge) {
 
883
                handleGrabEvent(fGrabWindow, xev);
 
884
            } else {
 
885
                handleWindowEvent(xev.xany.window, xev);
 
886
            }
 
887
            if (fGrabWindow) {
 
888
                if (xev.type == ButtonPress || xev.type == ButtonRelease || xev.type == MotionNotify)
 
889
                {
 
890
                    if (!fReplayEvent) {
 
891
                        XAllowEvents(xapp->display(), SyncPointer, CurrentTime);
 
892
                    }
 
893
                }
 
894
            }
 
895
        }
 
896
        XFlush(display());
 
897
        return true;
 
898
    }
 
899
    return false;
 
900
}
 
901
 
 
902
bool YXApplication::handleIdle() {
 
903
    return handleXEvents();
 
904
}
 
905
 
 
906
void YXApplication::handleWindowEvent(Window xwindow, XEvent &xev) {
 
907
    int rc = 0;
 
908
    union {
 
909
        YWindow *ptr;
 
910
        XPointer xptr;
 
911
    } window = { 0 };
 
912
 
 
913
    if ((rc = XFindContext(display(),
 
914
                           xwindow,
 
915
                           windowContext,
 
916
                           &(window.xptr))) == 0)
 
917
    {
 
918
        if ((xev.type == KeyPress || xev.type == KeyRelease)
 
919
            && window.ptr->toplevel() != 0) 
 
920
        {
 
921
            YWindow *w = window.ptr;
 
922
 
 
923
            w = w->toplevel();
 
924
 
 
925
            if (w->getFocusWindow() != 0)
 
926
                w = w->getFocusWindow();
 
927
 
 
928
            dispatchEvent(w, xev);
 
929
        } else {
 
930
            window.ptr->handleEvent(xev);
 
931
        }
 
932
    } else {
 
933
        if (xev.type == MapRequest) {
 
934
            // !!! java seems to do this ugliness
 
935
            //YFrameWindow *f = getFrame(xev.xany.window);
 
936
            msg("APP BUG? mapRequest for window %lX sent to destroyed frame %lX!",
 
937
                xev.xmaprequest.parent,
 
938
                xev.xmaprequest.window);
 
939
            desktop->handleEvent(xev);
 
940
        } else if (xev.type == ConfigureRequest) {
 
941
            msg("APP BUG? configureRequest for window %lX sent to destroyed frame %lX!",
 
942
                xev.xmaprequest.parent,
 
943
                xev.xmaprequest.window);
 
944
            desktop->handleEvent(xev);
 
945
        } else if (xev.type != DestroyNotify) {
 
946
            MSG(("unknown window 0x%lX event=%d", xev.xany.window, xev.type));
 
947
        }
 
948
    }
 
949
    if (xev.type == KeyPress || xev.type == KeyRelease) ///!!!
 
950
        afterWindowEvent(xev);
 
951
}
 
952
 
 
953
void YXApplication::flushXEvents() {
 
954
    XSync(display(), False);
 
955
}
 
956
 
 
957
void YXPoll::notifyRead() {
 
958
    owner()->handleXEvents();
 
959
}
 
960
 
 
961
void YXPoll::notifyWrite() { }
 
962
 
 
963
bool YXPoll::forRead() {
 
964
    return true;
 
965
}
 
966
 
 
967
bool YXPoll::forWrite() { return false; }