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