1 /*
2 * appbar.cc - Defines how appbar looks and feels
3 * Copyright (C) 2001 Frank Hale
4 * frankhale@yahoo.com
5 * http://sapphire.sourceforge.net/
6 *
7 * Updated: 24 July 2001
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #include "appbar.hh"
25
26 Appbar *ab;
27
28 unsigned long palette[PALETTE_COUNT];
29
signal_handler(int signal)30 void signal_handler(int signal)
31 {
32 switch(signal)
33 {
34 case SIGQUIT:
35 case SIGINT:
36 case SIGTERM:
37 ab->quit();
38 break;
39
40 //case SIGHUP:
41 //break;
42
43 case SIGCHLD:
44 wait(NULL);
45 break;
46 }
47 }
48
init_signals()49 void init_signals()
50 {
51 struct sigaction act;
52
53 act.sa_handler=signal_handler;
54 act.sa_flags=0;
55
56 sigaction(SIGQUIT, &act, NULL);
57 sigaction(SIGTERM, &act, NULL);
58 sigaction(SIGINT, &act, NULL);
59 //sigaction(SIGHUP, &act, NULL);
60 sigaction(SIGCHLD, &act, NULL);
61 }
62
Appbar(char * filename)63 Appbar::Appbar(char* filename)
64 {
65 XSizeHints appbarSizeHints;
66 CARD32 data[2];
67
68 ::ab=this;
69
70 init_signals();
71
72 placement = VERTICAL;
73 screen_placement = NORTHWEST;
74 one_click = false;
75 temp_color=0;
76
77 hidden=true;
78 window_width=0;
79
80 if (!(dpy = XOpenDisplay (NULL)))
81 {
82 std::cerr << "Can't open display!" << std::endl;
83 exit(0);
84 }
85
86 screen = DefaultScreen(dpy);
87 depth = DefaultDepth(dpy, screen);
88 visual = DefaultVisual(dpy, screen);
89 root = RootWindow(dpy, screen);
90
91 // The to and from structures are used in creating
92 // the color theme for the main window. This is just
93 // a default, this is configurable in the rc file.
94
95 // Nice shade of gray
96 from.red = 0xcc;
97 from.green = 0xcc;
98 from.blue = 0xcc;
99
100 // Another nice shade of gray
101 to.red = 0x99;
102 to.green = 0x99;
103 to.blue = 0x99;
104
105 gnome[WIN_STATE]=XInternAtom(dpy, "_WIN_STATE", False);
106 gnome[WIN_HINTS]=XInternAtom(dpy, "_WIN_HINTS", False);
107 gnome[WIN_LAYER]=XInternAtom(dpy, "_WIN_LAYER", False);
108 motif=XInternAtom(dpy, "_MOTIF_WM_HINTS", False);
109
110 atom_wm_state = XInternAtom(dpy, "WM_STATE", False);
111 atom_wm_protos = XInternAtom(dpy, "WM_PROTOCOLS", False);
112 atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
113
114 net_wm_state_skip_taskbar = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
115 net_wm_state_skip_pager = XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False);
116 net_wm_state_sticky = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False);
117 net_wm_strut = XInternAtom(dpy, "_NET_WM_STRUT", False);
118 net_wm_state_sticky = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False);
119
120 //win = XCreateSimpleWindow
121 // (dpy, DefaultRootWindow (dpy), 0, 0, 100, 25, 0,
122 // BlackPixel (dpy, DefaultScreen (dpy)),
123 // WhitePixel (dpy, DefaultScreen (dpy)));
124
125 XSetWindowAttributes attr;
126
127 attr.background_pixel = WhitePixel (dpy, DefaultScreen (dpy));
128 attr.event_mask = ButtonPressMask |
129 ButtonReleaseMask |
130 ExposureMask |
131 EnterWindowMask |
132 LeaveWindowMask ;
133
134 win = XCreateWindow(dpy,
135 root,
136 0,
137 0,
138 100,
139 25,
140 0,
141 CopyFromParent,
142 InputOutput,
143 CopyFromParent,
144 CWBackPixel | CWEventMask,
145 &attr);
146
147 //XSelectInput (dpy, win, ExposureMask |
148 // ButtonPressMask |
149 // ButtonReleaseMask |
150 // EnterWindowMask |
151 // LeaveWindowMask);
152
153 gnome_win_normal_hints = WIN_HINTS_SKIP_FOCUS |
154 WIN_HINTS_SKIP_TASKBAR |
155 WIN_HINTS_SKIP_WINLIST |
156 WIN_HINTS_DO_NOT_COVER ;
157
158 gnome_win_hints_no_on_top = WIN_HINTS_SKIP_FOCUS |
159 WIN_HINTS_SKIP_TASKBAR |
160 WIN_HINTS_SKIP_WINLIST ;
161
162 set_gnome_hint(win, WIN_STATE, WIN_STATE_STICKY);
163 set_gnome_hint(win, WIN_HINTS, gnome_win_normal_hints);
164 set_gnome_hint(win, WIN_LAYER, 0);
165
166 mwm_hints.flags=MWM_DECORATIONS;
167 mwm_hints.decorations=0;
168 set_mwm_hints(win, &mwm_hints);
169
170 screen_width = WidthOfScreen(ScreenOfDisplay(dpy, screen));
171 screen_height = HeightOfScreen(ScreenOfDisplay(dpy, screen));
172
173 image_control = new BImageControl(dpy, depth, root, screen, visual);
174
175 // Default color theme style
176 unsigned long style=0;
177 style = BImage_Flat | BImage_Gradient | BImage_Diagonal | BImage_Bevel1;
178 //style = BImage_Flat | BImage_Solid | BImage_Bevel1;
179
180 win_pix = None;
181
182 gc = XCreateGC (dpy, win, 0, NULL);
183
184 XColor xcl;
185 unsigned int i, j;
186
187 i = j = 0;
188 do
189 {
190 xcl.red = cols[i];
191 i++;
192 xcl.green = cols[i];
193 i++;
194 xcl.blue = cols[i];
195 i++;
196 XAllocColor (dpy, DefaultColormap (dpy, screen), &xcl);
197 palette[j] = xcl.pixel;
198 j++;
199 }
200 while (j < PALETTE_COUNT);
201
202 iconList = new std::list<Icon *>;
203
204 std::string appbar_rc_file = (std::string) filename; // APPBAR_RC_FILE;
205
206 std::cout << "Appbar is using rc file: " << appbar_rc_file << std::endl;
207
208 appbarConfig = new Scanner((char*) appbar_rc_file.c_str());
209 parseAppbarConfig(appbarConfig);
210
211 if(iconList->empty())
212 {
213 std::cerr << "appbar.rc contains no icons, using defaults." << std::endl;
214
215 Icon *t = new Icon(dpy, "images/terminal.xpm", win);
216 t->setExecuteCommand("xterm");
217 iconList->push_back(t);
218 }
219
220 if(placement==HORIZONTAL)
221 horizontalBarIconPlacement();
222
223 if(placement==VERTICAL)
224 verticalBarIconPlacement();
225
226 win_pix = image_control->renderImage(
227 window_width,
228 window_height,
229 style,
230 to,
231 from);
232
233 XSetWindowBackgroundPixmap(dpy, win, win_pix);
234
235 XResizeWindow(dpy,win, window_width , window_height);
236
237 appbarSizeHints.flags = PPosition | PSize;
238 appbarSizeHints.x = 0;
239 appbarSizeHints.y = 0;
240 appbarSizeHints.width = window_width;
241 appbarSizeHints.height = window_height;
242
243 //XSetNormalHints(dpy, win, &appbarSizeHints);
244
245 XChangeProperty (dpy, win, XA_WM_NORMAL_HINTS,
246 XA_WM_SIZE_HINTS, 32, PropModeReplace,
247 (unsigned char *) &appbarSizeHints, sizeof (XSizeHints) / 4);
248
249 appbarScreenPlacement(); // Move to right place before map?
250
251 XMapWindow(dpy,win);
252
253 data[0] = NormalState;
254 data[1] = None; /* Icon? We don't need no steenking icon. */
255
256 XChangeProperty(dpy, win, atom_wm_state, atom_wm_state,
257 32, PropModeReplace, (unsigned char *)data, 2);
258
259 doEventLoop();
260 }
261
~Appbar()262 Appbar::~Appbar()
263 {
264 quit();
265 }
266
267 // This function takes care of determing the position of the appbar
268 // and whether it's shaded or not.
appbarScreenPlacement()269 void Appbar::appbarScreenPlacement()
270 {
271 int new_x=0, new_y=0;
272
273 switch (screen_placement)
274 {
275 case NORTHEAST:
276 {
277 if(placement==HORIZONTAL)
278 {
279 if(hidden)
280 {
281 new_x = screen_width - window_width;
282 new_y = 0;
283 hidden=false;
284
285 setTopStrut();
286 }
287 else
288 {
289 new_x = screen_width - 10;
290 new_y = 0;
291 hidden=true;
292
293 turnOffStrut();
294 }
295 }
296
297 if(placement==VERTICAL)
298 {
299 if(hidden)
300 {
301 new_x = screen_width - window_width;
302 new_y = 0;
303
304 hidden=false;
305
306 setRightStrut();
307 }
308 else
309 {
310 new_x = screen_width - window_width;
311 new_y = -(window_height-9);
312
313 hidden=true;
314
315 turnOffStrut();
316 }
317 }
318 }
319 break;
320
321 case NORTHWEST:
322 if(placement==HORIZONTAL)
323 {
324 if(hidden)
325 {
326 new_x=0;
327 new_y=0;
328 hidden=false;
329
330 setTopStrut();
331 }
332 else
333 {
334 new_x = -(window_width-9);
335 new_y = 0;
336 hidden=true;
337
338 turnOffStrut();
339 }
340 }
341 else
342 if(placement==VERTICAL)
343 {
344 if(hidden)
345 {
346 new_x=0;
347 new_y=0;
348
349 hidden=false;
350
351 setLeftStrut();
352 }
353 else
354 {
355 new_x = 0;
356 new_y = -(window_height-9);
357
358 hidden=true;
359
360 turnOffStrut();
361 }
362 }
363 break;
364
365 case SOUTHEAST:
366 if(placement==HORIZONTAL)
367 {
368 if(hidden)
369 {
370 new_x = screen_width - window_width;
371 new_y = screen_height - window_height;
372 hidden=false;
373
374 setBottomStrut();
375 }
376 else
377 {
378 new_x = screen_width - 10;
379 new_y = screen_height - window_height;
380 hidden=true;
381
382 turnOffStrut();
383 }
384 }
385 else
386 if(placement==VERTICAL)
387 {
388 if(hidden)
389 {
390 new_x = screen_width - window_width;
391 new_y = screen_height - window_height;
392 hidden=false;
393
394 setRightStrut();
395 }
396 else
397 {
398 new_x = screen_width - window_width;
399 new_y = (screen_height - 10);
400 hidden=true;
401
402 turnOffStrut();
403 }
404 }
405 break;
406
407 case SOUTHWEST:
408 if(placement==HORIZONTAL)
409 {
410 if(hidden)
411 {
412 new_x = 0;
413 new_y = screen_height - window_height;
414 hidden=false;
415
416 setBottomStrut();
417 }
418 else
419 {
420 new_x = -(window_width-10);
421 new_y = screen_height - window_height;
422 hidden=true;
423
424 turnOffStrut();
425 }
426 }
427 else
428 if(placement==VERTICAL)
429 {
430 if(hidden)
431 {
432 new_x = 0;
433 new_y = screen_height - window_height;
434 hidden=false;
435
436 setLeftStrut();
437 }
438 else
439 {
440 new_x = 0;
441 new_y = (screen_height - 10);
442 hidden=true;
443
444 turnOffStrut();
445 }
446 }
447 break;
448 }
449
450 XMoveWindow(dpy,win, new_x, new_y);
451 }
452
453 // Positions icons horizontally on the appbar and resizes
454 // it accordingly.
horizontalBarIconPlacement()455 void Appbar::horizontalBarIconPlacement()
456 {
457 std::list<Icon *>::iterator it;
458 window_width = 1;
459 window_width= 5;
460
461 if ( (screen_placement == NORTHWEST) || (screen_placement == SOUTHWEST) )
462 window_width=5;
463
464 if ( (screen_placement == NORTHEAST) || (screen_placement == SOUTHEAST) )
465 window_width=13;
466
467 for(it = iconList->begin(); it != iconList->end(); it++)
468 {
469 XMapWindow(dpy, (*it)->getIconWindow());
470 XMoveWindow(dpy, (*it)->getIconWindow(), window_width, 5);
471 if (window_height < (int) ((*it)->getHeight() +12))
472 window_height = (*it)->getHeight() +12;
473 window_width+=(*it)->getWidth() + 6;
474 }
475 window_width += 15;
476 }
477
478 // Positions icons vertically on the appbar and resizes
479 // it accordingly.
480 //
481 // This function can be written better, its still not very
482 // well thought out. Icon wrapping is not really how I'd
483 // like it to be.
verticalBarIconPlacement()484 void Appbar::verticalBarIconPlacement()
485 {
486 std::list<Icon *>::iterator it;
487 window_width = 1;
488 window_height= 5;
489
490 if ( (screen_placement == NORTHWEST) || (screen_placement == NORTHEAST) )
491 window_height=5;
492
493 if ( (screen_placement == SOUTHWEST) || (screen_placement == SOUTHEAST) )
494 window_height=13;
495
496 for(it = iconList->begin(); it != iconList->end(); it++)
497 {
498 XMapWindow(dpy, (*it)->getIconWindow());
499 XMoveWindow(dpy, (*it)->getIconWindow(), 5, window_height);
500 if (window_width < (int) ((*it)->getWidth() +12))
501 window_width = (*it)->getWidth() +12;
502 window_height+=(*it)->getHeight() + 6;
503 }
504 window_height += 15;
505 }
506
doEventLoop()507 void Appbar::doEventLoop()
508 {
509 XEvent ev;
510
511 for (;;)
512 {
513 XNextEvent(dpy, &ev);
514
515 Icon* ico=NULL;
516
517 switch(ev.type)
518 {
519 case ButtonPress:
520 ico = findIconWindow(ev.xbutton.window);
521
522 if (ico)
523 {
524 ico->updateXYPos();
525 draw3DRectSunken(win, ico->getX()-1,
526 ico->getY()-1,
527 ico->getWidth()+1,
528 ico->getHeight()+1
529 );
530
531 }
532
533 break;
534
535 case ButtonRelease:
536
537 switch(ev.xbutton.button)
538 {
539 case Button1:
540 ico = findIconWindow(ev.xbutton.window);
541
542 if (ico)
543 {
544 ico->updateXYPos();
545 draw3DRectRaised(win, ico->getX()-1,
546 ico->getY()-1,
547 ico->getWidth()+1,
548 ico->getHeight()+1
549 );
550
551 ico->executeCommand();
552 }
553
554 if (ev.xbutton.window == win)
555 {
556 if(placement==HORIZONTAL)
557 {
558 if ( (screen_placement == NORTHWEST) || (screen_placement == SOUTHWEST) )
559 if(ev.xbutton.x >= window_width-10) appbarScreenPlacement();
560
561 if ( (screen_placement == NORTHEAST) || (screen_placement == SOUTHEAST) )
562 if(ev.xbutton.x <= 10) appbarScreenPlacement();
563 }
564
565 if(placement==VERTICAL)
566 {
567 if ( (screen_placement == NORTHWEST) || (screen_placement == NORTHEAST) )
568 if(ev.xbutton.y >= window_height-10) appbarScreenPlacement();
569
570 if ( (screen_placement == SOUTHWEST) || (screen_placement == SOUTHEAST) )
571 if(ev.xbutton.y <= 10) appbarScreenPlacement();
572 }
573 }
574
575 break;
576
577 case Button2:
578 if (ev.xbutton.window == win)
579 {
580 if(placement==HORIZONTAL)
581 {
582 if ( (screen_placement == NORTHWEST) || (screen_placement == SOUTHWEST) )
583 if(ev.xbutton.x >= window_width-10) quit();
584
585 if ( (screen_placement == NORTHEAST) || (screen_placement == SOUTHEAST) )
586 if(ev.xbutton.x <= 10) quit();
587 }
588
589 if(placement==VERTICAL)
590 {
591 if ( (screen_placement == NORTHWEST) || (screen_placement == NORTHEAST) )
592 if(ev.xbutton.y >= window_height-10) quit();
593
594 if ( (screen_placement == SOUTHWEST) || (screen_placement == SOUTHEAST) )
595 if(ev.xbutton.y <= 10) quit();
596 }
597 }
598 break;
599
600 //case Button3:
601 //
602 // Possibly allow for arbitrary execution of something later
603 // maybe for like a config tool to pop up. Anyway Mark wants it.
604 //
605 //break;
606
607 }
608 if (one_click) quit();
609 break;
610
611 //case DestroyNotify:
612 // quit();
613 //break;
614
615 case ClientMessage:
616 if (ev.xclient.message_type == atom_wm_protos)
617 {
618 if(ev.xclient.data.l[0]== (long) atom_wm_delete)
619 delete this;
620 }
621 break;
622
623 case EnterNotify:
624 ico = findIconWindow(ev.xcrossing.window);
625
626 if(ico)
627 {
628 ico->updateXYPos();
629 draw3DRectRaised(win, ico->getX()-1,
630 ico->getY()-1,
631 ico->getWidth()+1,
632 ico->getHeight()+1
633 );
634 }
635
636 break;
637
638 case LeaveNotify:
639 ico = findIconWindow(ev.xcrossing.window);
640
641 if (ico)
642 {
643 XClearWindow(dpy, win);
644
645 if(placement==HORIZONTAL)
646 drawHorizontalBarGrill();
647
648 if(placement==VERTICAL)
649 drawVerticalBarGrill();
650 }
651 break;
652
653 case Expose:
654 if(placement==HORIZONTAL)
655 drawHorizontalBarGrill();
656
657 if(placement==VERTICAL)
658 drawVerticalBarGrill();
659 break;
660 }
661 }
662 }
663
set_gnome_hint(Window w,int a,long value)664 void Appbar::set_gnome_hint(Window w, int a, long value)
665 {
666 XChangeProperty(dpy, w, gnome[a], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&value, 1);
667 }
668
set_mwm_hints(Window w,PropMwmHints * hints)669 void Appbar::set_mwm_hints(Window w, PropMwmHints *hints)
670 {
671 XChangeProperty(dpy, w, motif, motif, 32, PropModeReplace, (unsigned char *)hints, sizeof(*hints));
672 }
673
set_foreground(int index)674 void Appbar::set_foreground (int index)
675 {
676 XSetForeground (dpy, gc, palette[index]);
677 }
678
draw_dot(Window win,int x,int y)679 void Appbar::draw_dot (Window win, int x, int y)
680 {
681 set_foreground (4);
682 XDrawPoint (dpy, win, gc, x, y);
683 set_foreground (3);
684 XDrawPoint (dpy, win, gc, x + 1, y + 1);
685 }
686
draw3DLine(Window win,int style,int x1,int y1,int x2,int y2)687 void Appbar::draw3DLine(Window win, int style, int x1, int y1, int x2, int y2)
688 {
689 set_foreground(3);
690 XDrawLine(dpy, win, gc, x1, y1, x2, y2);
691 set_foreground(4);
692
693 if (style==HORIZONTAL)
694 XDrawLine(dpy, win, gc, x1, y1-1, x2, y2-1);
695
696 if (style==VERTICAL)
697 XDrawLine(dpy, win, gc, x1-1, y1, x2-1, y2);
698 }
699
draw3DRectSunken(Window win,int x,int y,int h,int w)700 void Appbar::draw3DRectSunken(Window win, int x, int y, int h, int w)
701 {
702 set_foreground(4);
703 XDrawLine(dpy, win, gc, x, y, x, y+h);
704 XDrawLine(dpy, win, gc, x, y, x+w, y);
705
706 set_foreground(3);
707 XDrawLine(dpy, win, gc, x+w, y, x+w, y+h);
708 XDrawLine(dpy, win, gc, x, y+h, x+w, y+h);
709 }
710
draw3DRectRaised(Window win,int x,int y,int h,int w)711 void Appbar::draw3DRectRaised(Window win, int x, int y, int h, int w)
712 {
713 set_foreground(3);
714 XDrawLine(dpy, win, gc, x, y, x, y+h);
715 XDrawLine(dpy, win, gc, x, y, x+w, y);
716
717 set_foreground(4);
718 XDrawLine(dpy, win, gc, x+w, y, x+w, y+h);
719 XDrawLine(dpy, win, gc, x, y+h, x+w, y+h);
720 }
721
drawHorizontalBarGrill()722 void Appbar::drawHorizontalBarGrill()
723 {
724 if ( (screen_placement == NORTHWEST) || (screen_placement == SOUTHWEST) )
725 {
726 draw3DLine(win, VERTICAL,
727 window_width-10,0,
728 window_width-10, window_height);
729
730 drawVerticalGrill(win, window_width-10, window_height);
731 }
732
733 if ( (screen_placement == NORTHEAST) || (screen_placement == SOUTHEAST) )
734 {
735 draw3DLine(win, VERTICAL,
736 10, 0,
737 10, window_height);
738
739 drawVerticalGrill(win, 0, window_height);
740 }
741 }
742
drawVerticalBarGrill()743 void Appbar::drawVerticalBarGrill()
744 {
745 if ( (screen_placement == SOUTHWEST) || (screen_placement == SOUTHEAST) )
746 {
747 draw3DLine(win, HORIZONTAL,
748 0, 10,
749 window_width, 10);
750
751 drawHoriontalGrill(win, 0, window_width);
752 }
753
754 if ( (screen_placement == NORTHEAST) || (screen_placement == NORTHWEST) )
755 {
756 draw3DLine(win, HORIZONTAL,
757 0, window_height-10,
758 window_width, window_height-10);
759
760 drawHoriontalGrill(win, window_height-10, window_width);
761 }
762 }
763
drawVerticalGrill(Window win,int x,int height)764 void Appbar::drawVerticalGrill (Window win, int x, int height)
765 {
766 int y = 0;
767 while (y < height - 5)
768 {
769 y += 3;
770 draw_dot (win, x + 3, y);
771 draw_dot (win, x + 6, y);
772 }
773 }
774
drawHoriontalGrill(Window win,int y,int width)775 void Appbar::drawHoriontalGrill(Window win, int y, int width)
776 {
777 int x = 0;
778 while (x < width - 5)
779 {
780 x += 3;
781 draw_dot (win, x, y + 3);
782 draw_dot (win, x, y + 6);
783 }
784 }
785
findIconWindow(Window win)786 Icon* Appbar::findIconWindow(Window win)
787 {
788 std::list<Icon *>::iterator it;
789 for(it = iconList->begin(); it != iconList->end() ; it++)
790 {
791 if((*it)->getIconWindow() == win)
792 return ((*it));
793 }
794
795 return NULL;
796 }
797
imageKeyword(Scanner * s)798 bool Appbar::imageKeyword(Scanner *s)
799 {
800 std::string t="image";
801 std::string a="";
802
803 if ( s->match ( t ) )
804 {
805 t = "=";
806
807 if ( s->match ( t ) )
808 {
809 while (! s->match( ";" ) )
810 {
811 a += s->currentToken();
812
813 s->getNextToken();
814 }
815
816 char *t = (char*) a.c_str();
817 current_icon->loadPixmap(t);
818
819 return true;
820 }
821 }
822
823 return false;
824 }
825
executeKeyword(Scanner * s)826 bool Appbar::executeKeyword(Scanner *s)
827 {
828 std::string t="execute";
829 std::string a="";
830
831 if ( s->match ( t ) )
832 {
833 t = "=";
834
835 if ( s->match ( t ) )
836 {
837 if(s->currentToken() == "}")
838 {
839 std::cerr << "parse error: cannot determine execute command, using default (xterm)." << std::endl;
840 current_icon->setExecuteCommand("xterm");
841 return true;
842 }
843
844 while (! s->match( ";" ) )
845 {
846 a += s->currentToken();
847 a += " "; // put whitespace back that may
848 // have gotten eaten by the scanner.
849 // This is probably not the best
850 // place to do it. The scanner should
851 // be smarter.
852
853 s->getNextToken();
854 }
855
856 char *t = (char*)a.c_str();
857 current_icon->setExecuteCommand(t);
858
859 return true;
860 }
861 }
862
863 return false;
864 }
865
iconKeyword(Scanner * s)866 bool Appbar::iconKeyword(Scanner *s)
867 {
868 std::string t="icon";
869
870 if ( s->match ( t ) )
871 {
872 t = "{";
873
874 if ( s->match ( t ) )
875 {
876 current_icon = new Icon(dpy, win);
877
878 imageKeyword(s);
879 executeKeyword(s);
880
881 iconList->push_back(current_icon);
882
883 t = "}";
884
885 if ( s->match ( t ) )
886 {
887 return true;
888 }
889 }
890
891 }
892
893 return false;
894 }
895
oneclickKeyword(Scanner * s)896 bool Appbar::oneclickKeyword(Scanner *s)
897 {
898 std::string t="one_click";
899
900 if ( s->match ( t ) )
901 {
902 one_click=true;
903 return true;
904 }
905
906 return false;
907 }
908
northeastKeyword(Scanner * s)909 bool Appbar::northeastKeyword(Scanner *s)
910 {
911 std::string t="northeast_placement";
912
913 if ( s->match ( t ) )
914 {
915 screen_placement=NORTHEAST;
916 return true;
917 }
918
919 return false;
920 }
921
northwestKeyword(Scanner * s)922 bool Appbar::northwestKeyword(Scanner *s)
923 {
924 std::string t="northwest_placement";
925
926 if ( s->match ( t ) )
927 {
928 screen_placement=NORTHWEST;
929 return true;
930 }
931
932 return false;
933 }
934
southeastKeyword(Scanner * s)935 bool Appbar::southeastKeyword(Scanner *s)
936 {
937 std::string t="southeast_placement";
938
939 if ( s->match ( t ) )
940 {
941 screen_placement=SOUTHEAST;
942 return true;
943 }
944
945 return false;
946 }
947
southwestKeyword(Scanner * s)948 bool Appbar::southwestKeyword(Scanner *s)
949 {
950 std::string t="southwest_placement";
951
952 if ( s->match ( t ) )
953 {
954 screen_placement=SOUTHWEST;
955 return true;
956 }
957
958 return false;
959 }
960
horizontalKeyword(Scanner * s)961 bool Appbar::horizontalKeyword(Scanner *s)
962 {
963 std::string t="horizontal_placement";
964
965 if ( s->match ( t ) )
966 {
967 placement=HORIZONTAL;
968 return true;
969 }
970
971 return false;
972 }
973
verticalKeyword(Scanner * s)974 bool Appbar::verticalKeyword(Scanner *s)
975 {
976 std::string t="vertical_placement";
977
978 if ( s->match ( t ) )
979 {
980 placement=VERTICAL;
981 return true;
982 }
983
984 return false;
985 }
986
rgbKeywords(Scanner * s)987 bool Appbar::rgbKeywords(Scanner *s)
988 {
989 std::string t="";
990 std::string a="";
991
992 if ( s->match ( "red" ) || s->match ( "green" ) || s->match ( "blue" ) )
993 {
994 t = "=";
995
996 if ( s->match ( t ) )
997 {
998 while (! s->match( ";" ) )
999 {
1000 a += s->currentToken();
1001
1002 s->getNextToken();
1003 }
1004
1005 temp_color = strtol(a.c_str(),0,16);
1006
1007 return true;
1008 }
1009 }
1010
1011 return false;
1012 }
1013
fromKeyword(Scanner * s)1014 bool Appbar::fromKeyword(Scanner *s)
1015 {
1016 std::string t="";
1017
1018 if ( s->match ( "appbar_color_from" ) )
1019 {
1020 t = "{";
1021
1022 if ( s->match ( t ) )
1023 {
1024 //cout << s->currentToken() << endl;
1025
1026 rgbKeywords(s);
1027 from.red = temp_color;
1028
1029 rgbKeywords(s);
1030 from.green = temp_color;
1031
1032 rgbKeywords(s);
1033 from.blue = temp_color;
1034
1035 t = "}";
1036
1037 if ( s->match ( t ) )
1038 {
1039 return true;
1040 }
1041 }
1042
1043 }
1044
1045 return false;
1046 }
1047
toKeyword(Scanner * s)1048 bool Appbar::toKeyword(Scanner *s)
1049 {
1050 std::string t="";
1051
1052 if ( s->match ( "appbar_color_to" ) )
1053 {
1054 t = "{";
1055
1056 if ( s->match ( t ) )
1057 {
1058 //cout << s->currentToken() << endl;
1059
1060 rgbKeywords(s);
1061 to.red = temp_color;
1062
1063 rgbKeywords(s);
1064 to.green = temp_color;
1065
1066 rgbKeywords(s);
1067 to.blue = temp_color;
1068
1069 t = "}";
1070
1071 if ( s->match ( t ) )
1072 {
1073 return true;
1074 }
1075 }
1076
1077 }
1078
1079 return false;
1080 }
1081
parseAppbarConfig(Scanner * s)1082 void Appbar::parseAppbarConfig(Scanner* s)
1083 {
1084 while(! s->eof())
1085 {
1086 s->getNextToken();
1087
1088 while ( iconKeyword(s) ||
1089 verticalKeyword(s) ||
1090 horizontalKeyword(s) ||
1091 oneclickKeyword(s) ||
1092 northeastKeyword(s) ||
1093 northwestKeyword(s) ||
1094 southeastKeyword(s) ||
1095 southwestKeyword(s) ||
1096 toKeyword(s) ||
1097 fromKeyword(s)
1098 ) {
1099 if(s->eof()) return;
1100 }
1101
1102 }
1103 }
1104
quit()1105 void Appbar::quit()
1106 {
1107 std::cerr << "Performing Appbar cleanup!" << std::endl;
1108
1109 iconList->clear();
1110 delete iconList;
1111
1112 image_control->removeImage( win_pix );
1113 delete image_control;
1114
1115 delete current_icon;
1116 delete appbarConfig;
1117
1118 XFreeGC(dpy, gc);
1119 XDestroyWindow (dpy, win);
1120 XCloseDisplay(dpy);
1121
1122 exit(0);
1123 }
1124
turnOffStrut()1125 void Appbar::turnOffStrut()
1126 {
1127 XDeleteProperty(dpy, win, net_wm_strut);
1128
1129 // This time we don't want always on top hint set.
1130 set_gnome_hint(win, WIN_HINTS, gnome_win_hints_no_on_top);
1131 }
1132
setLeftStrut()1133 void Appbar::setLeftStrut()
1134 {
1135 CARD32 strut[] = { window_width+2,0,0,0 };
1136 XChangeProperty (dpy, win, net_wm_strut, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &strut, 4);
1137
1138 set_gnome_hint(win, WIN_HINTS, gnome_win_normal_hints);
1139 }
1140
setRightStrut()1141 void Appbar::setRightStrut()
1142 {
1143 CARD32 strut[] = { 0,window_width+3,0,0 };
1144 XChangeProperty (dpy, win, net_wm_strut, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &strut, 4);
1145
1146 set_gnome_hint(win, WIN_HINTS, gnome_win_normal_hints);
1147 }
1148
setTopStrut()1149 void Appbar::setTopStrut()
1150 {
1151 CARD32 strut[] = { 0,0,window_height+2,0 };
1152 XChangeProperty (dpy, win, net_wm_strut, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &strut, 4);
1153
1154 set_gnome_hint(win, WIN_HINTS, gnome_win_normal_hints);
1155 }
1156
setBottomStrut()1157 void Appbar::setBottomStrut()
1158 {
1159 CARD32 strut[] = { 0,0,0,window_height+2 };
1160 XChangeProperty (dpy, win, net_wm_strut, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &strut, 4);
1161
1162 set_gnome_hint(win, WIN_HINTS, gnome_win_normal_hints);
1163 }
1164