1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
// -*- mode: C++; indent-tabs-mode: nil; -*-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "display.hh"
#include "screeninfo.hh"
#include "gccache.hh"
extern "C" {
#include <X11/keysym.h>
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif // HAVE_SIGNAL_H
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif // HAVE_FCNTL_H
#ifdef HAVE_UNISTD_H
# include <sys/types.h>
# include <unistd.h>
#endif // HAVE_UNISTD_H
#include "gettext.h"
#define _(str) gettext(str)
}
namespace otk {
Display *display = (Display*) 0;
int OBDisplay::xerrorHandler(Display *d, XErrorEvent *e)
{
#ifdef DEBUG
char errtxt[128];
XGetErrorText(d, e->error_code, errtxt, 128);
printf("X Error: %s\n", errtxt);
#else
(void)d;
(void)e;
#endif
return false;
}
void OBDisplay::initialize(char *name)
{
int junk;
(void)junk;
// Open the X display
if (!(display = XOpenDisplay(name))) {
printf(_("Unable to open connection to the X server. Please set the \n\
DISPLAY environment variable approriately, or use the '-display' command \n\
line argument.\n\n"));
::exit(1);
}
if (fcntl(ConnectionNumber(display), F_SETFD, 1) == -1) {
printf(_("Couldn't mark display connection as close-on-exec.\n\n"));
::exit(1);
}
// set our error handler for X errors
XSetErrorHandler(xerrorHandler);
// set the DISPLAY environment variable for any lauched children, to the
// display we're using, so they open in the right place.
// XXX rm -> std::string dtmp = "DISPLAY=" + DisplayString(display);
if (putenv(const_cast<char*>((std::string("DISPLAY=") +
DisplayString(display)).c_str()))) {
printf(_("warning: couldn't set environment variable 'DISPLAY'\n"));
perror("putenv()");
}
// find the availability of X extensions we like to use
#ifdef SHAPE
_shape = XShapeQueryExtension(display, &_shape_event_basep, &junk);
#else
_shape = false;
#endif
#ifdef XINERAMA
_xinerama = XineramaQueryExtension(display, &_xinerama_event_basep, &junk);
#else
_xinerama = false;
#endif // XINERAMA
// get lock masks that are defined by the display (not constant)
XModifierKeymap *modmap;
unsigned int NumLockMask = 0, ScrollLockMask = 0;
modmap = XGetModifierMapping(display);
if (modmap && modmap->max_keypermod > 0) {
const int mask_table[] = {
ShiftMask, LockMask, ControlMask, Mod1Mask,
Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
};
const size_t size = (sizeof(mask_table) / sizeof(mask_table[0])) *
modmap->max_keypermod;
// get the values of the keyboard lock modifiers
// Note: Caps lock is not retrieved the same way as Scroll and Num lock
// since it doesn't need to be.
const KeyCode num_lock = XKeysymToKeycode(display, XK_Num_Lock);
const KeyCode scroll_lock = XKeysymToKeycode(display, XK_Scroll_Lock);
for (size_t cnt = 0; cnt < size; ++cnt) {
if (! modmap->modifiermap[cnt]) continue;
if (num_lock == modmap->modifiermap[cnt])
NumLockMask = mask_table[cnt / modmap->max_keypermod];
if (scroll_lock == modmap->modifiermap[cnt])
ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
}
}
if (modmap) XFreeModifiermap(modmap);
_mask_list[0] = 0;
_mask_list[1] = LockMask;
_mask_list[2] = NumLockMask;
_mask_list[3] = LockMask | NumLockMask;
_mask_list[4] = ScrollLockMask;
_mask_list[5] = ScrollLockMask | LockMask;
_mask_list[6] = ScrollLockMask | NumLockMask;
_mask_list[7] = ScrollLockMask | LockMask | NumLockMask;
// Get information on all the screens which are available.
_screenInfoList.reserve(ScreenCount(display));
for (int i = 0; i < ScreenCount(display); ++i)
_screenInfoList.push_back(ScreenInfo(i));
_gccache = new BGCCache(_screenInfoList.size());
}
void OBDisplay::destroy()
{
delete _gccache;
XCloseDisplay(display);
}
}
|