]> Dogcows Code - chaz/openbox/blob - src/Screen.cc
Added Util.h, which contains only an ASSERT macro for now
[chaz/openbox] / src / Screen.cc
1 // Screen.cc for Openbox
2 // Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
3 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
22
23 // stupid macros needed to access some functions in version 2 of the GNU C
24 // library
25 #ifndef _GNU_SOURCE
26 #define _GNU_SOURCE
27 #endif // _GNU_SOURCE
28
29 #ifdef HAVE_CONFIG_H
30 # include "../config.h"
31 #endif // HAVE_CONFIG_H
32
33 #include <X11/Xatom.h>
34 #include <X11/keysym.h>
35
36 #include "i18n.h"
37 #include "openbox.h"
38 #include "Clientmenu.h"
39 #include "Iconmenu.h"
40 #include "Image.h"
41 #include "Screen.h"
42
43 #ifdef SLIT
44 #include "Slit.h"
45 #endif // SLIT
46
47 #include "Rootmenu.h"
48 #include "Toolbar.h"
49 #include "Window.h"
50 #include "Workspace.h"
51 #include "Workspacemenu.h"
52
53 #ifdef STDC_HEADERS
54 # include <stdlib.h>
55 # include <string.h>
56 # include <sys/types.h>
57 #endif // STDC_HEADERS
58
59 #ifdef HAVE_CTYPE_H
60 # include <ctype.h>
61 #endif // HAVE_CTYPE_H
62
63 #ifdef HAVE_DIRENT_H
64 # include <dirent.h>
65 #endif // HAVE_DIRENT_H
66
67 #ifdef HAVE_LOCALE_H
68 # include <locale.h>
69 #endif // HAVE_LOCALE_H
70
71 #ifdef HAVE_UNISTD_H
72 # include <sys/types.h>
73 # include <unistd.h>
74 #endif // HAVE_UNISTD_H
75
76 #ifdef HAVE_SYS_STAT_H
77 # include <sys/stat.h>
78 #endif // HAVE_SYS_STAT_H
79
80 #ifdef HAVE_STDARG_H
81 # include <stdarg.h>
82 #endif // HAVE_STDARG_H
83
84 #ifndef HAVE_SNPRINTF
85 # include "bsd-snprintf.h"
86 #endif // !HAVE_SNPRINTF
87
88 #ifndef MAXPATHLEN
89 #define MAXPATHLEN 255
90 #endif // MAXPATHLEN
91
92 #ifndef FONT_ELEMENT_SIZE
93 #define FONT_ELEMENT_SIZE 50
94 #endif // FONT_ELEMENT_SIZE
95
96 #include <string>
97 #include <algorithm>
98
99 static Bool running = True;
100
101 static int anotherWMRunning(Display *display, XErrorEvent *) {
102 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenAnotherWMRunning,
103 "BScreen::BScreen: an error occured while querying the X server.\n"
104 " another window manager already running on display %s.\n"),
105 DisplayString(display));
106
107 running = False;
108
109 return(-1);
110 }
111
112 struct dcmp {
113 bool operator()(const char *one, const char *two) const {
114 return (strcmp(one, two) < 0) ? True : False;
115 }
116 };
117
118 #ifndef HAVE_STRCASESTR
119 static const char * strcasestr(const char *str, const char *ptn) {
120 const char *s2, *p2;
121 for( ; *str; str++) {
122 for(s2=str,p2=ptn; ; s2++,p2++) {
123 if (!*p2) return str;
124 if (toupper(*s2) != toupper(*p2)) break;
125 }
126 }
127 return NULL;
128 }
129 #endif // HAVE_STRCASESTR
130
131 static const char *getFontElement(const char *pattern, char *buf, int bufsiz, ...) {
132 const char *p, *v;
133 char *p2;
134 va_list va;
135
136 va_start(va, bufsiz);
137 buf[bufsiz-1] = 0;
138 buf[bufsiz-2] = '*';
139 while((v = va_arg(va, char *)) != NULL) {
140 p = strcasestr(pattern, v);
141 if (p) {
142 strncpy(buf, p+1, bufsiz-2);
143 p2 = strchr(buf, '-');
144 if (p2) *p2=0;
145 va_end(va);
146 return p;
147 }
148 }
149 va_end(va);
150 strncpy(buf, "*", bufsiz);
151 return NULL;
152 }
153
154 static const char *getFontSize(const char *pattern, int *size) {
155 const char *p;
156 const char *p2=NULL;
157 int n=0;
158
159 for (p=pattern; 1; p++) {
160 if (!*p) {
161 if (p2!=NULL && n>1 && n<72) {
162 *size = n; return p2+1;
163 } else {
164 *size = 16; return NULL;
165 }
166 } else if (*p=='-') {
167 if (n>1 && n<72 && p2!=NULL) {
168 *size = n;
169 return p2+1;
170 }
171 p2=p; n=0;
172 } else if (*p>='0' && *p<='9' && p2!=NULL) {
173 n *= 10;
174 n += *p-'0';
175 } else {
176 p2=NULL; n=0;
177 }
178 }
179 }
180
181
182 BScreen::BScreen(Openbox &ob, int scrn) : ScreenInfo(ob, scrn), openbox(ob) {
183 event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
184 SubstructureRedirectMask | KeyPressMask | KeyReleaseMask |
185 ButtonPressMask | ButtonReleaseMask;
186
187 XErrorHandler old = XSetErrorHandler((XErrorHandler) anotherWMRunning);
188 XSelectInput(getBaseDisplay().getXDisplay(), getRootWindow(), event_mask);
189 XSync(getBaseDisplay().getXDisplay(), False);
190 XSetErrorHandler((XErrorHandler) old);
191
192 managed = running;
193 if (! managed) return;
194
195 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenManagingScreen,
196 "BScreen::BScreen: managing screen %d "
197 "using visual 0x%lx, depth %d\n"),
198 getScreenNumber(), XVisualIDFromVisual(getVisual()),
199 getDepth());
200
201 rootmenu = 0;
202
203 resource.mstyle.t_fontset = resource.mstyle.f_fontset =
204 resource.tstyle.fontset = resource.wstyle.fontset = (XFontSet) 0;
205 resource.mstyle.t_font = resource.mstyle.f_font = resource.tstyle.font =
206 resource.wstyle.font = (XFontStruct *) 0;
207 resource.root_command = NULL;
208
209 #ifdef HAVE_STRFTIME
210 resource.strftime_format = 0;
211 #endif // HAVE_STRFTIME
212
213 #ifdef HAVE_GETPID
214 pid_t bpid = getpid();
215
216 XChangeProperty(getBaseDisplay().getXDisplay(), getRootWindow(),
217 openbox.getOpenboxPidAtom(), XA_CARDINAL,
218 sizeof(pid_t) * 8, PropModeReplace,
219 (unsigned char *) &bpid, 1);
220 #endif // HAVE_GETPID
221
222 XDefineCursor(getBaseDisplay().getXDisplay(), getRootWindow(),
223 openbox.getSessionCursor());
224
225 workspaceNames = new LinkedList<char>;
226 workspacesList = new LinkedList<Workspace>;
227 rootmenuList = new LinkedList<Rootmenu>;
228 netizenList = new LinkedList<Netizen>;
229 iconList = new LinkedList<OpenboxWindow>;
230
231 image_control =
232 new BImageControl(openbox, *this, True, openbox.getColorsPerChannel(),
233 openbox.getCacheLife(), openbox.getCacheMax());
234 image_control->installRootColormap();
235 root_colormap_installed = True;
236
237 openbox.load_rc(this);
238
239 image_control->setDither(resource.image_dither);
240
241 LoadStyle();
242
243 XGCValues gcv;
244 unsigned long gc_value_mask = GCForeground;
245 if (! i18n->multibyte()) gc_value_mask |= GCFont;
246
247 gcv.foreground = WhitePixel(getBaseDisplay().getXDisplay(),
248 getScreenNumber())
249 ^ BlackPixel(getBaseDisplay().getXDisplay(),
250 getScreenNumber());
251 gcv.function = GXxor;
252 gcv.subwindow_mode = IncludeInferiors;
253 opGC = XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
254 GCForeground | GCFunction | GCSubwindowMode, &gcv);
255
256 gcv.foreground = resource.wstyle.l_text_focus.getPixel();
257 if (resource.wstyle.font)
258 gcv.font = resource.wstyle.font->fid;
259 resource.wstyle.l_text_focus_gc =
260 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
261 gc_value_mask, &gcv);
262
263 gcv.foreground = resource.wstyle.l_text_unfocus.getPixel();
264 if (resource.wstyle.font)
265 gcv.font = resource.wstyle.font->fid;
266 resource.wstyle.l_text_unfocus_gc =
267 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
268 gc_value_mask, &gcv);
269
270 gcv.foreground = resource.wstyle.b_pic_focus.getPixel();
271 resource.wstyle.b_pic_focus_gc =
272 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
273 GCForeground, &gcv);
274
275 gcv.foreground = resource.wstyle.b_pic_unfocus.getPixel();
276 resource.wstyle.b_pic_unfocus_gc =
277 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
278 GCForeground, &gcv);
279
280 gcv.foreground = resource.mstyle.t_text.getPixel();
281 if (resource.mstyle.t_font)
282 gcv.font = resource.mstyle.t_font->fid;
283 resource.mstyle.t_text_gc =
284 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
285 gc_value_mask, &gcv);
286
287 gcv.foreground = resource.mstyle.f_text.getPixel();
288 if (resource.mstyle.f_font)
289 gcv.font = resource.mstyle.f_font->fid;
290 resource.mstyle.f_text_gc =
291 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
292 gc_value_mask, &gcv);
293
294 gcv.foreground = resource.mstyle.h_text.getPixel();
295 resource.mstyle.h_text_gc =
296 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
297 gc_value_mask, &gcv);
298
299 gcv.foreground = resource.mstyle.d_text.getPixel();
300 resource.mstyle.d_text_gc =
301 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
302 gc_value_mask, &gcv);
303
304 gcv.foreground = resource.mstyle.hilite.getColor()->getPixel();
305 resource.mstyle.hilite_gc =
306 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
307 gc_value_mask, &gcv);
308
309 gcv.foreground = resource.tstyle.l_text.getPixel();
310 if (resource.tstyle.font)
311 gcv.font = resource.tstyle.font->fid;
312 resource.tstyle.l_text_gc =
313 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
314 gc_value_mask, &gcv);
315
316 gcv.foreground = resource.tstyle.w_text.getPixel();
317 resource.tstyle.w_text_gc =
318 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
319 gc_value_mask, &gcv);
320
321 gcv.foreground = resource.tstyle.c_text.getPixel();
322 resource.tstyle.c_text_gc =
323 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
324 gc_value_mask, &gcv);
325
326 gcv.foreground = resource.tstyle.b_pic.getPixel();
327 resource.tstyle.b_pic_gc =
328 XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
329 gc_value_mask, &gcv);
330
331 const char *s = i18n->getMessage(ScreenSet, ScreenPositionLength,
332 "0: 0000 x 0: 0000");
333 int l = strlen(s);
334
335 if (i18n->multibyte()) {
336 XRectangle ink, logical;
337 XmbTextExtents(resource.wstyle.fontset, s, l, &ink, &logical);
338 geom_w = logical.width;
339
340 geom_h = resource.wstyle.fontset_extents->max_ink_extent.height;
341 } else {
342 geom_h = resource.wstyle.font->ascent +
343 resource.wstyle.font->descent;
344
345 geom_w = XTextWidth(resource.wstyle.font, s, l);
346 }
347
348 geom_w += (resource.bevel_width * 2);
349 geom_h += (resource.bevel_width * 2);
350
351 XSetWindowAttributes attrib;
352 unsigned long mask = CWBorderPixel | CWColormap | CWSaveUnder;
353 attrib.border_pixel = getBorderColor()->getPixel();
354 attrib.colormap = getColormap();
355 attrib.save_under = True;
356
357 geom_window =
358 XCreateWindow(getBaseDisplay().getXDisplay(), getRootWindow(),
359 0, 0, geom_w, geom_h, resource.border_width, getDepth(),
360 InputOutput, getVisual(), mask, &attrib);
361 geom_visible = False;
362
363 if (resource.wstyle.l_focus.getTexture() & BImage_ParentRelative) {
364 if (resource.wstyle.t_focus.getTexture() ==
365 (BImage_Flat | BImage_Solid)) {
366 geom_pixmap = None;
367 XSetWindowBackground(getBaseDisplay().getXDisplay(), geom_window,
368 resource.wstyle.t_focus.getColor()->getPixel());
369 } else {
370 geom_pixmap = image_control->renderImage(geom_w, geom_h,
371 &resource.wstyle.t_focus);
372 XSetWindowBackgroundPixmap(getBaseDisplay().getXDisplay(),
373 geom_window, geom_pixmap);
374 }
375 } else {
376 if (resource.wstyle.l_focus.getTexture() ==
377 (BImage_Flat | BImage_Solid)) {
378 geom_pixmap = None;
379 XSetWindowBackground(getBaseDisplay().getXDisplay(), geom_window,
380 resource.wstyle.l_focus.getColor()->getPixel());
381 } else {
382 geom_pixmap = image_control->renderImage(geom_w, geom_h,
383 &resource.wstyle.l_focus);
384 XSetWindowBackgroundPixmap(getBaseDisplay().getXDisplay(),
385 geom_window, geom_pixmap);
386 }
387 }
388
389 workspacemenu = new Workspacemenu(*this);
390 iconmenu = new Iconmenu(*this);
391 configmenu = new Configmenu(*this);
392
393 Workspace *wkspc = (Workspace *) 0;
394 if (resource.workspaces != 0) {
395 for (int i = 0; i < resource.workspaces; ++i) {
396 wkspc = new Workspace(*this, workspacesList->count());
397 workspacesList->insert(wkspc);
398 workspacemenu->insert(wkspc->getName(), wkspc->getMenu());
399 }
400 } else {
401 wkspc = new Workspace(*this, workspacesList->count());
402 workspacesList->insert(wkspc);
403 workspacemenu->insert(wkspc->getName(), wkspc->getMenu());
404 }
405
406 workspacemenu->insert(i18n->getMessage(IconSet, IconIcons, "Icons"),
407 iconmenu);
408 workspacemenu->update();
409
410 current_workspace = workspacesList->first();
411 workspacemenu->setItemSelected(2, True);
412
413 toolbar = new Toolbar(*this);
414
415 #ifdef SLIT
416 slit = new Slit(*this);
417 #endif // SLIT
418
419 InitMenu();
420
421 raiseWindows(0, 0);
422 rootmenu->update();
423
424 changeWorkspaceID(0);
425
426 int i;
427 unsigned int nchild;
428 Window r, p, *children;
429 XQueryTree(getBaseDisplay().getXDisplay(), getRootWindow(), &r, &p,
430 &children, &nchild);
431
432 // preen the window list of all icon windows... for better dockapp support
433 for (i = 0; i < (int) nchild; i++) {
434 if (children[i] == None) continue;
435
436 XWMHints *wmhints = XGetWMHints(getBaseDisplay().getXDisplay(),
437 children[i]);
438
439 if (wmhints) {
440 if ((wmhints->flags & IconWindowHint) &&
441 (wmhints->icon_window != children[i]))
442 for (int j = 0; j < (int) nchild; j++)
443 if (children[j] == wmhints->icon_window) {
444 children[j] = None;
445
446 break;
447 }
448
449 XFree(wmhints);
450 }
451 }
452
453 // manage shown windows
454 for (i = 0; i < (int) nchild; ++i) {
455 if (children[i] == None || (! openbox.validateWindow(children[i])))
456 continue;
457
458 XWindowAttributes attrib;
459 if (XGetWindowAttributes(getBaseDisplay().getXDisplay(), children[i],
460 &attrib)) {
461 if (attrib.override_redirect) continue;
462
463 if (attrib.map_state != IsUnmapped) {
464 new OpenboxWindow(openbox, children[i], this);
465
466 OpenboxWindow *win = openbox.searchWindow(children[i]);
467 if (win) {
468 XMapRequestEvent mre;
469 mre.window = children[i];
470 win->restoreAttributes();
471 win->mapRequestEvent(&mre);
472 }
473 }
474 }
475 }
476
477 if (! resource.sloppy_focus)
478 XSetInputFocus(getBaseDisplay().getXDisplay(), toolbar->getWindowID(),
479 RevertToParent, CurrentTime);
480
481 XFree(children);
482 XFlush(getBaseDisplay().getXDisplay());
483 }
484
485
486 BScreen::~BScreen(void) {
487 if (! managed) return;
488
489 if (geom_pixmap != None)
490 image_control->removeImage(geom_pixmap);
491
492 if (geom_window != None)
493 XDestroyWindow(getBaseDisplay().getXDisplay(), geom_window);
494
495 removeWorkspaceNames();
496
497 while (workspacesList->count())
498 delete workspacesList->remove(0);
499
500 while (rootmenuList->count())
501 rootmenuList->remove(0);
502
503 while (iconList->count())
504 delete iconList->remove(0);
505
506 while (netizenList->count())
507 delete netizenList->remove(0);
508
509 #ifdef HAVE_STRFTIME
510 if (resource.strftime_format)
511 delete [] resource.strftime_format;
512 #endif // HAVE_STRFTIME
513
514 delete rootmenu;
515 delete workspacemenu;
516 delete iconmenu;
517 delete configmenu;
518
519 #ifdef SLIT
520 delete slit;
521 #endif // SLIT
522
523 delete toolbar;
524 delete image_control;
525
526 delete workspacesList;
527 delete workspaceNames;
528 delete rootmenuList;
529 delete iconList;
530 delete netizenList;
531
532 if (resource.wstyle.fontset)
533 XFreeFontSet(getBaseDisplay().getXDisplay(), resource.wstyle.fontset);
534 if (resource.mstyle.t_fontset)
535 XFreeFontSet(getBaseDisplay().getXDisplay(), resource.mstyle.t_fontset);
536 if (resource.mstyle.f_fontset)
537 XFreeFontSet(getBaseDisplay().getXDisplay(), resource.mstyle.f_fontset);
538 if (resource.tstyle.fontset)
539 XFreeFontSet(getBaseDisplay().getXDisplay(), resource.tstyle.fontset);
540
541 if (resource.wstyle.font)
542 XFreeFont(getBaseDisplay().getXDisplay(), resource.wstyle.font);
543 if (resource.mstyle.t_font)
544 XFreeFont(getBaseDisplay().getXDisplay(), resource.mstyle.t_font);
545 if (resource.mstyle.f_font)
546 XFreeFont(getBaseDisplay().getXDisplay(), resource.mstyle.f_font);
547 if (resource.tstyle.font)
548 XFreeFont(getBaseDisplay().getXDisplay(), resource.tstyle.font);
549 if (resource.root_command != NULL)
550 delete [] resource.root_command;
551
552 XFreeGC(getBaseDisplay().getXDisplay(), opGC);
553
554 XFreeGC(getBaseDisplay().getXDisplay(),
555 resource.wstyle.l_text_focus_gc);
556 XFreeGC(getBaseDisplay().getXDisplay(),
557 resource.wstyle.l_text_unfocus_gc);
558 XFreeGC(getBaseDisplay().getXDisplay(),
559 resource.wstyle.b_pic_focus_gc);
560 XFreeGC(getBaseDisplay().getXDisplay(),
561 resource.wstyle.b_pic_unfocus_gc);
562
563 XFreeGC(getBaseDisplay().getXDisplay(),
564 resource.mstyle.t_text_gc);
565 XFreeGC(getBaseDisplay().getXDisplay(),
566 resource.mstyle.f_text_gc);
567 XFreeGC(getBaseDisplay().getXDisplay(),
568 resource.mstyle.h_text_gc);
569 XFreeGC(getBaseDisplay().getXDisplay(),
570 resource.mstyle.d_text_gc);
571 XFreeGC(getBaseDisplay().getXDisplay(),
572 resource.mstyle.hilite_gc);
573
574 XFreeGC(getBaseDisplay().getXDisplay(),
575 resource.tstyle.l_text_gc);
576 XFreeGC(getBaseDisplay().getXDisplay(),
577 resource.tstyle.w_text_gc);
578 XFreeGC(getBaseDisplay().getXDisplay(),
579 resource.tstyle.c_text_gc);
580 XFreeGC(getBaseDisplay().getXDisplay(),
581 resource.tstyle.b_pic_gc);
582 }
583
584 void BScreen::readDatabaseTexture(const char *rname, const char *rclass,
585 BTexture *texture,
586 unsigned long default_pixel)
587 {
588 std::string s;
589
590 if (resource.styleconfig.getValue(rname, rclass, s))
591 image_control->parseTexture(texture, s.c_str());
592 else
593 texture->setTexture(BImage_Solid | BImage_Flat);
594
595 if (texture->getTexture() & BImage_Solid) {
596 int clen = strlen(rclass) + 32, nlen = strlen(rname) + 32;
597
598 char *colorclass = new char[clen], *colorname = new char[nlen];
599
600 sprintf(colorclass, "%s.Color", rclass);
601 sprintf(colorname, "%s.color", rname);
602
603 readDatabaseColor(colorname, colorclass, texture->getColor(),
604 default_pixel);
605
606 #ifdef INTERLACE
607 sprintf(colorclass, "%s.ColorTo", rclass);
608 sprintf(colorname, "%s.colorTo", rname);
609
610 readDatabaseColor(colorname, colorclass, texture->getColorTo(),
611 default_pixel);
612 #endif // INTERLACE
613
614 delete [] colorclass;
615 delete [] colorname;
616
617 if ((! texture->getColor()->isAllocated()) ||
618 (texture->getTexture() & BImage_Flat))
619 return;
620
621 XColor xcol;
622
623 xcol.red = (unsigned int) (texture->getColor()->getRed() +
624 (texture->getColor()->getRed() >> 1));
625 if (xcol.red >= 0xff) xcol.red = 0xffff;
626 else xcol.red *= 0xff;
627 xcol.green = (unsigned int) (texture->getColor()->getGreen() +
628 (texture->getColor()->getGreen() >> 1));
629 if (xcol.green >= 0xff) xcol.green = 0xffff;
630 else xcol.green *= 0xff;
631 xcol.blue = (unsigned int) (texture->getColor()->getBlue() +
632 (texture->getColor()->getBlue() >> 1));
633 if (xcol.blue >= 0xff) xcol.blue = 0xffff;
634 else xcol.blue *= 0xff;
635
636 if (! XAllocColor(getBaseDisplay().getXDisplay(),
637 getColormap(), &xcol))
638 xcol.pixel = 0;
639
640 texture->getHiColor()->setPixel(xcol.pixel);
641
642 xcol.red =
643 (unsigned int) ((texture->getColor()->getRed() >> 2) +
644 (texture->getColor()->getRed() >> 1)) * 0xff;
645 xcol.green =
646 (unsigned int) ((texture->getColor()->getGreen() >> 2) +
647 (texture->getColor()->getGreen() >> 1)) * 0xff;
648 xcol.blue =
649 (unsigned int) ((texture->getColor()->getBlue() >> 2) +
650 (texture->getColor()->getBlue() >> 1)) * 0xff;
651
652 if (! XAllocColor(getBaseDisplay().getXDisplay(),
653 getColormap(), &xcol))
654 xcol.pixel = 0;
655
656 texture->getLoColor()->setPixel(xcol.pixel);
657 } else if (texture->getTexture() & BImage_Gradient) {
658 int clen = strlen(rclass) + 10, nlen = strlen(rname) + 10;
659
660 char *colorclass = new char[clen], *colorname = new char[nlen],
661 *colortoclass = new char[clen], *colortoname = new char[nlen];
662
663 sprintf(colorclass, "%s.Color", rclass);
664 sprintf(colorname, "%s.color", rname);
665
666 sprintf(colortoclass, "%s.ColorTo", rclass);
667 sprintf(colortoname, "%s.colorTo", rname);
668
669 readDatabaseColor(colorname, colorclass, texture->getColor(),
670 default_pixel);
671 readDatabaseColor(colortoname, colortoclass, texture->getColorTo(),
672 default_pixel);
673
674 delete [] colorclass;
675 delete [] colorname;
676 delete [] colortoclass;
677 delete [] colortoname;
678 }
679 }
680
681
682 void BScreen::readDatabaseColor(const char *rname, const char *rclass,
683 BColor *color, unsigned long default_pixel)
684 {
685 std::string s;
686
687 if (resource.styleconfig.getValue(rname, rclass, s))
688 image_control->parseColor(color, s.c_str());
689 else {
690 // parsing with no color string just deallocates the color, if it has
691 // been previously allocated
692 image_control->parseColor(color);
693 color->setPixel(default_pixel);
694 }
695 }
696
697
698 void BScreen::readDatabaseFontSet(const char *rname, const char *rclass,
699 XFontSet *fontset) {
700 if (! fontset) return;
701
702 static char *defaultFont = "fixed";
703 bool load_default = false;
704 std::string s;
705
706 if (*fontset)
707 XFreeFontSet(getBaseDisplay().getXDisplay(), *fontset);
708
709 if (resource.styleconfig.getValue(rname, rclass, s)) {
710 if (! (*fontset = createFontSet(s.c_str())))
711 load_default = true;
712 } else
713 load_default = true;
714
715 if (load_default) {
716 *fontset = createFontSet(defaultFont);
717
718 if (! *fontset) {
719 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenDefaultFontLoadFail,
720 "BScreen::LoadStyle(): couldn't load default font.\n"));
721 exit(2);
722 }
723 }
724 }
725
726
727 void BScreen::readDatabaseFont(const char *rname, const char *rclass,
728 XFontStruct **font) {
729 if (! font) return;
730
731 static char *defaultFont = "fixed";
732 bool load_default = false;
733 std::string s;
734
735 if (*font)
736 XFreeFont(getBaseDisplay().getXDisplay(), *font);
737
738 if (resource.styleconfig.getValue(rname, rclass, s)) {
739 if ((*font = XLoadQueryFont(getBaseDisplay().getXDisplay(),
740 s.c_str())) == NULL) {
741 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenFontLoadFail,
742 "BScreen::LoadStyle(): couldn't load font '%s'\n"),
743 s.c_str());
744 load_default = true;
745 }
746 } else
747 load_default = true;
748
749 if (load_default) {
750 if ((*font = XLoadQueryFont(getBaseDisplay().getXDisplay(),
751 defaultFont)) == NULL) {
752 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenDefaultFontLoadFail,
753 "BScreen::LoadStyle(): couldn't load default font.\n"));
754 exit(2);
755 }
756 }
757 }
758
759
760 XFontSet BScreen::createFontSet(const char *fontname) {
761 XFontSet fs;
762 char **missing, *def = "-";
763 int nmissing, pixel_size = 0, buf_size = 0;
764 char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE];
765
766 fs = XCreateFontSet(getBaseDisplay().getXDisplay(),
767 fontname, &missing, &nmissing, &def);
768 if (fs && (! nmissing)) return fs;
769
770 #ifdef HAVE_SETLOCALE
771 if (! fs) {
772 if (nmissing) XFreeStringList(missing);
773
774 setlocale(LC_CTYPE, "C");
775 fs = XCreateFontSet(getBaseDisplay().getXDisplay(), fontname,
776 &missing, &nmissing, &def);
777 setlocale(LC_CTYPE, "");
778 }
779 #endif // HAVE_SETLOCALE
780
781 if (fs) {
782 XFontStruct **fontstructs;
783 char **fontnames;
784 XFontsOfFontSet(fs, &fontstructs, &fontnames);
785 fontname = fontnames[0];
786 }
787
788 getFontElement(fontname, weight, FONT_ELEMENT_SIZE,
789 "-medium-", "-bold-", "-demibold-", "-regular-", NULL);
790 getFontElement(fontname, slant, FONT_ELEMENT_SIZE,
791 "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
792 getFontSize(fontname, &pixel_size);
793
794 if (! strcmp(weight, "*")) strncpy(weight, "medium", FONT_ELEMENT_SIZE);
795 if (! strcmp(slant, "*")) strncpy(slant, "r", FONT_ELEMENT_SIZE);
796 if (pixel_size < 3) pixel_size = 3;
797 else if (pixel_size > 97) pixel_size = 97;
798
799 buf_size = strlen(fontname) + (FONT_ELEMENT_SIZE * 2) + 64;
800 char *pattern2 = new char[buf_size];
801 snprintf(pattern2, buf_size - 1,
802 "%s,"
803 "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
804 "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*",
805 fontname, weight, slant, pixel_size, pixel_size);
806 fontname = pattern2;
807
808 if (nmissing) XFreeStringList(missing);
809 if (fs) XFreeFontSet(getBaseDisplay().getXDisplay(), fs);
810
811 fs = XCreateFontSet(getBaseDisplay().getXDisplay(), fontname,
812 &missing, &nmissing, &def);
813 delete [] pattern2;
814
815 return fs;
816 }
817
818
819 void BScreen::reconfigure(void) {
820 LoadStyle();
821
822 XGCValues gcv;
823 unsigned long gc_value_mask = GCForeground;
824 if (! i18n->multibyte()) gc_value_mask |= GCFont;
825
826 gcv.foreground = WhitePixel(getBaseDisplay().getXDisplay(),
827 getScreenNumber());
828 gcv.function = GXinvert;
829 gcv.subwindow_mode = IncludeInferiors;
830 XChangeGC(getBaseDisplay().getXDisplay(), opGC,
831 GCForeground | GCFunction | GCSubwindowMode, &gcv);
832
833 gcv.foreground = resource.wstyle.l_text_focus.getPixel();
834 if (resource.wstyle.font)
835 gcv.font = resource.wstyle.font->fid;
836 XChangeGC(getBaseDisplay().getXDisplay(), resource.wstyle.l_text_focus_gc,
837 gc_value_mask, &gcv);
838
839 gcv.foreground = resource.wstyle.l_text_unfocus.getPixel();
840 XChangeGC(getBaseDisplay().getXDisplay(), resource.wstyle.l_text_unfocus_gc,
841 gc_value_mask, &gcv);
842
843 gcv.foreground = resource.wstyle.b_pic_focus.getPixel();
844 XChangeGC(getBaseDisplay().getXDisplay(), resource.wstyle.b_pic_focus_gc,
845 GCForeground, &gcv);
846
847 gcv.foreground = resource.wstyle.b_pic_unfocus.getPixel();
848 XChangeGC(getBaseDisplay().getXDisplay(), resource.wstyle.b_pic_unfocus_gc,
849 GCForeground, &gcv);
850
851 gcv.foreground = resource.mstyle.t_text.getPixel();
852 if (resource.mstyle.t_font)
853 gcv.font = resource.mstyle.t_font->fid;
854 XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.t_text_gc,
855 gc_value_mask, &gcv);
856
857 gcv.foreground = resource.mstyle.f_text.getPixel();
858 if (resource.mstyle.f_font)
859 gcv.font = resource.mstyle.f_font->fid;
860 XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.f_text_gc,
861 gc_value_mask, &gcv);
862
863 gcv.foreground = resource.mstyle.h_text.getPixel();
864 XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.h_text_gc,
865 gc_value_mask, &gcv);
866
867 gcv.foreground = resource.mstyle.d_text.getPixel();
868 XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.d_text_gc,
869 gc_value_mask, &gcv);
870
871 gcv.foreground = resource.mstyle.hilite.getColor()->getPixel();
872 XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.hilite_gc,
873 gc_value_mask, &gcv);
874
875 gcv.foreground = resource.tstyle.l_text.getPixel();
876 if (resource.tstyle.font)
877 gcv.font = resource.tstyle.font->fid;
878 XChangeGC(getBaseDisplay().getXDisplay(), resource.tstyle.l_text_gc,
879 gc_value_mask, &gcv);
880
881 gcv.foreground = resource.tstyle.w_text.getPixel();
882 XChangeGC(getBaseDisplay().getXDisplay(), resource.tstyle.w_text_gc,
883 gc_value_mask, &gcv);
884
885 gcv.foreground = resource.tstyle.c_text.getPixel();
886 XChangeGC(getBaseDisplay().getXDisplay(), resource.tstyle.c_text_gc,
887 gc_value_mask, &gcv);
888
889 gcv.foreground = resource.tstyle.b_pic.getPixel();
890 XChangeGC(getBaseDisplay().getXDisplay(), resource.tstyle.b_pic_gc,
891 gc_value_mask, &gcv);
892
893 const char *s = i18n->getMessage(ScreenSet, ScreenPositionLength,
894 "0: 0000 x 0: 0000");
895 int l = strlen(s);
896
897 if (i18n->multibyte()) {
898 XRectangle ink, logical;
899 XmbTextExtents(resource.wstyle.fontset, s, l, &ink, &logical);
900 geom_w = logical.width;
901
902 geom_h = resource.wstyle.fontset_extents->max_ink_extent.height;
903 } else {
904 geom_w = XTextWidth(resource.wstyle.font, s, l);
905
906 geom_h = resource.wstyle.font->ascent +
907 resource.wstyle.font->descent;
908 }
909
910 geom_w += (resource.bevel_width * 2);
911 geom_h += (resource.bevel_width * 2);
912
913 Pixmap tmp = geom_pixmap;
914 if (resource.wstyle.l_focus.getTexture() & BImage_ParentRelative) {
915 if (resource.wstyle.t_focus.getTexture() ==
916 (BImage_Flat | BImage_Solid)) {
917 geom_pixmap = None;
918 XSetWindowBackground(getBaseDisplay().getXDisplay(), geom_window,
919 resource.wstyle.t_focus.getColor()->getPixel());
920 } else {
921 geom_pixmap = image_control->renderImage(geom_w, geom_h,
922 &resource.wstyle.t_focus);
923 XSetWindowBackgroundPixmap(getBaseDisplay().getXDisplay(),
924 geom_window, geom_pixmap);
925 }
926 } else {
927 if (resource.wstyle.l_focus.getTexture() ==
928 (BImage_Flat | BImage_Solid)) {
929 geom_pixmap = None;
930 XSetWindowBackground(getBaseDisplay().getXDisplay(), geom_window,
931 resource.wstyle.l_focus.getColor()->getPixel());
932 } else {
933 geom_pixmap = image_control->renderImage(geom_w, geom_h,
934 &resource.wstyle.l_focus);
935 XSetWindowBackgroundPixmap(getBaseDisplay().getXDisplay(),
936 geom_window, geom_pixmap);
937 }
938 }
939 if (tmp) image_control->removeImage(tmp);
940
941 XSetWindowBorderWidth(getBaseDisplay().getXDisplay(), geom_window,
942 resource.border_width);
943 XSetWindowBorder(getBaseDisplay().getXDisplay(), geom_window,
944 resource.border_color.getPixel());
945
946 workspacemenu->reconfigure();
947 iconmenu->reconfigure();
948
949 {
950 int remember_sub = rootmenu->getCurrentSubmenu();
951 InitMenu();
952 raiseWindows(0, 0);
953 rootmenu->reconfigure();
954 rootmenu->drawSubmenu(remember_sub);
955 }
956
957 configmenu->reconfigure();
958
959 toolbar->reconfigure();
960
961 #ifdef SLIT
962 slit->reconfigure();
963 #endif // SLIT
964
965 LinkedListIterator<Workspace> wit(workspacesList);
966 for (Workspace *w = wit.current(); w; wit++, w = wit.current())
967 w->reconfigure();
968
969 LinkedListIterator<OpenboxWindow> iit(iconList);
970 for (OpenboxWindow *bw = iit.current(); bw; iit++, bw = iit.current())
971 if (bw->validateClient())
972 bw->reconfigure();
973
974 image_control->timeout();
975 }
976
977
978 void BScreen::rereadMenu(void) {
979 InitMenu();
980 raiseWindows(0, 0);
981
982 rootmenu->reconfigure();
983 }
984
985
986 void BScreen::removeWorkspaceNames(void) {
987 while (workspaceNames->count())
988 delete [] workspaceNames->remove(0);
989 }
990
991
992 void BScreen::LoadStyle(void) {
993 obResource &conf = resource.styleconfig;
994
995 conf.setFile(openbox.getStyleFilename());
996 if (!conf.load()) {
997 conf.setFile(DEFAULTSTYLE);
998 if (!conf.load()) {
999 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenDefaultStyleLoadFail,
1000 "BScreen::LoadStyle(): couldn't load "
1001 "default style.\n"));
1002 exit(2);
1003 }
1004 }
1005
1006 std::string s;
1007 long l;
1008
1009 // load fonts/fontsets
1010
1011 if (i18n->multibyte()) {
1012 readDatabaseFontSet("window.font", "Window.Font",
1013 &resource.wstyle.fontset);
1014 readDatabaseFontSet("toolbar.font", "Toolbar.Font",
1015 &resource.tstyle.fontset);
1016 readDatabaseFontSet("menu.title.font", "Menu.Title.Font",
1017 &resource.mstyle.t_fontset);
1018 readDatabaseFontSet("menu.frame.font", "Menu.Frame.Font",
1019 &resource.mstyle.f_fontset);
1020
1021 resource.mstyle.t_fontset_extents =
1022 XExtentsOfFontSet(resource.mstyle.t_fontset);
1023 resource.mstyle.f_fontset_extents =
1024 XExtentsOfFontSet(resource.mstyle.f_fontset);
1025 resource.tstyle.fontset_extents =
1026 XExtentsOfFontSet(resource.tstyle.fontset);
1027 resource.wstyle.fontset_extents =
1028 XExtentsOfFontSet(resource.wstyle.fontset);
1029 } else {
1030 readDatabaseFont("window.font", "Window.Font",
1031 &resource.wstyle.font);
1032 readDatabaseFont("menu.title.font", "Menu.Title.Font",
1033 &resource.mstyle.t_font);
1034 readDatabaseFont("menu.frame.font", "Menu.Frame.Font",
1035 &resource.mstyle.f_font);
1036 readDatabaseFont("toolbar.font", "Toolbar.Font",
1037 &resource.tstyle.font);
1038 }
1039
1040 // load window config
1041 readDatabaseTexture("window.title.focus", "Window.Title.Focus",
1042 &resource.wstyle.t_focus,
1043 WhitePixel(getBaseDisplay().getXDisplay(),
1044 getScreenNumber()));
1045 readDatabaseTexture("window.title.unfocus", "Window.Title.Unfocus",
1046 &resource.wstyle.t_unfocus,
1047 BlackPixel(getBaseDisplay().getXDisplay(),
1048 getScreenNumber()));
1049 readDatabaseTexture("window.label.focus", "Window.Label.Focus",
1050 &resource.wstyle.l_focus,
1051 WhitePixel(getBaseDisplay().getXDisplay(),
1052 getScreenNumber()));
1053 readDatabaseTexture("window.label.unfocus", "Window.Label.Unfocus",
1054 &resource.wstyle.l_unfocus,
1055 BlackPixel(getBaseDisplay().getXDisplay(),
1056 getScreenNumber()));
1057 readDatabaseTexture("window.handle.focus", "Window.Handle.Focus",
1058 &resource.wstyle.h_focus,
1059 WhitePixel(getBaseDisplay().getXDisplay(),
1060 getScreenNumber()));
1061 readDatabaseTexture("window.handle.unfocus", "Window.Handle.Unfocus",
1062 &resource.wstyle.h_unfocus,
1063 BlackPixel(getBaseDisplay().getXDisplay(),
1064 getScreenNumber()));
1065 readDatabaseTexture("window.grip.focus", "Window.Grip.Focus",
1066 &resource.wstyle.g_focus,
1067 WhitePixel(getBaseDisplay().getXDisplay(),
1068 getScreenNumber()));
1069 readDatabaseTexture("window.grip.unfocus", "Window.Grip.Unfocus",
1070 &resource.wstyle.g_unfocus,
1071 BlackPixel(getBaseDisplay().getXDisplay(),
1072 getScreenNumber()));
1073 readDatabaseTexture("window.button.focus", "Window.Button.Focus",
1074 &resource.wstyle.b_focus,
1075 WhitePixel(getBaseDisplay().getXDisplay(),
1076 getScreenNumber()));
1077 readDatabaseTexture("window.button.unfocus", "Window.Button.Unfocus",
1078 &resource.wstyle.b_unfocus,
1079 BlackPixel(getBaseDisplay().getXDisplay(),
1080 getScreenNumber()));
1081 readDatabaseTexture("window.button.pressed", "Window.Button.Pressed",
1082 &resource.wstyle.b_pressed,
1083 BlackPixel(getBaseDisplay().getXDisplay(),
1084 getScreenNumber()));
1085 readDatabaseColor("window.frame.focusColor",
1086 "Window.Frame.FocusColor",
1087 &resource.wstyle.f_focus,
1088 WhitePixel(getBaseDisplay().getXDisplay(),
1089 getScreenNumber()));
1090 readDatabaseColor("window.frame.unfocusColor",
1091 "Window.Frame.UnfocusColor",
1092 &resource.wstyle.f_unfocus,
1093 BlackPixel(getBaseDisplay().getXDisplay(),
1094 getScreenNumber()));
1095 readDatabaseColor("window.label.focus.textColor",
1096 "Window.Label.Focus.TextColor",
1097 &resource.wstyle.l_text_focus,
1098 BlackPixel(getBaseDisplay().getXDisplay(),
1099 getScreenNumber()));
1100 readDatabaseColor("window.label.unfocus.textColor",
1101 "Window.Label.Unfocus.TextColor",
1102 &resource.wstyle.l_text_unfocus,
1103 WhitePixel(getBaseDisplay().getXDisplay(),
1104 getScreenNumber()));
1105 readDatabaseColor("window.button.focus.picColor",
1106 "Window.Button.Focus.PicColor",
1107 &resource.wstyle.b_pic_focus,
1108 BlackPixel(getBaseDisplay().getXDisplay(),
1109 getScreenNumber()));
1110 readDatabaseColor("window.button.unfocus.picColor",
1111 "Window.Button.Unfocus.PicColor",
1112 &resource.wstyle.b_pic_unfocus,
1113 WhitePixel(getBaseDisplay().getXDisplay(),
1114 getScreenNumber()));
1115
1116 if (conf.getValue("window.justify", "Window.Justify", s)) {
1117 if (0 == strncasecmp(s.c_str(), "right", s.length()))
1118 resource.wstyle.justify = BScreen::RightJustify;
1119 else if (0 == strncasecmp(s.c_str(), "center", s.length()))
1120 resource.wstyle.justify = BScreen::CenterJustify;
1121 else
1122 resource.wstyle.justify = BScreen::LeftJustify;
1123 } else
1124 resource.wstyle.justify = BScreen::LeftJustify;
1125
1126 // load toolbar config
1127 readDatabaseTexture("toolbar", "Toolbar",
1128 &resource.tstyle.toolbar,
1129 BlackPixel(getBaseDisplay().getXDisplay(),
1130 getScreenNumber()));
1131 readDatabaseTexture("toolbar.label", "Toolbar.Label",
1132 &resource.tstyle.label,
1133 BlackPixel(getBaseDisplay().getXDisplay(),
1134 getScreenNumber()));
1135 readDatabaseTexture("toolbar.windowLabel", "Toolbar.WindowLabel",
1136 &resource.tstyle.window,
1137 BlackPixel(getBaseDisplay().getXDisplay(),
1138 getScreenNumber()));
1139 readDatabaseTexture("toolbar.button", "Toolbar.Button",
1140 &resource.tstyle.button,
1141 WhitePixel(getBaseDisplay().getXDisplay(),
1142 getScreenNumber()));
1143 readDatabaseTexture("toolbar.button.pressed", "Toolbar.Button.Pressed",
1144 &resource.tstyle.pressed,
1145 BlackPixel(getBaseDisplay().getXDisplay(),
1146 getScreenNumber()));
1147 readDatabaseTexture("toolbar.clock", "Toolbar.Clock",
1148 &resource.tstyle.clock,
1149 BlackPixel(getBaseDisplay().getXDisplay(),
1150 getScreenNumber()));
1151 readDatabaseColor("toolbar.label.textColor", "Toolbar.Label.TextColor",
1152 &resource.tstyle.l_text,
1153 WhitePixel(getBaseDisplay().getXDisplay(),
1154 getScreenNumber()));
1155 readDatabaseColor("toolbar.windowLabel.textColor",
1156 "Toolbar.WindowLabel.TextColor",
1157 &resource.tstyle.w_text,
1158 WhitePixel(getBaseDisplay().getXDisplay(),
1159 getScreenNumber()));
1160 readDatabaseColor("toolbar.clock.textColor", "Toolbar.Clock.TextColor",
1161 &resource.tstyle.c_text,
1162 WhitePixel(getBaseDisplay().getXDisplay(),
1163 getScreenNumber()));
1164 readDatabaseColor("toolbar.button.picColor", "Toolbar.Button.PicColor",
1165 &resource.tstyle.b_pic,
1166 BlackPixel(getBaseDisplay().getXDisplay(),
1167 getScreenNumber()));
1168
1169 if (conf.getValue("toolbar.justify", "Toolbar.Justify", s)) {
1170 if (0 == strncasecmp(s.c_str(), "right", s.length()))
1171 resource.tstyle.justify = BScreen::RightJustify;
1172 else if (0 == strncasecmp(s.c_str(), "center", s.length()))
1173 resource.tstyle.justify = BScreen::CenterJustify;
1174 else
1175 resource.tstyle.justify = BScreen::LeftJustify;
1176 } else
1177 resource.tstyle.justify = BScreen::LeftJustify;
1178
1179 // load menu config
1180 readDatabaseTexture("menu.title", "Menu.Title",
1181 &resource.mstyle.title,
1182 WhitePixel(getBaseDisplay().getXDisplay(),
1183 getScreenNumber()));
1184 readDatabaseTexture("menu.frame", "Menu.Frame",
1185 &resource.mstyle.frame,
1186 BlackPixel(getBaseDisplay().getXDisplay(),
1187 getScreenNumber()));
1188 readDatabaseTexture("menu.hilite", "Menu.Hilite",
1189 &resource.mstyle.hilite,
1190 WhitePixel(getBaseDisplay().getXDisplay(),
1191 getScreenNumber()));
1192 readDatabaseColor("menu.title.textColor", "Menu.Title.TextColor",
1193 &resource.mstyle.t_text,
1194 BlackPixel(getBaseDisplay().getXDisplay(),
1195 getScreenNumber()));
1196 readDatabaseColor("menu.frame.textColor", "Menu.Frame.TextColor",
1197 &resource.mstyle.f_text,
1198 WhitePixel(getBaseDisplay().getXDisplay(),
1199 getScreenNumber()));
1200 readDatabaseColor("menu.frame.disableColor", "Menu.Frame.DisableColor",
1201 &resource.mstyle.d_text,
1202 BlackPixel(getBaseDisplay().getXDisplay(),
1203 getScreenNumber()));
1204 readDatabaseColor("menu.hilite.textColor", "Menu.Hilite.TextColor",
1205 &resource.mstyle.h_text,
1206 BlackPixel(getBaseDisplay().getXDisplay(),
1207 getScreenNumber()));
1208
1209 if (conf.getValue("menu.title.justify", "Menu.Title.Justify", s)) {
1210 if (0 == strncasecmp(s.c_str(), "right", s.length()))
1211 resource.mstyle.t_justify = BScreen::RightJustify;
1212 else if (0 == strncasecmp(s.c_str(), "center", s.length()))
1213 resource.mstyle.t_justify = BScreen::CenterJustify;
1214 else
1215 resource.mstyle.t_justify = BScreen::LeftJustify;
1216 } else
1217 resource.mstyle.t_justify = BScreen::LeftJustify;
1218
1219 if (conf.getValue("menu.frame.justify", "Menu.Frame.Justify", s)) {
1220 if (0 == strncasecmp(s.c_str(), "right", s.length()))
1221 resource.mstyle.f_justify = BScreen::RightJustify;
1222 else if (0 == strncasecmp(s.c_str(), "center", s.length()))
1223 resource.mstyle.f_justify = BScreen::CenterJustify;
1224 else
1225 resource.mstyle.f_justify = BScreen::LeftJustify;
1226 } else
1227 resource.mstyle.f_justify = BScreen::LeftJustify;
1228
1229 if (conf.getValue("menu.bullet", "Menu.Bullet", s)) {
1230 if (0 == strncasecmp(s.c_str(), "empty", s.length()))
1231 resource.mstyle.bullet = Basemenu::Empty;
1232 else if (0 == strncasecmp(s.c_str(), "square", s.length()))
1233 resource.mstyle.bullet = Basemenu::Square;
1234 else if (0 == strncasecmp(s.c_str(), "diamond", s.length()))
1235 resource.mstyle.bullet = Basemenu::Diamond;
1236 else
1237 resource.mstyle.bullet = Basemenu::Triangle;
1238 } else
1239 resource.mstyle.bullet = Basemenu::Triangle;
1240
1241 if (conf.getValue("menu.bullet.position", "Menu.Bullet.Position", s)) {
1242 if (0 == strncasecmp(s.c_str(), "right", s.length()))
1243 resource.mstyle.bullet_pos = Basemenu::Right;
1244 else
1245 resource.mstyle.bullet_pos = Basemenu::Left;
1246 } else
1247 resource.mstyle.bullet_pos = Basemenu::Left;
1248
1249 readDatabaseColor("borderColor", "BorderColor", &resource.border_color,
1250 BlackPixel(getBaseDisplay().getXDisplay(),
1251 getScreenNumber()));
1252
1253 // load bevel, border and handle widths
1254 if (conf.getValue("handleWidth", "HandleWidth", l)) {
1255 if (l <= getWidth() / 2 && l != 0)
1256 resource.handle_width = l;
1257 else
1258 resource.handle_width = 6;
1259 } else
1260 resource.handle_width = 6;
1261
1262 if (conf.getValue("borderWidth", "BorderWidth", l))
1263 resource.border_width = l;
1264 else
1265 resource.border_width = 1;
1266
1267 if (conf.getValue("bevelWidth", "BevelWidth", l)) {
1268 if (l <= getWidth() / 2 && l != 0)
1269 resource.bevel_width = l;
1270 else
1271 resource.bevel_width = 3;
1272 } else
1273 resource.bevel_width = 3;
1274
1275 if (conf.getValue("frameWidth", "FrameWidth", l)) {
1276 if (l <= getWidth() / 2)
1277 resource.frame_width = l;
1278 else
1279 resource.frame_width = resource.bevel_width;
1280 } else
1281 resource.frame_width = resource.bevel_width;
1282
1283 const char *cmd = resource.root_command;
1284 if (cmd != NULL || conf.getValue("rootCommand", "RootCommand", s)) {
1285 if (cmd == NULL)
1286 cmd = s.c_str(); // not specified by the screen, so use the one from the
1287 // style file
1288 #ifndef __EMX__
1289 char displaystring[MAXPATHLEN];
1290 sprintf(displaystring, "DISPLAY=%s",
1291 DisplayString(getBaseDisplay().getXDisplay()));
1292 sprintf(displaystring + strlen(displaystring) - 1, "%d",
1293 getScreenNumber());
1294
1295 bexec(cmd, displaystring);
1296 #else // __EMX__
1297 spawnlp(P_NOWAIT, "cmd.exe", "cmd.exe", "/c", cmd, NULL);
1298 #endif // !__EMX__
1299 }
1300 }
1301
1302
1303 void BScreen::addIcon(OpenboxWindow *w) {
1304 if (! w) return;
1305
1306 w->setWorkspace(-1);
1307 w->setWindowNumber(iconList->count());
1308
1309 iconList->insert(w);
1310
1311 iconmenu->insert((const char **) w->getIconTitle());
1312 iconmenu->update();
1313 }
1314
1315
1316 void BScreen::removeIcon(OpenboxWindow *w) {
1317 if (! w) return;
1318
1319 iconList->remove(w->getWindowNumber());
1320
1321 iconmenu->remove(w->getWindowNumber());
1322 iconmenu->update();
1323
1324 LinkedListIterator<OpenboxWindow> it(iconList);
1325 OpenboxWindow *bw = it.current();
1326 for (int i = 0; bw; it++, bw = it.current())
1327 bw->setWindowNumber(i++);
1328 }
1329
1330
1331 OpenboxWindow *BScreen::getIcon(int index) {
1332 if (index >= 0 && index < iconList->count())
1333 return iconList->find(index);
1334
1335 return (OpenboxWindow *) 0;
1336 }
1337
1338
1339 int BScreen::addWorkspace(void) {
1340 Workspace *wkspc = new Workspace(*this, workspacesList->count());
1341 workspacesList->insert(wkspc);
1342
1343 workspacemenu->insert(wkspc->getName(), wkspc->getMenu(),
1344 wkspc->getWorkspaceID() + 2);
1345 workspacemenu->update();
1346
1347 toolbar->reconfigure();
1348
1349 updateNetizenWorkspaceCount();
1350
1351 return workspacesList->count();
1352 }
1353
1354
1355 int BScreen::removeLastWorkspace(void) {
1356 if (workspacesList->count() == 1)
1357 return 0;
1358
1359 Workspace *wkspc = workspacesList->last();
1360
1361 if (current_workspace->getWorkspaceID() == wkspc->getWorkspaceID())
1362 changeWorkspaceID(current_workspace->getWorkspaceID() - 1);
1363
1364 wkspc->removeAll();
1365
1366 workspacemenu->remove(wkspc->getWorkspaceID() + 2);
1367 workspacemenu->update();
1368
1369 workspacesList->remove(wkspc);
1370 delete wkspc;
1371
1372 toolbar->reconfigure();
1373
1374 updateNetizenWorkspaceCount();
1375
1376 return workspacesList->count();
1377 }
1378
1379
1380 void BScreen::changeWorkspaceID(int id) {
1381 if (! current_workspace) return;
1382
1383 if (id != current_workspace->getWorkspaceID()) {
1384 current_workspace->hideAll();
1385
1386 workspacemenu->setItemSelected(current_workspace->getWorkspaceID() + 2,
1387 False);
1388
1389 if (openbox.getFocusedWindow() &&
1390 openbox.getFocusedWindow()->getScreen() == this &&
1391 (! openbox.getFocusedWindow()->isStuck())) {
1392 current_workspace->setLastFocusedWindow(openbox.getFocusedWindow());
1393 openbox.setFocusedWindow((OpenboxWindow *) 0);
1394 }
1395
1396 current_workspace = getWorkspace(id);
1397
1398 workspacemenu->setItemSelected(current_workspace->getWorkspaceID() + 2,
1399 True);
1400 toolbar->redrawWorkspaceLabel(True);
1401
1402 current_workspace->showAll();
1403
1404 if (resource.focus_last && current_workspace->getLastFocusedWindow()) {
1405 XSync(openbox.getXDisplay(), False);
1406 current_workspace->getLastFocusedWindow()->setInputFocus();
1407 }
1408 }
1409
1410 updateNetizenCurrentWorkspace();
1411 }
1412
1413
1414 void BScreen::addNetizen(Netizen *n) {
1415 netizenList->insert(n);
1416
1417 n->sendWorkspaceCount();
1418 n->sendCurrentWorkspace();
1419
1420 LinkedListIterator<Workspace> it(workspacesList);
1421 for (Workspace *w = it.current(); w; it++, w = it.current()) {
1422 for (int i = 0; i < w->getCount(); i++)
1423 n->sendWindowAdd(w->getWindow(i)->getClientWindow(),
1424 w->getWorkspaceID());
1425 }
1426
1427 Window f = ((openbox.getFocusedWindow()) ?
1428 openbox.getFocusedWindow()->getClientWindow() : None);
1429 n->sendWindowFocus(f);
1430 }
1431
1432
1433 void BScreen::removeNetizen(Window w) {
1434 LinkedListIterator<Netizen> it(netizenList);
1435 int i = 0;
1436
1437 for (Netizen *n = it.current(); n; it++, i++, n = it.current())
1438 if (n->getWindowID() == w) {
1439 Netizen *tmp = netizenList->remove(i);
1440 delete tmp;
1441
1442 break;
1443 }
1444 }
1445
1446
1447 void BScreen::updateNetizenCurrentWorkspace(void) {
1448 LinkedListIterator<Netizen> it(netizenList);
1449 for (Netizen *n = it.current(); n; it++, n = it.current())
1450 n->sendCurrentWorkspace();
1451 }
1452
1453
1454 void BScreen::updateNetizenWorkspaceCount(void) {
1455 LinkedListIterator<Netizen> it(netizenList);
1456 for (Netizen *n = it.current(); n; it++, n = it.current())
1457 n->sendWorkspaceCount();
1458 }
1459
1460
1461 void BScreen::updateNetizenWindowFocus(void) {
1462 Window f = ((openbox.getFocusedWindow()) ?
1463 openbox.getFocusedWindow()->getClientWindow() : None);
1464 LinkedListIterator<Netizen> it(netizenList);
1465 for (Netizen *n = it.current(); n; it++, n = it.current())
1466 n->sendWindowFocus(f);
1467 }
1468
1469
1470 void BScreen::updateNetizenWindowAdd(Window w, unsigned long p) {
1471 LinkedListIterator<Netizen> it(netizenList);
1472 for (Netizen *n = it.current(); n; it++, n = it.current())
1473 n->sendWindowAdd(w, p);
1474 }
1475
1476
1477 void BScreen::updateNetizenWindowDel(Window w) {
1478 LinkedListIterator<Netizen> it(netizenList);
1479 for (Netizen *n = it.current(); n; it++, n = it.current())
1480 n->sendWindowDel(w);
1481 }
1482
1483
1484 void BScreen::updateNetizenWindowRaise(Window w) {
1485 LinkedListIterator<Netizen> it(netizenList);
1486 for (Netizen *n = it.current(); n; it++, n = it.current())
1487 n->sendWindowRaise(w);
1488 }
1489
1490
1491 void BScreen::updateNetizenWindowLower(Window w) {
1492 LinkedListIterator<Netizen> it(netizenList);
1493 for (Netizen *n = it.current(); n; it++, n = it.current())
1494 n->sendWindowLower(w);
1495 }
1496
1497
1498 void BScreen::updateNetizenConfigNotify(XEvent *e) {
1499 LinkedListIterator<Netizen> it(netizenList);
1500 for (Netizen *n = it.current(); n; it++, n = it.current())
1501 n->sendConfigNotify(e);
1502 }
1503
1504
1505 void BScreen::raiseWindows(Window *workspace_stack, int num) {
1506 Window *session_stack = new
1507 Window[(num + workspacesList->count() + rootmenuList->count() + 13)];
1508 int i = 0, k = num;
1509
1510 XRaiseWindow(getBaseDisplay().getXDisplay(), iconmenu->getWindowID());
1511 *(session_stack + i++) = iconmenu->getWindowID();
1512
1513 LinkedListIterator<Workspace> wit(workspacesList);
1514 for (Workspace *tmp = wit.current(); tmp; wit++, tmp = wit.current())
1515 *(session_stack + i++) = tmp->getMenu()->getWindowID();
1516
1517 *(session_stack + i++) = workspacemenu->getWindowID();
1518
1519 *(session_stack + i++) = configmenu->getFocusmenu()->getWindowID();
1520 *(session_stack + i++) = configmenu->getPlacementmenu()->getWindowID();
1521 *(session_stack + i++) = configmenu->getWindowID();
1522
1523 #ifdef SLIT
1524 *(session_stack + i++) = slit->getMenu()->getDirectionmenu()->getWindowID();
1525 *(session_stack + i++) = slit->getMenu()->getPlacementmenu()->getWindowID();
1526 *(session_stack + i++) = slit->getMenu()->getWindowID();
1527 #endif // SLIT
1528
1529 *(session_stack + i++) =
1530 toolbar->getMenu()->getPlacementmenu()->getWindowID();
1531 *(session_stack + i++) = toolbar->getMenu()->getWindowID();
1532
1533 LinkedListIterator<Rootmenu> rit(rootmenuList);
1534 for (Rootmenu *tmp = rit.current(); tmp; rit++, tmp = rit.current())
1535 *(session_stack + i++) = tmp->getWindowID();
1536 *(session_stack + i++) = rootmenu->getWindowID();
1537
1538 if (toolbar->isOnTop())
1539 *(session_stack + i++) = toolbar->getWindowID();
1540
1541 #ifdef SLIT
1542 if (slit->isOnTop())
1543 *(session_stack + i++) = slit->getWindowID();
1544 #endif // SLIT
1545
1546 while (k--)
1547 *(session_stack + i++) = *(workspace_stack + k);
1548
1549 XRestackWindows(getBaseDisplay().getXDisplay(), session_stack, i);
1550
1551 delete [] session_stack;
1552 }
1553
1554
1555 #ifdef HAVE_STRFTIME
1556 void BScreen::saveStrftimeFormat(const char *format) {
1557 if (resource.strftime_format)
1558 delete [] resource.strftime_format;
1559
1560 resource.strftime_format = bstrdup(format);
1561 }
1562 #endif // HAVE_STRFTIME
1563
1564
1565 void BScreen::addWorkspaceName(const char *name) {
1566 workspaceNames->insert(bstrdup(name));
1567 }
1568
1569
1570 char* BScreen::getNameOfWorkspace(int id) {
1571 char *name = (char *) 0;
1572
1573 if (id >= 0 && id < workspaceNames->count()) {
1574 char *wkspc_name = workspaceNames->find(id);
1575
1576 if (wkspc_name)
1577 name = wkspc_name;
1578 }
1579 return name;
1580 }
1581
1582
1583 void BScreen::reassociateWindow(OpenboxWindow *w, int wkspc_id, Bool ignore_sticky) {
1584 if (! w) return;
1585
1586 if (wkspc_id == -1)
1587 wkspc_id = current_workspace->getWorkspaceID();
1588
1589 if (w->getWorkspaceNumber() == wkspc_id)
1590 return;
1591
1592 if (w->isIconic()) {
1593 removeIcon(w);
1594 getWorkspace(wkspc_id)->addWindow(w);
1595 } else if (ignore_sticky || ! w->isStuck()) {
1596 getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
1597 getWorkspace(wkspc_id)->addWindow(w);
1598 }
1599 }
1600
1601
1602 void BScreen::nextFocus(void) {
1603 Bool have_focused = False;
1604 int focused_window_number = -1;
1605 OpenboxWindow *next;
1606
1607 if (openbox.getFocusedWindow()) {
1608 if (openbox.getFocusedWindow()->getScreen()->getScreenNumber() ==
1609 getScreenNumber()) {
1610 have_focused = True;
1611 focused_window_number = openbox.getFocusedWindow()->getWindowNumber();
1612 }
1613 }
1614
1615 if ((getCurrentWorkspace()->getCount() > 1) && have_focused) {
1616 int next_window_number = focused_window_number;
1617 do {
1618 if ((++next_window_number) >= getCurrentWorkspace()->getCount())
1619 next_window_number = 0;
1620
1621 next = getCurrentWorkspace()->getWindow(next_window_number);
1622 } while ((! next->setInputFocus()) && (next_window_number !=
1623 focused_window_number));
1624
1625 if (next_window_number != focused_window_number)
1626 getCurrentWorkspace()->raiseWindow(next);
1627 } else if (getCurrentWorkspace()->getCount() >= 1) {
1628 next = current_workspace->getWindow(0);
1629
1630 current_workspace->raiseWindow(next);
1631 next->setInputFocus();
1632 }
1633 }
1634
1635
1636 void BScreen::prevFocus(void) {
1637 Bool have_focused = False;
1638 int focused_window_number = -1;
1639 OpenboxWindow *prev;
1640
1641 if (openbox.getFocusedWindow()) {
1642 if (openbox.getFocusedWindow()->getScreen()->getScreenNumber() ==
1643 getScreenNumber()) {
1644 have_focused = True;
1645 focused_window_number = openbox.getFocusedWindow()->getWindowNumber();
1646 }
1647 }
1648
1649 if ((getCurrentWorkspace()->getCount() > 1) && have_focused) {
1650 int prev_window_number = focused_window_number;
1651 do {
1652 if ((--prev_window_number) < 0)
1653 prev_window_number = getCurrentWorkspace()->getCount() - 1;
1654
1655 prev = getCurrentWorkspace()->getWindow(prev_window_number);
1656 } while ((! prev->setInputFocus()) && (prev_window_number !=
1657 focused_window_number));
1658
1659 if (prev_window_number != focused_window_number)
1660 getCurrentWorkspace()->raiseWindow(prev);
1661 } else if (getCurrentWorkspace()->getCount() >= 1) {
1662 prev = current_workspace->getWindow(0);
1663
1664 current_workspace->raiseWindow(prev);
1665 prev->setInputFocus();
1666 }
1667 }
1668
1669
1670 void BScreen::raiseFocus(void) {
1671 Bool have_focused = False;
1672 int focused_window_number = -1;
1673
1674 if (openbox.getFocusedWindow()) {
1675 if (openbox.getFocusedWindow()->getScreen()->getScreenNumber() ==
1676 getScreenNumber()) {
1677 have_focused = True;
1678 focused_window_number = openbox.getFocusedWindow()->getWindowNumber();
1679 }
1680 }
1681
1682 if ((getCurrentWorkspace()->getCount() > 1) && have_focused)
1683 getWorkspace(openbox.getFocusedWindow()->getWorkspaceNumber())->
1684 raiseWindow(openbox.getFocusedWindow());
1685 }
1686
1687
1688 void BScreen::InitMenu(void) {
1689 if (rootmenu) {
1690 while (rootmenuList->count())
1691 rootmenuList->remove(0);
1692
1693 while (rootmenu->getCount())
1694 rootmenu->remove(0);
1695 } else {
1696 rootmenu = new Rootmenu(*this);
1697 }
1698 Bool defaultMenu = True;
1699
1700 if (openbox.getMenuFilename()) {
1701 FILE *menu_file = fopen(openbox.getMenuFilename(), "r");
1702
1703 if (!menu_file) {
1704 perror(openbox.getMenuFilename());
1705 } else {
1706 if (feof(menu_file)) {
1707 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenEmptyMenuFile,
1708 "%s: Empty menu file"),
1709 openbox.getMenuFilename());
1710 } else {
1711 char line[1024], label[1024];
1712 memset(line, 0, 1024);
1713 memset(label, 0, 1024);
1714
1715 while (fgets(line, 1024, menu_file) && ! feof(menu_file)) {
1716 if (line[0] != '#') {
1717 int i, key = 0, index = -1, len = strlen(line);
1718
1719 key = 0;
1720 for (i = 0; i < len; i++) {
1721 if (line[i] == '[') index = 0;
1722 else if (line[i] == ']') break;
1723 else if (line[i] != ' ')
1724 if (index++ >= 0)
1725 key += tolower(line[i]);
1726 }
1727
1728 if (key == 517) {
1729 index = -1;
1730 for (i = index; i < len; i++) {
1731 if (line[i] == '(') index = 0;
1732 else if (line[i] == ')') break;
1733 else if (index++ >= 0) {
1734 if (line[i] == '\\' && i < len - 1) i++;
1735 label[index - 1] = line[i];
1736 }
1737 }
1738
1739 if (index == -1) index = 0;
1740 label[index] = '\0';
1741
1742 rootmenu->setLabel(label);
1743 defaultMenu = parseMenuFile(menu_file, rootmenu);
1744 break;
1745 }
1746 }
1747 }
1748 }
1749 fclose(menu_file);
1750 }
1751 }
1752
1753 if (defaultMenu) {
1754 rootmenu->setInternalMenu();
1755 rootmenu->insert(i18n->getMessage(ScreenSet, Screenxterm, "xterm"),
1756 BScreen::Execute,
1757 i18n->getMessage(ScreenSet, Screenxterm, "xterm"));
1758 rootmenu->insert(i18n->getMessage(ScreenSet, ScreenRestart, "Restart"),
1759 BScreen::Restart);
1760 rootmenu->insert(i18n->getMessage(ScreenSet, ScreenExit, "Exit"),
1761 BScreen::Exit);
1762 } else {
1763 openbox.saveMenuFilename(openbox.getMenuFilename());
1764 }
1765 }
1766
1767
1768 Bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
1769 char line[1024], label[1024], command[1024];
1770
1771 while (! feof(file)) {
1772 memset(line, 0, 1024);
1773 memset(label, 0, 1024);
1774 memset(command, 0, 1024);
1775
1776 if (fgets(line, 1024, file)) {
1777 if (line[0] != '#') {
1778 register int i, key = 0, parse = 0, index = -1,
1779 line_length = strlen(line),
1780 label_length = 0, command_length = 0;
1781
1782 // determine the keyword
1783 key = 0;
1784 for (i = 0; i < line_length; i++) {
1785 if (line[i] == '[') parse = 1;
1786 else if (line[i] == ']') break;
1787 else if (line[i] != ' ')
1788 if (parse)
1789 key += tolower(line[i]);
1790 }
1791
1792 // get the label enclosed in ()'s
1793 parse = 0;
1794
1795 for (i = 0; i < line_length; i++) {
1796 if (line[i] == '(') {
1797 index = 0;
1798 parse = 1;
1799 } else if (line[i] == ')') break;
1800 else if (index++ >= 0) {
1801 if (line[i] == '\\' && i < line_length - 1) i++;
1802 label[index - 1] = line[i];
1803 }
1804 }
1805
1806 if (parse) {
1807 label[index] = '\0';
1808 label_length = index;
1809 } else {
1810 label[0] = '\0';
1811 label_length = 0;
1812 }
1813
1814 // get the command enclosed in {}'s
1815 parse = 0;
1816 index = -1;
1817 for (i = 0; i < line_length; i++) {
1818 if (line[i] == '{') {
1819 index = 0;
1820 parse = 1;
1821 } else if (line[i] == '}') break;
1822 else if (index++ >= 0) {
1823 if (line[i] == '\\' && i < line_length - 1) i++;
1824 command[index - 1] = line[i];
1825 }
1826 }
1827
1828 if (parse) {
1829 command[index] = '\0';
1830 command_length = index;
1831 } else {
1832 command[0] = '\0';
1833 command_length = 0;
1834 }
1835
1836 switch (key) {
1837 case 311: //end
1838 return ((menu->getCount() == 0) ? True : False);
1839
1840 break;
1841
1842 case 333: // nop
1843 menu->insert(label);
1844
1845 break;
1846
1847 case 421: // exec
1848 if ((! *label) && (! *command)) {
1849 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenEXECError,
1850 "BScreen::parseMenuFile: [exec] error, "
1851 "no menu label and/or command defined\n"));
1852 continue;
1853 }
1854
1855 menu->insert(label, BScreen::Execute, command);
1856
1857 break;
1858
1859 case 442: // exit
1860 if (! *label) {
1861 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenEXITError,
1862 "BScreen::parseMenuFile: [exit] error, "
1863 "no menu label defined\n"));
1864 continue;
1865 }
1866
1867 menu->insert(label, BScreen::Exit);
1868
1869 break;
1870
1871 case 561: // style
1872 {
1873 if ((! *label) || (! *command)) {
1874 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenSTYLEError,
1875 "BScreen::parseMenuFile: [style] error, "
1876 "no menu label and/or filename defined\n"));
1877 continue;
1878 }
1879
1880 char style[MAXPATHLEN];
1881
1882 // perform shell style ~ home directory expansion
1883 char *homedir = 0;
1884 int homedir_len = 0;
1885 if (*command == '~' && *(command + 1) == '/') {
1886 homedir = getenv("HOME");
1887 homedir_len = strlen(homedir);
1888 }
1889
1890 if (homedir && homedir_len != 0) {
1891 strncpy(style, homedir, homedir_len);
1892
1893 strncpy(style + homedir_len, command + 1,
1894 command_length - 1);
1895 *(style + command_length + homedir_len - 1) = '\0';
1896 } else {
1897 strncpy(style, command, command_length);
1898 *(style + command_length) = '\0';
1899 }
1900
1901 menu->insert(label, BScreen::SetStyle, style);
1902 }
1903
1904 break;
1905
1906 case 630: // config
1907 if (! *label) {
1908 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenCONFIGError,
1909 "BScreen::parseMenufile: [config] error, "
1910 "no label defined"));
1911 continue;
1912 }
1913
1914 menu->insert(label, configmenu);
1915
1916 break;
1917
1918 case 740: // include
1919 {
1920 if (! *label) {
1921 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenINCLUDEError,
1922 "BScreen::parseMenuFile: [include] error, "
1923 "no filename defined\n"));
1924 continue;
1925 }
1926
1927 char newfile[MAXPATHLEN];
1928
1929 // perform shell style ~ home directory expansion
1930 char *homedir = 0;
1931 int homedir_len = 0;
1932 if (*label == '~' && *(label + 1) == '/') {
1933 homedir = getenv("HOME");
1934 homedir_len = strlen(homedir);
1935 }
1936
1937 if (homedir && homedir_len != 0) {
1938 strncpy(newfile, homedir, homedir_len);
1939
1940 strncpy(newfile + homedir_len, label + 1,
1941 label_length - 1);
1942 *(newfile + label_length + homedir_len - 1) = '\0';
1943 } else {
1944 strncpy(newfile, label, label_length);
1945 *(newfile + label_length) = '\0';
1946 }
1947
1948 if (newfile) {
1949 FILE *submenufile = fopen(newfile, "r");
1950
1951 if (submenufile) {
1952 struct stat buf;
1953 if (fstat(fileno(submenufile), &buf) ||
1954 (! S_ISREG(buf.st_mode))) {
1955 fprintf(stderr,
1956 i18n->getMessage(ScreenSet, ScreenINCLUDEErrorReg,
1957 "BScreen::parseMenuFile: [include] error: "
1958 "'%s' is not a regular file\n"), newfile);
1959 break;
1960 }
1961
1962 if (! feof(submenufile)) {
1963 if (! parseMenuFile(submenufile, menu))
1964 openbox.saveMenuFilename(newfile);
1965
1966 fclose(submenufile);
1967 }
1968 } else
1969 perror(newfile);
1970 }
1971 }
1972
1973 break;
1974
1975 case 767: // submenu
1976 {
1977 if (! *label) {
1978 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenSUBMENUError,
1979 "BScreen::parseMenuFile: [submenu] error, "
1980 "no menu label defined\n"));
1981 continue;
1982 }
1983
1984 Rootmenu *submenu = new Rootmenu(*this);
1985
1986 if (*command)
1987 submenu->setLabel(command);
1988 else
1989 submenu->setLabel(label);
1990
1991 parseMenuFile(file, submenu);
1992 submenu->update();
1993 menu->insert(label, submenu);
1994 rootmenuList->insert(submenu);
1995 }
1996
1997 break;
1998
1999 case 773: // restart
2000 {
2001 if (! *label) {
2002 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenRESTARTError,
2003 "BScreen::parseMenuFile: [restart] error, "
2004 "no menu label defined\n"));
2005 continue;
2006 }
2007
2008 if (*command)
2009 menu->insert(label, BScreen::RestartOther, command);
2010 else
2011 menu->insert(label, BScreen::Restart);
2012 }
2013
2014 break;
2015
2016 case 845: // reconfig
2017 {
2018 if (! *label) {
2019 fprintf(stderr, i18n->getMessage(ScreenSet, ScreenRECONFIGError,
2020 "BScreen::parseMenuFile: [reconfig] error, "
2021 "no menu label defined\n"));
2022 continue;
2023 }
2024
2025 menu->insert(label, BScreen::Reconfigure);
2026 }
2027
2028 break;
2029
2030 case 995: // stylesdir
2031 case 1113: // stylesmenu
2032 {
2033 Bool newmenu = ((key == 1113) ? True : False);
2034
2035 if ((! *label) || ((! *command) && newmenu)) {
2036 fprintf(stderr,
2037 i18n->getMessage(ScreenSet, ScreenSTYLESDIRError,
2038 "BScreen::parseMenuFile: [stylesdir/stylesmenu]"
2039 " error, no directory defined\n"));
2040 continue;
2041 }
2042
2043 char stylesdir[MAXPATHLEN];
2044
2045 char *directory = ((newmenu) ? command : label);
2046 int directory_length = ((newmenu) ? command_length : label_length);
2047
2048 // perform shell style ~ home directory expansion
2049 char *homedir = 0;
2050 int homedir_len = 0;
2051
2052 if (*directory == '~' && *(directory + 1) == '/') {
2053 homedir = getenv("HOME");
2054 homedir_len = strlen(homedir);
2055 }
2056
2057 if (homedir && homedir_len != 0) {
2058 strncpy(stylesdir, homedir, homedir_len);
2059
2060 strncpy(stylesdir + homedir_len, directory + 1,
2061 directory_length - 1);
2062 *(stylesdir + directory_length + homedir_len - 1) = '\0';
2063 } else {
2064 strncpy(stylesdir, directory, directory_length);
2065 *(stylesdir + directory_length) = '\0';
2066 }
2067
2068 struct stat statbuf;
2069
2070 if (! stat(stylesdir, &statbuf)) {
2071 if (S_ISDIR(statbuf.st_mode)) {
2072 Rootmenu *stylesmenu;
2073
2074 if (newmenu)
2075 stylesmenu = new Rootmenu(*this);
2076 else
2077 stylesmenu = menu;
2078
2079 DIR *d = opendir(stylesdir);
2080 int entries = 0;
2081 struct dirent *p;
2082
2083 // get the total number of directory entries
2084 while ((p = readdir(d))) entries++;
2085 rewinddir(d);
2086
2087 char **ls = new char* [entries];
2088 int index = 0;
2089 while ((p = readdir(d)))
2090 ls[index++] = bstrdup(p->d_name);
2091
2092 closedir(d);
2093
2094 std::sort(ls, ls + entries, dcmp());
2095
2096 int n, slen = strlen(stylesdir);
2097 for (n = 0; n < entries; n++) {
2098 if (ls[n][strlen(ls[n])-1] != '~') {
2099 int nlen = strlen(ls[n]);
2100 char style[MAXPATHLEN + 1];
2101
2102 strncpy(style, stylesdir, slen);
2103 *(style + slen) = '/';
2104 strncpy(style + slen + 1, ls[n], nlen + 1);
2105
2106 if ((! stat(style, &statbuf)) && S_ISREG(statbuf.st_mode))
2107 stylesmenu->insert(ls[n], BScreen::SetStyle, style);
2108 }
2109
2110 delete [] ls[n];
2111 }
2112
2113 delete [] ls;
2114
2115 stylesmenu->update();
2116
2117 if (newmenu) {
2118 stylesmenu->setLabel(label);
2119 menu->insert(label, stylesmenu);
2120 rootmenuList->insert(stylesmenu);
2121 }
2122
2123 openbox.saveMenuFilename(stylesdir);
2124 } else {
2125 fprintf(stderr, i18n->getMessage(ScreenSet,
2126 ScreenSTYLESDIRErrorNotDir,
2127 "BScreen::parseMenuFile:"
2128 " [stylesdir/stylesmenu] error, %s is not a"
2129 " directory\n"), stylesdir);
2130 }
2131 } else {
2132 fprintf(stderr,
2133 i18n->getMessage(ScreenSet, ScreenSTYLESDIRErrorNoExist,
2134 "BScreen::parseMenuFile: [stylesdir/stylesmenu]"
2135 " error, %s does not exist\n"), stylesdir);
2136 }
2137
2138 break;
2139 }
2140
2141 case 1090: // workspaces
2142 {
2143 if (! *label) {
2144 fprintf(stderr,
2145 i18n->getMessage(ScreenSet, ScreenWORKSPACESError,
2146 "BScreen:parseMenuFile: [workspaces] error, "
2147 "no menu label defined\n"));
2148 continue;
2149 }
2150
2151 menu->insert(label, workspacemenu);
2152
2153 break;
2154 }
2155 }
2156 }
2157 }
2158 }
2159
2160 return ((menu->getCount() == 0) ? True : False);
2161 }
2162
2163
2164 void BScreen::shutdown(void) {
2165 openbox.grab();
2166
2167 XSelectInput(getBaseDisplay().getXDisplay(), getRootWindow(), NoEventMask);
2168 XSync(getBaseDisplay().getXDisplay(), False);
2169
2170 LinkedListIterator<Workspace> it(workspacesList);
2171 for (Workspace *w = it.current(); w; it++, w = it.current())
2172 w->shutdown();
2173
2174 while (iconList->count()) {
2175 iconList->first()->restore();
2176 delete iconList->first();
2177 }
2178
2179 #ifdef SLIT
2180 slit->shutdown();
2181 #endif // SLIT
2182
2183 openbox.ungrab();
2184 }
2185
2186
2187 void BScreen::showPosition(int x, int y) {
2188 if (! geom_visible) {
2189 XMoveResizeWindow(getBaseDisplay().getXDisplay(), geom_window,
2190 (getWidth() - geom_w) / 2,
2191 (getHeight() - geom_h) / 2, geom_w, geom_h);
2192 XMapWindow(getBaseDisplay().getXDisplay(), geom_window);
2193 XRaiseWindow(getBaseDisplay().getXDisplay(), geom_window);
2194
2195 geom_visible = True;
2196 }
2197
2198 char label[1024];
2199
2200 sprintf(label, i18n->getMessage(ScreenSet, ScreenPositionFormat,
2201 "X: %4d x Y: %4d"), x, y);
2202
2203 XClearWindow(getBaseDisplay().getXDisplay(), geom_window);
2204
2205 if (i18n->multibyte()) {
2206 XmbDrawString(getBaseDisplay().getXDisplay(), geom_window,
2207 resource.wstyle.fontset, resource.wstyle.l_text_focus_gc,
2208 resource.bevel_width, resource.bevel_width -
2209 resource.wstyle.fontset_extents->max_ink_extent.y,
2210 label, strlen(label));
2211 } else {
2212 XDrawString(getBaseDisplay().getXDisplay(), geom_window,
2213 resource.wstyle.l_text_focus_gc,
2214 resource.bevel_width,
2215 resource.wstyle.font->ascent +
2216 resource.bevel_width, label, strlen(label));
2217 }
2218 }
2219
2220
2221 void BScreen::showGeometry(unsigned int gx, unsigned int gy) {
2222 if (! geom_visible) {
2223 XMoveResizeWindow(getBaseDisplay().getXDisplay(), geom_window,
2224 (getWidth() - geom_w) / 2,
2225 (getHeight() - geom_h) / 2, geom_w, geom_h);
2226 XMapWindow(getBaseDisplay().getXDisplay(), geom_window);
2227 XRaiseWindow(getBaseDisplay().getXDisplay(), geom_window);
2228
2229 geom_visible = True;
2230 }
2231
2232 char label[1024];
2233
2234 sprintf(label, i18n->getMessage(ScreenSet, ScreenGeometryFormat,
2235 "W: %4d x H: %4d"), gx, gy);
2236
2237 XClearWindow(getBaseDisplay().getXDisplay(), geom_window);
2238
2239 if (i18n->multibyte()) {
2240 XmbDrawString(getBaseDisplay().getXDisplay(), geom_window,
2241 resource.wstyle.fontset, resource.wstyle.l_text_focus_gc,
2242 resource.bevel_width, resource.bevel_width -
2243 resource.wstyle.fontset_extents->max_ink_extent.y,
2244 label, strlen(label));
2245 } else {
2246 XDrawString(getBaseDisplay().getXDisplay(), geom_window,
2247 resource.wstyle.l_text_focus_gc,
2248 resource.bevel_width,
2249 resource.wstyle.font->ascent +
2250 resource.bevel_width, label, strlen(label));
2251 }
2252 }
2253
2254
2255 void BScreen::hideGeometry(void) {
2256 if (geom_visible) {
2257 XUnmapWindow(getBaseDisplay().getXDisplay(), geom_window);
2258 geom_visible = False;
2259 }
2260 }
This page took 0.139526 seconds and 4 git commands to generate.