3 * This module is all new
7 /* This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * fvwm pager handling code
34 #include <X11/Xutil.h>
35 #include <X11/Xproto.h>
36 #include <X11/Xatom.h>
37 #include <X11/Intrinsic.h>
38 #include <X11/keysym.h>
40 #include "libs/fvwmlib.h"
41 #include "libs/FScreen.h"
42 #include "libs/FShape.h"
43 #include "libs/Module.h"
44 #include "libs/Colorset.h"
45 #include "libs/Graphics.h"
46 #include "fvwm/fvwm.h"
47 #include "libs/PictureGraphics.h"
48 #include "FvwmPager.h"
51 extern ScreenInfo Scr
;
54 Pixel back_pix
, fore_pix
, hi_pix
;
57 extern int windowcolorset
, activecolorset
;
58 extern Pixel win_back_pix
, win_fore_pix
, win_hi_back_pix
, win_hi_fore_pix
;
59 extern Bool win_pix_set
, win_hi_pix_set
;
60 extern int window_w
, window_h
,window_x
,window_y
,usposition
,uselabel
,xneg
,yneg
;
61 extern int StartIconic
;
63 extern int LabelsBelow
;
64 extern int ShapeLabels
;
65 extern int ShowBalloons
, ShowPagerBalloons
, ShowIconBalloons
;
66 extern char *BalloonFormatString
;
67 extern char *WindowLabelFormat
;
68 extern char *PagerFore
, *PagerBack
, *HilightC
;
69 extern char *BalloonFore
, *BalloonBack
, *BalloonBorderColor
;
70 extern Window BalloonView
;
71 extern unsigned int WindowBorderWidth
;
72 extern unsigned int MinSize
;
73 extern Bool WindowBorders3d
;
74 extern Bool UseSkipList
;
75 extern FvwmPicture
*PixmapBack
;
76 extern FvwmPicture
*HilightPixmap
;
77 extern int HilightDesks
;
78 extern char fAlwaysCurrentDesk
;
80 extern int MoveThreshold
;
82 extern int icon_w
, icon_h
, icon_x
, icon_y
, icon_xneg
, icon_yneg
;
83 FlocaleFont
*Ffont
, *FwindowFont
;
84 FlocaleWinString
*FwinString
;
86 extern PagerWindow
*Start
;
87 extern PagerWindow
*FocusWin
;
88 static Atom wm_del_win
;
92 extern int desk1
, desk2
, ndesks
;
93 extern int Rows
,Columns
;
102 int FvwmErrorHandler(Display
*, XErrorEvent
*);
103 extern Bool is_transient
;
104 extern Bool do_ignore_next_button_release
;
105 extern Bool use_dashed_separators
;
106 extern Bool use_no_separators
;
109 /* assorted gray bitmaps for decorative borders */
112 static char g_bits
[] = {0x02, 0x01};
116 static char l_g_bits
[] = {0x08, 0x02};
120 static char s_g_bits
[] = {0x01, 0x02, 0x04, 0x08};
123 Window icon_win
; /* icon window */
125 static int MyVx
, MyVy
; /* copy of Scr.Vx/y for drag logic */
127 static char *GetBalloonLabel(const PagerWindow
*pw
,const char *fmt
);
128 extern void ExitPager(void);
130 Pixmap default_pixmap
= None
;
133 #define MYFPRINTF(X) \
141 #define MAX_UNPROCESSED_MESSAGES 1
142 /* sums up pixels to scroll. If do_send_message is True a Scroll command is
143 * sent back to fvwm. The function shall be called with is_message_recieved
144 * True when the Scroll command has been processed by fvwm. This is checked
145 * by talking to ourself. */
146 static void do_scroll(int sx
, int sy
, Bool do_send_message
,
147 Bool is_message_recieved
)
151 static int messages_sent
= 0;
155 if (is_message_recieved
)
157 /* There might be other modules with the same name, or someone
158 might send ScrollDone other than the module, so just treat
159 any negative count as zero. */
160 if (--messages_sent
< 0)
165 if ((do_send_message
|| messages_sent
< MAX_UNPROCESSED_MESSAGES
) &&
166 ( psx
!= 0 || psy
!= 0 ))
168 sprintf(command
, "Scroll %dp %dp", psx
, psy
);
169 SendText(fd
, command
, 0);
171 SendText(fd
, "Send_Reply ScrollDone", 0);
177 void HandleScrollDone(void)
179 do_scroll(0, 0, True
, True
);
182 /* discard certain events on a window */
183 static void discard_events(long event_type
, Window w
, XEvent
*last_ev
)
188 while (FCheckTypedWindowEvent(dpy
, w
, event_type
, &e
))
193 memcpy(last_ev
, &e
, sizeof(XEvent
));
203 * CalcGeom - calculates the size and position of a mini-window
204 * given the real window size.
205 * You can always tell bad code by the size of the comments.
207 static void CalcGeom(PagerWindow
*t
, int win_w
, int win_h
,
208 int *x_ret
, int *y_ret
, int *w_ret
, int *h_ret
)
210 int virt
, virt2
, edge
, edge2
, size
, page
, over
;
212 /* coordinate of left hand edge on virtual desktop */
213 virt
= Scr
.Vx
+ t
->x
;
215 /* position of left hand edge of mini-window on pager window */
216 edge
= (virt
* win_w
) / Scr
.VWidth
;
218 /* absolute coordinate of right hand edge on virtual desktop */
219 virt
+= t
->width
- 1;
221 /* to calculate the right edge, mirror the window and use the same
222 * calculations as for the left edge for consistency. */
223 virt2
= Scr
.VWidth
- 1 - virt
;
224 edge2
= (virt2
* win_w
) / Scr
.VWidth
;
226 /* then mirror it back to get the real coordinate */
227 edge2
= win_w
- 1 - edge2
;
229 /* Calculate the mini-window's width by subtracting its LHS
230 * from its RHS. This theoretically means that the width will
231 * vary slightly as the window travels around the screen, but
232 * this way ensures that the mini-windows in the pager match
233 * the actual screen layout. */
234 size
= edge2
- edge
+ 1;
236 /* Make size big enough to be visible */
237 if (size
< MinSize
) {
239 /* this mini-window has to be grown to be visible
240 * which way it grows depends on some magic:
241 * normally it will grow right but if the window is on the right hand
242 * edge of a page it should be grown left so that the pager looks better */
244 /* work out the page that the right hand edge is on */
245 page
= virt
/ Scr
.MyDisplayWidth
;
247 /* if the left edge is on the same page then possibly move it left */
248 if (page
== ((virt
- t
->width
+ 1) / Scr
.MyDisplayWidth
)) {
249 /* calculate how far the mini-window right edge overlaps the page line */
250 /* beware that the "over" is actually one greater than on screen, but
251 this discrepancy is catered for in the next two lines */
252 over
= edge
+ size
- ((page
+ 1) * win_w
* Scr
.MyDisplayWidth
) /
255 /* if the mini-window right edge is beyond the mini-window pager grid */
257 /* move it left by the amount of pager grid overlap (!== the growth) */
262 /* fill in return values */
266 /* same code for y axis */
267 virt
= Scr
.Vy
+ t
->y
;
268 edge
= (virt
* win_h
) / Scr
.VHeight
;
269 virt
+= t
->height
- 1;
270 virt2
= Scr
.VHeight
- 1 - virt
;
271 edge2
= (virt2
* win_h
) / Scr
.VHeight
;
272 edge2
= win_h
- 1 - edge2
;
273 size
= edge2
- edge
+ 1;
277 page
= virt
/ Scr
.MyDisplayHeight
;
278 if (page
== ((virt
- t
->height
+ 1) / Scr
.MyDisplayHeight
)) {
279 over
= edge
+ size
- ((page
+ 1) * win_h
* Scr
.MyDisplayHeight
) /
292 * Initialize_viz_pager - creates a temp window of the correct visual
293 * so that pixmaps may be created for use with the main window
295 void initialize_viz_pager(void)
297 XSetWindowAttributes attr
;
300 /* FIXME: I think that we only need that Pdepth ==
301 * DefaultDepth(dpy, Scr.screen) to use the Scr.Root for Scr.Pager_w */
304 Scr
.Pager_w
= Scr
.Root
;
308 attr
.background_pixmap
= None
;
309 attr
.border_pixel
= 0;
310 attr
.colormap
= Pcmap
;
311 Scr
.Pager_w
= XCreateWindow(
312 dpy
, Scr
.Root
, -10, -10, 10, 10, 0, Pdepth
,
313 InputOutput
, Pvisual
,
314 CWBackPixmap
|CWBorderPixel
|CWColormap
, &attr
);
315 Scr
.NormalGC
= fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, 0, &xgcv
);
317 Scr
.NormalGC
= fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, 0, NULL
);
319 xgcv
.plane_mask
= AllPlanes
;
320 Scr
.MiniIconGC
= fvwmlib_XCreateGC(
321 dpy
, Scr
.Pager_w
, GCPlaneMask
, &xgcv
);
322 Scr
.black
= GetColor("Black");
324 /* Transparent background are only allowed when the depth matched the
326 if (Pdepth
== DefaultDepth(dpy
, Scr
.screen
))
328 default_pixmap
= ParentRelative
;
334 /* see also change colorset */
335 void draw_desk_background(int i
, int page_w
, int page_h
)
337 if (Desks
[i
].colorset
> -1)
340 dpy
, Desks
[i
].title_w
, Colorset
[Desks
[i
].colorset
].fg
);
342 dpy
, Desks
[i
].w
, Colorset
[Desks
[i
].colorset
].fg
);
344 dpy
, Desks
[i
].NormalGC
,Colorset
[Desks
[i
].colorset
].fg
);
346 dpy
, Desks
[i
].DashedGC
,Colorset
[Desks
[i
].colorset
].fg
);
349 if (CSET_IS_TRANSPARENT(Desks
[i
].colorset
))
352 dpy
, Desks
[i
].title_w
,
354 &Colorset
[Desks
[i
].colorset
],
361 dpy
, Desks
[i
].title_w
, desk_w
,
363 &Colorset
[Desks
[i
].colorset
], Pdepth
,
367 if (label_h
!= 0 && uselabel
&& !LabelsBelow
&&
368 !CSET_IS_TRANSPARENT(Desks
[i
].colorset
))
370 SetWindowBackgroundWithOffset(
371 dpy
, Desks
[i
].w
, 0, -label_h
, desk_w
,
372 desk_h
+ label_h
, &Colorset
[Desks
[i
].colorset
],
373 Pdepth
, Scr
.NormalGC
, True
);
377 if (CSET_IS_TRANSPARENT(Desks
[i
].colorset
))
380 dpy
, Desks
[i
].w
, desk_w
, desk_h
,
381 &Colorset
[Desks
[i
].colorset
], Pdepth
,
387 dpy
, Desks
[i
].w
, desk_w
,
389 &Colorset
[Desks
[i
].colorset
],
390 Pdepth
, Scr
.NormalGC
, True
);
394 XClearArea(dpy
,Desks
[i
].w
, 0, 0, 0, 0,True
);
395 if (Desks
[i
].highcolorset
> -1)
398 dpy
, Desks
[i
].HiliteGC
,
399 Colorset
[Desks
[i
].highcolorset
].bg
);
401 dpy
, Desks
[i
].rvGC
, Colorset
[Desks
[i
].highcolorset
].fg
);
405 dpy
, Desks
[i
].CPagerWin
, page_w
, page_h
,
406 &Colorset
[Desks
[i
].highcolorset
], Pdepth
,
412 XClearArea(dpy
,Desks
[i
].title_w
, 0, 0, 0, 0,True
);
421 * Initialize_pager - creates the pager window, if needed
424 * x,y location of the window
427 char *pager_name
= "Fvwm Pager";
428 XSizeHints sizehints
=
430 (PMinSize
| PResizeInc
| PBaseSize
| PWinGravity
),
431 0, 0, 100, 100, /* x, y, width and height */
432 1, 1, /* Min width and height */
433 0, 0, /* Max width and height */
434 1, 1, /* Width and height increments */
435 {0, 0}, {0, 0}, /* Aspect ratio - not used */
436 1, 1, /* base size */
437 (NorthWestGravity
) /* gravity */
440 void initialize_balloon_window(void)
443 unsigned long valuemask
;
444 XSetWindowAttributes attributes
;
445 extern int BalloonBorderWidth
;
447 /* create balloon window
448 -- ric@giccs.georgetown.edu */
451 Scr
.balloon_w
= None
;
454 valuemask
= CWOverrideRedirect
| CWEventMask
| CWColormap
;
455 /* tell WM to ignore this window */
456 attributes
.override_redirect
= True
;
457 attributes
.event_mask
= ExposureMask
;
458 attributes
.colormap
= Pcmap
;
459 /* now create the window */
460 Scr
.balloon_w
= XCreateWindow(
461 dpy
, Scr
.Root
, 0, 0, /* coords set later */ 1, 1,
462 BalloonBorderWidth
, Pdepth
, InputOutput
, Pvisual
, valuemask
,
464 Scr
.balloon_gc
= fvwmlib_XCreateGC(dpy
, Scr
.balloon_w
, 0, &xgcv
);
465 /* Make sure we don't get balloons initially with the Icon option. */
466 ShowBalloons
= ShowPagerBalloons
;
471 void initialize_pager(void)
476 unsigned long valuemask
;
477 XSetWindowAttributes attributes
;
478 extern char *WindowBack
, *WindowFore
, *WindowHiBack
, *WindowHiFore
;
479 extern char *BalloonFont
;
480 extern char *font_string
, *smallFont
;
484 FlocaleFont
*balloon_font
;
486 /* I don't think that this is necessary - just let pager die */
487 /* domivogt (07-mar-1999): But it is! A window being moved in the pager
488 * might die at any moment causing the Xlib calls to generate BadMatch
489 * errors. Without an error handler the pager will die! */
490 XSetErrorHandler(FvwmErrorHandler
);
492 wm_del_win
= XInternAtom(dpy
,"WM_DELETE_WINDOW",False
);
495 /* Note: "font" is always created, whether labels are used or not
496 because a GC below is set to use a font. dje Dec 2001.
497 OK, I fixed the GC below, but now something else is blowing up.
498 Right now, I've got to do some Real Life stuff, so this kludge is
499 in place, its still better than I found it.
500 I hope that I've fixed this (olicha)
502 Ffont
= FlocaleLoadFont(dpy
, font_string
, MyName
);
504 label_h
= (uselabel
) ? Ffont
->height
+ 2 : 0;
506 /* init our Flocale window string */
507 FlocaleAllocateWinString(&FwinString
);
509 /* Check that shape extension exists. */
510 if (FHaveShapeExtension
&& ShapeLabels
)
512 ShapeLabels
= (FShapesSupported
) ? 1 : 0;
515 if(smallFont
!= NULL
)
517 FwindowFont
= FlocaleLoadFont(dpy
, smallFont
, MyName
);
520 /* Load the colors */
521 fore_pix
= GetColor(PagerFore
);
522 back_pix
= GetColor(PagerBack
);
523 hi_pix
= GetColor(HilightC
);
525 if (windowcolorset
>= 0)
527 win_back_pix
= Colorset
[windowcolorset
].bg
;
528 win_fore_pix
= Colorset
[windowcolorset
].fg
;
531 else if (WindowBack
&& WindowFore
)
533 win_back_pix
= GetColor(WindowBack
);
534 win_fore_pix
= GetColor(WindowFore
);
538 if (activecolorset
>= 0)
540 win_hi_back_pix
= Colorset
[activecolorset
].bg
;
541 win_hi_fore_pix
= Colorset
[activecolorset
].fg
;
542 win_hi_pix_set
= True
;
544 else if (WindowHiBack
&& WindowHiFore
)
546 win_hi_back_pix
= GetColor(WindowHiBack
);
547 win_hi_fore_pix
= GetColor(WindowHiFore
);
548 win_hi_pix_set
= True
;
551 /* Load pixmaps for mono use */
555 XCreatePixmapFromBitmapData(dpy
,Scr
.Pager_w
,g_bits
, g_width
,g_height
,
556 fore_pix
,back_pix
,Pdepth
);
557 Scr
.light_gray_pixmap
=
558 XCreatePixmapFromBitmapData(dpy
,Scr
.Pager_w
,l_g_bits
,l_g_width
,
560 fore_pix
,back_pix
,Pdepth
);
561 Scr
.sticky_gray_pixmap
=
562 XCreatePixmapFromBitmapData(dpy
,Scr
.Pager_w
,s_g_bits
,s_g_width
,
564 fore_pix
,back_pix
,Pdepth
);
568 n
= Scr
.VxMax
/ Scr
.MyDisplayWidth
;
569 m
= Scr
.VyMax
/ Scr
.MyDisplayHeight
;
571 /* Size the window */
581 Rows
= ndesks
/Columns
;
582 if(Rows
*Columns
< ndesks
)
590 Columns
= ndesks
/Rows
;
591 if(Rows
*Columns
< ndesks
)
595 if(Rows
*Columns
< ndesks
)
599 Rows
= ndesks
/Columns
;
600 if (Rows
*Columns
< ndesks
)
604 sizehints
.width_inc
= Columns
*(n
+1);
605 sizehints
.height_inc
= Rows
*(m
+1);
606 sizehints
.base_width
= Columns
* n
+ Columns
- 1;
607 sizehints
.base_height
= Rows
* (m
+ label_h
+ 1) - 1;
610 window_w
= (window_w
- sizehints
.base_width
) / sizehints
.width_inc
;
611 window_w
= window_w
* sizehints
.width_inc
+ sizehints
.base_width
;
615 window_w
= Columns
* (Scr
.VWidth
/ Scr
.VScale
+ n
) + Columns
- 1;
619 window_h
= (window_h
- sizehints
.base_height
) / sizehints
.height_inc
;
620 window_h
= window_h
* sizehints
.height_inc
+ sizehints
.base_height
;
624 window_h
= Rows
* (Scr
.VHeight
/ Scr
.VScale
+ m
+ label_h
+ 1) - 1;
626 desk_w
= (window_w
- Columns
+ 1) / Columns
;
627 desk_h
= (window_h
- Rows
* label_h
- Rows
+ 1) / Rows
;
631 fscreen_scr_arg fscr
;
633 fscr
.xypos
.x
= window_x
;
634 fscr
.xypos
.y
= window_y
;
636 &fscr
, FSCREEN_XYPOS
,
637 &screen_g
.x
, &screen_g
.y
, &screen_g
.width
, &screen_g
.height
);
638 if (window_w
+ window_x
> screen_g
.x
+ screen_g
.width
)
640 window_x
= screen_g
.x
+ screen_g
.width
- Scr
.MyDisplayWidth
;
643 if (window_h
+ window_y
> screen_g
.y
+ screen_g
.height
)
645 window_y
= screen_g
.y
+ screen_g
.height
- Scr
.MyDisplayHeight
;
651 sizehints
.win_gravity
= NorthEastGravity
;
652 window_x
= Scr
.MyDisplayWidth
- window_w
+ window_x
;
656 window_y
= Scr
.MyDisplayHeight
- window_h
+ window_y
;
657 if(sizehints
.win_gravity
== NorthEastGravity
)
658 sizehints
.win_gravity
= SouthEastGravity
;
660 sizehints
.win_gravity
= SouthWestGravity
;
662 sizehints
.width
= window_w
;
663 sizehints
.height
= window_h
;
666 sizehints
.flags
|= USPosition
;
668 valuemask
= (CWBackPixmap
| CWBorderPixel
| CWColormap
| CWEventMask
);
669 attributes
.background_pixmap
= default_pixmap
;
670 attributes
.border_pixel
= 0;
671 attributes
.colormap
= Pcmap
;
672 attributes
.event_mask
= (StructureNotifyMask
);
674 /* destroy the temp window first, don't worry if it's the Root */
675 if (Scr
.Pager_w
!= Scr
.Root
)
676 XDestroyWindow(dpy
, Scr
.Pager_w
);
677 Scr
.Pager_w
= XCreateWindow (dpy
, Scr
.Root
, window_x
, window_y
, window_w
,
678 window_h
, 0, Pdepth
, InputOutput
, Pvisual
,
679 valuemask
, &attributes
);
680 XSetWMProtocols(dpy
,Scr
.Pager_w
,&wm_del_win
,1);
681 /* hack to prevent mapping on wrong screen with StartsOnScreen */
682 FScreenMangleScreenIntoUSPosHints(FSCREEN_XYPOS
, &sizehints
);
683 XSetWMNormalHints(dpy
,Scr
.Pager_w
,&sizehints
);
686 XSetTransientForHint(dpy
, Scr
.Pager_w
, Scr
.Root
);
689 if((desk1
==desk2
)&&(Desks
[0].label
!= NULL
))
691 if (FlocaleTextListToTextProperty(
692 dpy
, &Desks
[0].label
, 1, XStdICCTextStyle
, &name
) == 0)
694 fprintf(stderr
,"%s: fatal error: cannot allocate desk name", MyName
);
700 if (FlocaleTextListToTextProperty(
701 dpy
, &Desks
[0].label
, 1, XStdICCTextStyle
, &name
) == 0)
703 fprintf(stderr
,"%s: fatal error: cannot allocate pager name", MyName
);
708 attributes
.event_mask
= (StructureNotifyMask
| ExposureMask
);
710 icon_w
= (window_w
- Columns
+1)/Columns
;
712 icon_h
= (window_h
- Rows
* label_h
- Rows
+ 1)/Rows
;
714 icon_w
= (icon_w
/ (n
+1)) *(n
+1)+n
;
715 icon_h
= (icon_h
/ (m
+1)) *(m
+1)+m
;
716 icon_win
= XCreateWindow (dpy
, Scr
.Root
, window_x
, window_y
, icon_w
, icon_h
,
717 0, Pdepth
, InputOutput
, Pvisual
, valuemask
,
719 XGrabButton(dpy
, 1, AnyModifier
, icon_win
,
720 True
, ButtonPressMask
| ButtonReleaseMask
|ButtonMotionMask
,
721 GrabModeAsync
, GrabModeAsync
, None
,
723 XGrabButton(dpy
, 2, AnyModifier
, icon_win
,
724 True
, ButtonPressMask
| ButtonReleaseMask
|ButtonMotionMask
,
725 GrabModeAsync
, GrabModeAsync
, None
,
727 XGrabButton(dpy
, 3, AnyModifier
, icon_win
,
728 True
, ButtonPressMask
| ButtonReleaseMask
|ButtonMotionMask
,
729 GrabModeAsync
, GrabModeAsync
, None
,
733 wmhints
.initial_state
= NormalState
;
735 wmhints
.initial_state
= IconicState
;
737 if (icon_x
!= -10000)
740 icon_x
= Scr
.MyDisplayWidth
+ icon_x
- icon_w
;
741 if (icon_y
!= -10000)
744 icon_y
= Scr
.MyDisplayHeight
+ icon_y
- icon_h
;
752 wmhints
.icon_x
= icon_x
;
753 wmhints
.icon_y
= icon_y
;
754 wmhints
.flags
= IconPositionHint
;
756 wmhints
.icon_window
= icon_win
;
757 wmhints
.input
= False
;
758 wmhints
.flags
|= InputHint
| StateHint
| IconWindowHint
;
760 class1
.res_name
= MyName
;
761 class1
.res_class
= "FvwmPager";
763 XSetWMProperties(dpy
,Scr
.Pager_w
,&name
,&name
,NULL
,0,
764 &sizehints
,&wmhints
,&class1
);
765 XFree((char *)name
.value
);
767 /* change colour/font for labelling mini-windows */
768 XSetForeground(dpy
, Scr
.NormalGC
, focus_fore_pix
);
770 if (FwindowFont
!= NULL
&& FwindowFont
->font
!= NULL
)
771 XSetFont(dpy
, Scr
.NormalGC
, FwindowFont
->font
->fid
);
773 /* create the 3d bevel GC's if necessary */
774 if (windowcolorset
>= 0) {
775 gcv
.foreground
= Colorset
[windowcolorset
].hilite
;
776 Scr
.whGC
= fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, GCForeground
, &gcv
);
777 gcv
.foreground
= Colorset
[windowcolorset
].shadow
;
778 Scr
.wsGC
= fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, GCForeground
, &gcv
);
780 if (activecolorset
>= 0) {
781 gcv
.foreground
= Colorset
[activecolorset
].hilite
;
782 Scr
.ahGC
= fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, GCForeground
, &gcv
);
783 gcv
.foreground
= Colorset
[activecolorset
].shadow
;
784 Scr
.asGC
= fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, GCForeground
, &gcv
);
787 balloon_font
= FlocaleLoadFont(dpy
, BalloonFont
, MyName
);
788 for(i
=0;i
<ndesks
;i
++)
790 w
= window_w
/ Columns
;
792 x
= (w
+ 1) * (i
% Columns
);
793 y
= (h
+ 1) * (i
/ Columns
);
795 /* create the GC for desk labels */
796 gcv
.foreground
= (Desks
[i
].colorset
< 0) ? fore_pix
797 : Colorset
[Desks
[i
].colorset
].fg
;
798 if (uselabel
&& Ffont
&& Ffont
->font
) {
799 gcv
.font
= Ffont
->font
->fid
;
801 fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, GCForeground
| GCFont
, &gcv
);
804 fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, GCForeground
, &gcv
);
806 /* create the active desk hilite GC */
808 gcv
.foreground
= fore_pix
;
810 gcv
.foreground
= (Desks
[i
].highcolorset
< 0) ? hi_pix
811 : Colorset
[Desks
[i
].highcolorset
].bg
;
812 Desks
[i
].HiliteGC
= fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, GCForeground
, &gcv
);
814 /* create the hilight desk title drawing GC */
815 if ((Pdepth
< 2) || (fore_pix
== hi_pix
))
816 gcv
.foreground
= (Desks
[i
].highcolorset
< 0) ? back_pix
817 : Colorset
[Desks
[i
].highcolorset
].fg
;
819 gcv
.foreground
= (Desks
[i
].highcolorset
< 0) ? fore_pix
820 : Colorset
[Desks
[i
].highcolorset
].fg
;
822 if (uselabel
&& Ffont
&& Ffont
->font
) {
824 fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, GCForeground
| GCFont
, &gcv
);
827 fvwmlib_XCreateGC(dpy
, Scr
.Pager_w
, GCForeground
, &gcv
);
829 /* create the virtual page boundary GC */
830 gcv
.foreground
= (Desks
[i
].colorset
< 0) ? fore_pix
831 : Colorset
[Desks
[i
].colorset
].fg
;
833 gcv
.line_style
= (use_dashed_separators
) ? LineOnOffDash
: LineSolid
;
836 dpy
, Scr
.Pager_w
, GCForeground
| GCLineStyle
| GCLineWidth
, &gcv
);
837 if (use_dashed_separators
)
839 /* Although this should already be the default for a freshly created GC,
840 * some X servers do not draw properly dashed lines if the dash style is
841 * not set explicitly. */
844 XSetDashes(dpy
, Desks
[i
].DashedGC
, 0, dash_list
, 2);
847 valuemask
= (CWBorderPixel
| CWColormap
| CWEventMask
);
848 if (Desks
[i
].colorset
>= 0 && Colorset
[Desks
[i
].colorset
].pixmap
)
850 valuemask
|= CWBackPixmap
;
851 attributes
.background_pixmap
= Colorset
[Desks
[i
].colorset
].pixmap
;
855 valuemask
|= CWBackPixel
;
856 attributes
.background_pixel
= (Desks
[i
].colorset
< 0) ?
857 (Desks
[i
].Dcolor
? GetColor(Desks
[i
].Dcolor
) : back_pix
)
858 : Colorset
[Desks
[i
].colorset
].bg
;
861 attributes
.border_pixel
= (Desks
[i
].colorset
< 0) ? fore_pix
862 : Colorset
[Desks
[i
].colorset
].fg
;
863 attributes
.event_mask
= (ExposureMask
| ButtonReleaseMask
);
864 Desks
[i
].title_w
= XCreateWindow(
865 dpy
, Scr
.Pager_w
, x
- 1, y
- 1, w
, h
, 1, CopyFromParent
, InputOutput
,
866 CopyFromParent
, valuemask
, &attributes
);
867 attributes
.event_mask
= (ExposureMask
| ButtonReleaseMask
|
868 ButtonPressMask
|ButtonMotionMask
);
869 /* or just: desk_h = h - label_h; */
870 desk_h
= (window_h
- Rows
* label_h
- Rows
+ 1) / Rows
;
872 valuemask
&= ~(CWBackPixel
);
875 if (Desks
[i
].colorset
> -1 &&
876 Colorset
[Desks
[i
].colorset
].pixmap
)
878 valuemask
|= CWBackPixmap
;
879 attributes
.background_pixmap
= None
; /* set later */
881 else if (Desks
[i
].bgPixmap
)
883 valuemask
|= CWBackPixmap
;
884 attributes
.background_pixmap
= Desks
[i
].bgPixmap
->picture
;
886 else if (Desks
[i
].Dcolor
)
888 valuemask
|= CWBackPixel
;
889 attributes
.background_pixel
= GetColor(Desks
[i
].Dcolor
);
893 valuemask
|= CWBackPixmap
;
894 attributes
.background_pixmap
= PixmapBack
->picture
;
898 valuemask
|= CWBackPixel
;
899 attributes
.background_pixel
= (Desks
[i
].colorset
< 0) ? back_pix
900 : Colorset
[Desks
[i
].colorset
].bg
;
903 Desks
[i
].w
= XCreateWindow(
904 dpy
, Desks
[i
].title_w
, x
- 1, LabelsBelow
? -1 : label_h
- 1, w
, desk_h
,
905 1, CopyFromParent
, InputOutput
, CopyFromParent
, valuemask
, &attributes
);
909 valuemask
&= ~(CWBackPixel
| CWBackPixmap
);
911 attributes
.event_mask
= 0;
913 if (Desks
[i
].highcolorset
> -1 &&
914 Colorset
[Desks
[i
].highcolorset
].pixmap
)
916 valuemask
|= CWBackPixmap
;
917 attributes
.background_pixmap
= None
; /* set later */
919 else if (HilightPixmap
)
921 valuemask
|= CWBackPixmap
;
922 attributes
.background_pixmap
= HilightPixmap
->picture
;
926 valuemask
|= CWBackPixel
;
927 attributes
.background_pixel
= (Desks
[i
].highcolorset
< 0) ? hi_pix
928 : Colorset
[Desks
[i
].highcolorset
].bg
;
932 h
= desk_h
/ (m
+ 1);
933 Desks
[i
].CPagerWin
=XCreateWindow(dpy
, Desks
[i
].w
, -32768, -32768, w
, h
, 0,
934 CopyFromParent
, InputOutput
,
935 CopyFromParent
, valuemask
, &attributes
);
936 draw_desk_background(i
, w
, h
);
937 XMapRaised(dpy
,Desks
[i
].CPagerWin
);
941 draw_desk_background(i
, 0, 0);
944 XMapRaised(dpy
,Desks
[i
].w
);
945 XMapRaised(dpy
,Desks
[i
].title_w
);
947 /* get font for balloon */
948 Desks
[i
].balloon
.Ffont
= balloon_font
;
949 if (Desks
[i
].balloon
.Ffont
== NULL
)
951 fprintf(stderr
, "%s: No fonts available, giving up!.\n", MyName
);
953 Desks
[i
].balloon
.height
= Desks
[i
].balloon
.Ffont
->height
+ 1;
955 initialize_balloon_window();
956 XMapRaised(dpy
,Scr
.Pager_w
);
960 void UpdateWindowShape(void)
962 if (FHaveShapeExtension
)
964 int i
, j
, cnt
, shape_count
, x_pos
, y_pos
;
967 if (!ShapeLabels
|| !uselabel
|| label_h
<=0)
971 ndesks
+ ((Scr
.CurrentDesk
< desk1
|| Scr
.CurrentDesk
>desk2
) ? 0 : 1);
973 shape
= (XRectangle
*)alloca (shape_count
* sizeof (XRectangle
));
979 y_pos
= (LabelsBelow
? 0 : label_h
);
981 for (i
= 0; i
< Rows
; ++i
)
984 for (j
= 0; j
< Columns
; ++j
)
988 shape
[cnt
].x
= x_pos
;
989 shape
[cnt
].y
= y_pos
;
990 shape
[cnt
].width
= desk_w
+ 1;
991 shape
[cnt
].height
= desk_h
+ 2;
993 if (cnt
== Scr
.CurrentDesk
- desk1
)
995 shape
[ndesks
].x
= x_pos
;
997 (LabelsBelow
? y_pos
+ desk_h
+ 2 : y_pos
- label_h
);
998 shape
[ndesks
].width
= desk_w
;
999 shape
[ndesks
].height
= label_h
+ 2;
1003 x_pos
+= desk_w
+ 1;
1005 y_pos
+= desk_h
+ 2 + label_h
;
1008 FShapeCombineRectangles(
1009 dpy
, Scr
.Pager_w
, FShapeBounding
, 0, 0, shape
, shape_count
, FShapeSet
, 0);
1017 * Decide what to do about received X events
1020 void DispatchEvent(XEvent
*Event
)
1023 Window JunkRoot
, JunkChild
;
1029 Bool do_move_page
= False
;
1033 switch(Event
->xany
.type
)
1036 HandleEnterNotify(Event
);
1040 UnmapBalloonWindow();
1042 case ConfigureNotify
:
1043 w
= Event
->xconfigure
.window
;
1044 discard_events(ConfigureNotify
, Event
->xconfigure
.window
, Event
);
1047 /* icon_win is not handled here */
1048 discard_events(Expose
, w
, NULL
);
1053 HandleExpose(Event
);
1058 XLookupString(&(Event
->xkey
), &keychar
, 1, &keysym
, NULL
);
1063 do_move_page
= True
;
1067 do_move_page
= True
;
1071 do_move_page
= True
;
1075 do_move_page
= True
;
1078 /* does not return */
1085 sprintf(command
,"Scroll %d %d", dx
, dy
);
1086 SendText(fd
, command
, 0);
1091 if (do_ignore_next_button_release
)
1093 do_ignore_next_button_release
= False
;
1096 if (Event
->xbutton
.button
== 3)
1098 for(i
=0;i
<ndesks
;i
++)
1100 if(Event
->xany
.window
== Desks
[i
].w
)
1102 if (FQueryPointer(dpy
, Desks
[i
].w
, &JunkRoot
, &JunkChild
,
1103 &JunkX
, &JunkY
,&x
, &y
, &JunkMask
) == False
)
1105 /* pointer is on a different screen - that's okay here */
1107 Scroll(desk_w
, desk_h
, x
, y
, i
, False
);
1110 if(Event
->xany
.window
== icon_win
)
1112 if (FQueryPointer(dpy
, icon_win
, &JunkRoot
, &JunkChild
,
1113 &JunkX
, &JunkY
,&x
, &y
, &JunkMask
) == False
)
1115 /* pointer is on a different screen - that's okay here */
1117 Scroll(icon_w
, icon_h
, x
, y
, 0, True
);
1119 /* Flush any pending scroll operations */
1120 do_scroll(0, 0, True
, False
);
1122 else if((Event
->xbutton
.button
== 1)||
1123 (Event
->xbutton
.button
== 2))
1125 for(i
=0;i
<ndesks
;i
++)
1127 if(Event
->xany
.window
== Desks
[i
].w
)
1128 SwitchToDeskAndPage(i
,Event
);
1129 else if(Event
->xany
.window
== Desks
[i
].title_w
)
1132 if(Event
->xany
.window
== icon_win
)
1134 IconSwitchPage(Event
);
1139 /* does not return */
1144 do_ignore_next_button_release
= False
;
1146 UnmapBalloonWindow();
1147 if (((Event
->xbutton
.button
== 2)||
1148 ((Event
->xbutton
.button
== 3)&&
1149 (Event
->xbutton
.state
& Mod1Mask
)))&&
1150 (Event
->xbutton
.subwindow
!= None
))
1154 else if (Event
->xbutton
.button
== 3)
1156 /* save initial virtual desk position for drag */
1159 for(i
=0;i
<ndesks
;i
++)
1161 if(Event
->xany
.window
== Desks
[i
].w
)
1163 if (FQueryPointer(dpy
, Desks
[i
].w
, &JunkRoot
, &JunkChild
,
1164 &JunkX
, &JunkY
,&x
, &y
, &JunkMask
) == False
)
1166 /* pointer is on a different screen - that's okay here */
1168 Scroll(desk_w
, desk_h
, x
, y
, Scr
.CurrentDesk
, False
);
1169 if (Scr
.CurrentDesk
!= i
+ desk1
)
1177 if(Event
->xany
.window
== icon_win
)
1179 if (FQueryPointer(dpy
, icon_win
, &JunkRoot
, &JunkChild
,
1180 &JunkX
, &JunkY
,&x
, &y
, &JunkMask
) == False
)
1182 /* pointer is on a different screen - that's okay here */
1184 Scroll(icon_w
, icon_h
, x
, y
, 0, True
);
1189 do_ignore_next_button_release
= False
;
1190 while(FCheckMaskEvent(dpy
, PointerMotionMask
| ButtonMotionMask
,Event
))
1193 if(Event
->xmotion
.state
& Button3MotionMask
)
1195 for(i
=0;i
<ndesks
;i
++)
1197 if(Event
->xany
.window
== Desks
[i
].w
)
1199 if (FQueryPointer(dpy
, Desks
[i
].w
, &JunkRoot
, &JunkChild
,
1200 &JunkX
, &JunkY
,&x
, &y
, &JunkMask
) == False
)
1202 /* pointer is on a different screen - that's okay here */
1204 Scroll(desk_w
, desk_h
, x
, y
, i
, False
);
1207 if(Event
->xany
.window
== icon_win
)
1209 if (FQueryPointer(dpy
, icon_win
, &JunkRoot
, &JunkChild
,
1210 &JunkX
, &JunkY
,&x
, &y
, &JunkMask
) == False
)
1212 /* pointer is on a different screen - that's okay here */
1214 Scroll(icon_w
, icon_h
, x
, y
, 0, True
);
1221 if ((Event
->xclient
.format
==32) &&
1222 (Event
->xclient
.data
.l
[0]==wm_del_win
))
1224 /* does not return */
1231 void HandleEnterNotify(XEvent
*Event
)
1235 Bool is_icon_view
= False
;
1236 extern Bool do_focus_on_enter
;
1238 if (!ShowBalloons
&& !do_focus_on_enter
)
1242 /* is this the best way to match X event window ID to PagerWindow ID? */
1243 for ( t
= Start
; t
!= NULL
; t
= t
->next
)
1245 if ( t
->PagerView
== Event
->xcrossing
.window
)
1249 if ( t
->IconView
== Event
->xcrossing
.window
)
1251 is_icon_view
= True
;
1262 MapBalloonWindow(t
, is_icon_view
);
1265 if (do_focus_on_enter
)
1267 SendText(fd
, "Silent FlipFocus NoWarp", t
->w
);
1272 XRectangle
get_expose_bound(XEvent
*Event
)
1275 int ex
, ey
, ex2
, ey2
;
1277 ex
= Event
->xexpose
.x
;
1278 ey
= Event
->xexpose
.y
;
1279 ex2
= Event
->xexpose
.x
+ Event
->xexpose
.width
;
1280 ey2
= Event
->xexpose
.y
+ Event
->xexpose
.height
;
1281 while (FCheckTypedWindowEvent(dpy
, Event
->xany
.window
, Expose
, Event
))
1283 ex
= min(ex
, Event
->xexpose
.x
);
1284 ey
= min(ey
, Event
->xexpose
.y
);
1285 ex2
= max(ex2
, Event
->xexpose
.x
+ Event
->xexpose
.width
);
1286 ey2
= max(ey2
, Event
->xexpose
.y
+ Event
->xexpose
.height
);
1295 void HandleExpose(XEvent
*Event
)
1301 /* it will be good to have full "clipping redraw". Do that for
1302 * desk label only for now */
1303 for(i
=0;i
<ndesks
;i
++)
1305 /* ric@giccs.georgetown.edu */
1306 if (Event
->xany
.window
== Desks
[i
].w
||
1307 Event
->xany
.window
== Desks
[i
].title_w
)
1309 r
= get_expose_bound(Event
);
1310 DrawGrid(i
, 0, Event
->xany
.window
, &r
);
1314 if (Event
->xany
.window
== Scr
.balloon_w
)
1316 DrawInBalloonWindow(Scr
.balloon_desk
);
1319 if(Event
->xany
.window
== icon_win
)
1322 for (t
= Start
; t
!= NULL
; t
= t
->next
)
1324 if (t
->PagerView
== Event
->xany
.window
)
1330 else if(t
->IconView
== Event
->xany
.window
)
1333 PictureIconWindow(t
);
1334 BorderIconWindow(t
);
1338 discard_events(Expose
, Event
->xany
.window
, NULL
);
1343 * Respond to a change in window geometry.
1346 void ReConfigure(void)
1349 unsigned border_width
, depth
;
1350 int n
,m
,w
,h
,n1
,m1
,x
,y
,i
,j
,k
;
1353 int is_size_changed
;
1357 if (!XGetGeometry(dpy
, Scr
.Pager_w
, &root
, &x
, &y
, (unsigned *)&window_w
,
1358 (unsigned *)&window_h
, &border_width
,&depth
))
1362 is_size_changed
= (old_ww
!= window_w
|| old_wh
!= window_h
);
1364 n1
= Scr
.Vx
/ Scr
.MyDisplayWidth
;
1365 m1
= Scr
.Vy
/ Scr
.MyDisplayHeight
;
1366 n
= Scr
.VxMax
/ Scr
.MyDisplayWidth
;
1367 m
= Scr
.VyMax
/ Scr
.MyDisplayHeight
;
1369 sizehints
.width_inc
= Columns
* (n
+ 1);
1370 sizehints
.height_inc
= Rows
* (m
+ 1);
1371 sizehints
.base_width
= Columns
* n
+ Columns
- 1;
1372 sizehints
.base_height
= Rows
*(m
+ label_h
+1) - 1;
1373 sizehints
.min_width
= sizehints
.base_width
;
1374 sizehints
.min_height
= sizehints
.base_height
;
1377 window_w
= (window_w
- sizehints
.base_width
) / sizehints
.width_inc
;
1378 window_w
= window_w
* sizehints
.width_inc
+ sizehints
.base_width
;
1382 window_h
= (window_h
- sizehints
.base_height
) / sizehints
.height_inc
;
1383 window_h
= window_h
* sizehints
.height_inc
+ sizehints
.base_height
;
1385 desk_w
= (window_w
- Columns
+ 1) / Columns
;
1386 desk_h
= (window_h
- Rows
* label_h
- Rows
+ 1) / Rows
;
1387 w
= (desk_w
- n
)/(n
+1);
1388 h
= (desk_h
- m
)/(m
+1);
1390 XSetWMNormalHints(dpy
,Scr
.Pager_w
,&sizehints
);
1392 x
= (desk_w
- n
) * Scr
.Vx
/ Scr
.VWidth
+ n1
;
1393 y
= (desk_h
- m
) * Scr
.Vy
/ Scr
.VHeight
+ m1
;
1397 for(j
=0;j
<Columns
;j
++)
1403 dpy
,Desks
[i
].title_w
, (desk_w
+1)*j
-1,(desk_h
+label_h
+1)*k
-1,
1404 desk_w
,desk_h
+label_h
);
1406 dpy
,Desks
[i
].w
, -1, (LabelsBelow
) ? -1 : label_h
- 1, desk_w
,desk_h
);
1407 if (!is_size_changed
)
1409 if (CSET_IS_TRANSPARENT(Desks
[i
].colorset
))
1411 draw_desk_background(i
, w
, h
);
1416 if(i
== Scr
.CurrentDesk
- desk1
)
1417 XMoveResizeWindow(dpy
, Desks
[i
].CPagerWin
, x
,y
,w
,h
);
1419 XMoveResizeWindow(dpy
, Desks
[i
].CPagerWin
, -32768, -32768,w
,h
);
1421 draw_desk_background(i
, w
, h
);
1425 /* reconfigure all the subordinate windows */
1431 * Respond to a "background" change: update the Parental Relative cset
1436 * Root -> pager window (pr) -> title window -> desk window -> window view
1437 * | |-> hilight desk
1438 * |-> icon_window -> icon view
1442 /* update the hilight desk and the windows: desk color change */
1444 void update_pr_transparent_subwindows(int i
)
1450 n
= Scr
.VxMax
/ Scr
.MyDisplayWidth
;
1451 m
= Scr
.VyMax
/ Scr
.MyDisplayHeight
;
1452 w
= (desk_w
- n
)/(n
+1);
1453 h
= (desk_h
- m
)/(m
+1);
1455 if (CSET_IS_TRANSPARENT_PR(Desks
[i
].highcolorset
) && HilightDesks
)
1457 SetWindowBackground(
1458 dpy
, Desks
[i
].CPagerWin
, w
, h
,
1459 &Colorset
[Desks
[i
].highcolorset
],
1460 Pdepth
, Scr
.NormalGC
, True
);
1464 for(t
= Start
; t
!= NULL
; t
= t
->next
)
1466 cset
= (t
!= FocusWin
) ? windowcolorset
: activecolorset
;
1467 if (t
->desk
!= i
&& !CSET_IS_TRANSPARENT_PR(cset
))
1471 if (t
->PagerView
!= None
)
1473 SetWindowBackground(
1474 dpy
, t
->PagerView
, t
->pager_view_width
,
1475 t
->pager_view_height
,
1476 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
1480 SetWindowBackground(
1481 dpy
, t
->IconView
, t
->icon_view_width
,
1482 t
->icon_view_height
,
1483 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
1488 /* update all the parental relative windows: pr background change */
1489 void update_pr_transparent_windows(void)
1495 n
= Scr
.VxMax
/ Scr
.MyDisplayWidth
;
1496 m
= Scr
.VyMax
/ Scr
.MyDisplayHeight
;
1497 w
= (desk_w
- n
)/(n
+1);
1498 h
= (desk_h
- m
)/(m
+1);
1502 for(j
=0;j
<Columns
;j
++)
1507 if (CSET_IS_TRANSPARENT_PR(Desks
[i
].colorset
))
1509 draw_desk_background(i
, w
, h
);
1511 else if (CSET_IS_TRANSPARENT_PR(
1512 Desks
[i
].highcolorset
) && HilightDesks
)
1514 SetWindowBackground(
1515 dpy
, Desks
[i
].CPagerWin
, w
, h
,
1516 &Colorset
[Desks
[i
].highcolorset
],
1517 Pdepth
, Scr
.NormalGC
, True
);
1522 /* subordinate windows with a pr parent desk */
1524 for(t
= Start
; t
!= NULL
; t
= t
->next
)
1526 cset
= (t
!= FocusWin
) ? windowcolorset
: activecolorset
;
1527 if (!CSET_IS_TRANSPARENT_PR(cset
) ||
1528 (fAlwaysCurrentDesk
&&
1529 !CSET_IS_TRANSPARENT_PR(Desks
[0].colorset
)) ||
1530 (!fAlwaysCurrentDesk
&&
1531 !CSET_IS_TRANSPARENT_PR(Desks
[t
->desk
].colorset
)))
1535 if (t
->PagerView
!= None
)
1537 SetWindowBackground(
1538 dpy
, t
->PagerView
, t
->pager_view_width
,
1539 t
->pager_view_height
,
1540 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
1542 if (t
->desk
&& t
->IconView
)
1544 SetWindowBackground(
1545 dpy
, t
->IconView
, t
->icon_view_width
,
1546 t
->icon_view_height
,
1547 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
1552 if (BalloonView
!= None
)
1554 cset
= Desks
[Scr
.balloon_desk
].ballooncolorset
;
1555 if (CSET_IS_TRANSPARENT_PR(cset
))
1557 XClearArea(dpy
, Scr
.balloon_w
, 0, 0, 0, 0, True
);
1562 void MovePage(Bool is_new_desk
)
1564 int n1
,m1
,x
,y
,n
,m
,i
,w
,h
;
1566 char str
[100],*sptr
;
1567 static int icon_desk_shown
= -1000;
1570 n1
= Scr
.Vx
/Scr
.MyDisplayWidth
;
1571 m1
= Scr
.Vy
/Scr
.MyDisplayHeight
;
1572 n
= Scr
.VxMax
/ Scr
.MyDisplayWidth
;
1573 m
= Scr
.VyMax
/ Scr
.MyDisplayHeight
;
1575 x
= (desk_w
- n
) * Scr
.Vx
/ Scr
.VWidth
+ n1
;
1576 y
= (desk_h
- m
) * Scr
.Vy
/ Scr
.VHeight
+ m1
;
1577 w
= (desk_w
- n
)/(n
+1);
1578 h
= (desk_h
- m
)/(m
+1);
1580 for(i
=0;i
<ndesks
;i
++)
1584 if(i
== Scr
.CurrentDesk
- desk1
)
1586 XMoveWindow(dpy
, Desks
[i
].CPagerWin
, x
,y
);
1587 XLowerWindow(dpy
,Desks
[i
].CPagerWin
);
1588 if (CSET_IS_TRANSPARENT(Desks
[i
].highcolorset
))
1590 SetWindowBackground(
1591 dpy
, Desks
[i
].CPagerWin
, w
, h
,
1592 &Colorset
[Desks
[i
].highcolorset
], Pdepth
,
1593 Scr
.NormalGC
, True
);
1598 XMoveWindow(dpy
, Desks
[i
].CPagerWin
, -32768,-32768);
1604 ReConfigureIcons(!is_new_desk
);
1606 if(Scr
.CurrentDesk
!= icon_desk_shown
)
1608 icon_desk_shown
= Scr
.CurrentDesk
;
1610 if((Scr
.CurrentDesk
>= desk1
)&&(Scr
.CurrentDesk
<=desk2
))
1611 sptr
= Desks
[Scr
.CurrentDesk
-desk1
].label
;
1614 sprintf(str
, "GotoDesk %d", Scr
.CurrentDesk
);
1618 if (FlocaleTextListToTextProperty(
1619 dpy
, &sptr
, 1, XStdICCTextStyle
, &name
) == 0)
1621 fprintf(stderr
,"%s: cannot allocate window name", MyName
);
1624 XSetWMIconName(dpy
,Scr
.Pager_w
,&name
);
1629 void ReConfigureAll(void)
1636 MoveResizePagerView(t
, True
);
1641 void ReConfigureIcons(Bool do_reconfigure_desk_only
)
1646 for (t
= Start
; t
!= NULL
; t
= t
->next
)
1648 if (do_reconfigure_desk_only
&& t
->desk
!= Scr
.CurrentDesk
)
1650 CalcGeom(t
, icon_w
, icon_h
, &x
, &y
, &w
, &h
);
1653 t
->icon_view_width
= w
;
1654 t
->icon_view_height
= h
;
1655 if(Scr
.CurrentDesk
== t
->desk
)
1656 XMoveResizeWindow(dpy
, t
->IconView
, x
, y
, w
, h
);
1658 XMoveResizeWindow(dpy
, t
->IconView
, -32768, -32768, w
, h
);
1664 * Draw grid lines for desk #i
1667 void DrawGrid(int desk
, int erase
, Window ew
, XRectangle
*r
)
1669 int y
, y1
, y2
, x
, x1
, x2
,d
,w
;
1675 if((desk
< 0 ) || (desk
>= ndesks
))
1679 if (!ew
|| ew
== Desks
[desk
].w
)
1681 x
= Scr
.MyDisplayWidth
;
1684 while (x
< Scr
.VWidth
)
1686 x1
= (x
* desk_w
) / Scr
.VWidth
;
1687 if (!use_no_separators
)
1690 dpy
,Desks
[desk
].w
,Desks
[desk
].DashedGC
,
1693 x
+= Scr
.MyDisplayWidth
;
1695 y
= Scr
.MyDisplayHeight
;
1698 while(y
< Scr
.VHeight
)
1700 y1
= (y
* desk_h
) / Scr
.VHeight
;
1701 if (!use_no_separators
)
1704 dpy
,Desks
[desk
].w
,Desks
[desk
].DashedGC
,
1707 y
+= Scr
.MyDisplayHeight
;
1711 if (ew
&& ew
!= Desks
[desk
].title_w
)
1721 bound
.width
= r
->width
;
1722 bound
.height
= r
->height
;
1723 region
= XCreateRegion();
1724 XUnionRectWithRegion (&bound
, region
, region
);
1729 bound
.y
= (LabelsBelow
? desk_h
: 0);
1730 bound
.width
= desk_w
;
1731 bound
.height
= label_h
;
1734 if (FftSupport
&& Ffont
->fftf
.fftfont
!= NULL
)
1738 if(((Scr
.CurrentDesk
- desk1
) == desk
) && !ShapeLabels
)
1743 dpy
,Desks
[desk
].title_w
,Desks
[desk
].HiliteGC
,
1744 bound
.x
, bound
.y
, bound
.width
, bound
.height
);
1749 if(uselabel
&& erase
)
1751 XClearArea(dpy
,Desks
[desk
].title_w
,
1752 bound
.x
, bound
.y
, bound
.width
, bound
.height
,
1758 ptr
= Desks
[desk
].label
;
1759 w
= FlocaleTextWidth(Ffont
,ptr
,strlen(ptr
));
1762 sprintf(str
,"%d",d
);
1764 w
= FlocaleTextWidth(Ffont
,ptr
,strlen(ptr
));
1766 if((w
<= desk_w
)&&(uselabel
))
1768 FwinString
->str
= ptr
;
1769 FwinString
->win
= Desks
[desk
].title_w
;
1770 if(desk
== (Scr
.CurrentDesk
- desk1
))
1772 cs
= Desks
[desk
].highcolorset
;
1773 FwinString
->gc
= Desks
[desk
].rvGC
;
1777 cs
= Desks
[desk
].colorset
;
1778 FwinString
->gc
= Desks
[desk
].NormalGC
;
1781 FwinString
->flags
.has_colorset
= False
;
1784 FwinString
->colorset
= &Colorset
[cs
];
1785 FwinString
->flags
.has_colorset
= True
;
1787 FwinString
->x
= (desk_w
- w
)/2;
1788 FwinString
->y
= (LabelsBelow
?
1789 desk_h
+ Ffont
->ascent
+ 1 : Ffont
->ascent
+ 1);
1792 FwinString
->flags
.has_clip_region
= True
;
1793 FwinString
->clip_region
= region
;
1794 XSetRegion(dpy
, FwinString
->gc
, region
);
1798 FwinString
->flags
.has_clip_region
= False
;
1800 FlocaleDrawString(dpy
, Ffont
, FwinString
, 0);
1803 XDestroyRegion(region
);
1804 FwinString
->flags
.has_clip_region
= False
;
1805 FwinString
->clip_region
= None
;
1806 XSetClipMask(dpy
, FwinString
->gc
, None
);
1810 if (FShapesSupported
)
1812 UpdateWindowShape ();
1817 void DrawIconGrid(int erase
)
1819 int y
, y1
, y2
, x
, x1
, x2
,w
,h
,n
,m
,n1
,m1
;
1824 int tmp
=(Scr
.CurrentDesk
- desk1
);
1826 if ((tmp
< 0) || (tmp
>= ndesks
))
1829 XSetWindowBackgroundPixmap(dpy
, icon_win
,PixmapBack
->picture
);
1831 XSetWindowBackground(dpy
, icon_win
, back_pix
);
1835 if (Desks
[tmp
].bgPixmap
)
1836 XSetWindowBackgroundPixmap(
1837 dpy
, icon_win
,Desks
[tmp
].bgPixmap
->picture
);
1838 else if (Desks
[tmp
].Dcolor
)
1839 XSetWindowBackground(dpy
, icon_win
, GetColor(Desks
[tmp
].Dcolor
));
1840 else if (PixmapBack
)
1841 XSetWindowBackgroundPixmap(dpy
, icon_win
, PixmapBack
->picture
);
1843 XSetWindowBackground(dpy
, icon_win
, back_pix
);
1846 XClearWindow(dpy
,icon_win
);
1849 x
= Scr
.MyDisplayWidth
;
1852 while(x
< Scr
.VWidth
)
1854 x1
= x
* icon_w
/ Scr
.VWidth
;
1855 if (!use_no_separators
)
1856 for(i
=0;i
<ndesks
;i
++)
1857 XDrawLine(dpy
,icon_win
,Desks
[i
].DashedGC
,x1
,y1
,x1
,y2
);
1858 x
+= Scr
.MyDisplayWidth
;
1861 y
= Scr
.MyDisplayHeight
;
1864 while(y
< Scr
.VHeight
)
1866 y1
= y
* icon_h
/ Scr
.VHeight
;
1867 if (!use_no_separators
)
1868 for(i
=0;i
<ndesks
;i
++)
1869 XDrawLine(dpy
,icon_win
,Desks
[i
].DashedGC
,x1
,y1
,x2
,y1
);
1870 y
+= Scr
.MyDisplayHeight
;
1872 n1
= Scr
.Vx
/ Scr
.MyDisplayWidth
;
1873 m1
= Scr
.Vy
/ Scr
.MyDisplayHeight
;
1874 n
= Scr
.VxMax
/ Scr
.MyDisplayWidth
;
1875 m
= Scr
.VyMax
/ Scr
.MyDisplayHeight
;
1876 w
= (icon_w
- n
) / (n
+ 1);
1877 h
= (icon_h
- m
) / (m
+ 1);
1879 x
= (icon_w
- n
) * Scr
.Vx
/ Scr
.VWidth
+ n1
;
1880 y
= (icon_h
- m
) * Scr
.Vy
/ Scr
.VHeight
+ m1
;
1886 for(i
=0;i
<ndesks
;i
++)
1887 XCopyArea(dpy
, HilightPixmap
->picture
, icon_win
, Scr
.NormalGC
, 0, 0,
1892 for(i
=0;i
<ndesks
;i
++)
1893 XFillRectangle (dpy
, icon_win
, Desks
[i
].HiliteGC
, x
, y
, w
, h
);
1899 void SwitchToDesk(int Desk
)
1903 sprintf(command
, "GotoDesk 0 %d", Desk
+ desk1
);
1904 SendText(fd
,command
,0);
1908 void SwitchToDeskAndPage(int Desk
, XEvent
*Event
)
1912 if (Scr
.CurrentDesk
!= (Desk
+ desk1
))
1915 /* patch to let mouse button 3 change desks and do not cling to a page */
1916 vx
= Event
->xbutton
.x
* Scr
.VWidth
/ (desk_w
* Scr
.MyDisplayWidth
);
1917 vy
= Event
->xbutton
.y
* Scr
.VHeight
/ (desk_h
* Scr
.MyDisplayHeight
);
1918 Scr
.Vx
= vx
* Scr
.MyDisplayWidth
;
1919 Scr
.Vy
= vy
* Scr
.MyDisplayHeight
;
1920 sprintf(command
, "GotoDeskAndPage %d %d %d", Desk
+ desk1
, vx
, vy
);
1921 SendText(fd
, command
, 0);
1926 int x
= Event
->xbutton
.x
* Scr
.VWidth
/ (desk_w
* Scr
.MyDisplayWidth
);
1927 int y
= Event
->xbutton
.y
* Scr
.VHeight
/ (desk_h
* Scr
.MyDisplayHeight
);
1929 /* Fix for buggy XFree86 servers that report button release events
1930 * incorrectly when moving fast. Not perfect, but should at least prevent
1931 * that we get a random page. */
1936 if (x
* Scr
.MyDisplayWidth
> Scr
.VxMax
)
1937 x
= Scr
.VxMax
/ Scr
.MyDisplayWidth
;
1938 if (y
* Scr
.MyDisplayHeight
> Scr
.VyMax
)
1939 y
= Scr
.VyMax
/ Scr
.MyDisplayHeight
;
1940 sprintf(command
, "GotoPage %d %d", x
, y
);
1941 SendText(fd
, command
, 0);
1946 void IconSwitchPage(XEvent
*Event
)
1950 sprintf(command
,"GotoPage %d %d",
1951 Event
->xbutton
.x
* Scr
.VWidth
/ (icon_w
* Scr
.MyDisplayWidth
),
1952 Event
->xbutton
.y
* Scr
.VHeight
/ (icon_h
* Scr
.MyDisplayHeight
));
1953 SendText(fd
, command
, 0);
1958 void AddNewWindow(PagerWindow
*t
)
1960 unsigned long valuemask
;
1961 XSetWindowAttributes attributes
;
1964 i
= t
->desk
- desk1
;
1965 CalcGeom(t
, desk_w
, desk_h
, &x
, &y
, &w
, &h
);
1966 t
->pager_view_x
= x
;
1967 t
->pager_view_y
= y
;
1968 t
->pager_view_width
= w
;
1969 t
->pager_view_height
= h
;
1970 valuemask
= CWBackPixel
| CWEventMask
;
1971 attributes
.background_pixel
= t
->back
;
1972 attributes
.event_mask
= ExposureMask
;
1974 /* ric@giccs.georgetown.edu -- added Enter and Leave events for
1975 popping up balloon window */
1976 attributes
.event_mask
=
1977 ExposureMask
| EnterWindowMask
| LeaveWindowMask
;
1979 if ((i
>= 0) && (i
< ndesks
))
1981 t
->PagerView
= XCreateWindow(
1982 dpy
,Desks
[i
].w
, x
, y
, w
, h
, 0, CopyFromParent
,
1983 InputOutput
, CopyFromParent
, valuemask
, &attributes
);
1984 if (windowcolorset
> -1)
1986 SetWindowBackground(
1987 dpy
, t
->PagerView
, w
, h
,
1988 &Colorset
[windowcolorset
], Pdepth
,
1989 Scr
.NormalGC
, True
);
1991 if (!UseSkipList
|| !DO_SKIP_WINDOW_LIST(t
))
1993 if (IS_ICONIFIED(t
))
1996 dpy
, t
->PagerView
, -32768, -32768, 1,
1999 XMapRaised(dpy
, t
->PagerView
);
2004 t
->PagerView
= None
;
2007 CalcGeom(t
, icon_w
, icon_h
, &x
, &y
, &w
, &h
);
2010 t
->icon_view_width
= w
;
2011 t
->icon_view_height
= h
;
2012 if(Scr
.CurrentDesk
!= t
->desk
)
2017 t
->IconView
= XCreateWindow(
2018 dpy
,icon_win
, x
, y
, w
, h
, 0, CopyFromParent
, InputOutput
,
2019 CopyFromParent
, valuemask
, &attributes
);
2020 if (windowcolorset
> -1)
2022 SetWindowBackground(
2023 dpy
, t
->IconView
, w
, h
, &Colorset
[windowcolorset
],
2024 Pdepth
, Scr
.NormalGC
, True
);
2026 if(Scr
.CurrentDesk
== t
->desk
)
2029 dpy
, 2, AnyModifier
, t
->IconView
, True
,
2030 ButtonPressMask
| ButtonReleaseMask
|ButtonMotionMask
,
2031 GrabModeAsync
, GrabModeAsync
, None
, None
);
2033 if (!UseSkipList
|| !DO_SKIP_WINDOW_LIST(t
))
2035 if (IS_ICONIFIED(t
))
2038 dpy
, t
->IconView
, -32768, -32768, 1,
2041 XMapRaised(dpy
, t
->IconView
);
2042 t
->myflags
.is_mapped
= 1;
2046 t
->myflags
.is_mapped
= 0;
2054 void ChangeDeskForWindow(PagerWindow
*t
,long newdesk
)
2057 Bool size_changed
= False
;
2059 i
= newdesk
- desk1
;
2060 if(t
->PagerView
== None
)
2063 XDestroyWindow(dpy
,t
->IconView
);
2068 CalcGeom(t
, desk_w
, desk_h
, &x
, &y
, &w
, &h
);
2069 size_changed
= (t
->pager_view_width
!= w
|| t
->pager_view_height
!= h
);
2070 t
->pager_view_x
= x
;
2071 t
->pager_view_y
= y
;
2072 t
->pager_view_width
= w
;
2073 t
->pager_view_height
= h
;
2075 if ((i
>= 0) && (i
< ndesks
))
2079 XReparentWindow(dpy
, t
->PagerView
, Desks
[i
].w
, x
, y
);
2081 XResizeWindow(dpy
, t
->PagerView
, w
, h
);
2082 cset
= (t
!= FocusWin
) ? windowcolorset
: activecolorset
;
2083 if (cset
> -1 && (size_changed
|| CSET_IS_TRANSPARENT(cset
)))
2085 SetWindowBackground(
2086 dpy
, t
->PagerView
, t
->pager_view_width
, t
->pager_view_height
,
2087 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
2092 XDestroyWindow(dpy
,t
->PagerView
);
2093 t
->PagerView
= None
;
2097 CalcGeom(t
, icon_w
, icon_h
, &x
, &y
, &w
, &h
);
2098 size_changed
= (t
->icon_view_width
!= w
|| t
->icon_view_height
!= h
);
2101 t
->icon_view_width
= w
;
2102 t
->icon_view_height
= h
;
2103 if(Scr
.CurrentDesk
!= t
->desk
)
2104 XMoveResizeWindow(dpy
,t
->IconView
,-32768,-32768,w
,h
);
2109 XMoveResizeWindow(dpy
,t
->IconView
,x
,y
,w
,h
);
2110 cset
= (t
!= FocusWin
) ? windowcolorset
: activecolorset
;
2111 if (cset
> -1 && (size_changed
|| CSET_IS_TRANSPARENT(cset
)))
2113 SetWindowBackground(
2114 dpy
, t
->IconView
, t
->icon_view_width
, t
->icon_view_height
,
2115 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
2120 void MoveResizePagerView(PagerWindow
*t
, Bool do_force_redraw
)
2124 Bool position_changed
;
2126 if (UseSkipList
&& DO_SKIP_WINDOW_LIST(t
) && t
->myflags
.is_mapped
)
2129 XUnmapWindow(dpy
, t
->PagerView
);
2131 XUnmapWindow(dpy
, t
->IconView
);
2132 t
->myflags
.is_mapped
= 0;
2134 else if (UseSkipList
&& !DO_SKIP_WINDOW_LIST(t
) && !t
->myflags
.is_mapped
)
2137 XMapRaised(dpy
, t
->PagerView
);
2139 XMapRaised(dpy
, t
->IconView
);
2140 t
->myflags
.is_mapped
= 1;
2143 CalcGeom(t
, desk_w
, desk_h
, &x
, &y
, &w
, &h
);
2144 position_changed
= (t
->pager_view_x
!= x
|| t
->pager_view_y
!= y
);
2145 size_changed
= (t
->pager_view_width
!= w
|| t
->pager_view_height
!= h
);
2146 t
->pager_view_x
= x
;
2147 t
->pager_view_y
= y
;
2148 t
->pager_view_width
= w
;
2149 t
->pager_view_height
= h
;
2150 if (t
->PagerView
!= None
)
2152 if (size_changed
|| position_changed
|| do_force_redraw
)
2156 XMoveResizeWindow(dpy
, t
->PagerView
, x
, y
, w
, h
);
2157 cset
= (t
!= FocusWin
) ? windowcolorset
: activecolorset
;
2158 if (cset
> -1 && (size_changed
|| CSET_IS_TRANSPARENT(cset
)))
2160 SetWindowBackground(
2161 dpy
, t
->PagerView
, t
->pager_view_width
, t
->pager_view_height
,
2162 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
2166 else if (t
->desk
>= desk1
&& t
->desk
<= desk2
)
2168 XDestroyWindow(dpy
, t
->IconView
);
2173 CalcGeom(t
, icon_w
, icon_h
, &x
, &y
, &w
, &h
);
2174 position_changed
= (t
->icon_view_x
!= x
|| t
->icon_view_y
!= y
);
2175 size_changed
= (t
->icon_view_width
!= w
|| t
->icon_view_height
!= h
);
2178 t
->icon_view_width
= w
;
2179 t
->icon_view_height
= h
;
2180 if (Scr
.CurrentDesk
== t
->desk
)
2184 XMoveResizeWindow(dpy
, t
->IconView
, x
, y
, w
, h
);
2185 cset
= (t
!= FocusWin
) ? windowcolorset
: activecolorset
;
2186 if (cset
> -1 && (size_changed
|| CSET_IS_TRANSPARENT(cset
)))
2188 SetWindowBackground(
2189 dpy
, t
->IconView
, t
->icon_view_width
, t
->icon_view_height
,
2190 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
2195 XMoveResizeWindow(dpy
, t
->IconView
, -32768, -32768, w
, h
);
2200 void MoveStickyWindow(Bool is_new_page
, Bool is_new_desk
)
2204 for (t
= Start
; t
!= NULL
; t
= t
->next
)
2207 is_new_desk
&& t
->desk
!= Scr
.CurrentDesk
&&
2208 ((IS_ICONIFIED(t
) && IS_ICON_STICKY_ACROSS_DESKS(t
)) ||
2209 IS_STICKY_ACROSS_DESKS(t
)))
2211 ChangeDeskForWindow(t
, Scr
.CurrentDesk
);
2215 ((IS_ICONIFIED(t
) &&
2216 IS_ICON_STICKY_ACROSS_PAGES(t
)) ||
2217 IS_STICKY_ACROSS_PAGES(t
)))
2219 MoveResizePagerView(t
, True
);
2224 void Hilight(PagerWindow
*t
, int on
)
2234 if(t
->PagerView
!= None
)
2235 XSetWindowBackgroundPixmap(dpy
,t
->PagerView
,Scr
.gray_pixmap
);
2236 XSetWindowBackgroundPixmap(dpy
,t
->IconView
,Scr
.gray_pixmap
);
2240 if(IS_STICKY_ACROSS_DESKS(t
) || IS_STICKY_ACROSS_PAGES(t
))
2242 if(t
->PagerView
!= None
)
2243 XSetWindowBackgroundPixmap(dpy
,t
->PagerView
,
2244 Scr
.sticky_gray_pixmap
);
2245 XSetWindowBackgroundPixmap(dpy
,t
->IconView
,
2246 Scr
.sticky_gray_pixmap
);
2250 if(t
->PagerView
!= None
)
2251 XSetWindowBackgroundPixmap(dpy
,t
->PagerView
,
2252 Scr
.light_gray_pixmap
);
2253 XSetWindowBackgroundPixmap(dpy
,t
->IconView
,
2254 Scr
.light_gray_pixmap
);
2257 if(t
->PagerView
!= None
)
2258 XClearArea(dpy
, t
->PagerView
, 0, 0, 0, 0, True
);
2259 XClearArea(dpy
, t
->IconView
, 0, 0, 0, 0, True
);
2266 cset
= (on
) ? activecolorset
: windowcolorset
;
2267 pix
= (on
) ? focus_pix
: t
->back
;
2270 if (t
->PagerView
!= None
)
2272 XSetWindowBackground(dpy
,t
->PagerView
,pix
);
2273 XClearArea(dpy
, t
->PagerView
, 0, 0, 0, 0, True
);
2275 XSetWindowBackground(dpy
,t
->IconView
,pix
);
2276 XClearArea(dpy
, t
->IconView
, 0, 0, 0, 0, True
);
2280 if (t
->PagerView
!= None
)
2282 SetWindowBackground(
2283 dpy
, t
->PagerView
, t
->pager_view_width
, t
->pager_view_height
,
2284 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
2286 SetWindowBackground(
2287 dpy
, t
->IconView
, t
->icon_view_width
, t
->icon_view_height
,
2288 &Colorset
[cset
], Pdepth
, Scr
.NormalGC
, True
);
2293 /* Use Desk == -1 to scroll the icon window */
2294 void Scroll(int window_w
, int window_h
, int x
, int y
, int Desk
,
2295 Bool do_scroll_icon
)
2297 static int last_sx
= -999999;
2298 static int last_sy
= -999999;
2303 /* Desk < 0 means we want to scroll an icon window */
2304 if (Desk
>= 0 && Desk
+ desk1
!= Scr
.CurrentDesk
)
2309 /* center around mouse */
2310 adjx
= (desk_w
/ (1 + Scr
.VxMax
/ Scr
.MyDisplayWidth
));
2311 adjy
= (desk_h
/ (1 + Scr
.VyMax
/ Scr
.MyDisplayHeight
));
2315 /* adjust for pointer going out of range */
2325 if (x
> window_w
-adjx
)
2329 if (y
> window_h
-adjy
)
2338 sx
= (x
* Scr
.VWidth
/ window_w
- MyVx
);
2342 sy
= (y
* Scr
.VHeight
/ window_h
- MyVy
);
2344 MYFPRINTF((stderr
,"[scroll]: %d %d %d %d %d %d\n", window_w
, window_h
,
2346 if (sx
== 0 && sy
== 0)
2350 if (Wait
== 0 || last_sx
!= sx
|| last_sy
!= sy
)
2352 do_scroll(sx
, sy
, False
, False
);
2354 /* Here we need to track the view offset on the desk. */
2355 /* sx/y are are pixels on the screen to scroll. */
2356 /* We don't use Scr.Vx/y since they lag the true position. */
2379 void MoveWindow(XEvent
*Event
)
2382 int x1
, y1
, wx
, wy
, n
, x
, y
, xi
= 0, yi
= 0, wx1
, wy1
, x2
, y2
;
2387 int NewDesk
, KeepMoving
= 0;
2390 Window JunkRoot
, JunkChild
;
2393 int do_switch_desk_later
= 0;
2396 while (t
!= NULL
&& t
->PagerView
!= Event
->xbutton
.subwindow
)
2404 while (t
!= NULL
&& t
->IconView
!= Event
->xbutton
.subwindow
)
2410 IconMoveWindow(Event
, t
);
2415 if (t
== NULL
|| !t
->allowed_actions
.is_movable
)
2420 NewDesk
= t
->desk
- desk1
;
2421 if (NewDesk
< 0 || NewDesk
>= ndesks
)
2426 n
= Scr
.VxMax
/ Scr
.MyDisplayWidth
;
2427 m
= Scr
.VyMax
/ Scr
.MyDisplayHeight
;
2428 n1
= (Scr
.Vx
+ t
->x
) / Scr
.MyDisplayWidth
;
2429 m1
= (Scr
.Vy
+ t
->y
) / Scr
.MyDisplayHeight
;
2430 wx
= (Scr
.Vx
+ t
->x
) * (desk_w
- n
) / Scr
.VWidth
+ n1
;
2431 wy
= (Scr
.Vy
+ t
->y
) * (desk_h
- m
) / Scr
.VHeight
+ m1
;
2432 wx1
= wx
+ (desk_w
+ 1) * (NewDesk
% Columns
);
2433 wy1
= wy
+ label_h
+ (desk_h
+ label_h
+ 1) * (NewDesk
/ Columns
);
2439 XReparentWindow(dpy
, t
->PagerView
, Scr
.Pager_w
, wx1
, wy1
);
2440 XRaiseWindow(dpy
, t
->PagerView
);
2442 XTranslateCoordinates(dpy
, Event
->xany
.window
, t
->PagerView
,
2443 Event
->xbutton
.x
, Event
->xbutton
.y
, &x1
, &y1
,
2449 FMaskEvent(dpy
, ButtonReleaseMask
| ButtonMotionMask
|
2450 ExposureMask
, Event
);
2451 if (Event
->type
== MotionNotify
)
2453 XTranslateCoordinates(dpy
, Event
->xany
.window
,
2454 Scr
.Pager_w
, Event
->xmotion
.x
,
2455 Event
->xmotion
.y
, &x
, &y
,
2464 if (x
< -5 || y
< -5 || x
> window_w
+ 5 ||
2470 XMoveWindow(dpy
, t
->PagerView
, x
- x1
, y
- y1
);
2472 else if (Event
->type
== ButtonRelease
)
2474 XTranslateCoordinates(dpy
, Event
->xany
.window
,
2475 Scr
.Pager_w
, Event
->xbutton
.x
,
2476 Event
->xbutton
.y
, &x
, &y
,
2478 XMoveWindow(dpy
, t
->PagerView
, x
- x1
, y
- y1
);
2481 else if (Event
->type
== Expose
)
2483 HandleExpose(Event
);
2489 if (abs(x
- xi
) < MoveThreshold
&&
2490 abs(y
- yi
) < MoveThreshold
)
2497 NewDesk
= Scr
.CurrentDesk
;
2499 if (NewDesk
>= desk1
&& NewDesk
<= desk2
)
2501 XReparentWindow(dpy
, t
->PagerView
,
2502 Desks
[NewDesk
-desk1
].w
, 0, 0);
2506 XDestroyWindow(dpy
, t
->PagerView
);
2507 t
->PagerView
= None
;
2509 if (FQueryPointer(dpy
, Scr
.Root
, &JunkRoot
, &JunkChild
,
2510 &x
, &y
, &JunkX
, &JunkY
, &JunkMask
) == False
)
2512 /* pointer is on a different screen */
2516 XUngrabPointer(dpy
,CurrentTime
);
2519 if (NewDesk
!= t
->desk
)
2521 /* griph: This used to move to NewDesk, but NewDesk
2522 * is current desk, and if fvwm is on another
2523 * desk (due to async operation) we have to move
2524 * the window to it anyway or "Move Pointer" will
2525 * move an invisible window. */
2527 SendText(fd
, "Silent MoveToDesk", t
->w
);
2530 SendText(fd
, "Silent Raise", t
->w
);
2531 SendText(fd
, "Silent Move Pointer", t
->w
);
2536 column
= x
/ (desk_w
+ 1);
2537 if (column
>= Columns
)
2539 column
= Columns
- 1;
2545 row
= y
/ (desk_h
+ label_h
+ 1);
2554 NewDesk
= column
+ row
* Columns
;
2558 if (NewDesk
>= ndesks
)
2563 while (NewDesk
>= ndesks
)
2568 NewDesk
= ndesks
- 1;
2571 XTranslateCoordinates(dpy
, Scr
.Pager_w
, Desks
[NewDesk
].w
,
2572 x
- x1
, y
- y1
, &x2
, &y2
, &dumwin
);
2574 n1
= x2
* Scr
.VWidth
/ (desk_w
* Scr
.MyDisplayWidth
);
2575 m1
= y2
* Scr
.VHeight
/ (desk_h
* Scr
.MyDisplayHeight
);
2576 x
= (x2
- n1
) * Scr
.VWidth
/ (desk_w
- n
) - Scr
.Vx
;
2577 y
= (y2
- m1
) * Scr
.VHeight
/ (desk_h
- m
) - Scr
.Vy
;
2578 /* force onto desk */
2579 if (x
+ t
->frame_width
+ Scr
.Vx
< 0 )
2581 x
= -Scr
.Vx
- t
->frame_width
;
2583 if (y
+ t
->frame_height
+ Scr
.Vy
< 0)
2585 y
= -Scr
.Vy
- t
->frame_height
;
2587 if (x
+ Scr
.Vx
>= Scr
.VWidth
)
2589 x
= Scr
.VWidth
- Scr
.Vx
- 1;
2591 if (y
+ Scr
.Vy
>= Scr
.VHeight
)
2593 y
= Scr
.VHeight
- Scr
.Vy
- 1;
2595 if ((IS_ICONIFIED(t
) && IS_ICON_STICKY_ACROSS_DESKS(t
)) ||
2596 (IS_STICKY_ACROSS_DESKS(t
)))
2598 NewDesk
= Scr
.CurrentDesk
- desk1
;
2599 if (x
> Scr
.MyDisplayWidth
- 16)
2601 x
= Scr
.MyDisplayWidth
- 16;
2603 if (y
> Scr
.MyDisplayHeight
- 16)
2605 y
= Scr
.MyDisplayHeight
- 16;
2607 if (x
+ t
->width
< 16)
2611 if (y
+ t
->height
< 16)
2616 if (NewDesk
+ desk1
!= t
->desk
)
2618 if ((IS_ICONIFIED(t
) && IS_ICON_STICKY_ACROSS_DESKS(t
))
2619 || (IS_STICKY_ACROSS_DESKS(t
)))
2621 NewDesk
= Scr
.CurrentDesk
- desk1
;
2622 if (t
->desk
!= Scr
.CurrentDesk
)
2624 ChangeDeskForWindow(t
,Scr
.CurrentDesk
);
2627 else if (NewDesk
+ desk1
!= Scr
.CurrentDesk
)
2629 sprintf(command
, "Silent MoveToDesk 0 %d",
2631 SendText(fd
, command
, t
->w
);
2632 t
->desk
= NewDesk
+ desk1
;
2636 do_switch_desk_later
= 1;
2640 if (NewDesk
>= 0 && NewDesk
< ndesks
)
2642 XReparentWindow(dpy
, t
->PagerView
,
2643 Desks
[NewDesk
].w
, x2
, y2
);
2645 XClearArea(dpy
, t
->PagerView
, 0, 0, 0, 0, True
);
2649 sprintf(buf
, "Silent Move +%dp +%dp", x
, y
);
2651 SendText(fd
, buf
, t
->w
);
2656 MoveResizePagerView(t
, True
);
2658 SendText(fd
, "Silent Raise", t
->w
);
2660 if (do_switch_desk_later
)
2662 sprintf(command
, "Silent MoveToDesk 0 %d", NewDesk
+
2664 SendText(fd
, command
, t
->w
);
2665 t
->desk
= NewDesk
+ desk1
;
2667 if (Scr
.CurrentDesk
== t
->desk
)
2673 SendText(fd
, "Silent FlipFocus NoWarp", t
->w
);
2678 /* does not return */
2687 * FvwmErrorHandler - displays info on internal errors
2690 int FvwmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
2693 extern Bool error_occured
;
2694 error_occured
= True
;
2697 /* really should just exit here... */
2698 /* domivogt (07-mar-1999): No, not really. See comment above. */
2699 PrintXErrorAndCoredump(dpy
, event
, MyName
);
2704 static void draw_window_border(PagerWindow
*t
, Window w
, int width
, int height
)
2708 if (!WindowBorders3d
|| windowcolorset
< 0 || activecolorset
< 0)
2710 XSetForeground(dpy
, Scr
.NormalGC
, Scr
.black
);
2712 dpy
, w
, 0, 0, width
- 1, t
->pager_view_height
- 1,
2713 Scr
.NormalGC
, Scr
.NormalGC
, WindowBorderWidth
);
2715 else if (t
== FocusWin
)
2718 dpy
, w
, 0, 0, width
- 1, height
- 1,
2719 Scr
.ahGC
, Scr
.asGC
, WindowBorderWidth
);
2724 dpy
, w
, 0, 0, width
- 1, height
- 1,
2725 Scr
.whGC
, Scr
.wsGC
, WindowBorderWidth
);
2730 void BorderWindow(PagerWindow
*t
)
2733 t
, t
->PagerView
, t
->pager_view_width
, t
->pager_view_height
);
2736 void BorderIconWindow(PagerWindow
*t
)
2739 t
, t
->IconView
, t
->icon_view_width
, t
->icon_view_height
);
2742 static void do_label_window(PagerWindow
*t
, Window w
)
2748 XSetForeground(dpy
, Scr
.NormalGC
, focus_fore_pix
);
2749 cs
= activecolorset
;
2753 XSetForeground(dpy
, Scr
.NormalGC
, t
->text
);
2754 cs
= windowcolorset
;
2757 if (FwindowFont
== NULL
)
2761 if (MiniIcons
&& t
->mini_icon
.picture
&& (t
->PagerView
!= None
))
2763 /* will draw picture instead... */
2766 if (t
->icon_name
== NULL
)
2771 /* Update the window label for this window */
2772 if (t
->window_label
)
2773 free(t
->window_label
);
2774 t
->window_label
= GetBalloonLabel(t
, WindowLabelFormat
);
2777 if (FftSupport
&& FwindowFont
!= NULL
&& FwindowFont
->fftf
.fftfont
!= NULL
)
2778 XClearWindow(dpy
, w
);
2779 FwinString
->str
= t
->window_label
;
2780 FwinString
->win
= w
;
2781 FwinString
->gc
= Scr
.NormalGC
;
2782 FwinString
->flags
.has_colorset
= False
;
2785 FwinString
->colorset
= &Colorset
[cs
];
2786 FwinString
->flags
.has_colorset
= True
;
2789 FwinString
->y
= FwindowFont
->ascent
+2;
2790 FlocaleDrawString(dpy
, FwindowFont
, FwinString
, 0);
2794 void LabelWindow(PagerWindow
*t
)
2796 do_label_window(t
, t
->PagerView
);
2799 void LabelIconWindow(PagerWindow
*t
)
2801 do_label_window(t
, t
->IconView
);
2804 static void do_picture_window(
2805 PagerWindow
*t
, Window w
, int width
, int height
)
2813 FvwmRenderAttributes fra
;
2817 if (t
->mini_icon
.picture
&& w
!= None
)
2819 dest_w
= t
->mini_icon
.width
;
2820 dest_h
= t
->mini_icon
.height
;
2821 if (width
> t
->mini_icon
.width
)
2823 iconX
= (width
- t
->mini_icon
.width
) / 2;
2825 else if (width
< t
->mini_icon
.width
)
2828 src_x
= (t
->mini_icon
.width
- width
) / 2;
2835 if (height
> t
->mini_icon
.height
)
2837 iconY
= (height
- t
->mini_icon
.height
) / 2;
2839 else if (height
< t
->mini_icon
.height
)
2842 src_y
= (t
->mini_icon
.height
- height
) / 2;
2849 fra
.mask
= FRAM_DEST_IS_A_WINDOW
;
2852 cs
= activecolorset
;
2856 cs
= windowcolorset
;
2858 if (t
->mini_icon
.alpha
!= None
||
2860 Colorset
[cs
].icon_alpha_percent
< 100))
2862 XClearArea(dpy
, w
, iconX
, iconY
,
2864 t
->mini_icon
.height
, False
);
2868 fra
.mask
|= FRAM_HAVE_ICON_CSET
;
2869 fra
.colorset
= &Colorset
[cs
];
2871 PGraphicsRenderPicture(
2872 dpy
, w
, &t
->mini_icon
, &fra
, w
,
2873 Scr
.MiniIconGC
, None
, None
, src_x
, src_y
,
2874 t
->mini_icon
.width
- src_x
,
2875 t
->mini_icon
.height
- src_y
,
2876 iconX
, iconY
, dest_w
, dest_h
, False
);
2881 void PictureWindow (PagerWindow
*t
)
2883 do_picture_window(t
, t
->PagerView
, t
->pager_view_width
, t
->pager_view_height
);
2886 void PictureIconWindow (PagerWindow
*t
)
2888 do_picture_window(t
, t
->IconView
, t
->icon_view_width
, t
->icon_view_height
);
2891 void IconMoveWindow(XEvent
*Event
, PagerWindow
*t
)
2893 int x1
, y1
, finished
= 0, wx
, wy
, n
, x
= 0, y
= 0, xi
= 0, yi
= 0;
2898 Window JunkRoot
, JunkChild
;
2902 if (t
== NULL
|| !t
->allowed_actions
.is_movable
)
2907 n
= Scr
.VxMax
/ Scr
.MyDisplayWidth
;
2908 m
= Scr
.VyMax
/ Scr
.MyDisplayHeight
;
2909 n1
= (Scr
.Vx
+ t
->x
) / Scr
.MyDisplayWidth
;
2910 m1
= (Scr
.Vy
+ t
->y
) / Scr
.MyDisplayHeight
;
2911 wx
= (Scr
.Vx
+ t
->x
) * (icon_w
- n
) / Scr
.VWidth
+ n1
;
2912 wy
= (Scr
.Vy
+ t
->y
) * (icon_h
- m
) / Scr
.VHeight
+ m1
;
2914 XRaiseWindow(dpy
, t
->IconView
);
2916 XTranslateCoordinates(dpy
, Event
->xany
.window
, t
->IconView
,
2917 Event
->xbutton
.x
, Event
->xbutton
.y
, &x1
, &y1
,
2921 FMaskEvent(dpy
, ButtonReleaseMask
| ButtonMotionMask
|
2922 ExposureMask
, Event
);
2924 if (Event
->type
== MotionNotify
)
2926 x
= Event
->xbutton
.x
;
2927 y
= Event
->xbutton
.y
;
2935 XMoveWindow(dpy
, t
->IconView
, x
- x1
, y
- y1
);
2936 if (x
< -5 || y
< -5 || x
> icon_w
+ 5 ||
2943 else if (Event
->type
== ButtonRelease
)
2945 x
= Event
->xbutton
.x
;
2946 y
= Event
->xbutton
.y
;
2947 XMoveWindow(dpy
, t
->PagerView
, x
- x1
, y
- y1
);
2950 else if (Event
->type
== Expose
)
2952 HandleExpose(Event
);
2958 if (abs(x
- xi
) < MoveThreshold
&&
2959 abs(y
- yi
) < MoveThreshold
)
2967 if (FQueryPointer(dpy
, Scr
.Root
, &JunkRoot
, &JunkChild
,
2968 &x
, &y
, &JunkX
, &JunkY
, &JunkMask
) == False
)
2970 /* pointer is on a different screen */
2974 XUngrabPointer(dpy
, CurrentTime
);
2976 SendText(fd
, "Silent Raise", t
->w
);
2977 SendText(fd
, "Silent Move Pointer", t
->w
);
2983 n1
= x
* Scr
.VWidth
/ (icon_w
* Scr
.MyDisplayWidth
);
2984 m1
= y
* Scr
.VHeight
/ (icon_h
* Scr
.MyDisplayHeight
);
2985 x
= (x
- n1
) * Scr
.VWidth
/ (icon_w
- n
) - Scr
.Vx
;
2986 y
= (y
- m1
) * Scr
.VHeight
/ (icon_h
- m
) - Scr
.Vy
;
2987 /* force onto desk */
2988 if (x
+ t
->icon_width
+ Scr
.Vx
< 0 )
2990 x
= - Scr
.Vx
- t
->icon_width
;
2992 if (y
+ t
->icon_height
+ Scr
.Vy
< 0)
2994 y
= - Scr
.Vy
- t
->icon_height
;
2996 if (x
+ Scr
.Vx
>= Scr
.VWidth
)
2998 x
= Scr
.VWidth
- Scr
.Vx
- 1;
3000 if (y
+ Scr
.Vy
>= Scr
.VHeight
)
3002 y
= Scr
.VHeight
- Scr
.Vy
- 1;
3004 if ((IS_ICONIFIED(t
) && IS_ICON_STICKY_ACROSS_DESKS(t
)) ||
3005 IS_STICKY_ACROSS_DESKS(t
))
3007 if (x
> Scr
.MyDisplayWidth
- 16)
3009 x
= Scr
.MyDisplayWidth
- 16;
3011 if (y
> Scr
.MyDisplayHeight
- 16)
3013 y
= Scr
.MyDisplayHeight
- 16;
3015 if (x
+ t
->width
< 16)
3019 if (y
+ t
->height
< 16)
3027 sprintf(buf
, "Silent Move +%dp +%dp", x
, y
);
3028 SendText(fd
, buf
, t
->w
);
3033 MoveResizePagerView(t
, True
);
3035 SendText(fd
, "Silent Raise", t
->w
);
3036 SendText(fd
, "Silent FlipFocus NoWarp", t
->w
);
3040 /* does not return */
3046 void setup_balloon_window(int i
)
3048 XSetWindowAttributes xswa
;
3049 unsigned long valuemask
;
3051 if (!ShowBalloons
&& Scr
.balloon_w
== None
)
3055 XUnmapWindow(dpy
, Scr
.balloon_w
);
3056 if (Desks
[i
].ballooncolorset
< 0)
3058 xswa
.border_pixel
= (!BalloonBorderColor
) ?
3059 fore_pix
: GetColor(BalloonBorderColor
);
3060 xswa
.background_pixel
=
3061 (!BalloonBack
) ? back_pix
: GetColor(BalloonBack
);
3062 valuemask
= CWBackPixel
| CWBorderPixel
;
3066 xswa
.border_pixel
= Colorset
[Desks
[i
].ballooncolorset
].fg
;
3067 xswa
.background_pixel
= Colorset
[Desks
[i
].ballooncolorset
].bg
;
3068 if (Colorset
[Desks
[i
].ballooncolorset
].pixmap
)
3071 xswa
.background_pixmap
= None
;
3072 valuemask
= CWBackPixmap
| CWBorderPixel
;;
3076 valuemask
= CWBackPixel
| CWBorderPixel
;
3079 XChangeWindowAttributes(dpy
, Scr
.balloon_w
, valuemask
, &xswa
);
3084 void setup_balloon_gc(int i
, PagerWindow
*t
)
3087 unsigned long valuemask
;
3089 valuemask
= GCForeground
;
3090 if (Desks
[i
].ballooncolorset
< 0)
3093 (!BalloonFore
) ? fore_pix
: GetColor(BalloonFore
);
3094 if (BalloonFore
== NULL
)
3096 XSetForeground(dpy
, Scr
.balloon_gc
, t
->text
);
3101 xgcv
.foreground
= Colorset
[Desks
[i
].ballooncolorset
].fg
;
3103 if (Desks
[i
].balloon
.Ffont
->font
!= NULL
)
3105 xgcv
.font
= Desks
[i
].balloon
.Ffont
->font
->fid
;
3106 valuemask
|= GCFont
;
3108 XChangeGC(dpy
, Scr
.balloon_gc
, valuemask
, &xgcv
);
3113 /* Just maps window ... draw stuff in it later after Expose event
3114 -- ric@giccs.georgetown.edu */
3115 void MapBalloonWindow(PagerWindow
*t
, Bool is_icon_view
)
3117 extern char *BalloonBack
;
3118 extern int BalloonYOffset
;
3119 extern int BalloonBorderWidth
;
3121 int view_width
, view_height
;
3128 view
= t
->PagerView
;
3129 view_width
= t
->pager_view_width
;
3130 view_height
= t
->pager_view_height
;
3135 view_width
= t
->icon_view_width
;
3136 view_height
= t
->icon_view_height
;
3139 /* associate balloon with its pager window */
3140 if (fAlwaysCurrentDesk
)
3146 i
= t
->desk
- desk1
;
3148 Scr
.balloon_desk
= i
;
3149 /* get the label for this balloon */
3150 if (Scr
.balloon_label
)
3152 free(Scr
.balloon_label
);
3154 Scr
.balloon_label
= GetBalloonLabel(t
, BalloonFormatString
);
3156 if (Scr
.balloon_label
== NULL
)
3158 /* dont draw empty labels */
3162 setup_balloon_window(i
);
3163 setup_balloon_gc(i
, t
);
3164 /* calculate window width to accommodate string */
3165 new_g
.height
= Desks
[i
].balloon
.height
;
3167 if (Scr
.balloon_label
)
3169 new_g
.width
+= FlocaleTextWidth(
3170 Desks
[i
].balloon
.Ffont
, Scr
.balloon_label
,
3171 strlen(Scr
.balloon_label
));
3173 /* get x and y coords relative to pager window */
3174 x
= (view_width
/ 2) - (new_g
.width
/ 2) - BalloonBorderWidth
;
3175 if (BalloonYOffset
> 0)
3177 y
= view_height
+ BalloonYOffset
- 1;
3181 y
= BalloonYOffset
- new_g
.height
+ 1 -
3182 (2 * BalloonBorderWidth
);
3184 /* balloon is a top-level window, therefore need to
3185 translate pager window coords to root window coords */
3186 XTranslateCoordinates(
3187 dpy
, view
, Scr
.Root
, x
, y
, &new_g
.x
, &new_g
.y
,
3189 /* make sure balloon doesn't go off screen
3190 * (actually 2 pixels from edge rather than 0 just to be pretty :-) */
3191 /* too close to top ... make yoffset +ve */
3194 y
= - BalloonYOffset
- 1 + view_height
;
3195 XTranslateCoordinates(
3196 dpy
, view
, Scr
.Root
, x
, y
, &new_g
.x
, &new_g
.y
, &dummy
);
3198 /* too close to bottom ... make yoffset -ve */
3199 else if ( new_g
.y
+ new_g
.height
>
3200 Scr
.MyDisplayHeight
- (2 * BalloonBorderWidth
) - 2 )
3202 y
= - BalloonYOffset
+ 1 - new_g
.height
-
3203 (2 * BalloonBorderWidth
);
3204 XTranslateCoordinates(
3205 dpy
, view
, Scr
.Root
, x
, y
, &new_g
.x
, &new_g
.y
, &dummy
);
3207 /* too close to left */
3212 /* too close to right */
3213 else if (new_g
.x
+ new_g
.width
>
3214 Scr
.MyDisplayWidth
- (2 * BalloonBorderWidth
) - 2 )
3216 new_g
.x
= Scr
.MyDisplayWidth
- new_g
.width
-
3217 (2 * BalloonBorderWidth
) - 2;
3219 /* make changes to window */
3221 dpy
, Scr
.balloon_w
, new_g
.x
, new_g
.y
, new_g
.width
,
3223 /* if background not set in config make it match pager window */
3224 if ( BalloonBack
== NULL
)
3226 XSetWindowBackground(dpy
, Scr
.balloon_w
, t
->back
);
3228 if (Desks
[i
].ballooncolorset
> -1)
3230 SetWindowBackground(
3231 dpy
, Scr
.balloon_w
, new_g
.width
, new_g
.height
,
3232 &Colorset
[Desks
[i
].ballooncolorset
], Pdepth
,
3233 Scr
.NormalGC
, True
);
3236 Colorset
[Desks
[i
].ballooncolorset
].fg
);
3238 XMapRaised(dpy
, Scr
.balloon_w
);
3244 static void InsertExpand(char **dest
, char *s
)
3251 len
= strlen(*dest
) + strlen(s
) + 1;
3252 *dest
= (char *)safemalloc(len
);
3260 /* Generate the BallonLabel from the format string
3261 -- disching@fmi.uni-passau.de */
3262 char *GetBalloonLabel(const PagerWindow
*pw
,const char *fmt
)
3264 char *dest
= safestrdup("");
3265 const char *pos
= fmt
;
3271 if (*pos
=='%' && *(pos
+1)!='\0') {
3275 InsertExpand(&dest
, pw
->icon_name
);
3278 InsertExpand(&dest
, pw
->window_name
);
3281 InsertExpand(&dest
, pw
->res_name
);
3284 InsertExpand(&dest
, pw
->res_class
);
3288 InsertExpand(&dest
, buffer
);
3294 InsertExpand(&dest
, buffer
);
3302 /* -- ric@giccs.georgetown.edu */
3303 void UnmapBalloonWindow (void)
3305 XUnmapWindow(dpy
, Scr
.balloon_w
);
3310 /* Draws string in balloon window -- call after it's received Expose event
3311 -- ric@giccs.georgetown.edu */
3312 void DrawInBalloonWindow (int i
)
3314 FwinString
->str
= Scr
.balloon_label
;
3315 FwinString
->win
= Scr
.balloon_w
;
3316 FwinString
->gc
= Scr
.balloon_gc
;
3317 if (Desks
[i
].ballooncolorset
>= 0)
3319 FwinString
->colorset
= &Colorset
[Desks
[i
].ballooncolorset
];
3320 FwinString
->flags
.has_colorset
= True
;
3324 FwinString
->flags
.has_colorset
= False
;
3327 FwinString
->y
= Desks
[i
].balloon
.Ffont
->ascent
;
3328 FlocaleDrawString(dpy
, Desks
[i
].balloon
.Ffont
, FwinString
, 0);
3333 static void set_window_colorset_background(
3334 PagerWindow
*t
, colorset_t
*csetp
)
3336 if (t
->PagerView
!= None
)
3338 SetWindowBackground(
3339 dpy
, t
->PagerView
, t
->pager_view_width
, t
->pager_view_height
,
3340 csetp
, Pdepth
, Scr
.NormalGC
, True
);
3342 SetWindowBackground(
3343 dpy
, t
->IconView
, t
->icon_view_width
, t
->icon_view_height
,
3344 csetp
, Pdepth
, Scr
.NormalGC
, True
);
3349 /* should be in sync with draw_desk_background */
3350 void change_colorset(int colorset
)
3359 XSetWindowBackgroundPixmap(dpy
, Scr
.Pager_w
, default_pixmap
);
3360 for(i
=0;i
<ndesks
;i
++)
3362 if (Desks
[i
].highcolorset
== colorset
)
3364 XSetForeground(dpy
, Desks
[i
].HiliteGC
,Colorset
[colorset
].bg
);
3365 XSetForeground(dpy
, Desks
[i
].rvGC
, Colorset
[colorset
].fg
);
3368 if (uselabel
&& (i
== Scr
.CurrentDesk
))
3370 SetWindowBackground(
3371 dpy
, Desks
[i
].title_w
, desk_w
, desk_h
, &Colorset
[colorset
], Pdepth
,
3372 Scr
.NormalGC
, True
);
3374 SetWindowBackground(
3375 dpy
, Desks
[i
].CPagerWin
, 0, 0, &Colorset
[colorset
], Pdepth
,
3376 Scr
.NormalGC
, True
);
3377 XLowerWindow(dpy
,Desks
[i
].CPagerWin
);
3381 if (Desks
[i
].colorset
== colorset
)
3383 XSetWindowBorder(dpy
, Desks
[i
].title_w
, Colorset
[colorset
].fg
);
3384 XSetWindowBorder(dpy
, Desks
[i
].w
, Colorset
[colorset
].fg
);
3385 XSetForeground(dpy
, Desks
[i
].NormalGC
,Colorset
[colorset
].fg
);
3386 XSetForeground(dpy
, Desks
[i
].DashedGC
,Colorset
[colorset
].fg
);
3389 SetWindowBackground(
3390 dpy
, Desks
[i
].title_w
, desk_w
, desk_h
+ label_h
, &Colorset
[colorset
],
3391 Pdepth
, Scr
.NormalGC
, True
);
3393 if (label_h
!= 0 && uselabel
&& !LabelsBelow
&&
3394 !CSET_IS_TRANSPARENT_PR(Desks
[i
].colorset
))
3396 SetWindowBackgroundWithOffset(
3397 dpy
, Desks
[i
].w
, 0, -label_h
, desk_w
, desk_h
+ label_h
,
3398 &Colorset
[colorset
], Pdepth
, Scr
.NormalGC
, True
);
3402 SetWindowBackground(
3403 dpy
, Desks
[i
].w
, desk_w
, desk_h
+ label_h
,
3404 &Colorset
[Desks
[i
].colorset
], Pdepth
, Scr
.NormalGC
, True
);
3406 update_pr_transparent_subwindows(i
);
3408 else if (Desks
[i
].highcolorset
== colorset
&& uselabel
)
3410 SetWindowBackground(
3411 dpy
, Desks
[i
].title_w
, 0, 0, &Colorset
[Desks
[i
].colorset
], Pdepth
,
3412 Scr
.NormalGC
, True
);
3415 if (ShowBalloons
&& Desks
[Scr
.balloon_desk
].ballooncolorset
== colorset
)
3417 XSetWindowBackground(dpy
, Scr
.balloon_w
, Colorset
[colorset
].fg
);
3418 XSetForeground(dpy
,Scr
.balloon_gc
, Colorset
[colorset
].fg
);
3419 XClearArea(dpy
, Scr
.balloon_w
, 0, 0, 0, 0, True
);
3422 if (windowcolorset
== colorset
)
3424 colorset_t
*csetp
= &Colorset
[colorset
];
3426 XSetForeground(dpy
, Scr
.whGC
, csetp
->hilite
);
3427 XSetForeground(dpy
, Scr
.wsGC
, csetp
->shadow
);
3428 win_back_pix
= csetp
->bg
;
3429 win_fore_pix
= csetp
->fg
;
3431 for (t
= Start
; t
!= NULL
; t
= t
->next
)
3433 t
->text
= Colorset
[colorset
].fg
;
3436 set_window_colorset_background(t
, csetp
);
3440 if (activecolorset
== colorset
)
3442 colorset_t
*csetp
= &Colorset
[colorset
];
3444 focus_fore_pix
= csetp
->fg
;
3445 XSetForeground(dpy
, Scr
.ahGC
, csetp
->hilite
);
3446 XSetForeground(dpy
, Scr
.asGC
, csetp
->shadow
);
3447 win_hi_back_pix
= csetp
->bg
;
3448 win_hi_fore_pix
= csetp
->fg
;
3449 win_hi_pix_set
= True
;
3452 set_window_colorset_background(FocusWin
, csetp
);