aboutsummaryrefslogtreecommitdiff
path: root/src/BaseDisplay.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/BaseDisplay.cc')
-rw-r--r--src/BaseDisplay.cc448
1 files changed, 0 insertions, 448 deletions
diff --git a/src/BaseDisplay.cc b/src/BaseDisplay.cc
deleted file mode 100644
index 1993793..0000000
--- a/src/BaseDisplay.cc
+++ /dev/null
@@ -1,448 +0,0 @@
1// BaseDisplay.cc for Fluxbox Window manager
2// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen(at)linuxmail.org)
3//
4// BaseDisplay.cc for Blackbox - an X11 Window manager
5// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
6//
7// Permission is hereby granted, free of charge, to any person obtaining a
8// copy of this software and associated documentation files (the "Software"),
9// to deal in the Software without restriction, including without limitation
10// the rights to use, copy, modify, merge, publish, distribute, sublicense,
11// and/or sell copies of the Software, and to permit persons to whom the
12// Software is furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE.
24
25// $Id: BaseDisplay.cc,v 1.28 2003/05/07 11:43:03 fluxgen Exp $
26
27
28
29#include "BaseDisplay.hh"
30#include "i18n.hh"
31#include "Timer.hh"
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif // HAVE_CONFIG_H
36
37// use GNU extensions
38#ifndef _GNU_SOURCE
39#define _GNU_SOURCE
40#endif // _GNU_SOURCE
41
42#include <X11/Xutil.h>
43
44#ifdef SHAPE
45#include <X11/extensions/shape.h>
46#endif // SHAPE
47
48#ifdef HAVE_FCNTL_H
49#include <fcntl.h>
50#endif // HAVE_FCNTL_H
51
52#include <cstdio>
53#include <cstdlib>
54#include <cstring>
55
56#ifdef HAVE_UNISTD_H
57#include <sys/types.h>
58#include <unistd.h>
59#endif // HAVE_UNISTD_H
60
61#ifdef HAVE_SYS_SELECT_H
62#include <sys/select.h>
63#endif // HAVE_SYS_SELECT_H
64
65#ifdef HAVE_SIGNAL_H
66#include <signal.h>
67#endif // HAVE_SIGNAL_H
68
69#ifndef SA_NODEFER
70#ifdef SA_INTERRUPT
71#define SA_NODEFER SA_INTERRUPT
72#else // !SA_INTERRUPT
73#define SA_NODEFER (0)
74#endif // SA_INTERRUPT
75#endif // SA_NODEFER
76
77#ifdef HAVE_SYS_WAIT_H
78#include <sys/types.h>
79#include <sys/wait.h>
80#endif // HAVE_SYS_WAIT_H
81
82#if defined(HAVE_PROCESS_H) && defined(__EMX__)
83#include <process.h>
84#endif // HAVE_PROCESS_H && __EMX__
85
86#include <iostream>
87using namespace std;
88
89// X error handler to handle any and all X errors while the application is
90// running
91static Bool internal_error = False;
92static Window last_bad_window = None;
93
94
95static int handleXErrors(Display *d, XErrorEvent *e) {
96#ifdef DEBUG
97 char errtxt[128];
98
99 XGetErrorText(d, e->error_code, errtxt, 128);
100 fprintf(stderr,
101 I18n::instance()->
102 getMessage(
103 FBNLS::BaseDisplaySet, FBNLS::BaseDisplayXError,
104 "%s: X error: %s(%d) opcodes %d/%d\n resource 0x%lx\n"),
105 BaseDisplay::instance()->getApplicationName(), errtxt, e->error_code,
106 e->request_code, e->minor_code, e->resourceid);
107
108#endif // !DEBUG
109
110 if (e->error_code == BadWindow)
111 last_bad_window = e->resourceid;
112
113 if (internal_error)
114 abort();
115
116 return(False);
117}
118
119
120
121BaseDisplay *BaseDisplay::s_singleton = 0;
122
123BaseDisplay::BaseDisplay(const char *app_name, const char *dpy_name):FbTk::App(dpy_name),
124 m_startup(true), m_shutdown(false),
125 m_display_name(XDisplayName(dpy_name)), m_app_name(app_name),
126 m_server_grabs(0)
127{
128 if (s_singleton != 0)
129 throw string("Can't create more than one instance of BaseDisplay!");
130
131 s_singleton = this;
132
133 last_bad_window = None;
134 I18n *i18n = I18n::instance();
135
136 if (display() == 0) {
137 throw string("Can not connect to X server."
138 "Make sure you started X before you start Fluxbox and"
139 "that you do not have any other window manager running at the same time.");
140 /*
141 i18n->
142 getMessage(
143 FBNLS::BaseDisplaySet, FBNLS::BaseDisplayXConnectFail,
144 "BaseDisplay::BaseDisplay: connection to X server failed."));
145 */
146 } else if (fcntl(ConnectionNumber(display()), F_SETFD, 1) == -1) {
147 throw string(
148 i18n->
149 getMessage(
150 FBNLS::BaseDisplaySet, FBNLS::BaseDisplayCloseOnExecFail,
151 "BaseDisplay::BaseDisplay: couldn't mark display connection "
152 "as close-on-exec"));
153
154 }
155
156
157 number_of_screens = ScreenCount(display());
158
159#ifdef SHAPE
160 shape.extensions = XShapeQueryExtension(display(), &shape.event_basep,
161 &shape.error_basep);
162#else // !SHAPE
163 shape.extensions = False;
164#endif // SHAPE
165
166
167 XSetErrorHandler((XErrorHandler) handleXErrors);
168
169 for (int i = 0; i < number_of_screens; i++) {
170 ScreenInfo *screeninfo = new ScreenInfo(i);
171 screenInfoList.push_back(screeninfo);
172 }
173}
174
175
176BaseDisplay::~BaseDisplay() {
177
178 ScreenInfoList::iterator it = screenInfoList.begin();
179 ScreenInfoList::iterator it_end = screenInfoList.end();
180 for (; it != it_end; ++it) {
181 delete (*it);
182 }
183
184 s_singleton = 0;
185}
186
187BaseDisplay *BaseDisplay::instance() {
188 if (s_singleton == 0)
189 throw string("BaseDisplay not created!");
190
191 return s_singleton;
192}
193
194void BaseDisplay::eventLoop() {
195 run();
196
197 while ((! m_shutdown) && (! internal_error)) {
198 if (XPending(display())) {
199 XEvent e;
200 XNextEvent(display(), &e);
201
202 if (last_bad_window != None && e.xany.window == last_bad_window) {
203#ifdef DEBUG
204 fprintf(stderr,
205 I18n::instance()->
206 getMessage(
207 FBNLS::BaseDisplaySet, FBNLS::BaseDisplayBadWindowRemove,
208 "BaseDisplay::eventLoop(): removing bad window "
209 "from event queue\n"));
210#endif // DEBUG
211 } else {
212 last_bad_window = None;
213 handleEvent(&e);
214 }
215 } else {
216 FbTk::Timer::updateTimers(ConnectionNumber(display())); //handle all timers
217 }
218 }
219}
220
221
222bool BaseDisplay::validateWindow(Window window) {
223 XEvent event;
224 if (XCheckTypedWindowEvent(display(), window, DestroyNotify, &event)) {
225 XPutBackEvent(display(), &event);
226 return false;
227 }
228
229 return true;
230}
231
232
233void BaseDisplay::grab() {
234 if (! m_server_grabs++)
235 XGrabServer(display());
236}
237
238
239void BaseDisplay::ungrab() {
240 if (! --m_server_grabs)
241 XUngrabServer(display());
242 if (m_server_grabs < 0)
243 m_server_grabs = 0;
244}
245
246ScreenInfo::ScreenInfo(int num) {
247 basedisplay = BaseDisplay::instance();
248 Display * const disp = basedisplay->getXDisplay();
249 screen_number = num;
250
251 root_window = RootWindow(disp, screen_number);
252 depth = DefaultDepth(disp, screen_number);
253
254 width =
255 WidthOfScreen(ScreenOfDisplay(disp, screen_number));
256 height =
257 HeightOfScreen(ScreenOfDisplay(disp, screen_number));
258
259 // search for a TrueColor Visual... if we can't find one... we will use the
260 // default visual for the screen
261 XVisualInfo vinfo_template, *vinfo_return;
262 int vinfo_nitems;
263
264 vinfo_template.screen = screen_number;
265 vinfo_template.c_class = TrueColor;
266
267 visual = (Visual *) 0;
268
269 if ((vinfo_return = XGetVisualInfo(disp,
270 VisualScreenMask | VisualClassMask,
271 &vinfo_template, &vinfo_nitems)) &&
272 vinfo_nitems > 0) {
273
274 for (int i = 0; i < vinfo_nitems; i++) {
275 if (depth < (vinfo_return + i)->depth) {
276 depth = (vinfo_return + i)->depth;
277 visual = (vinfo_return + i)->visual;
278 }
279 }
280
281 XFree(vinfo_return);
282 }
283
284 if (visual) {
285 m_colormap = XCreateColormap(disp, root_window,
286 visual, AllocNone);
287 } else {
288 visual = DefaultVisual(disp, screen_number);
289 m_colormap = DefaultColormap(disp, screen_number);
290 }
291
292#ifdef XINERAMA
293 // check if we have Xinerama extension enabled
294 if (XineramaIsActive(disp)) {
295 m_hasXinerama = true;
296 xineramaLastHead = 0;
297 xineramaInfos =
298 XineramaQueryScreens(disp, &xineramaNumHeads);
299 } else {
300 m_hasXinerama = false;
301 xineramaInfos = 0; // make sure we don't point anywhere we shouldn't
302 }
303#endif // XINERAMA
304}
305
306ScreenInfo::~ScreenInfo() {
307#ifdef XINERAMA
308 if (m_hasXinerama) { // only free if we first had it
309 XFree(xineramaInfos);
310 xineramaInfos = 0;
311 }
312#endif // XINERAMA
313}
314
315#ifdef XINERAMA
316
317/**
318 Searches for the head at the coordinates
319 x,y. If it fails or Xinerama isn't
320 activated it'll return head nr 0
321*/
322unsigned int ScreenInfo::getHead(int x, int y) const {
323
324 // is Xinerama extensions enabled?
325 if (hasXinerama()) {
326 // check if last head is still active
327 /* if ((xineramaInfos[xineramaLastHead].x_org <= x) &&
328 ((xineramaInfos[xineramaLastHead].x_org +
329 xineramaInfos[xineramaLastHead].width) > x) &&
330 (xineramaInfos[xineramaLastHead].y_org <= y) &&
331 ((xineramaInfos[xineramaLastHead].y_org +
332 xineramaInfos[xineramaLastHead].height) > y)) {
333 return xineramaLastHead;
334 } else { */
335 // go trough all the heads, and search
336 for (int i = 0; (signed) i < xineramaNumHeads; i++) {
337 if (xineramaInfos[i].x_org <= x &&
338 (xineramaInfos[i].x_org + xineramaInfos[i].width) > x &&
339 xineramaInfos[i].y_org <= y &&
340 (xineramaInfos[i].y_org + xineramaInfos[i].height) > y)
341 // return (xineramaLastHead = i);
342 return i;
343 }
344 // }
345 }
346
347 return 0;
348}
349
350/**
351 Searches for the head that the pointer
352 currently is on, if it isn't found
353 the first one is returned
354*/
355unsigned int ScreenInfo::getCurrHead(void) const {
356
357 // is Xinerama extensions enabled?
358 if (hasXinerama()) {
359 int x, y, wX, wY;
360 unsigned int mask;
361 Window rRoot, rChild;
362 // get pointer cordinates
363 if ( (XQueryPointer(basedisplay->getXDisplay(), root_window,
364 &rRoot, &rChild, &x, &y, &wX, &wY, &mask)) != 0 ) {
365 return getHead(x, y);
366 }
367 }
368
369 return 0;
370}
371
372/**
373 @return the width of head
374*/
375unsigned int ScreenInfo::getHeadWidth(unsigned int head) const {
376
377 if (hasXinerama()) {
378 if ((signed) head >= xineramaNumHeads) {
379#ifdef DEBUG
380 cerr << __FILE__ << ":" <<__LINE__ << ": " <<
381 "Head: " << head << " doesn't exist!" << endl;
382#endif // DEBUG
383 return xineramaInfos[xineramaNumHeads - 1].width;
384 } else
385 return xineramaInfos[head].width;
386 }
387
388 return getWidth();
389
390}
391
392/**
393 @return the heigt of head
394*/
395unsigned int ScreenInfo::getHeadHeight(unsigned int head) const {
396
397 if (hasXinerama()) {
398 if ((signed) head >= xineramaNumHeads) {
399#ifdef DEBUG
400 cerr << __FILE__ << ":" <<__LINE__ << ": " <<
401 "Head: " << head << " doesn't exist!" << endl;
402#endif // DEBUG
403 return xineramaInfos[xineramaNumHeads - 1].height;
404 } else
405 return xineramaInfos[head].height;
406 }
407
408 return getHeight();
409}
410
411
412/**
413 @return the X start of head nr head
414*/
415int ScreenInfo::getHeadX(unsigned int head) const {
416 if (hasXinerama()) {
417 if ((signed) head >= xineramaNumHeads) {
418#ifdef DEBUG
419 cerr << __FILE__ << ":" <<__LINE__ << ": " <<
420 "Head: " << head << " doesn't exist!" << endl;
421#endif // DEBUG
422 return xineramaInfos[head = xineramaNumHeads - 1].x_org;
423 } else
424 return xineramaInfos[head].x_org;
425 }
426
427 return 0;
428}
429
430/**
431 @return the Y start of head
432*/
433int ScreenInfo::getHeadY(unsigned int head) const {
434 if (hasXinerama()) {
435 if ((signed) head >= xineramaNumHeads) {
436#ifdef DEBUG
437 cerr << __FILE__ << ":" <<__LINE__ << ": " <<
438 "Head: " << head << " doesn't exist!" << endl;
439#endif // DEBUG
440 return xineramaInfos[xineramaNumHeads - 1].y_org;
441 } else
442 return xineramaInfos[head].y_org;
443 }
444
445 return 0;
446}
447
448#endif // XINERAMA