1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <locale.h>
8 #include <string.h>
9 #include <signal.h>
10
11 #include <gdk/gdk.h>
12
13 #include "panel.h"
14 #include "misc.h"
15 #include "bg.h"
16 #include "main.h"
17 #include "gdk-helper.h"
18
19 #define VERSION "1.1.8"
20
21 static gchar version[] = VERSION;
22 int distance=0, distancefrom=DISTANCEFROM_TOP;
23 int expand=1 , padding=0;
24
25
26 //#define DEBUG
27 #include "dbg.h"
28
29
30 static panel *p;
31 static gchar *transparent_rc = "style 'transparent-style'\n"
32 "{\n"
33 "bg_pixmap[NORMAL] = \"<parent>\"\n"
34 "bg_pixmap[INSENSITIVE] = \"<parent>\"\n"
35 "bg_pixmap[PRELIGHT] = \"<parent>\"\n"
36 "bg_pixmap[SELECTED] = \"<parent>\"\n"
37 "bg_pixmap[ACTIVE] = \"<parent>\"\n"
38 "}\n"
39 "class \"GtkEventBox\" style \"transparent-style\"\n"
40 "class \"GtkSocket\" style \"transparent-style\"\n"
41 "class \"GtkBar\" style \"transparent-style\"\n"
42 "class \"GtkBox\" style \"transparent-style\"\n"
43 "\n";
44
45 static void set_bg(GtkWidget *widget, panel *p);
46
47 /****************************************************
48 * panel's handlers for WM events *
49 ****************************************************/
50 /*
51 static void
52 panel_del_wm_strut(panel *p)
53 {
54 XDeleteProperty(gdk_helper_display(), p->topxwin, a_NET_WM_STRUT);
55 XDeleteProperty(gdk_helper_display(), p->topxwin, a_NET_WM_STRUT_PARTIAL);
56 }
57 */
58
59 static void
panel_set_wm_strut(panel * p)60 panel_set_wm_strut(panel *p)
61 {
62 unsigned long data[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
63 int i = 4;
64
65 ENTER;
66 if (!GTK_WIDGET_MAPPED (p->topgwin))
67 return;
68 switch (p->edge) {
69 case EDGE_LEFT:
70 i = 0;
71 data[i] = p->aw;
72 data[4 + i*2] = p->ay;
73 data[5 + i*2] = p->ay + p->ah - 1;
74 break;
75 case EDGE_RIGHT:
76 i = 1;
77 data[i] = p->aw;
78 data[4 + i*2] = p->ay;
79 data[5 + i*2] = p->ay + p->ah - 1;
80 break;
81 case EDGE_TOP:
82 i = 2;
83 data[i] = p->ah;
84 data[4 + i*2] = p->ax;
85 data[5 + i*2] = p->ax + p->aw - 1;
86 break;
87 case EDGE_BOTTOM:
88 i = 3;
89 data[i] = p->ah;
90 data[4 + i*2] = p->ax;
91 data[5 + i*2] = p->ax + p->aw - 1 ;
92 break;
93 default:
94 ERR("wrong edge %d. strut won't be set\n", p->edge);
95 RET();
96 }
97 DBG("type %d. width %d. from %d to %d\n", i, data[i], data[4 + i*2], data[5 + i*2]);
98
99 XChangeProperty(gdk_helper_display(), p->topxwin, a_NET_WM_STRUT_PARTIAL,
100 XA_CARDINAL, 32, PropModeReplace, (unsigned char *) data, 12);
101 /* old spec, for wms that do not support STRUT_PARTIAL */
102 XChangeProperty(gdk_helper_display(), p->topxwin, a_NET_WM_STRUT,
103 XA_CARDINAL, 32, PropModeReplace, (unsigned char *) data, 4);
104
105 RET();
106 }
107
108 static GdkFilterReturn
panel_wm_events(GdkXEvent * xevent,GdkEvent * event,panel * p)109 panel_wm_events(GdkXEvent *xevent, GdkEvent *event, panel *p)
110 {
111 Atom at;
112 Window win;
113 XEvent *ev = (XEvent *) xevent;
114
115 ENTER;
116 DBG("win = 0x%x\n", ev->xproperty.window);
117 if ( ev->type != PropertyNotify )
118 RET(GDK_FILTER_CONTINUE);
119
120 at = ev->xproperty.atom;
121 win = ev->xproperty.window;
122 if (win == GDK_ROOT_WINDOW()) {
123 if (at == a_XROOTPMAP_ID) {
124 bg_rootbg_changed();
125 set_bg(p->topgwin, p);
126 gtk_widget_queue_draw(p->topgwin);
127 DBG("a_XROOTPMAP_ID\n");
128 }
129 }
130 RET(GDK_FILTER_CONTINUE);
131 }
132
133 /****************************************************
134 * panel's handlers for GTK events *
135 ****************************************************/
136
137
138 static gint
panel_delete_event(GtkWidget * widget,GdkEvent * event,gpointer data)139 panel_delete_event(GtkWidget * widget, GdkEvent * event, gpointer data)
140 {
141 ENTER;
142 RET(FALSE);
143 }
144
145 static gint
panel_destroy_event(GtkWidget * widget,GdkEvent * event,gpointer data)146 panel_destroy_event(GtkWidget * widget, GdkEvent * event, gpointer data)
147 {
148 ENTER;
149 // TODO need to cleanup
150 gtk_main_quit();
151 RET(FALSE);
152 }
153
154
155
156 static gint
panel_size_req(GtkWidget * widget,GtkRequisition * req,panel * p)157 panel_size_req(GtkWidget *widget, GtkRequisition *req, panel *p)
158 {
159 ENTER;
160 DBG("IN req=(%d, %d)\n", req->width, req->height);
161 if (p->widthtype == WIDTH_REQUEST)
162 p->width = (p->orientation == ORIENT_HORIZ) ? req->width : req->height;
163 if (p->heighttype == HEIGHT_REQUEST)
164 p->height = (p->orientation == ORIENT_HORIZ) ? req->height : req->width;
165 calculate_position(p, distance,distancefrom);
166 req->width = p->aw;
167 req->height = p->ah;
168 DBG("OUT req=(%d, %d)\n", req->width, req->height);
169 RET( TRUE );
170 }
171
172 static gint
panel_size_alloc(GtkWidget * widget,GtkAllocation * a,panel * p)173 panel_size_alloc(GtkWidget *widget, GtkAllocation *a, panel *p)
174 {
175 ENTER;
176 DBG("new alloc: size (%d, %d). pos (%d, %d)\n", a->width, a->height, a->x, a->y);
177 DBG("old alloc: size (%d, %d). pos (%d, %d)\n", p->aw, p->ah, p->ax, p->ay);
178 if (p->widthtype == WIDTH_REQUEST)
179 p->width = (p->orientation == ORIENT_HORIZ) ? a->width : a->height;
180 if (p->heighttype == HEIGHT_REQUEST)
181 p->height = (p->orientation == ORIENT_HORIZ) ? a->height : a->width;
182 calculate_position(p, distance,distancefrom);
183 DBG("pref alloc: size (%d, %d). pos (%d, %d)\n", p->aw, p->ah, p->ax, p->ay);
184 if (a->width == p->aw && a->height == p->ah && a->x == p->ax && a->y == p ->ay) {
185 DBG("actual coords eq to preffered. just returning\n");
186 RET(TRUE);
187 }
188
189 gtk_window_move(GTK_WINDOW(p->topgwin), p->ax, p->ay);
190 if (p->setstrut)
191 panel_set_wm_strut(p);
192 RET(TRUE);
193 }
194
195
196
197
198 /****************************************************
199 * panel creation *
200 ****************************************************/
201
202 static void
set_bg(GtkWidget * widget,panel * p)203 set_bg(GtkWidget *widget, panel *p)
204 {
205 ENTER;
206 if (p->gtopbg)
207 g_object_unref(p->gtopbg);
208 p->gtopbg = bg_new_for_win(p->topxwin);
209
210 modify_drawable(p->gtopbg, p->topgwin->style->black_gc, p->tintcolor, p->alpha);
211
212 gdk_window_set_back_pixmap(p->topgwin->window, p->gtopbg, FALSE);
213 gdk_window_clear(p->topgwin->window);
214 gtk_widget_queue_draw_area (p->topgwin, 0, 0, 2000, 2000);
215 RET();
216 }
217
218 static void
panel_style_set(GtkWidget * widget,GtkStyle * s,panel * p)219 panel_style_set(GtkWidget *widget, GtkStyle *s, panel *p)
220 {
221 ENTER;
222
223 gtk_rc_parse_string(transparent_rc);
224 if (GTK_WIDGET_REALIZED(widget))
225 set_bg(widget, p);
226 RET();
227 }
228
229 static gboolean
panel_configure_event(GtkWidget * widget,GdkEventConfigure * event,panel * p)230 panel_configure_event(GtkWidget *widget, GdkEventConfigure *event, panel *p)
231 {
232 static gint x = 0, y = 0, width = 0, height = 0;
233
234 ENTER;
235 if (x == event->x && y == event->y
236 && width == event->width && height == event->height)
237 RET(FALSE);
238 x = event->x;
239 y = event->y;
240 width = event->width;
241 height = event->height;
242 set_bg(widget, p);
243 RET(FALSE);
244 }
245
246 static gboolean
panel_monitors_changed(GdkScreen * s,panel * p)247 panel_monitors_changed(GdkScreen* s, panel* p)
248 {
249 ENTER;
250 if ( p->on_primary ) {
251 p->monitor = gdk_screen_get_primary_monitor(s);
252 }
253 calculate_position(p, distance,distancefrom);
254 gdk_window_move_resize(p->topgwin->window, p->ax, p->ay, p->aw, p->ah);
255 if (p->setstrut)
256 panel_set_wm_strut(p);
257 RET(TRUE);
258 }
259
260 void
panel_start_gui(panel * p)261 panel_start_gui(panel *p)
262 {
263 ENTER;
264 //gtk_rc_parse_string(transparent_rc);
265 p->topgwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
266
267 gtk_container_set_border_width(GTK_CONTAINER(p->topgwin), 0);
268 gtk_window_set_resizable(GTK_WINDOW(p->topgwin), FALSE);
269 gtk_window_set_wmclass(GTK_WINDOW(p->topgwin), "panel", "trayer");
270 gtk_window_set_title(GTK_WINDOW(p->topgwin), "panel");
271 gtk_window_set_position(GTK_WINDOW(p->topgwin), GTK_WIN_POS_CENTER);
272 g_signal_connect ( G_OBJECT(p->topgwin) , "delete-event" , G_CALLBACK(panel_delete_event) , p);
273 g_signal_connect ( G_OBJECT(p->topgwin) , "destroy-event", G_CALLBACK(panel_destroy_event), p);
274 g_signal_connect ( G_OBJECT (p->topgwin), "size-request" , G_CALLBACK(panel_size_req) , p);
275 g_signal_connect ( G_OBJECT (p->topgwin), "size-allocate", G_CALLBACK(panel_size_alloc), p);
276
277 if (p->transparent) {
278 g_signal_connect (G_OBJECT (p->topgwin), "configure-event", G_CALLBACK(panel_configure_event), p);
279 g_signal_connect (G_OBJECT (p->topgwin), "style-set", G_CALLBACK( panel_style_set), p);
280 }
281
282 GdkDisplay *display = gdk_display_get_default ();
283 GdkScreen *screen = gdk_display_get_default_screen(display);
284 g_signal_connect ( screen, "monitors-changed", G_CALLBACK(panel_monitors_changed), (gpointer)p );
285
286 if (p->on_primary) {
287 p->monitor = gdk_screen_get_primary_monitor(screen);
288
289 }
290
291 gtk_widget_realize(p->topgwin);
292 gdk_window_set_decorations(p->topgwin->window, 0);
293 gtk_widget_set_app_paintable(p->topgwin, TRUE);
294
295 p->lbox = p->my_box_new(FALSE, 0);
296 gtk_container_set_border_width(GTK_CONTAINER(p->lbox), 0);
297 gtk_container_add(GTK_CONTAINER(p->topgwin), p->lbox);
298 gtk_widget_show(p->lbox);
299
300 if (p->allign == ALLIGN_RIGHT) {
301 GtkWidget * expander = p->my_box_new(FALSE, 0);
302 gtk_box_pack_start(GTK_BOX(p->lbox), expander, TRUE, TRUE, 0);
303 gtk_widget_show(expander);
304 }
305
306 p->box = p->my_box_new(FALSE, 1);
307 gtk_container_set_border_width(GTK_CONTAINER(p->box), 1);
308 gtk_box_pack_start(GTK_BOX(p->lbox), p->box, FALSE, TRUE, padding);
309 gtk_widget_show(p->box);
310
311 // get properties on topgwin
312 p->topGdkWindow = gtk_widget_get_window(p->topgwin);
313 p->topxwin = GDK_WINDOW_XWINDOW(GTK_WIDGET(p->topgwin)->window);
314
315 bg_init(gdk_helper_display());
316
317 /* make our window unfocusable */
318 gdk_window_set_accept_focus(p->topGdkWindow,False);
319
320 if (p->setdocktype) {
321 gdk_window_set_type_hint(p->topGdkWindow,GDK_WINDOW_TYPE_HINT_DOCK);
322 }
323
324 Xclimsg(p->topxwin, a_NET_WM_DESKTOP, 0xFFFFFFFF, 0, 0, 0, 0);
325
326 /************************/
327 /* Window Mapping Point */
328 gtk_widget_show_all(p->topgwin);
329 Xclimsg(p->topxwin, a_NET_WM_DESKTOP, 0xFFFFFFFF, 0, 0, 0, 0);
330
331 gdk_window_stick ( p->topGdkWindow);
332 gdk_window_set_skip_pager_hint ( p->topGdkWindow, True );
333 gdk_window_set_skip_taskbar_hint ( p->topGdkWindow, True );
334
335 XSelectInput (gdk_helper_display(), GDK_ROOT_WINDOW(), PropertyChangeMask);
336 XSelectInput (gdk_helper_display(), p->topxwin, PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
337 gdk_window_add_filter(gdk_get_default_root_window (), (GdkFilterFunc)panel_wm_events, p);
338
339 calculate_position(p, distance,distancefrom);
340 gdk_window_move_resize(p->topgwin->window, p->ax, p->ay, p->aw, p->ah);
341 if (p->setstrut)
342 panel_set_wm_strut(p);
343 if (p->lower)
344 XLowerWindow(gdk_helper_display(), p->topxwin);
345
346 RET();
347 }
348
349 static int
panel_parse_global(panel * p)350 panel_parse_global(panel *p)
351 {
352 ENTER;
353 p->orientation = (p->edge == EDGE_TOP || p->edge == EDGE_BOTTOM)
354 ? ORIENT_HORIZ : ORIENT_VERT;
355 if (p->orientation == ORIENT_HORIZ) {
356 p->my_box_new = gtk_hbox_new;
357 } else {
358 p->my_box_new = gtk_vbox_new;
359 }
360 if (p->width < 0)
361 p->width = 100;
362 if (p->widthtype == WIDTH_PERCENT && p->width > 100)
363 p->width = 100;
364 p->heighttype = HEIGHT_PIXEL;
365 if (p->heighttype == HEIGHT_PIXEL) {
366 if (p->height < PANEL_HEIGHT_MIN) {
367 ERR( "height is bound by %i pixels\n", PANEL_HEIGHT_MIN );
368 p->height = PANEL_HEIGHT_MIN;
369 } else if (p->height > PANEL_HEIGHT_MAX) {
370 ERR( "height is bound by %i pixels\n", PANEL_HEIGHT_MAX );
371 p->height = PANEL_HEIGHT_MAX;
372 }
373 }
374 panel_start_gui(p);
375 RET(1);
376 }
377
378 int
panel_start(panel * p)379 panel_start(panel *p)
380 {
381 /* parse global section */
382 ENTER;
383
384 if (!panel_parse_global(p))
385 RET(0);
386
387 if (!tray_constructor(p))
388 RET(0);
389
390 gtk_widget_show_all(p->topgwin);
391 RET(1);
392 }
393
panel_stop(panel * p)394 void panel_stop(panel *p)
395 {
396 ENTER;
397
398 tray_destructor(p);
399 XSelectInput (gdk_helper_display(), GDK_ROOT_WINDOW(), NoEventMask);
400 gdk_window_remove_filter(gdk_get_default_root_window (), (GdkFilterFunc)panel_wm_events, p);
401 gtk_widget_destroy(p->topgwin);
402 RET();
403 }
404
405 void
usage()406 usage()
407 {
408 ENTER;
409 printf("trayer %s - lightweight GTK2+ systray for UNIX desktops\n", version);
410 printf("Command line options:\n");
411 printf(" -h -- print this help and exit\n");
412 printf(" -v -- print version and exit\n");
413 printf(" -l -- lower the window on startup\n");
414 printf(" --edge <left|right|top|bottom|none> (default:bottom) \n");
415 printf(" --align <left|right|center> (default:center)\n");
416 printf(" --margin <number> (default:0)\n");
417 printf(" --widthtype <request|pixel|percent> (default:percent)\n");
418 printf(" --width <number> (default:%i)\n",PANEL_WIDTH_DEFAULT);
419 printf(" --heighttype <request|pixel> (default:pixel)\n");
420 printf(" --height <number> (default:%i)\n",PANEL_HEIGHT_DEFAULT);
421 printf(" --SetDockType <true|false> (default:true)\n");
422 printf(" --SetPartialStrut <true|false> (default:true)\n");
423 printf(" --transparent <true|false> (default:false)\n");
424 printf(" --alpha <number> (default:127)\n");
425 printf(" --tint <int> (default:0xFFFFFFFF)\n");
426 printf(" --distance <number> (default:0)\n");
427 printf(" --distancefrom <left|right|top|bottom> (default:top) \n");
428 printf(" --expand <false|true> (default:true)\n");
429 printf(" --padding <number> (default:0)\n");
430 printf(" --monitor <number|primary> (default:0)\n");
431 printf(" --iconspacing <number> (default:0)\n");
432 }
433
434 void
handle_error(Display * d,XErrorEvent * ev)435 handle_error(Display * d, XErrorEvent * ev)
436 {
437 char buf[256];
438
439 ENTER;
440 XGetErrorText(gdk_helper_display(), ev->error_code, buf, 256);
441 ERR( "trayer : X error: %s\n", buf);
442 RET();
443 }
444
445 int
main(int argc,char * argv[],char * env[])446 main(int argc, char *argv[], char *env[])
447 {
448 int i;
449
450 ENTER;
451 setlocale(LC_CTYPE, "");
452 gtk_init(&argc, &argv);
453 XSetLocaleModifiers("");
454 XSetErrorHandler((XErrorHandler) handle_error);
455 // resolve xatoms
456 resolve_atoms();
457
458 p = g_new0(panel, 1);
459 memset(p, 0, sizeof(panel));
460 p->allign = ALLIGN_CENTER;
461 p->edge = EDGE_BOTTOM;
462 p->widthtype = WIDTH_PERCENT;
463 p->width = PANEL_WIDTH_DEFAULT;
464 p->heighttype = HEIGHT_PIXEL;
465 p->height = PANEL_HEIGHT_DEFAULT;
466 p->setdocktype = 1;
467 p->setstrut = 0;
468 p->transparent = 0;
469 p->icon_spacing = 0;
470 p->alpha = 127;
471 p->tintcolor = 0xFFFFFFFF;
472 p->xtopbg = None;
473 p->monitor = 0;
474 p->margin = 0;
475 p->on_primary = 0;
476
477 for (i = 1; i < argc; i++) {
478 if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
479 usage();
480 exit(0);
481 } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
482 printf("trayer %s\n", version);
483 exit(0);
484 } else if (!strcmp(argv[i], "-l")) {
485 p->lower = 1;
486 } else if (!strcmp(argv[i], "--edge")) {
487 i++;
488 if (i == argc) {
489 ERR( "trayer: missing edge parameter value\n");
490 usage();
491 exit(1);
492 } else {
493 p->edge = str2num(edge_pair, argv[i], EDGE_NONE);
494 }
495 } else if (!strcmp(argv[i], "--align")) {
496 i++;
497 if (i == argc) {
498 ERR( "trayer: missing align parameter value\n");
499 usage();
500 exit(1);
501 } else {
502 p->allign = str2num(allign_pair, argv[i], ALLIGN_NONE);
503 }
504 } else if (!strcmp(argv[i], "--margin")) {
505 i++;
506 if (i == argc) {
507 ERR( "trayer: missing margin parameter value\n");
508 usage();
509 exit(1);
510 } else {
511 p->margin = atoi(argv[i]);
512 }
513 } else if (!strcmp(argv[i], "--widthtype")) {
514 i++;
515 if (i == argc) {
516 ERR( "trayer: missing widthtype parameter value\n");
517 usage();
518 exit(1);
519 } else {
520 p->widthtype = str2num(width_pair, argv[i], WIDTH_NONE);
521 }
522 } else if (!strcmp(argv[i], "--width")) {
523 i++;
524 if (i == argc) {
525 ERR( "trayer: missing width parameter value\n");
526 usage();
527 exit(1);
528 } else {
529 p->width = atoi(argv[i]);
530 }
531 } else if (!strcmp(argv[i], "--heighttype")) {
532 i++;
533 if (i == argc) {
534 ERR( "trayer: missing heighttype parameter value\n");
535 usage();
536 exit(1);
537 } else {
538 p->heighttype = str2num(height_pair, argv[i], HEIGHT_NONE);
539 }
540 } else if (!strcmp(argv[i], "--height")) {
541 i++;
542 if (i == argc) {
543 ERR( "trayer: missing height parameter value\n");
544 usage();
545 exit(1);
546 } else {
547 p->height = atoi(argv[i]);
548 }
549 } else if (!strcmp(argv[i], "--SetDockType")) {
550 i++;
551 if (i == argc) {
552 ERR( "trayer: missing SetDockType parameter value\n");
553 usage();
554 exit(1);
555 } else {
556 p->setdocktype = str2num(bool_pair, argv[i], 0);
557 }
558 } else if (!strcmp(argv[i], "--SetPartialStrut")) {
559 i++;
560 if (i == argc) {
561 ERR( "trayer: missing SetPartialStrut parameter value\n");
562 usage();
563 exit(1);
564 } else {
565 p->setstrut = str2num(bool_pair, argv[i], 0);
566 }
567 } else if (!strcmp(argv[i], "--transparent")) {
568 i++;
569 if (i == argc) {
570 ERR( "trayer: missing transparent parameter value\n");
571 usage();
572 exit(1);
573 } else {
574 p->transparent = str2num(bool_pair, argv[i], 1);
575 }
576 } else if (!strcmp(argv[i], "--alpha")) {
577 i++;
578 if (i == argc) {
579 ERR( "trayer: missing alpha parameter value\n");
580 usage();
581 exit(1);
582 } else {
583 p->alpha = atoi(argv[i]);
584 }
585 } else if (!strcmp(argv[i], "--tint")) {
586 i++;
587 if (i == argc) {
588 ERR( "trayer: missing tint parameter value\n");
589 usage();
590 exit(1);
591 } else {
592 p->tintcolor = strtoul(argv[i], NULL, 0);
593 }
594 } else if (!strcmp(argv[i], "--distance")) {
595 i++;
596 if (i == argc) {
597 ERR( "trayer: missing distance parameter value\n");
598 usage();
599 exit(1);
600 } else {
601 distance = atoi(argv[i]);
602 }
603 } else if (!strcmp(argv[i], "--distancefrom")) {
604 i++;
605 if (i == argc) {
606 ERR( "trayer: missing distancefrom parameter value\n");
607 usage();
608 exit(1);
609 } else {
610 distancefrom = str2num(distancefrom_pair, argv[i], DISTANCEFROM_NONE);
611 }
612 } else if (!strcmp(argv[i], "--expand")) {
613 i++;
614 if (i == argc) {
615 ERR( "trayer: missing expand parameter value\n");
616 usage();
617 exit(1);
618 } else {
619 expand = str2num(bool_pair, argv[i], 1);
620 }
621 } else if (!strcmp(argv[i], "--padding")) {
622 i++;
623 if (i == argc) {
624 ERR( "trayer: missing padding parameter value\n");
625 usage();
626 exit(1);
627 } else {
628 padding = atoi(argv[i]);
629 }
630 } else if (!strcmp(argv[i], "--monitor")) {
631 i++;
632 if (i == argc) {
633 ERR( "trayer: missing monitor parameter value\n");
634 usage();
635 exit(1);
636 } else {
637 if (g_ascii_isdigit(argv[i][0])) {
638 p->monitor = atoi(argv[i]);
639 } else if (!strcmp(argv[i], "primary")) {
640 p->on_primary = 1;
641 }
642 }
643 } else if (!strcmp(argv[i], "--iconspacing")) {
644 i++;
645 if (i == argc) {
646 ERR( "trayer: missing icon padding parameter value\n");
647 usage();
648 exit(1);
649 } else {
650 p->icon_spacing = atoi(argv[i]);
651 }
652 } else {
653 printf("trayer: unknown option - %s\n", argv[i]);
654 usage();
655 exit(1);
656 }
657 }
658 g_return_val_if_fail (p != NULL, 1);
659 if (!panel_start(p)) {
660 ERR( "trayer: can't start panel\n");
661 exit(1);
662 }
663 gtk_main();
664 panel_stop(p);
665 g_free(p);
666
667 exit(0);
668 }
669
670