todo-2.6 -- add note for fvwm-menu-desktop (2.6.X release)
[fvwm.git] / modules / FvwmPager / FvwmPager.c
blobb254aba2a1dd2936de7c0eb68c71d5ac5a867b68
1 /* -*-c-*- */
2 /* This module, and the entire ModuleDebugger program, and the concept for
3 * interfacing this module to the Window Manager, are all original work
4 * by Robert Nation
6 * Copyright 1994, Robert Nation. No guarantees or warantees or anything
7 * are provided or implied in any way whatsoever. Use this program at your
8 * own risk. Permission to use this program for any purpose is given,
9 * as long as the copyright is kept intact. */
11 /* This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "config.h"
28 #include <stdio.h>
29 #include <signal.h>
30 #include <fcntl.h>
31 #include <sys/wait.h>
32 #include "libs/ftime.h"
33 #include <ctype.h>
35 #ifdef HAVE_SYS_BSDTYPES_H
36 #include <sys/bsdtypes.h> /* Saul */
37 #endif /* Saul */
39 #include <X11/Xlib.h>
40 #include <X11/Xutil.h>
41 #include <X11/Xproto.h>
42 #include <X11/Xatom.h>
43 #include <X11/Intrinsic.h>
44 #include <X11/keysym.h>
46 #include "libs/Module.h"
47 #include "libs/fvwmlib.h"
48 #include "libs/FScreen.h"
49 #include "libs/FShape.h"
50 #include "libs/FRenderInit.h"
51 #include "libs/Colorset.h"
52 #include "libs/Flocale.h"
53 #include "libs/fvwmsignal.h"
54 #include "libs/Grab.h"
55 #include "libs/Parse.h"
56 #include "libs/Strings.h"
57 #include "libs/System.h"
59 #include "fvwm/fvwm.h"
60 #include "FvwmPager.h"
63 char *MyName;
64 int fd[2];
66 PagerStringList *FindDeskStrings(int desk);
67 PagerStringList *NewPagerStringItem(PagerStringList *last, int desk);
68 extern FlocaleFont *FwindowFont;
69 extern Pixmap default_pixmap;
73 * Screen, font, etc info
76 ScreenInfo Scr;
77 PagerWindow *Start = NULL;
78 PagerWindow *FocusWin = NULL;
80 Display *dpy; /* which display are we talking to */
81 int x_fd;
82 fd_set_size_t fd_width;
84 char *PagerFore = NULL;
85 char *PagerBack = NULL;
86 char *font_string = NULL;
87 char *smallFont = NULL;
88 char *HilightC = NULL;
90 FvwmPicture *HilightPixmap = NULL;
91 int HilightDesks = 1;
93 char *WindowBack = NULL;
94 char *WindowFore = NULL;
95 char *WindowHiBack = NULL;
96 char *WindowHiFore = NULL;
97 char *WindowLabelFormat = NULL;
99 unsigned int WindowBorderWidth = DEFAULT_PAGER_WINDOW_BORDER_WIDTH;
100 unsigned int MinSize = 2 * DEFAULT_PAGER_WINDOW_BORDER_WIDTH + 1;
101 Bool WindowBorders3d = False;
103 Bool UseSkipList = False;
105 FvwmPicture *PixmapBack = NULL;
107 char *ImagePath = NULL;
109 #define DEFAULT_PAGER_MOVE_THRESHOLD 3
110 int MoveThreshold = DEFAULT_PAGER_MOVE_THRESHOLD;
112 int ShowBalloons = 0, ShowPagerBalloons = 0, ShowIconBalloons = 0;
113 Bool do_focus_on_enter = False;
114 Bool use_dashed_separators = True;
115 Bool use_no_separators = False;
116 char *BalloonTypeString = NULL;
117 char *BalloonBack = NULL;
118 char *BalloonFore = NULL;
119 char *BalloonFont = NULL;
120 char *BalloonBorderColor = NULL;
121 char *BalloonFormatString = NULL;
122 int BalloonBorderWidth = 1;
123 int BalloonYOffset = 3;
124 Window BalloonView = None;
126 int window_w=0, window_h=0, window_x=0, window_y=0;
127 int icon_x=-10000, icon_y=-10000, icon_w=0, icon_h=0;
128 int usposition = 0,uselabel = 1;
129 int xneg = 0, yneg = 0;
130 int icon_xneg = 0, icon_yneg = 0;
131 extern DeskInfo *Desks;
132 int StartIconic = 0;
133 int MiniIcons = 0;
134 int LabelsBelow = 0;
135 int ShapeLabels = 0;
136 int Rows = -1, Columns = -1;
137 int desk1=0, desk2 =0;
138 int ndesks = 0;
139 int windowcolorset = -1;
140 int activecolorset = -1;
141 static int globalcolorset = -1;
142 static int globalballooncolorset = -1;
143 static int globalhighcolorset = -1;
144 Pixel win_back_pix;
145 Pixel win_fore_pix;
146 Bool win_pix_set = False;
147 Pixel win_hi_back_pix;
148 Pixel win_hi_fore_pix;
149 Bool win_hi_pix_set = False;
150 char fAlwaysCurrentDesk = 0;
151 PagerStringList string_list = { NULL, 0, -1, -1, -1, NULL, NULL, NULL };
152 Bool is_transient = False;
153 Bool do_ignore_next_button_release = False;
154 Bool error_occured = False;
155 Bool Swallowed = False;
157 static void SetDeskLabel(int desk, const char *label);
158 static RETSIGTYPE TerminateHandler(int);
159 void ExitPager(void);
163 * Procedure:
164 * main - start of module
167 int main(int argc, char **argv)
169 char *display_name = NULL;
170 int itemp,i;
171 char line[100];
172 short opt_num;
173 Window JunkRoot, JunkChild;
174 int JunkX, JunkY;
175 unsigned JunkMask;
177 FlocaleInit(LC_CTYPE, "", "", "FvwmPager");
179 /* Save our program name - for error messages */
180 MyName = GetFileNameFromPath(argv[0]);
182 if(argc < 6)
184 fprintf(stderr,"%s Version %s should only be executed by fvwm!\n",MyName,
185 VERSION);
186 exit(1);
189 #ifdef HAVE_SIGACTION
191 struct sigaction sigact;
193 sigemptyset(&sigact.sa_mask);
194 sigaddset(&sigact.sa_mask, SIGPIPE);
195 sigaddset(&sigact.sa_mask, SIGTERM);
196 sigaddset(&sigact.sa_mask, SIGQUIT);
197 sigaddset(&sigact.sa_mask, SIGINT);
198 sigaddset(&sigact.sa_mask, SIGHUP);
199 # ifdef SA_INTERRUPT
200 sigact.sa_flags = SA_INTERRUPT;
201 # else
202 sigact.sa_flags = 0;
203 # endif
204 sigact.sa_handler = TerminateHandler;
206 sigaction(SIGPIPE, &sigact, NULL);
207 sigaction(SIGTERM, &sigact, NULL);
208 sigaction(SIGQUIT, &sigact, NULL);
209 sigaction(SIGINT, &sigact, NULL);
210 sigaction(SIGHUP, &sigact, NULL);
212 #else
213 /* We don't have sigaction(), so fall back to less robust methods. */
214 #ifdef USE_BSD_SIGNALS
215 fvwmSetSignalMask( sigmask(SIGPIPE) |
216 sigmask(SIGTERM) |
217 sigmask(SIGQUIT) |
218 sigmask(SIGINT) |
219 sigmask(SIGHUP) );
220 #endif
221 signal(SIGPIPE, TerminateHandler);
222 signal(SIGTERM, TerminateHandler);
223 signal(SIGQUIT, TerminateHandler);
224 signal(SIGINT, TerminateHandler);
225 signal(SIGHUP, TerminateHandler);
226 #ifdef HAVE_SIGINTERRUPT
227 siginterrupt(SIGPIPE, 1);
228 siginterrupt(SIGTERM, 1);
229 siginterrupt(SIGQUIT, 1);
230 siginterrupt(SIGINT, 1);
231 siginterrupt(SIGHUP, 1);
232 #endif
233 #endif
235 fd[0] = atoi(argv[1]);
236 fd[1] = atoi(argv[2]);
238 fd_width = GetFdWidth();
240 opt_num = 6;
241 if (argc >= 7 && (StrEquals(argv[opt_num], "-transient") ||
242 StrEquals(argv[opt_num], "transient")))
244 opt_num++;
245 is_transient = True;
246 do_ignore_next_button_release = True;
249 /* Check for an alias */
250 if (argc >= opt_num + 1)
252 char *s;
254 if (!StrEquals(argv[opt_num], "*"))
256 for (s = argv[opt_num]; *s; s++)
258 if (!isdigit(*s) &&
259 (*s != '-' || s != argv[opt_num] || *(s+1) == 0))
261 free(MyName);
262 MyName=safestrdup(argv[opt_num]);
263 opt_num++;
264 break;
270 if (argc < opt_num + 1)
272 desk1 = Scr.CurrentDesk;
273 desk2 = Scr.CurrentDesk;
275 else if (StrEquals(argv[opt_num], "*"))
277 desk1 = Scr.CurrentDesk;
278 desk2 = Scr.CurrentDesk;
279 fAlwaysCurrentDesk = 1;
281 else
283 desk1 = atoi(argv[opt_num]);
284 if (argc == opt_num+1)
285 desk2 = desk1;
286 else
287 desk2 = atoi(argv[opt_num+1]);
288 if(desk2 < desk1)
290 itemp = desk1;
291 desk1 = desk2;
292 desk2 = itemp;
295 ndesks = desk2 - desk1 + 1;
297 Desks = (DeskInfo *)safemalloc(ndesks*sizeof(DeskInfo));
298 memset(Desks, 0, ndesks * sizeof(DeskInfo));
299 for(i=0;i<ndesks;i++)
301 sprintf(line,"Desk %d",i+desk1);
302 CopyString(&Desks[i].label,line);
303 Desks[i].colorset = -1;
304 Desks[i].highcolorset = -1;
305 Desks[i].ballooncolorset = -1;
308 /* Initialize X connection */
309 if (!(dpy = XOpenDisplay(display_name)))
311 fprintf(stderr,"%s: can't open display %s", MyName,
312 XDisplayName(display_name));
313 exit (1);
316 x_fd = XConnectionNumber(dpy);
317 flib_init_graphics(dpy);
319 Scr.screen = DefaultScreen(dpy);
320 Scr.Root = RootWindow(dpy, Scr.screen);
321 /* make a temp window for any pixmaps, deleted later */
322 initialize_viz_pager();
324 SetMessageMask(fd,
325 M_VISIBLE_NAME |
326 M_ADD_WINDOW|
327 M_CONFIGURE_WINDOW|
328 M_DESTROY_WINDOW|
329 M_FOCUS_CHANGE|
330 M_NEW_PAGE|
331 M_NEW_DESK|
332 M_RAISE_WINDOW|
333 M_LOWER_WINDOW|
334 M_ICONIFY|
335 M_ICON_LOCATION|
336 M_DEICONIFY|
337 M_RES_NAME|
338 M_RES_CLASS|
339 M_CONFIG_INFO|
340 M_END_CONFIG_INFO|
341 M_MINI_ICON|
342 M_END_WINDOWLIST|
343 M_RESTACK);
344 SetMessageMask(fd,
345 MX_VISIBLE_ICON_NAME|
346 MX_PROPERTY_CHANGE|
347 MX_REPLY);
348 ParseOptions();
349 if (is_transient)
351 if (FQueryPointer(
352 dpy, Scr.Root, &JunkRoot, &JunkChild, &window_x, &window_y, &JunkX,
353 &JunkY, &JunkMask) == False)
355 /* pointer is on a different screen */
356 window_x = 0;
357 window_y = 0;
359 usposition = 1;
360 xneg = 0;
361 yneg = 0;
364 if (PagerFore == NULL)
365 PagerFore = safestrdup("black");
367 if (PagerBack == NULL)
368 PagerBack = safestrdup("white");
370 if (HilightC == NULL)
371 HilightC = safestrdup(PagerFore);
373 if (WindowLabelFormat == NULL)
374 WindowLabelFormat = safestrdup("%i");
376 if ((HilightC == NULL) && (HilightPixmap == NULL))
377 HilightDesks = 0;
379 if (BalloonBorderColor == NULL)
380 BalloonBorderColor = safestrdup("black");
382 if (BalloonTypeString == NULL)
383 BalloonTypeString = safestrdup("%i");
385 if (BalloonFormatString == NULL)
386 BalloonFormatString = safestrdup("%i");
388 /* open a pager window */
389 initialize_pager();
391 /* Create a list of all windows */
392 /* Request a list of all windows,
393 * wait for ConfigureWindow packets */
394 SendInfo(fd,"Send_WindowList",0);
396 if (is_transient)
398 Bool is_pointer_grabbed = False;
399 Bool is_keyboard_grabbed = False;
400 XSync(dpy,0);
401 for (i = 0; i < 50 && !(is_pointer_grabbed && is_keyboard_grabbed); i++)
403 if (!is_pointer_grabbed &&
404 XGrabPointer(
405 dpy, Scr.Root, True,
406 ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|
407 PointerMotionMask|EnterWindowMask|LeaveWindowMask, GrabModeAsync,
408 GrabModeAsync, None, None, CurrentTime) == GrabSuccess)
410 is_pointer_grabbed = True;
412 if (!is_keyboard_grabbed &&
413 XGrabKeyboard(
414 dpy, Scr.Root, True, GrabModeAsync, GrabModeAsync, CurrentTime) ==
415 GrabSuccess)
417 is_keyboard_grabbed = True;
419 /* If you go too fast, other windows may not get a change to release
420 * any grab that they have. */
421 usleep(20000);
423 if (!is_pointer_grabbed)
425 XBell(dpy, 0);
426 fprintf(stderr,
427 "%s: could not grab pointer in transient mode. exiting.\n",
428 MyName);
429 exit(1);
432 XSync(dpy,0);
435 /* tell fvwm we're running */
436 SendFinishedStartupNotification(fd);
438 Loop(fd);
439 #ifdef FVWM_DEBUG_MSGS
440 if ( isTerminated )
442 fprintf(stderr, "%s: Received signal: exiting...\n", MyName);
444 #endif
446 return 0;
451 * Procedure:
452 * Loop - wait for data to process
455 void Loop(int *fd)
457 XEvent Event;
459 while( !isTerminated )
461 if(My_XNextEvent(dpy,&Event))
462 DispatchEvent(&Event);
463 if (error_occured)
465 Window root;
466 unsigned border_width, depth;
467 int x,y;
469 if(XGetGeometry(dpy,Scr.Pager_w,&root,&x,&y,
470 (unsigned *)&window_w,(unsigned *)&window_h,
471 &border_width,&depth)==0)
473 /* does not return */
474 ExitPager();
476 error_occured = False;
484 * Procedure:
485 * Process message - examines packet types, and takes appropriate action
488 void process_message( FvwmPacket* packet )
490 unsigned long type = packet->type;
491 unsigned long length = packet->size;
492 unsigned long* body = packet->body;
494 switch (type)
496 case M_ADD_WINDOW:
497 list_configure(body);
498 break;
499 case M_CONFIGURE_WINDOW:
500 list_configure(body);
501 break;
502 case M_DESTROY_WINDOW:
503 list_destroy(body);
504 break;
505 case M_FOCUS_CHANGE:
506 list_focus(body);
507 break;
508 case M_NEW_PAGE:
509 list_new_page(body);
510 break;
511 case M_NEW_DESK:
512 list_new_desk(body);
513 break;
514 case M_RAISE_WINDOW:
515 list_raise(body);
516 break;
517 case M_LOWER_WINDOW:
518 list_lower(body);
519 break;
520 case M_ICONIFY:
521 case M_ICON_LOCATION:
522 list_iconify(body);
523 break;
524 case M_DEICONIFY:
525 list_deiconify(body, length);
526 break;
527 case M_RES_CLASS:
528 case M_RES_NAME:
529 case M_VISIBLE_NAME:
530 list_window_name(body,type);
531 break;
532 case MX_VISIBLE_ICON_NAME:
533 list_icon_name(body);
534 break;
535 case M_MINI_ICON:
536 list_mini_icon(body);
537 break;
538 case M_END_WINDOWLIST:
539 list_end();
540 break;
541 case M_RESTACK:
542 list_restack(body,length);
543 break;
544 case M_CONFIG_INFO:
545 list_config_info(body);
546 break;
547 case MX_PROPERTY_CHANGE:
548 list_property_change(body);
549 break;
550 case MX_REPLY:
551 list_reply(body);
552 break;
553 default:
554 /* ignore unknown packet */
555 break;
562 * Procedure:
563 * SIGPIPE handler - SIGPIPE means fvwm is dying
566 static RETSIGTYPE
567 TerminateHandler(int sig)
569 fvwmSetTerminate(sig);
570 SIGNAL_RETURN;
573 RETSIGTYPE DeadPipe(int nonsense)
575 exit(0);
576 SIGNAL_RETURN;
581 * Procedure:
582 * handle_config_win_package - updates a PagerWindow
583 * with respect to a ConfigWinPacket
585 void handle_config_win_package(PagerWindow *t,
586 ConfigWinPacket *cfgpacket)
588 if (t->w != None && t->w != cfgpacket->w)
590 /* Should never happen */
591 fprintf(stderr,"%s: Error: Internal window list corrupt\n",MyName);
592 /* might be a good idea to exit here */
593 return;
595 t->w = cfgpacket->w;
596 t->frame = cfgpacket->frame;
597 t->frame_x = cfgpacket->frame_x;
598 t->frame_y = cfgpacket->frame_y;
599 t->frame_width = cfgpacket->frame_width;
600 t->frame_height = cfgpacket->frame_height;
602 t->desk = cfgpacket->desk;
604 t->title_height = cfgpacket->title_height;
605 t->border_width = cfgpacket->border_width;
607 t->icon_w = cfgpacket->icon_w;
608 t->icon_pixmap_w = cfgpacket->icon_pixmap_w;
610 memcpy(&(t->flags), &(cfgpacket->flags), sizeof(cfgpacket->flags));
611 memcpy(&(t->allowed_actions), &(cfgpacket->allowed_actions),
612 sizeof(cfgpacket->allowed_actions));
614 if (win_pix_set)
616 t->text = win_fore_pix;
617 t->back = win_back_pix;
619 else
621 t->text = cfgpacket->TextPixel;
622 t->back = cfgpacket->BackPixel;
625 if (IS_ICONIFIED(t))
627 /* For new windows icon_x and icon_y will be zero until
628 * iconify message is recived
630 t->x = t->icon_x;
631 t->y = t->icon_y;
632 t->width = t->icon_width;
633 t->height = t->icon_height;
634 if(IS_ICON_SUPPRESSED(t) || t->width == 0 || t->height == 0)
636 t->x = -32768;
637 t->y = -32768;
640 else
642 t->x = t->frame_x;
643 t->y = t->frame_y;
644 t->width = t->frame_width;
645 t->height = t->frame_height;
651 * Procedure:
652 * list_add - displays packet contents to stderr
655 void list_add(unsigned long *body)
657 PagerWindow *t,**prev;
658 int i=0;
659 struct ConfigWinPacket *cfgpacket = (void *) body;
661 t = Start;
662 prev = &Start;
664 while(t!= NULL)
666 if (t->w == cfgpacket->w)
668 /* it's already there, do nothing */
669 return;
671 prev = &(t->next);
672 t = t->next;
673 i++;
675 *prev = (PagerWindow *)safemalloc(sizeof(PagerWindow));
676 memset(*prev, 0, sizeof(PagerWindow));
677 handle_config_win_package(*prev, cfgpacket);
678 AddNewWindow(*prev);
680 return;
685 * Procedure:
686 * list_configure - displays packet contents to stderr
689 void list_configure(unsigned long *body)
691 PagerWindow *t;
692 Window target_w;
693 struct ConfigWinPacket *cfgpacket = (void *) body;
694 Bool is_new_desk;
696 target_w = cfgpacket->w;
697 t = Start;
698 while((t!= NULL)&&(t->w != target_w))
700 t = t->next;
702 if(t== NULL)
704 list_add(body);
705 return;
708 is_new_desk = (t->desk != cfgpacket->desk);
709 handle_config_win_package(t, cfgpacket);
711 if (is_new_desk)
713 ChangeDeskForWindow(t, cfgpacket->desk);
715 else
717 MoveResizePagerView(t, False);
723 * Procedure:
724 * list_destroy - displays packet contents to stderr
727 void list_destroy(unsigned long *body)
729 PagerWindow *t,**prev;
730 Window target_w;
732 target_w = body[0];
733 t = Start;
734 prev = &Start;
735 while((t!= NULL)&&(t->w != target_w))
737 prev = &(t->next);
738 t = t->next;
740 if(t!= NULL)
742 if(prev != NULL)
743 *prev = t->next;
744 /* remove window from the chain */
745 if(t->PagerView != None)
746 XDestroyWindow(dpy,t->PagerView);
747 XDestroyWindow(dpy,t->IconView);
748 if(FocusWin == t)
749 FocusWin = NULL;
750 if(t->res_class != NULL)
751 free(t->res_class);
752 if(t->res_name != NULL)
753 free(t->res_name);
754 if(t->window_name != NULL)
755 free(t->window_name);
756 if(t->icon_name != NULL)
757 free(t->icon_name);
758 free(t);
764 * Procedure:
765 * list_focus - displays packet contents to stderr
768 void list_focus(unsigned long *body)
770 PagerWindow *t;
771 Window target_w;
772 extern Pixel focus_pix, focus_fore_pix;
773 Bool do_force_update = False;
775 target_w = body[0];
776 if (win_hi_pix_set)
778 if (focus_pix != win_hi_back_pix || focus_fore_pix != win_hi_fore_pix)
780 do_force_update = True;
782 focus_pix = win_hi_back_pix;
783 focus_fore_pix = win_hi_fore_pix;
785 else
787 if (focus_pix != body[4] || focus_fore_pix != body[3])
789 do_force_update = True;
791 focus_pix = body[4];
792 focus_fore_pix = body[3];
794 t = Start;
795 while((t!= NULL)&&(t->w != target_w))
797 t = t->next;
799 if (t != FocusWin || do_force_update)
801 if (FocusWin != NULL)
802 Hilight(FocusWin, False);
803 FocusWin = t;
804 if (FocusWin != NULL)
805 Hilight(FocusWin, True);
811 * Procedure:
812 * list_new_page - displays packet contents to stderr
815 void list_new_page(unsigned long *body)
817 Scr.Vx = body[0];
818 Scr.Vy = body[1];
819 if (Scr.CurrentDesk != body[2])
821 /* first handle the new desk */
822 body[0] = body[2];
823 list_new_desk(body);
825 if (Scr.VxPages != body[5] || Scr.VyPages != body[6])
827 Scr.VxPages = body[5];
828 Scr.VyPages = body[6];
829 Scr.VWidth = Scr.VxPages * Scr.MyDisplayWidth;
830 Scr.VHeight = Scr.VyPages * Scr.MyDisplayHeight;
831 Scr.VxMax = Scr.VWidth - Scr.MyDisplayWidth;
832 Scr.VyMax = Scr.VHeight - Scr.MyDisplayHeight;
833 ReConfigure();
835 MovePage(False);
836 MoveStickyWindow(True, False);
837 Hilight(FocusWin,True);
842 * Procedure:
843 * list_new_desk - displays packet contents to stderr
846 void list_new_desk(unsigned long *body)
848 int oldDesk;
849 int change_cs = -1;
850 int change_ballooncs = -1;
851 int change_highcs = -1;
853 oldDesk = Scr.CurrentDesk;
854 Scr.CurrentDesk = (long)body[0];
855 if (fAlwaysCurrentDesk && oldDesk != Scr.CurrentDesk)
857 PagerWindow *t;
858 PagerStringList *item;
859 char line[100];
861 desk1 = Scr.CurrentDesk;
862 desk2 = Scr.CurrentDesk;
863 for (t = Start; t != NULL; t = t->next)
865 if (t->desk == oldDesk || t->desk == Scr.CurrentDesk)
866 ChangeDeskForWindow(t, t->desk);
868 item = FindDeskStrings(Scr.CurrentDesk);
869 if (Desks[0].label != NULL)
871 free(Desks[0].label);
872 Desks[0].label = NULL;
874 if (item->next != NULL && item->next->label != NULL)
876 CopyString(&Desks[0].label, item->next->label);
878 else
880 sprintf(line, "Desk %d", desk1);
881 CopyString(&Desks[0].label, line);
883 XStoreName(dpy, Scr.Pager_w, Desks[0].label);
884 XSetIconName(dpy, Scr.Pager_w, Desks[0].label);
886 if (Desks[0].bgPixmap != NULL)
888 PDestroyFvwmPicture(dpy, Desks[0].bgPixmap);
889 Desks[0].bgPixmap = NULL;
892 if (Desks[0].Dcolor != NULL)
894 free (Desks[0].Dcolor);
895 Desks[0].Dcolor = NULL;
898 if (item->next != NULL)
900 change_cs = item->next->colorset;
901 change_ballooncs = item->next->ballooncolorset;
902 change_highcs = item->next->highcolorset;
904 if (change_cs < 0)
906 change_cs = globalcolorset;
908 Desks[0].colorset = change_cs;
909 if (change_cs > -1)
911 /* use our colour set if we have one */
912 change_colorset(change_cs);
914 else if (item->next != NULL && item->next->bgPixmap != NULL)
916 Desks[0].bgPixmap = item->next->bgPixmap;
917 Desks[0].bgPixmap->count++;
918 XSetWindowBackgroundPixmap(dpy, Desks[0].w,
919 Desks[0].bgPixmap->picture);
921 else if (item->next != NULL && item->next->Dcolor != NULL)
923 CopyString(&Desks[0].Dcolor, item->next->Dcolor);
924 XSetWindowBackground(dpy, Desks[0].w, GetColor(Desks[0].Dcolor));
926 else if (PixmapBack != NULL)
928 Desks[0].bgPixmap = PixmapBack;
929 Desks[0].bgPixmap->count++;
930 XSetWindowBackgroundPixmap(dpy, Desks[0].w,
931 Desks[0].bgPixmap->picture);
933 else
935 CopyString(&Desks[0].Dcolor, PagerBack);
936 XSetWindowBackground(dpy, Desks[0].w, GetColor(Desks[0].Dcolor));
939 if (item->next != NULL && item->next->Dcolor != NULL)
941 CopyString(&Desks[0].Dcolor, item->next->Dcolor);
943 else
945 CopyString(&Desks[0].Dcolor, PagerBack);
947 if (change_cs < 0 || Colorset[change_cs].pixmap != ParentRelative)
948 XSetWindowBackground(dpy, Desks[0].title_w, GetColor(Desks[0].Dcolor));
950 /* update the colour sets for the desk */
951 if (change_ballooncs < 0)
953 change_ballooncs = globalballooncolorset;
955 Desks[0].ballooncolorset = change_ballooncs;
956 if (change_highcs < 0)
958 change_highcs = globalhighcolorset;
960 Desks[0].highcolorset = change_highcs;
961 if (change_ballooncs > -1 && change_ballooncs != change_cs)
963 change_colorset(change_ballooncs);
965 if (change_highcs > -1 && change_highcs != change_cs &&
966 change_highcs != change_ballooncs)
968 change_colorset(change_highcs);
970 XClearWindow(dpy, Desks[0].w);
971 XClearWindow(dpy, Desks[0].title_w);
972 } /* if (fAlwaysCurrentDesk && oldDesk != Scr.CurrentDesk) */
973 else if (!fAlwaysCurrentDesk)
975 int i;
976 char *name;
977 char line[100];
979 i = Scr.CurrentDesk - desk1;
980 if (i >= 0 && i < ndesks && Desks[i].label != NULL)
982 name = Desks[i].label;
984 else
986 sprintf(line, "Desk %d", Scr.CurrentDesk);
987 name = &(line[0]);
989 XStoreName(dpy, Scr.Pager_w, name);
990 XSetIconName(dpy, Scr.Pager_w, name);
993 MovePage(True);
994 DrawGrid(oldDesk - desk1, 1, None, NULL);
995 DrawGrid(Scr.CurrentDesk - desk1, 1, None, NULL);
996 MoveStickyWindow(False, True);
998 Hilight(FocusWin,False);
1000 Hilight(FocusWin,True);
1005 * Procedure:
1006 * list_raise - displays packet contents to stderr
1009 void list_raise(unsigned long *body)
1011 PagerWindow *t;
1012 Window target_w;
1014 target_w = body[0];
1015 t = Start;
1016 while((t!= NULL)&&(t->w != target_w))
1018 t = t->next;
1020 if(t!= NULL)
1022 if(t->PagerView != None)
1023 XRaiseWindow(dpy,t->PagerView);
1024 XRaiseWindow(dpy,t->IconView);
1031 * Procedure:
1032 * list_lower - displays packet contents to stderr
1035 void list_lower(unsigned long *body)
1037 PagerWindow *t;
1038 Window target_w;
1040 target_w = body[0];
1041 t = Start;
1042 while((t!= NULL)&&(t->w != target_w))
1044 t = t->next;
1046 if(t!= NULL)
1048 if(t->PagerView != None)
1049 XLowerWindow(dpy,t->PagerView);
1050 if (HilightDesks && (t->desk - desk1>=0) && (t->desk - desk1<ndesks))
1051 XLowerWindow(dpy,Desks[t->desk - desk1].CPagerWin);
1052 XLowerWindow(dpy,t->IconView);
1059 * Procedure:
1060 * list_iconify - displays packet contents to stderr
1063 void list_iconify(unsigned long *body)
1065 PagerWindow *t;
1066 Window target_w;
1068 target_w = body[0];
1069 t = Start;
1070 while (t != NULL && t->w != target_w)
1072 t = t->next;
1074 if (t != NULL)
1076 t->t = (char *)body[2];
1077 t->frame = body[1];
1078 t->icon_x = body[3];
1079 t->icon_y = body[4];
1080 t->icon_width = body[5];
1081 t->icon_height = body[6];
1082 SET_ICONIFIED(t, True);
1083 if (IS_ICON_SUPPRESSED(t) || t->icon_width == 0 ||
1084 t->icon_height == 0)
1086 t->x = -32768;
1087 t->y = -32768;
1089 else
1091 t->x = t->icon_x;
1092 t->y = t->icon_y;
1094 t->width = t->icon_width;
1095 t->height = t->icon_height;
1096 /* if iconifying main pager window turn balloons on or off */
1097 if ( t->w == Scr.Pager_w )
1099 ShowBalloons = ShowIconBalloons;
1101 MoveResizePagerView(t, True);
1104 return;
1110 * Procedure:
1111 * list_deiconify - displays packet contents to stderr
1115 void list_deiconify(unsigned long *body, unsigned long length)
1117 PagerWindow *t;
1118 Window target_w;
1120 target_w = body[0];
1121 t = Start;
1122 while((t!= NULL)&&(t->w != target_w))
1124 t = t->next;
1126 if (t == NULL)
1128 return;
1130 else
1132 SET_ICONIFIED(t, False);
1133 if (length >= 11 + FvwmPacketHeaderSize)
1135 t->frame_x = body[7];
1136 t->frame_y = body[8];
1137 t->frame_width = body[9];
1138 t->frame_height = body[10];
1140 t->x = t->frame_x;
1141 t->y = t->frame_y;
1142 t->width = t->frame_width;
1143 t->height = t->frame_height;
1145 /* if deiconifying main pager window turn balloons on or off */
1146 if ( t->w == Scr.Pager_w )
1147 ShowBalloons = ShowPagerBalloons;
1149 MoveResizePagerView(t, True);
1152 return;
1156 void list_window_name(unsigned long *body,unsigned long type)
1158 PagerWindow *t;
1159 Window target_w;
1161 target_w = body[0];
1162 t = Start;
1163 while((t!= NULL)&&(t->w != target_w))
1165 t = t->next;
1167 if(t!= NULL)
1169 switch (type) {
1170 case M_RES_CLASS:
1171 if(t->res_class != NULL)
1172 free(t->res_class);
1173 CopyString(&t->res_class,(char *)(&body[3]));
1174 break;
1175 case M_RES_NAME:
1176 if(t->res_name != NULL)
1177 free(t->res_name);
1178 CopyString(&t->res_name,(char *)(&body[3]));
1179 break;
1180 case M_VISIBLE_NAME:
1181 if(t->window_name != NULL)
1182 free(t->window_name);
1183 CopyString(&t->window_name,(char *)(&body[3]));
1184 break;
1186 /* repaint by clearing window */
1187 if ((FwindowFont != NULL) && (t->icon_name != NULL)
1188 && !(MiniIcons && t->mini_icon.picture)) {
1189 if (t->PagerView)
1190 XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True);
1191 if (t->IconView);
1192 XClearArea(dpy, t->IconView, 0, 0, 0, 0, True);
1194 if (ShowBalloons && BalloonView)
1196 /* update balloons */
1197 if (BalloonView == t->PagerView)
1199 UnmapBalloonWindow();
1200 MapBalloonWindow(t, False);
1202 else if (BalloonView == t->IconView)
1204 UnmapBalloonWindow();
1205 MapBalloonWindow(t, True);
1213 * Procedure:
1214 * list_icon_name - displays packet contents to stderr
1217 void list_icon_name(unsigned long *body)
1219 PagerWindow *t;
1220 Window target_w;
1222 target_w = body[0];
1223 t = Start;
1224 while((t!= NULL)&&(t->w != target_w))
1226 t = t->next;
1228 if(t!= NULL)
1230 if(t->icon_name != NULL)
1231 free(t->icon_name);
1232 CopyString(&t->icon_name,(char *)(&body[3]));
1233 /* repaint by clearing window */
1234 if ((FwindowFont != NULL) && (t->icon_name != NULL)
1235 && !(MiniIcons && t->mini_icon.picture)) {
1236 if (t->PagerView)
1237 XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True);
1238 if (t->IconView);
1239 XClearArea(dpy, t->IconView, 0, 0, 0, 0, True);
1245 void list_mini_icon(unsigned long *body)
1247 PagerWindow *t;
1248 Window target_w;
1249 MiniIconPacket *mip = (MiniIconPacket *) body;
1251 target_w = body[0];
1252 t = Start;
1253 while (t && (t->w != mip->w))
1254 t = t->next;
1255 if (t)
1257 t->mini_icon.width = mip->width;
1258 t->mini_icon.height = mip->height;
1259 t->mini_icon.depth = mip->depth;
1260 t->mini_icon.picture = mip->picture;
1261 t->mini_icon.mask = mip->mask;
1262 t->mini_icon.alpha = mip->alpha;
1263 /* repaint by clearing window */
1264 if (MiniIcons && t->mini_icon.picture) {
1265 if (t->PagerView)
1266 XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True);
1267 if (t->IconView);
1268 XClearArea(dpy, t->IconView, 0, 0, 0, 0, True);
1273 void list_restack(unsigned long *body, unsigned long length)
1275 PagerWindow *t;
1276 Window target_w;
1277 Window *wins;
1278 int i, j, d;
1280 wins = (Window *) safemalloc (length * sizeof (Window));
1281 /* first restack in the icon view */
1282 j = 0;
1283 for (i = 0; i < (length - FvwmPacketHeaderSize); i += 3)
1285 target_w = body[i];
1286 t = Start;
1287 while((t!= NULL)&&(t->w != target_w))
1289 t = t->next;
1291 if (t != NULL)
1293 wins[j++] = t->IconView;
1296 XRestackWindows(dpy, wins, j);
1298 /* now restack each desk separately, since they have separate roots */
1299 for (d = 0; d < ndesks; d++)
1301 j = 0;
1302 for (i = 0; i < (length - 4); i+=3)
1304 target_w = body[i];
1305 t = Start;
1306 while((t!= NULL)&&((t->w != target_w)||(t->desk != d+desk1)))
1308 t = t->next;
1310 if (t != NULL)
1312 if (t->PagerView != None)
1314 wins[j++] = t->PagerView;
1318 XRestackWindows(dpy, wins, j);
1320 free (wins);
1326 * Procedure:
1327 * list_end - displays packet contents to stderr
1330 void list_end(void)
1332 unsigned int nchildren,i;
1333 Window root, parent, *children;
1334 PagerWindow *ptr;
1336 if(!XQueryTree(dpy, Scr.Root, &root, &parent, &children,
1337 &nchildren))
1338 return;
1340 for(i=0; i<nchildren;i++)
1342 ptr = Start;
1343 while(ptr != NULL)
1345 if((ptr->frame == children[i])||(ptr->icon_w == children[i])||
1346 (ptr->icon_pixmap_w == children[i]))
1348 if(ptr->PagerView != None)
1349 XRaiseWindow(dpy,ptr->PagerView);
1350 XRaiseWindow(dpy,ptr->IconView);
1352 ptr = ptr->next;
1357 if(nchildren > 0)
1358 XFree((char *)children);
1362 void list_config_info(unsigned long *body)
1364 char *tline, *token;
1365 int color;
1367 tline = (char*)&(body[3]);
1368 token = PeekToken(tline, &tline);
1369 if (StrEquals(token, "Colorset"))
1371 color = LoadColorset(tline);
1372 change_colorset(color);
1374 else if (StrEquals(token, XINERAMA_CONFIG_STRING))
1376 FScreenConfigureModule(tline);
1378 else if (StrEquals(token, "DesktopName"))
1380 int val;
1381 if (GetIntegerArguments(tline, &tline, &val, 1) > 0)
1383 SetDeskLabel(val, (const char *)tline);
1385 else
1387 return;
1389 if (fAlwaysCurrentDesk)
1391 if (Scr.CurrentDesk == val)
1392 val = 0;
1394 else if ((val >= desk1) && (val <=desk2))
1396 val = val - desk1;
1398 DrawGrid(val, True, None, NULL);
1402 void list_property_change(unsigned long *body)
1404 if (body[0] == MX_PROPERTY_CHANGE_BACKGROUND)
1407 if (((!Swallowed && body[2] == 0) || (Swallowed && body[2] == Scr.Pager_w)))
1409 update_pr_transparent_windows();
1412 else if (body[0] == MX_PROPERTY_CHANGE_SWALLOW && body[2] == Scr.Pager_w)
1414 Swallowed = body[1];
1419 void list_reply(unsigned long *body)
1421 char *tline;
1422 tline = (char*)&(body[3]);
1423 if (strcmp(tline, "ScrollDone") == 0)
1425 HandleScrollDone();
1431 * Waits for next X event, or for an auto-raise timeout.
1434 int My_XNextEvent(Display *dpy, XEvent *event)
1436 fd_set in_fdset;
1437 static int miss_counter = 0;
1439 if(FPending(dpy))
1441 FNextEvent(dpy,event);
1442 return 1;
1445 FD_ZERO(&in_fdset);
1446 FD_SET(x_fd,&in_fdset);
1447 FD_SET(fd[1],&in_fdset);
1449 if (fvwmSelect(fd_width, &in_fdset, 0, 0, NULL) > 0)
1451 if(FD_ISSET(x_fd, &in_fdset))
1453 if(FPending(dpy))
1455 FNextEvent(dpy,event);
1456 miss_counter = 0;
1457 return 1;
1459 miss_counter++;
1460 #ifdef WORRY_ABOUT_MISSED_XEVENTS
1461 if(miss_counter > 100)
1462 DeadPipe(0);
1463 #endif
1466 if(FD_ISSET(fd[1], &in_fdset))
1468 FvwmPacket* packet = ReadFvwmPacket(fd[1]);
1469 if ( packet == NULL )
1470 exit(0);
1471 process_message( packet );
1474 return 0;
1479 /* This function is really tricky. The two offsets are the offsets of the
1480 * colorset members of the DeskInfo and PagerSringList structures to be
1481 * modified. The lines accessing this info look very ugly, but they work. */
1482 static void ParseColorset(char *arg1, char *arg2, void *offset_deskinfo,
1483 void *offset_item, int *colorset_global)
1485 Bool all_desks = False;
1486 int colorset = 0;
1487 int i;
1488 int desk;
1489 unsigned long colorset_offset = (unsigned long)offset_deskinfo;
1490 unsigned long item_colorset_offset = (unsigned long)offset_item;
1492 sscanf(arg2, "%d", &colorset);
1493 AllocColorset(colorset);
1494 if (StrEquals(arg1, "*"))
1496 all_desks = True;
1497 desk = Scr.CurrentDesk;
1499 else
1501 desk = desk1;
1502 sscanf(arg1,"%d",&desk);
1504 if (fAlwaysCurrentDesk)
1506 if (all_desks)
1508 *colorset_global = colorset;
1510 else
1512 PagerStringList *item;
1514 item = FindDeskStrings(desk);
1515 if (item->next != NULL)
1517 *(int *)(((char *)(item->next)) + item_colorset_offset) = colorset;
1519 else
1521 /* new Dcolor and desktop */
1522 item = NewPagerStringItem(item, desk);
1523 *(int *)(((char *)item) + item_colorset_offset) = colorset;
1526 if (desk == Scr.CurrentDesk || all_desks)
1528 *(int *)(((char *)&Desks[0]) + colorset_offset) = colorset;
1531 else if (all_desks)
1533 for (i = 0; i < ndesks; i++)
1535 *(int *)(((char *)&Desks[i]) + colorset_offset) = colorset;
1538 else if((desk >= desk1)&&(desk <=desk2))
1540 *(int *)(((char *)&Desks[desk - desk1]) + colorset_offset) = colorset;
1543 return;
1546 static void SetDeskLabel(int desk, const char *label)
1548 PagerStringList *item;
1550 if (fAlwaysCurrentDesk)
1552 item = FindDeskStrings(desk);
1553 if (item->next != NULL)
1555 /* replace label */
1556 if (item->next->label != NULL)
1558 free(item->next->label);
1559 item->next->label = NULL;
1561 CopyString(&(item->next->label), label);
1563 else
1565 /* new Dcolor and desktop */
1566 item = NewPagerStringItem(item, desk);
1567 CopyString(&(item->label), label);
1569 if (desk == Scr.CurrentDesk)
1571 free(Desks[0].label);
1572 CopyString(&Desks[0].label, label);
1575 else if((desk >= desk1)&&(desk <=desk2))
1577 free(Desks[desk - desk1].label);
1578 CopyString(&Desks[desk - desk1].label, label);
1584 * This routine is responsible for reading and parsing the config file
1587 void ParseOptions(void)
1589 char *tline= NULL;
1590 int desk;
1591 int dx = 3;
1592 int dy = 3;
1593 FvwmPictureAttributes fpa;
1594 Scr.FvwmRoot = NULL;
1595 Scr.Hilite = NULL;
1596 Scr.VScale = 32;
1598 Scr.MyDisplayWidth = DisplayWidth(dpy, Scr.screen);
1599 Scr.MyDisplayHeight = DisplayHeight(dpy, Scr.screen);
1601 fpa.mask = 0;
1602 if (Pdepth <= 8)
1604 fpa.mask |= FPAM_DITHER;
1606 InitGetConfigLine(fd,CatString3("*",MyName,0));
1607 for (GetConfigLine(fd,&tline); tline != NULL; GetConfigLine(fd,&tline))
1609 int g_x, g_y, flags;
1610 unsigned width,height;
1611 char *resource;
1612 char *arg1;
1613 char *arg2;
1614 char *tline2;
1615 char *token;
1616 char *next;
1617 Bool MoveThresholdSetForModule = False;
1619 arg1 = arg2 = NULL;
1621 token = PeekToken(tline, &next);
1622 if (StrEquals(token, "Colorset"))
1624 LoadColorset(next);
1625 continue;
1627 else if (StrEquals(token, XINERAMA_CONFIG_STRING))
1629 FScreenConfigureModule(next);
1631 else if (StrEquals(token, "DesktopSize"))
1633 token = PeekToken(next, &next);
1634 if (token)
1636 sscanf(token, "%d", &dx);
1637 token = PeekToken(next, &next);
1638 if (token)
1639 sscanf(token, "%d", &dy);
1641 continue;
1643 else if (StrEquals(token, "ImagePath"))
1645 if (ImagePath != NULL)
1647 free(ImagePath);
1648 ImagePath = NULL;
1650 GetNextToken(next, &ImagePath);
1652 continue;
1654 else if (StrEquals(token, "MoveThreshold"))
1656 if (!MoveThresholdSetForModule)
1658 int val;
1659 if (GetIntegerArguments(next, NULL, &val, 1) > 0)
1661 if (val >= 0)
1662 MoveThreshold = val;
1663 else
1664 MoveThreshold = DEFAULT_PAGER_MOVE_THRESHOLD;
1667 continue;
1669 else if (StrEquals(token, "DesktopName"))
1671 int val;
1672 if (GetIntegerArguments(next, &next, &val, 1) > 0)
1674 SetDeskLabel(val, (const char *)next);
1676 continue;
1679 tline2 = GetModuleResource(tline, &resource, MyName);
1680 if (!resource)
1681 continue;
1682 tline2 = GetNextToken(tline2, &arg1);
1683 if (!arg1)
1685 arg1 = (char *)safemalloc(1);
1686 arg1[0] = 0;
1688 tline2 = GetNextToken(tline2, &arg2);
1689 if (!arg2)
1691 arg2 = (char *)safemalloc(1);
1692 arg2[0] = 0;
1695 if(StrEquals(resource,"Colorset"))
1697 ParseColorset(arg1, arg2,
1698 &(((DeskInfo *)(NULL))->colorset),
1699 &(((PagerStringList *)(NULL))->colorset),
1700 &globalcolorset);
1702 else if(StrEquals(resource,"BalloonColorset"))
1704 ParseColorset(arg1, arg2,
1705 &(((DeskInfo *)(NULL))->ballooncolorset),
1706 &(((PagerStringList *)(NULL))->ballooncolorset),
1707 &globalballooncolorset);
1709 else if(StrEquals(resource,"HilightColorset"))
1711 ParseColorset(arg1, arg2,
1712 &(((DeskInfo *)(NULL))->highcolorset),
1713 &(((PagerStringList *)(NULL))->highcolorset),
1714 &globalhighcolorset);
1716 else if (StrEquals(resource, "Geometry"))
1718 window_w = 0;
1719 window_h = 0;
1720 window_x = 0;
1721 window_y = 0;
1722 xneg = 0;
1723 yneg = 0;
1724 usposition = 0;
1725 flags = FScreenParseGeometry(arg1,&g_x,&g_y,&width,&height);
1726 if (flags & WidthValue)
1728 window_w = width;
1730 if (flags & HeightValue)
1732 window_h = height;
1734 if (flags & XValue)
1736 window_x = g_x;
1737 usposition = 1;
1738 if (flags & XNegative)
1740 xneg = 1;
1743 if (flags & YValue)
1745 window_y = g_y;
1746 usposition = 1;
1747 if (flags & YNegative)
1749 yneg = 1;
1753 else if (StrEquals(resource, "IconGeometry"))
1755 icon_w = 0;
1756 icon_h = 0;
1757 icon_x = -10000;
1758 icon_y = -10000;
1759 icon_xneg = 0;
1760 icon_yneg = 0;
1761 flags = FScreenParseGeometry(arg1,&g_x,&g_y,&width,&height);
1762 if (flags & WidthValue)
1763 icon_w = width;
1764 if (flags & HeightValue)
1765 icon_h = height;
1766 if (flags & XValue)
1768 icon_x = g_x;
1769 if (flags & XNegative)
1771 icon_xneg = 1;
1774 if (flags & YValue)
1776 icon_y = g_y;
1777 if (flags & YNegative)
1779 icon_yneg = 1;
1783 else if (StrEquals(resource, "Label"))
1785 if (StrEquals(arg1, "*"))
1787 desk = Scr.CurrentDesk;
1789 else
1791 desk = desk1;
1792 sscanf(arg1,"%d",&desk);
1794 SetDeskLabel(desk, (const char *)arg2);
1796 else if (StrEquals(resource, "Font"))
1798 if (font_string)
1799 free(font_string);
1800 CopyStringWithQuotes(&font_string, next);
1801 if(strncasecmp(font_string,"none",4) == 0)
1803 uselabel = 0;
1804 if (font_string)
1806 free(font_string);
1807 font_string = NULL;
1811 else if (StrEquals(resource, "Fore"))
1813 if(Pdepth > 1)
1815 if (PagerFore)
1816 free(PagerFore);
1817 CopyString(&PagerFore,arg1);
1820 else if (StrEquals(resource, "Back"))
1822 if(Pdepth > 1)
1824 if (PagerBack)
1825 free(PagerBack);
1826 CopyString(&PagerBack,arg1);
1829 else if (StrEquals(resource, "DeskColor"))
1831 if (StrEquals(arg1, "*"))
1833 desk = Scr.CurrentDesk;
1835 else
1837 desk = desk1;
1838 sscanf(arg1,"%d",&desk);
1840 if (fAlwaysCurrentDesk)
1842 PagerStringList *item;
1844 item = FindDeskStrings(desk);
1845 if (item->next != NULL)
1847 /* replace Dcolor */
1848 if (item->next->Dcolor != NULL)
1850 free(item->next->Dcolor);
1851 item->next->Dcolor = NULL;
1853 CopyString(&(item->next->Dcolor), arg2);
1855 else
1857 /* new Dcolor and desktop */
1858 item = NewPagerStringItem(item, desk);
1859 CopyString(&(item->Dcolor), arg2);
1861 if (desk == Scr.CurrentDesk)
1863 free(Desks[0].Dcolor);
1864 CopyString(&Desks[0].Dcolor, arg2);
1867 else if((desk >= desk1)&&(desk <=desk2))
1869 free(Desks[desk - desk1].Dcolor);
1870 CopyString(&Desks[desk - desk1].Dcolor, arg2);
1873 else if (StrEquals(resource, "DeskPixmap"))
1875 if (StrEquals(arg1, "*"))
1877 desk = Scr.CurrentDesk;
1879 else
1881 desk = desk1;
1882 sscanf(arg1,"%d",&desk);
1884 if (fAlwaysCurrentDesk)
1886 PagerStringList *item;
1888 item = FindDeskStrings(desk);
1890 if (item->next != NULL)
1892 if (item->next->bgPixmap != NULL)
1894 PDestroyFvwmPicture(dpy, item->next->bgPixmap);
1895 item->next->bgPixmap = NULL;
1897 item->next->bgPixmap = PCacheFvwmPicture(
1898 dpy, Scr.Pager_w, ImagePath, arg2, fpa);
1900 else
1902 /* new Dcolor and desktop */
1903 item = NewPagerStringItem(item, desk);
1904 item->bgPixmap = PCacheFvwmPicture(
1905 dpy, Scr.Pager_w, ImagePath, arg2, fpa);
1907 if (desk == Scr.CurrentDesk)
1909 if (Desks[0].bgPixmap != NULL)
1911 PDestroyFvwmPicture(dpy, Desks[0].bgPixmap);
1912 Desks[0].bgPixmap = NULL;
1915 Desks[0].bgPixmap = PCacheFvwmPicture(
1916 dpy, Scr.Pager_w, ImagePath, arg2, fpa);
1919 else if((desk >= desk1)&&(desk <=desk2))
1921 int dNr = desk - desk1;
1923 if (Desks[dNr].bgPixmap != NULL)
1925 PDestroyFvwmPicture(dpy, Desks[dNr].bgPixmap);
1926 Desks[dNr].bgPixmap = NULL;
1928 Desks[dNr].bgPixmap = PCacheFvwmPicture(
1929 dpy, Scr.Pager_w, ImagePath, arg2, fpa);
1933 else if (StrEquals(resource, "Pixmap"))
1935 if(Pdepth > 1)
1937 if (PixmapBack) {
1938 PDestroyFvwmPicture (dpy, PixmapBack);
1939 PixmapBack = NULL;
1942 PixmapBack = PCacheFvwmPicture(
1943 dpy, Scr.Pager_w, ImagePath, arg1, fpa);
1947 else if (StrEquals(resource, "HilightPixmap"))
1949 if(Pdepth > 1)
1951 if (HilightPixmap) {
1952 PDestroyFvwmPicture (dpy, HilightPixmap);
1953 HilightPixmap = NULL;
1956 HilightPixmap = PCacheFvwmPicture (
1957 dpy, Scr.Pager_w, ImagePath, arg1, fpa);
1961 else if (StrEquals(resource, "DeskHilight"))
1963 HilightDesks = 1;
1965 else if (StrEquals(resource, "NoDeskHilight"))
1967 HilightDesks = 0;
1969 else if (StrEquals(resource, "Hilight"))
1971 if(Pdepth > 1)
1973 if (HilightC)
1974 free(HilightC);
1975 CopyString(&HilightC,arg1);
1978 else if (StrEquals(resource, "SmallFont"))
1980 if (smallFont)
1981 free(smallFont);
1982 CopyStringWithQuotes(&smallFont, next);
1983 if (strncasecmp(smallFont,"none",4) == 0)
1985 free(smallFont);
1986 smallFont = NULL;
1989 else if (StrEquals(resource, "MiniIcons"))
1991 MiniIcons = 1;
1993 else if (StrEquals(resource, "StartIconic"))
1995 StartIconic = 1;
1997 else if (StrEquals(resource, "NoStartIconic"))
1999 StartIconic = 0;
2001 else if (StrEquals(resource, "LabelsBelow"))
2003 LabelsBelow = 1;
2005 else if (StrEquals(resource, "LabelsAbove"))
2007 LabelsBelow = 0;
2009 else if (FHaveShapeExtension && StrEquals(resource, "ShapeLabels"))
2011 ShapeLabels = 1;
2013 else if (FHaveShapeExtension && StrEquals(resource, "NoShapeLabels"))
2015 ShapeLabels = 0;
2017 else if (StrEquals(resource, "Rows"))
2019 sscanf(arg1,"%d",&Rows);
2021 else if (StrEquals(resource, "Columns"))
2023 sscanf(arg1,"%d",&Columns);
2025 else if (StrEquals(resource, "DeskTopScale"))
2027 sscanf(arg1,"%d",&Scr.VScale);
2029 else if (StrEquals(resource, "WindowColors"))
2031 if (Pdepth > 1)
2033 if (WindowFore)
2034 free(WindowFore);
2035 if (WindowBack)
2036 free(WindowBack);
2037 if (WindowHiFore)
2038 free(WindowHiFore);
2039 if (WindowHiBack)
2040 free(WindowHiBack);
2041 CopyString(&WindowFore, arg1);
2042 CopyString(&WindowBack, arg2);
2043 tline2 = GetNextToken(tline2, &WindowHiFore);
2044 GetNextToken(tline2, &WindowHiBack);
2047 else if (StrEquals(resource, "WindowBorderWidth"))
2049 sscanf(arg1, "%d", &WindowBorderWidth);
2050 MinSize = 2 * WindowBorderWidth + 1;
2052 else if (StrEquals(resource, "Window3dBorders"))
2054 WindowBorders3d = True;
2056 else if (StrEquals(resource,"WindowColorsets"))
2058 sscanf(arg1,"%d",&windowcolorset);
2059 AllocColorset(windowcolorset);
2060 sscanf(arg2,"%d",&activecolorset);
2061 AllocColorset(activecolorset);
2063 else if (StrEquals(resource,"WindowLabelFormat"))
2065 if (WindowLabelFormat)
2066 free(WindowLabelFormat);
2067 CopyString(&WindowLabelFormat,arg1);
2069 else if (StrEquals(resource,"UseSkipList"))
2071 UseSkipList = True;
2073 else if (StrEquals(resource, "MoveThreshold"))
2075 int val;
2076 if (GetIntegerArguments(next, NULL, &val, 1) > 0 && val >= 0)
2078 MoveThreshold = val;
2079 MoveThresholdSetForModule = True;
2082 else if (StrEquals(resource, "SloppyFocus"))
2084 do_focus_on_enter = True;
2086 else if (StrEquals(resource, "SolidSeparators"))
2088 use_dashed_separators = False;
2089 use_no_separators = False;
2091 else if (StrEquals(resource, "NoSeparators"))
2093 use_no_separators = True;
2095 /* ... and get Balloon config options ...
2096 -- ric@giccs.georgetown.edu */
2097 else if (StrEquals(resource, "Balloons"))
2099 if (BalloonTypeString)
2100 free(BalloonTypeString);
2101 CopyString(&BalloonTypeString, arg1);
2103 if ( strncasecmp(BalloonTypeString, "Pager", 5) == 0 ) {
2104 ShowPagerBalloons = 1;
2105 ShowIconBalloons = 0;
2107 else if ( strncasecmp(BalloonTypeString, "Icon", 4) == 0 ) {
2108 ShowPagerBalloons = 0;
2109 ShowIconBalloons = 1;
2111 else {
2112 ShowPagerBalloons = 1;
2113 ShowIconBalloons = 1;
2116 /* turn this on initially so balloon window is created; later this
2117 variable is changed to match ShowPagerBalloons or ShowIconBalloons
2118 whenever we receive iconify or deiconify packets */
2119 ShowBalloons = 1;
2122 else if (StrEquals(resource, "BalloonBack"))
2124 if (Pdepth > 1)
2126 if (BalloonBack)
2127 free(BalloonBack);
2128 CopyString(&BalloonBack, arg1);
2132 else if (StrEquals(resource, "BalloonFore"))
2134 if (Pdepth > 1)
2136 if (BalloonFore)
2137 free(BalloonFore);
2138 CopyString(&BalloonFore, arg1);
2142 else if (StrEquals(resource, "BalloonFont"))
2144 if (BalloonFont)
2145 free(BalloonFont);
2146 CopyStringWithQuotes(&BalloonFont, next);
2149 else if (StrEquals(resource, "BalloonBorderColor"))
2151 if (BalloonBorderColor)
2152 free(BalloonBorderColor);
2153 CopyString(&BalloonBorderColor, arg1);
2156 else if (StrEquals(resource, "BalloonBorderWidth"))
2158 sscanf(arg1, "%d", &BalloonBorderWidth);
2161 else if (StrEquals(resource, "BalloonYOffset"))
2163 sscanf(arg1, "%d", &BalloonYOffset);
2164 if (BalloonYOffset == 0)
2166 fprintf(stderr,
2167 "%s: Warning:"
2168 " you're not allowed BalloonYOffset 0; defaulting to +3\n",
2169 MyName);
2170 /* we don't allow yoffset of 0 because it allows direct transit from
2171 * pager window to balloon window, setting up a LeaveNotify/EnterNotify
2172 * event loop */
2173 BalloonYOffset = 3;
2176 else if (StrEquals(resource,"BalloonStringFormat"))
2178 if (BalloonFormatString)
2179 free(BalloonFormatString);
2180 CopyString(&BalloonFormatString,arg1);
2183 free(resource);
2184 free(arg1);
2185 free(arg2);
2188 Scr.VxMax = dx * Scr.MyDisplayWidth - Scr.MyDisplayWidth;
2189 Scr.VyMax = dy * Scr.MyDisplayHeight - Scr.MyDisplayHeight;
2190 if (Scr.VxMax < 0)
2191 Scr.VxMax = 0;
2192 if (Scr.VyMax < 0)
2193 Scr.VyMax = 0;
2194 Scr.VWidth = Scr.VxMax + Scr.MyDisplayWidth;
2195 Scr.VHeight = Scr.VyMax + Scr.MyDisplayHeight;
2196 Scr.VxPages = Scr.VWidth / Scr.MyDisplayWidth;
2197 Scr.VyPages = Scr.VHeight / Scr.MyDisplayHeight;
2198 Scr.Vx = 0;
2199 Scr.Vy = 0;
2201 return;
2204 /* Returns the item in the sring list that has item->next->desk == desk or
2205 * the last item (item->next == NULL) if no entry matches the desk number. */
2206 PagerStringList *FindDeskStrings(int desk)
2208 PagerStringList *item;
2210 item = &string_list;
2211 while (item->next != NULL)
2213 if (item->next->desk == desk)
2214 break;
2215 item = item->next;
2217 return item;
2220 PagerStringList *NewPagerStringItem(PagerStringList *last, int desk)
2222 PagerStringList *newitem;
2224 newitem = (PagerStringList *)safemalloc(sizeof(PagerStringList));
2225 memset(newitem, 0, sizeof(PagerStringList));
2226 last->next = newitem;
2227 newitem->colorset = -1;
2228 newitem->highcolorset = -1;
2229 newitem->ballooncolorset = -1;
2230 newitem->desk = desk;
2232 return newitem;
2235 void ExitPager(void)
2237 if (is_transient)
2239 XUngrabPointer(dpy,CurrentTime);
2240 MyXUngrabServer(dpy);
2241 XSync(dpy,0);
2243 XUngrabKeyboard(dpy, CurrentTime);
2244 exit(0);