251
232
shape.extensions = False;
254
xa_wm_colormap_windows =
255
XInternAtom(display, "WM_COLORMAP_WINDOWS", False);
256
xa_wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False);
257
xa_wm_state = XInternAtom(display, "WM_STATE", False);
258
xa_wm_change_state = XInternAtom(display, "WM_CHANGE_STATE", False);
259
xa_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
260
xa_wm_take_focus = XInternAtom(display, "WM_TAKE_FOCUS", False);
261
motif_wm_hints = XInternAtom(display, "_MOTIF_WM_HINTS", False);
263
blackbox_hints = XInternAtom(display, "_BLACKBOX_HINTS", False);
264
blackbox_attributes = XInternAtom(display, "_BLACKBOX_ATTRIBUTES", False);
265
blackbox_change_attributes =
266
XInternAtom(display, "_BLACKBOX_CHANGE_ATTRIBUTES", False);
268
blackbox_structure_messages =
269
XInternAtom(display, "_BLACKBOX_STRUCTURE_MESSAGES", False);
270
blackbox_notify_startup =
271
XInternAtom(display, "_BLACKBOX_NOTIFY_STARTUP", False);
272
blackbox_notify_window_add =
273
XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_ADD", False);
274
blackbox_notify_window_del =
275
XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_DEL", False);
276
blackbox_notify_current_workspace =
277
XInternAtom(display, "_BLACKBOX_NOTIFY_CURRENT_WORKSPACE", False);
278
blackbox_notify_workspace_count =
279
XInternAtom(display, "_BLACKBOX_NOTIFY_WORKSPACE_COUNT", False);
280
blackbox_notify_window_focus =
281
XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_FOCUS", False);
282
blackbox_notify_window_raise =
283
XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_RAISE", False);
284
blackbox_notify_window_lower =
285
XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_LOWER", False);
287
blackbox_change_workspace =
288
XInternAtom(display, "_BLACKBOX_CHANGE_WORKSPACE", False);
289
blackbox_change_window_focus =
290
XInternAtom(display, "_BLACKBOX_CHANGE_WINDOW_FOCUS", False);
291
blackbox_cycle_window_focus =
292
XInternAtom(display, "_BLACKBOX_CYCLE_WINDOW_FOCUS", False);
296
net_supported = XInternAtom(display, "_NET_SUPPORTED", False);
297
net_client_list = XInternAtom(display, "_NET_CLIENT_LIST", False);
298
net_client_list_stacking = XInternAtom(display, "_NET_CLIENT_LIST_STACKING", False);
299
net_number_of_desktops = XInternAtom(display, "_NET_NUMBER_OF_DESKTOPS", False);
300
net_desktop_geometry = XInternAtom(display, "_NET_DESKTOP_GEOMETRY", False);
301
net_desktop_viewport = XInternAtom(display, "_NET_DESKTOP_VIEWPORT", False);
302
net_current_desktop = XInternAtom(display, "_NET_CURRENT_DESKTOP", False);
303
net_desktop_names = XInternAtom(display, "_NET_DESKTOP_NAMES", False);
304
net_active_window = XInternAtom(display, "_NET_ACTIVE_WINDOW", False);
305
net_workarea = XInternAtom(display, "_NET_WORKAREA", False);
306
net_supporting_wm_check = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
307
net_virtual_roots = XInternAtom(display, "_NET_VIRTUAL_ROOTS", False);
309
net_close_window = XInternAtom(display, "_NET_CLOSE_WINDOW", False);
310
net_wm_moveresize = XInternAtom(display, "_NET_WM_MOVERESIZE", False);
312
net_properties = XInternAtom(display, "_NET_PROPERTIES", False);
313
net_wm_name = XInternAtom(display, "_NET_WM_NAME", False);
314
net_wm_desktop = XInternAtom(display, "_NET_WM_DESKTOP", False);
315
net_wm_window_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
316
net_wm_state = XInternAtom(display, "_NET_WM_STATE", False);
317
net_wm_strut = XInternAtom(display, "_NET_WM_STRUT", False);
318
net_wm_icon_geometry = XInternAtom(display, "_NET_WM_ICON_GEOMETRY", False);
319
net_wm_icon = XInternAtom(display, "_NET_WM_ICON", False);
320
net_wm_pid = XInternAtom(display, "_NET_WM_PID", False);
321
net_wm_handled_icons = XInternAtom(display, "_NET_WM_HANDLED_ICONS", False);
323
net_wm_ping = XInternAtom(display, "_NET_WM_PING", False);
327
cursor.session = XCreateFontCursor(display, XC_left_ptr);
328
cursor.move = XCreateFontCursor(display, XC_fleur);
329
cursor.ll_angle = XCreateFontCursor(display, XC_ll_angle);
330
cursor.lr_angle = XCreateFontCursor(display, XC_lr_angle);
332
235
XSetErrorHandler((XErrorHandler) handleXErrors);
334
timerList = new LinkedList<BTimer>;
336
screenInfoList = new LinkedList<ScreenInfo>;
337
for (int i = 0; i < number_of_screens; i++) {
338
ScreenInfo *screeninfo = new ScreenInfo(this, i);
339
screenInfoList->insert(screeninfo);
237
screenInfoList.reserve(ScreenCount(display));
238
for (int i = 0; i < ScreenCount(display); ++i)
239
screenInfoList.push_back(ScreenInfo(this, i));
342
241
NumLockMask = ScrollLockMask = 0;
352
251
// get the values of the keyboard lock modifiers
353
252
// Note: Caps lock is not retrieved the same way as Scroll and Num lock
354
253
// since it doesn't need to be.
355
const KeyCode num_lock_code = XKeysymToKeycode(display, XK_Num_Lock);
356
const KeyCode scroll_lock_code = XKeysymToKeycode(display, XK_Scroll_Lock);
254
const KeyCode num_lock = XKeysymToKeycode(display, XK_Num_Lock);
255
const KeyCode scroll_lock = XKeysymToKeycode(display, XK_Scroll_Lock);
358
257
for (size_t cnt = 0; cnt < size; ++cnt) {
359
258
if (! modmap->modifiermap[cnt]) continue;
361
if (num_lock_code == modmap->modifiermap[cnt])
362
NumLockMask = mask_table[cnt / modmap->max_keypermod];
363
if (scroll_lock_code == modmap->modifiermap[cnt])
364
ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
260
if (num_lock == modmap->modifiermap[cnt])
261
NumLockMask = mask_table[cnt / modmap->max_keypermod];
262
if (scroll_lock == modmap->modifiermap[cnt])
263
ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
369
268
MaskList[1] = LockMask;
370
269
MaskList[2] = NumLockMask;
371
MaskList[3] = ScrollLockMask;
372
MaskList[4] = LockMask | NumLockMask;
373
MaskList[5] = NumLockMask | ScrollLockMask;
374
MaskList[6] = LockMask | ScrollLockMask;
375
MaskList[7] = LockMask | NumLockMask | ScrollLockMask;
270
MaskList[3] = LockMask | NumLockMask;
271
MaskList[4] = ScrollLockMask;
272
MaskList[5] = ScrollLockMask | LockMask;
273
MaskList[6] = ScrollLockMask | NumLockMask;
274
MaskList[7] = ScrollLockMask | LockMask | NumLockMask;
376
275
MaskListLength = sizeof(MaskList) / sizeof(MaskList[0]);
378
277
if (modmap) XFreeModifiermap(const_cast<XModifierKeymap*>(modmap));
279
gccache = (BGCCache*) 0;
382
283
BaseDisplay::~BaseDisplay(void) {
383
while (screenInfoList->count()) {
384
ScreenInfo *si = screenInfoList->first();
386
screenInfoList->remove(si);
390
delete screenInfoList;
392
// we don't create the BTimers, we don't delete them
393
while (timerList->count())
394
timerList->remove(0);
398
286
XCloseDisplay(display);
462
318
// check for timer timeout
463
319
gettimeofday(&now, 0);
465
LinkedListIterator<BTimer> it(timerList);
466
for(BTimer *timer = it.current(); timer; it++, timer = it.current()) {
467
tm.tv_sec = timer->getStartTime().tv_sec +
468
timer->getTimeout().tv_sec;
469
tm.tv_usec = timer->getStartTime().tv_usec +
470
timer->getTimeout().tv_usec;
472
if ((now.tv_sec < tm.tv_sec) ||
473
(now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))
321
// there is a small chance for deadlock here:
322
// *IF* the timer list keeps getting refreshed *AND* the time between
323
// timer->start() and timer->shouldFire() is within the timer's period
324
// then the timer will keep firing. This should be VERY near impossible.
325
while (! timerList.empty()) {
326
BTimer *timer = timerList.top();
327
if (! timer->shouldFire(now))
476
332
timer->fireTimeout();
478
// restart the current timer so that the start time is updated
479
if (! timer->doOnce()) timer->start();
334
if (timer->isRecurring())
487
const Bool BaseDisplay::validateWindow(Window window) {
489
if (XCheckTypedWindowEvent(display, window, DestroyNotify, &event)) {
490
XPutBackEvent(display, &event);
499
void BaseDisplay::grab(void) {
500
if (! server_grabs++)
501
XGrabServer(display);
505
void BaseDisplay::ungrab(void) {
506
if (! --server_grabs)
507
XUngrabServer(display);
509
if (server_grabs < 0) server_grabs = 0;
513
342
void BaseDisplay::addTimer(BTimer *timer) {
514
343
if (! timer) return;
516
LinkedListIterator<BTimer> it(timerList);
518
for (BTimer *tmp = it.current(); tmp; it++, index++, tmp = it.current())
519
if ((tmp->getTimeout().tv_sec > timer->getTimeout().tv_sec) ||
520
((tmp->getTimeout().tv_sec == timer->getTimeout().tv_sec) &&
521
(tmp->getTimeout().tv_usec >= timer->getTimeout().tv_usec)))
524
timerList->insert(timer, index);
345
timerList.push(timer);
528
349
void BaseDisplay::removeTimer(BTimer *timer) {
529
timerList->remove(timer);
350
timerList.release(timer);
534
* Grabs a button, but also grabs the button in every possible combination with
535
* the keyboard lock keys, so that they do not cancel out the event.
355
* Grabs a button, but also grabs the button in every possible combination
356
* with the keyboard lock keys, so that they do not cancel out the event.
358
* if allow_scroll_lock is true then only the top half of the lock mask
359
* table is used and scroll lock is ignored. This value defaults to false.
537
361
void BaseDisplay::grabButton(unsigned int button, unsigned int modifiers,
538
Window grab_window, Bool owner_events,
539
unsigned int event_mask, int pointer_mode,
540
int keybaord_mode, Window confine_to,
543
for (size_t cnt = 0; cnt < MaskListLength; ++cnt) {
362
Window grab_window, bool owner_events,
363
unsigned int event_mask, int pointer_mode,
364
int keyboard_mode, Window confine_to,
365
Cursor cursor, bool allow_scroll_lock) const {
366
unsigned int length = (allow_scroll_lock) ? MaskListLength / 2:
368
for (size_t cnt = 0; cnt < length; ++cnt) {
544
369
XGrabButton(display, button, modifiers | MaskList[cnt], grab_window,
545
owner_events, event_mask, pointer_mode, keybaord_mode, confine_to,
370
owner_events, event_mask, pointer_mode, keyboard_mode,
551
377
* Releases the grab on a button, and ungrabs all possible combinations of the
552
378
* keyboard lock keys.
554
380
void BaseDisplay::ungrabButton(unsigned int button, unsigned int modifiers,
555
Window grab_window) const {
381
Window grab_window) const {
556
382
for (size_t cnt = 0; cnt < MaskListLength; ++cnt) {
557
383
XUngrabButton(display, button, modifiers | MaskList[cnt], grab_window);
562
ScreenInfo::ScreenInfo(BaseDisplay *d, int num) {
388
const ScreenInfo* BaseDisplay::getScreenInfo(unsigned int s) const {
389
if (s < screenInfoList.size())
390
return &screenInfoList[s];
391
return (const ScreenInfo*) 0;
395
BGCCache* BaseDisplay::gcCache(void) const {
397
gccache = new BGCCache(this, screenInfoList.size());
403
ScreenInfo::ScreenInfo(BaseDisplay *d, unsigned int num) {
564
405
screen_number = num;
566
407
root_window = RootWindow(basedisplay->getXDisplay(), screen_number);
409
rect.setSize(WidthOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
411
HeightOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
415
If the default depth is at least 8 we will use that,
416
otherwise we try to find the largest TrueColor visual.
417
Preference is given to 24 bit over larger depths if 24 bit is an option.
567
420
depth = DefaultDepth(basedisplay->getXDisplay(), screen_number);
570
WidthOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(), screen_number));
572
HeightOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(), screen_number));
574
// search for a TrueColor Visual... if we can't find one... we will use the
575
// default visual for the screen
576
XVisualInfo vinfo_template, *vinfo_return;
579
vinfo_template.screen = screen_number;
580
vinfo_template.c_class = TrueColor;
582
visual = (Visual *) 0;
584
if ((vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(),
585
VisualScreenMask | VisualClassMask,
586
&vinfo_template, &vinfo_nitems)) &&
588
for (int i = 0; i < vinfo_nitems; i++) {
589
if (depth < (vinfo_return + i)->depth) {
590
depth = (vinfo_return + i)->depth;
591
visual = (vinfo_return + i)->visual;
421
visual = DefaultVisual(basedisplay->getXDisplay(), screen_number);
422
colormap = DefaultColormap(basedisplay->getXDisplay(), screen_number);
425
// search for a TrueColor Visual... if we can't find one...
426
// we will use the default visual for the screen
427
XVisualInfo vinfo_template, *vinfo_return;
431
vinfo_template.screen = screen_number;
432
vinfo_template.c_class = TrueColor;
434
vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(),
435
VisualScreenMask | VisualClassMask,
436
&vinfo_template, &vinfo_nitems);
439
for (int i = 0; i < vinfo_nitems; ++i) {
440
if (vinfo_return[i].depth > max_depth) {
441
if (max_depth == 24 && vinfo_return[i].depth > 24)
442
break; // prefer 24 bit over 32
443
max_depth = vinfo_return[i].depth;
447
if (max_depth < depth) best = -1;
451
depth = vinfo_return[best].depth;
452
visual = vinfo_return[best].visual;
453
colormap = XCreateColormap(basedisplay->getXDisplay(), root_window,
595
457
XFree(vinfo_return);
599
colormap = XCreateColormap(basedisplay->getXDisplay(), root_window,
602
visual = DefaultVisual(basedisplay->getXDisplay(), screen_number);
603
colormap = DefaultColormap(basedisplay->getXDisplay(), screen_number);
460
// get the default display string and strip the screen number
461
string default_string = DisplayString(basedisplay->getXDisplay());
462
const string::size_type pos = default_string.rfind(".");
463
if (pos != string::npos)
464
default_string.resize(pos);
466
display_string = string("DISPLAY=") + default_string + '.' +
467
itostring(static_cast<unsigned long>(screen_number));