2 /* This module, and the entire GoodStuff program, and the concept for
3 * interfacing this module to the Window Manager, are all original work
6 * Copyright 1993, 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
27 #define MAX_ICON_NAME_LEN 255
32 #ifdef HAVE_SYS_BSDTYPES_H
33 #include <sys/bsdtypes.h> /* Saul */
39 #include "libs/ftime.h"
42 #include <sys/select.h>
46 #include <X11/Xatom.h>
48 #include "libs/Module.h"
49 #include "libs/fvwmlib.h"
50 #include "libs/Colorset.h"
51 #include "libs/PictureBase.h"
52 #include "libs/FScreen.h"
53 #include "libs/Graphics.h"
54 #include "libs/Parse.h"
55 #include "libs/Strings.h"
57 #include "FvwmScroll.h"
59 static int Width
= 300, Height
= 300;
60 static int target_width
, target_height
;
61 static int target_x_offset
= 0, target_y_offset
= 0;
69 #define SCROLL_BAR_WIDTH 9
74 static Window main_win
,holder_win
;
75 static Pixel hilite_pix
,shadow_pix
;
77 extern char *BackColor
;
79 #define MW_EVENTS (ExposureMask | StructureNotifyMask| ButtonReleaseMask |\
80 ButtonPressMask | ButtonMotionMask | FocusChangeMask)
83 Atom _XA_WM_PROTOCOLS
;
84 Atom _XA_WM_COLORMAP_WINDOWS
;
88 * Sizes and creates the window
91 XSizeHints mysizehints
;
92 void CreateWindow(int x
,int y
, int w
, int h
)
96 XSetWindowAttributes attributes
;
100 wm_del_win
= XInternAtom(dpy
,"WM_DELETE_WINDOW",False
);
101 _XA_WM_PROTOCOLS
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
103 mysizehints
.flags
= PWinGravity
| PResizeInc
| PBaseSize
| PMaxSize
| PMinSize
104 | USSize
| USPosition
;
105 /* subtract one for the right/bottom border */
106 mysizehints
.width_inc
= 1;
107 mysizehints
.height_inc
= 1;
108 mysizehints
.base_height
= BAR_WIDTH
+ PAD_WIDTH3
;
109 mysizehints
.base_width
= BAR_WIDTH
+ PAD_WIDTH3
;
111 if ( Percent_V
> -1 )
113 Width
= (ScreenWidth
* Percent_V
)/100;
114 if ( Width
> (w
+ BAR_WIDTH
+ PAD_WIDTH3
) || Percent_V
== 0 )
115 Width
= w
+ BAR_WIDTH
+ PAD_WIDTH3
;
119 Width
= w
/Reduction_V
+ BAR_WIDTH
+ PAD_WIDTH3
;
122 if ( Percent_H
> -1 )
124 Height
= (ScreenHeight
* Percent_H
)/100;
125 if ( Height
> h
|| Percent_H
== 0 )
126 Height
= h
+ BAR_WIDTH
+ PAD_WIDTH3
;
130 Height
= h
/Reduction_H
+ BAR_WIDTH
+ PAD_WIDTH3
;
135 mysizehints
.width
= Width
;
136 mysizehints
.height
= Height
;
139 mysizehints
.max_width
= w
+ BAR_WIDTH
+ PAD_WIDTH3
;
140 mysizehints
.max_height
= h
+ BAR_WIDTH
+ PAD_WIDTH3
;
142 mysizehints
.win_gravity
= NorthWestGravity
;
144 attributes
.backing_store
= NotUseful
;
145 attributes
.background_pixel
= (colorset
< 0) ? GetColor(BackColor
)
146 : Colorset
[colorset
].bg
;
147 attributes
.border_pixel
= 0;
148 attributes
.colormap
= Pcmap
;
149 main_win
= XCreateWindow(dpy
, Root
, wx
, wy
,
150 mysizehints
.width
, mysizehints
.height
, 0, Pdepth
,
151 InputOutput
, Pvisual
, CWBackingStore
| CWBackPixel
152 | CWBorderPixel
| CWColormap
, &attributes
);
154 hilite_pix
= (colorset
< 0) ? GetHilite(attributes
.background_pixel
)
155 : Colorset
[colorset
].hilite
;
156 shadow_pix
= (colorset
< 0) ? GetShadow(attributes
.background_pixel
)
157 : Colorset
[colorset
].shadow
;
159 XSetWMProtocols(dpy
,main_win
,&wm_del_win
,1);
161 /* hack to prevent mapping on wrong screen with StartsOnScreen */
162 FScreenMangleScreenIntoUSPosHints(FSCREEN_XYPOS
, &mysizehints
);
163 XSetWMNormalHints(dpy
,main_win
,&mysizehints
);
164 XSelectInput(dpy
,main_win
,MW_EVENTS
);
165 change_window_name(module
->name
);
167 holder_win
= XCreateWindow(dpy
, main_win
, PAD_WIDTH3
, PAD_WIDTH3
,
168 mysizehints
.width
- BAR_WIDTH
- PAD_WIDTH3
,
169 mysizehints
.height
- BAR_WIDTH
- PAD_WIDTH3
,
170 0, Pdepth
, InputOutput
, Pvisual
, CWBackingStore
171 | CWBackPixel
| CWBorderPixel
| CWColormap
,
173 XMapWindow(dpy
,holder_win
);
177 gcv
.foreground
= hilite_pix
;
178 hiliteGC
= fvwmlib_XCreateGC(dpy
, holder_win
, gcm
, &gcv
);
179 gcv
.foreground
= shadow_pix
;
180 shadowGC
= fvwmlib_XCreateGC(dpy
, holder_win
, gcm
, &gcv
);
183 SetWindowBackground(dpy
, main_win
, mysizehints
.width
, mysizehints
.height
,
184 &Colorset
[(colorset
)], Pdepth
, shadowGC
,
187 _XA_WM_COLORMAP_WINDOWS
= XInternAtom (dpy
, "WM_COLORMAP_WINDOWS", False
);
191 LoopOnEvents - Process all the X events we get
204 void LoopOnEvents(Window target
)
210 unsigned int tw
, th
, depth
, border_width
;
215 unsigned long nitems
, bytesafter
;
217 while (FPending(dpy
)) {
218 FNextEvent(dpy
,&Event
);
222 while (FCheckTypedWindowEvent(
223 dpy
, main_win
, Expose
, &Event
));
225 RedrawWindow(target
);
228 case ConfigureNotify
:
229 while (FCheckTypedWindowEvent(
230 dpy
, main_win
, ConfigureNotify
, &ev
))
232 if (!ev
.xconfigure
.send_event
)
234 Event
.xconfigure
.send_event
= True
;
237 dpy
, main_win
, &root
,&x
, &y
, &tw
, &th
,
238 &border_width
, &depth
))
242 if ((tw
!= Width
) || (th
!= Height
))
246 dpy
, main_win
, tw
, th
,
247 &Colorset
[(colorset
)], Pdepth
,
251 tw
- BAR_WIDTH
- PAD_WIDTH3
,
252 th
- BAR_WIDTH
- PAD_WIDTH3
);
255 if (target_y_offset
> target_height
- Height
+
258 target_height
- Height
+
260 if (target_y_offset
< 0)
262 if (target_x_offset
> target_width
- Width
+
265 target_width
- Width
+ BAR_WIDTH
;
266 if (target_x_offset
< 0)
270 dpy
, target
, -target_x_offset
,
273 else if (Event
.xconfigure
.send_event
&&
274 CSET_IS_TRANSPARENT(colorset
))
277 dpy
, main_win
, tw
, th
,
278 &Colorset
[(colorset
)], Pdepth
,
284 if((Event
.xbutton
.y
> Height
-BAR_WIDTH
) &&
285 (Event
.xbutton
.x
< SCROLL_BAR_WIDTH
+PAD_WIDTH3
))
289 RedrawWindow(target
);
291 else if((Event
.xbutton
.y
> Height
- BAR_WIDTH
) &&
292 (Event
.xbutton
.x
> Width
- BAR_WIDTH
-
293 SCROLL_BAR_WIDTH
-2) &&
294 (Event
.xbutton
.x
< Width
-BAR_WIDTH
))
298 RedrawWindow(target
);
300 else if((Event
.xbutton
.y
< SCROLL_BAR_WIDTH
+PAD_WIDTH3
)
301 && (Event
.xbutton
.x
> Width
-BAR_WIDTH
))
305 RedrawWindow(target
);
307 else if((Event
.xbutton
.y
> Height
- BAR_WIDTH
-
308 SCROLL_BAR_WIDTH
-2) &&
309 (Event
.xbutton
.y
< Height
-BAR_WIDTH
)&&
310 (Event
.xbutton
.x
> Width
-BAR_WIDTH
))
314 RedrawWindow(target
);
316 else if((Event
.xbutton
.x
> Width
- BAR_WIDTH
)&&
317 (Event
.xbutton
.y
< Height
- BAR_WIDTH
))
321 (Event
.xbutton
.y
- PAD_WIDTH3
-
322 SCROLL_BAR_WIDTH
)* target_height
/
323 (Height
-BAR_WIDTH
-PAD_WIDTH3
-
325 if(target_y_offset
+Height
-BAR_WIDTH
-PAD_WIDTH3
>
328 target_height
- Height
+BAR_WIDTH
330 if(target_y_offset
< 0)
333 dpy
,target
,-target_x_offset
,
335 RedrawWindow(target
);
337 else if((Event
.xbutton
.y
> Height
- BAR_WIDTH
) &&
338 (Event
.xbutton
.x
< Width
- BAR_WIDTH
))
342 (Event
.xbutton
.x
-PAD_WIDTH3
-
343 SCROLL_BAR_WIDTH
)* target_width
/
344 (Width
-BAR_WIDTH
-PAD_WIDTH3
-
346 if(target_x_offset
< 0)
349 if(target_x_offset
+ Width
-BAR_WIDTH
-PAD_WIDTH3
>
352 target_width
- Width
+ BAR_WIDTH
+
355 dpy
,target
,-target_x_offset
,
357 RedrawWindow(target
);
359 else if((Event
.xbutton
.y
> Height
- BAR_WIDTH
) &&
360 (Event
.xbutton
.x
> Width
- BAR_WIDTH
))
365 RedrawWindow(target
);
369 if((Event
.xbutton
.y
> Height
- BAR_WIDTH
) &&
370 (Event
.xbutton
.x
> Width
- BAR_WIDTH
)&&
373 XUnmapWindow(dpy
,main_win
);
374 XReparentWindow(dpy
,target
,Root
,x
,y
);
378 if((motion
== LEFT
)&&
379 (Event
.xbutton
.y
> Height
-BAR_WIDTH
) &&
380 (Event
.xbutton
.x
< SCROLL_BAR_WIDTH
+PAD_WIDTH3
))
382 target_x_offset
-= (Width
-BAR_WIDTH
-PAD_WIDTH2
);
383 if(target_x_offset
< 0)
386 dpy
,target
,-target_x_offset
,
391 else if((motion
== RIGHT
)&&
392 (Event
.xbutton
.y
> Height
-BAR_WIDTH
) &&
394 Width
-BAR_WIDTH
-SCROLL_BAR_WIDTH
-2) &&
395 (Event
.xbutton
.x
< Width
-BAR_WIDTH
))
397 target_x_offset
+= (Width
-BAR_WIDTH
-PAD_WIDTH2
);
398 if(target_x_offset
+Width
-BAR_WIDTH
-PAD_WIDTH3
>
401 target_width
- Width
+BAR_WIDTH
+
404 dpy
,target
,-target_x_offset
,
409 else if((motion
== TOP
)&&
410 (Event
.xbutton
.y
<SCROLL_BAR_WIDTH
+PAD_WIDTH3
)&&
411 (Event
.xbutton
.x
> Width
-BAR_WIDTH
))
413 target_y_offset
-= (Height
-BAR_WIDTH
-PAD_WIDTH2
);
414 if(target_y_offset
< 0)
417 dpy
,target
,-target_x_offset
,
422 else if((motion
== BOTTOM
)&&
424 Height
-BAR_WIDTH
-SCROLL_BAR_WIDTH
-2) &&
425 (Event
.xbutton
.y
< Height
-BAR_WIDTH
)&&
426 (Event
.xbutton
.x
> Width
-BAR_WIDTH
))
428 target_y_offset
+= (Height
-BAR_WIDTH
-PAD_WIDTH2
);
429 if(target_y_offset
+Height
-BAR_WIDTH
-PAD_WIDTH3
>
431 target_y_offset
= target_height
-
432 Height
+BAR_WIDTH
+PAD_WIDTH3
;
434 dpy
,target
,-target_x_offset
,
439 if(motion
== VERTICAL
)
442 (Event
.xbutton
.y
-PAD_WIDTH3
-
443 SCROLL_BAR_WIDTH
)*target_height
/
444 (Height
-BAR_WIDTH
-PAD_WIDTH3
-
446 if(target_y_offset
+Height
-BAR_WIDTH
-PAD_WIDTH3
>
448 target_y_offset
= target_height
- Height
+
449 BAR_WIDTH
+PAD_WIDTH3
;
450 if(target_y_offset
< 0)
453 dpy
,target
,-target_x_offset
,
456 if(motion
== HORIZONTAL
)
459 (Event
.xbutton
.x
-PAD_WIDTH3
-
460 SCROLL_BAR_WIDTH
) * target_width
/
461 (Width
-BAR_WIDTH
-PAD_WIDTH3
-
463 if(target_x_offset
< 0)
466 if(target_x_offset
+ Width
-BAR_WIDTH
-PAD_WIDTH3
>
469 target_width
- Width
+
470 BAR_WIDTH
+PAD_WIDTH3
;
472 dpy
,target
,-target_x_offset
,
475 RedrawWindow(target
);
480 if((motion
== LEFT
)&&
481 ((Event
.xmotion
.y
< Height
-BAR_WIDTH
) ||
482 (Event
.xmotion
.x
> SCROLL_BAR_WIDTH
+PAD_WIDTH3
)))
487 else if((motion
== RIGHT
)&&
488 ((Event
.xmotion
.y
< Height
-BAR_WIDTH
) ||
490 Width
-BAR_WIDTH
-SCROLL_BAR_WIDTH
-2) ||
491 (Event
.xmotion
.x
> Width
-BAR_WIDTH
)))
496 else if((motion
== TOP
)&&
497 ((Event
.xmotion
.y
>SCROLL_BAR_WIDTH
+PAD_WIDTH3
)||
498 (Event
.xmotion
.x
< Width
-BAR_WIDTH
)))
503 else if((motion
== BOTTOM
)&&
505 Height
-BAR_WIDTH
-SCROLL_BAR_WIDTH
-2) ||
506 (Event
.xmotion
.y
> Height
-BAR_WIDTH
)||
507 (Event
.xmotion
.x
< Width
-BAR_WIDTH
)))
512 if(motion
== VERTICAL
)
515 (Event
.xmotion
.y
-PAD_WIDTH3
-
516 SCROLL_BAR_WIDTH
)*target_height
/
517 (Height
-BAR_WIDTH
-PAD_WIDTH3
-
519 if(target_y_offset
+Height
-BAR_WIDTH
-PAD_WIDTH3
>
522 target_height
- Height
+BAR_WIDTH
+
524 if(target_y_offset
< 0)
527 dpy
,target
,-target_x_offset
,
530 if(motion
== HORIZONTAL
)
533 (Event
.xmotion
.x
-PAD_WIDTH3
-
534 SCROLL_BAR_WIDTH
)* target_width
/
535 (Width
-BAR_WIDTH
-PAD_WIDTH3
-
537 if(target_x_offset
< 0)
540 if(target_x_offset
+ Width
-BAR_WIDTH
-PAD_WIDTH3
>
543 target_width
- Width
+ BAR_WIDTH
+
546 dpy
,target
,-target_x_offset
,
549 if((motion
== QUIT
)&&
550 ((Event
.xbutton
.y
< Height
- BAR_WIDTH
)||
551 (Event
.xbutton
.x
< Width
- BAR_WIDTH
)))
556 RedrawWindow(target
);
559 if ((Event
.xclient
.format
==32) &&
560 (Event
.xclient
.data
.l
[0]==wm_del_win
))
566 if(Event
.xproperty
.atom
== XA_WM_NAME
)
568 if(XFetchName(dpy
, target
, &temp
)==0)
570 change_window_name(temp
);
572 else if (Event
.xproperty
.atom
== XA_WM_ICON_NAME
)
574 if (XGetWindowProperty (
576 target
, Event
.xproperty
.atom
, 0L,
577 (long)MAX_ICON_NAME_LEN
, False
, XA_STRING
,
578 &actual
,&actual_format
, &nitems
,
579 &bytesafter
, (unsigned char **) &prop
)
580 == Success
&& (prop
!= NULL
))
581 change_icon_name(prop
);
583 else if(Event
.xproperty
.atom
== XA_WM_HINTS
)
587 wmhints
= XGetWMHints(dpy
,target
);
588 XSetWMHints(dpy
,main_win
, wmhints
);
591 else if(Event
.xproperty
.atom
== XA_WM_NORMAL_HINTS
)
593 /* don't do Normal Hints. They alter the size of
596 else if (Event
.xproperty
.atom
== _XA_WM_COLORMAP_WINDOWS
)
598 /* ignore colormap stuff. The FvwmScroll window
599 * may have a different visual to the client and
600 so cannot pass this on */
612 XMapWindow(dpy
,main_win
);
615 XSetInputFocus(dpy
,target
,RevertToParent
,CurrentTime
);
618 /* FvwmScroll may not have the same visual as the
619 * captured window and so cannot share its colormap
621 XWindowAttributes xwa;
622 if(XGetWindowAttributes(dpy,target, &xwa) != 0)
624 XSetWindowColormap(dpy,main_win,xwa.colormap);
636 ProcessMessage - Process the message coming from Fvwm
638 void ProcessMessage(unsigned long type
,unsigned long *body
)
645 tline
= (char*)&body
[3];
646 tline
= GetNextToken(tline
, &token
);
647 if (StrEquals(token
, "Colorset"))
649 /* track all colorset changes and update display
651 if (LoadColorset(tline
) == colorset
)
654 dpy
, hiliteGC
,Colorset
[colorset
].hilite
);
656 dpy
, shadowGC
, Colorset
[colorset
].shadow
);
658 dpy
, main_win
, Width
, Height
,
659 &Colorset
[colorset
], Pdepth
, shadowGC
,
665 case MX_PROPERTY_CHANGE
:
666 if (body
[0] == MX_PROPERTY_CHANGE_BACKGROUND
&& body
[2] == 0 &&
667 CSET_IS_TRANSPARENT_PR(colorset
))
670 dpy
, main_win
, Width
, Height
,
672 Pdepth
, shadowGC
, True
);
679 Loop - Read and redraw until we die, blocking when can't read
681 void Loop(Window target
)
689 FD_SET(fd
[1], &fdset
);
690 FD_SET(x_fd
, &fdset
);
692 LoopOnEvents(target
);
694 select(fd_width
, SELECT_FD_SET_CAST
&fdset
, NULL
, NULL
, NULL
);
696 /* parse any config lines (colorsets) */
697 if (FD_ISSET(fd
[1], &fdset
))
699 packet
= ReadFvwmPacket(fd
[1]);
702 /* fvwm has gone away or done KillModule */
703 XUnmapWindow(dpy
,main_win
);
704 XReparentWindow(dpy
,target
,Root
,0,0);
710 ProcessMessage(packet
->type
, packet
->body
);
725 void RedrawWindow(Window target
)
727 static int xv
= 0,yv
= 0,hv
=0,wv
=0;
728 static int xh
=0,yh
=0,hh
=0,wh
=0;
732 while (FCheckTypedWindowEvent(dpy
, main_win
, Expose
, &dummy
))
735 XSetWindowBorderWidth(dpy
,target
,0);
737 RelieveRectangle(dpy
, main_win
, PAD_WIDTH3
- 2, PAD_WIDTH3
- 2,
738 Width
-BAR_WIDTH
- PAD_WIDTH3
+ 3,
739 Height
-BAR_WIDTH
- PAD_WIDTH3
+ 3,
740 shadowGC
, hiliteGC
, 2);
742 y
= (Height
-BAR_WIDTH
-PAD_WIDTH3
-2*SCROLL_BAR_WIDTH
)*
743 target_y_offset
/target_height
744 + PAD_WIDTH2
+ 2 + SCROLL_BAR_WIDTH
;
745 x
= Width
-SCROLL_BAR_WIDTH
- PAD_WIDTH2
-2;
746 w
= SCROLL_BAR_WIDTH
;
747 h
= (Height
-BAR_WIDTH
-PAD_WIDTH3
-2*SCROLL_BAR_WIDTH
)*
748 (Height
-BAR_WIDTH
-PAD_WIDTH3
)/
750 if((y
!=yv
)||(x
!= xv
)||(w
!= wv
)||(h
!= hv
)||(exposed
& 1))
756 XClearArea(dpy
,main_win
,x
,PAD_WIDTH3
+SCROLL_BAR_WIDTH
,
757 w
,Height
-BAR_WIDTH
-PAD_WIDTH3
-2*SCROLL_BAR_WIDTH
,False
);
759 RelieveRectangle(dpy
, main_win
, x
, y
, w
- 1, h
- 1,
760 hiliteGC
, shadowGC
, 2);
763 RelieveRectangle(dpy
, main_win
, x
- 2, PAD_WIDTH2
, w
+ 3,
764 Height
- BAR_WIDTH
- PAD_WIDTH2
+ 1,
765 shadowGC
, hiliteGC
, 2);
769 RedrawTopButton(shadowGC
,hiliteGC
,x
,PAD_WIDTH3
);
771 RedrawTopButton(hiliteGC
,shadowGC
,x
,PAD_WIDTH3
);
773 RedrawBottomButton(shadowGC
,hiliteGC
,x
,
774 Height
-BAR_WIDTH
-SCROLL_BAR_WIDTH
);
776 RedrawBottomButton(hiliteGC
,shadowGC
,x
,
777 Height
-BAR_WIDTH
-SCROLL_BAR_WIDTH
);
780 x
= (Width
-BAR_WIDTH
-PAD_WIDTH3
-2*SCROLL_BAR_WIDTH
)*target_x_offset
/
781 target_width
+PAD_WIDTH2
+2 + SCROLL_BAR_WIDTH
;
782 y
= Height
-SCROLL_BAR_WIDTH
-PAD_WIDTH2
-2;
783 w
= (Width
-BAR_WIDTH
-PAD_WIDTH3
-2*SCROLL_BAR_WIDTH
)*
784 (Width
-BAR_WIDTH
-PAD_WIDTH3
)/target_width
;
785 h
= SCROLL_BAR_WIDTH
;
786 if((y
!=yh
)||(x
!= xh
)||(w
!= wh
)||(h
!= hh
)||(exposed
& 1))
792 XClearArea(dpy
,main_win
,PAD_WIDTH3
+SCROLL_BAR_WIDTH
,y
,
793 Width
-BAR_WIDTH
-PAD_WIDTH3
-2*SCROLL_BAR_WIDTH
,h
,False
);
794 RelieveRectangle(dpy
, main_win
, x
, y
, w
- 1, h
- 1,
795 hiliteGC
, shadowGC
, 2);
799 RelieveRectangle(dpy
, main_win
, PAD_WIDTH2
, y
- 2,
800 Width
- BAR_WIDTH
- PAD_WIDTH2
+ 1, h
+ 2,
801 shadowGC
, hiliteGC
, 2);
806 RedrawLeftButton(shadowGC
,hiliteGC
,PAD_WIDTH3
,y
);
808 RedrawLeftButton(hiliteGC
,shadowGC
,PAD_WIDTH3
,y
);
810 RedrawRightButton(shadowGC
,hiliteGC
,
811 Width
-BAR_WIDTH
-SCROLL_BAR_WIDTH
,y
);
813 RedrawRightButton(hiliteGC
,shadowGC
,
814 Width
-BAR_WIDTH
-SCROLL_BAR_WIDTH
,y
);
819 XClearArea(dpy
,main_win
,Width
-BAR_WIDTH
+2,
820 Height
-BAR_WIDTH
+2,BAR_WIDTH
-3,BAR_WIDTH
-3,False
);
822 RelieveRectangle(dpy
, main_win
, Width
- SCROLL_BAR_WIDTH
- PAD_WIDTH2
- 4,
823 Height
- SCROLL_BAR_WIDTH
- PAD_WIDTH2
- 4,
824 SCROLL_BAR_WIDTH
+ 3, SCROLL_BAR_WIDTH
+ 3,
825 shadowGC
, hiliteGC
, 2);
827 RelieveRectangle(dpy
, main_win
, Width
- SCROLL_BAR_WIDTH
- PAD_WIDTH2
- 4,
828 Height
- SCROLL_BAR_WIDTH
- PAD_WIDTH2
- 4,
829 SCROLL_BAR_WIDTH
+ 3,SCROLL_BAR_WIDTH
+ 3,
830 hiliteGC
, shadowGC
, 2);
837 * Change the window name displayed in the title bar.
839 void change_window_name(char *str
)
846 if (XStringListToTextProperty(&str
,1,&name
) == 0)
848 fprintf(stderr
,"%s: cannot allocate window name\n",module
->name
);
851 XSetWMName(dpy
,main_win
,&name
);
857 * Change the window name displayed in the icon.
859 void change_icon_name(char *str
)
865 if (XStringListToTextProperty(&str
,1,&name
) == 0)
867 fprintf(stderr
,"%s: cannot allocate window name\n",module
->name
);
870 XSetWMIconName(dpy
,main_win
,&name
);
875 void GrabWindow(Window target
)
879 unsigned int tw
,th
,border_width
,depth
;
884 unsigned long nitems
, bytesafter
;
886 XUnmapWindow(dpy
,target
);
888 if (!XGetGeometry(dpy
,target
,&root
,&x
,&y
,
889 (unsigned int *)&tw
,(unsigned int *)&th
,
890 (unsigned int *)&border_width
,
891 (unsigned int *)&depth
))
893 fprintf(stderr
,"%s: cannot get window geometry\n", module
->name
);
898 XTranslateCoordinates(dpy
, target
, Root
, 0, 0, &x
,&y
, &Junk
);
900 CreateWindow(x
,y
,tw
,th
);
901 XSetWindowBorderWidth(dpy
,target
,0);
902 XReparentWindow(dpy
,target
, holder_win
,0,0);
903 XMapWindow(dpy
,target
);
904 XSelectInput(dpy
,target
, PropertyChangeMask
|StructureNotifyMask
);
905 if(XFetchName(dpy
, target
, &temp
)==0)
907 if (XGetWindowProperty (dpy
,
908 target
, XA_WM_ICON_NAME
, 0L,
909 (long)MAX_ICON_NAME_LEN
, False
, XA_STRING
,
910 &actual
,&actual_format
, &nitems
,
911 &bytesafter
, (unsigned char **) &prop
)
912 == Success
&& (prop
!= NULL
))
914 change_icon_name(prop
);
917 change_window_name(temp
);
921 wmhints
= XGetWMHints(dpy
,target
);
924 XSetWMHints(dpy
,main_win
, wmhints
);
928 /* FvwmScroll may not share the same visual as the target window
929 * and so cannot share its colormap {
930 XWindowAttributes xwa;
931 if(XGetWindowAttributes(dpy,target, &xwa) != 0)
933 XSetWindowColormap(dpy,main_win,xwa.colormap);
937 XMapWindow(dpy
,main_win
);
938 RedrawWindow(target
);
946 void RedrawLeftButton(GC rgc
, GC sgc
,int x1
,int y1
)
951 seg
[i
].x1
= x1
+1; seg
[i
].y1
= y1
+SCROLL_BAR_WIDTH
/2;
952 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
++].y2
= y1
+1;
954 seg
[i
].x1
= x1
; seg
[i
].y1
= y1
+SCROLL_BAR_WIDTH
/2;
955 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
++].y2
= y1
;
956 XDrawSegments(dpy
, main_win
, rgc
, seg
, i
);
959 seg
[i
].x1
= x1
+1; seg
[i
].y1
=y1
+ SCROLL_BAR_WIDTH
/2;
960 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
++].y2
=y1
+ SCROLL_BAR_WIDTH
- 2;
962 seg
[i
].x1
= x1
; seg
[i
].y1
= y1
+SCROLL_BAR_WIDTH
/2;
963 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 1;
965 seg
[i
].x1
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
].y1
= y1
+1;
966 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 2;
968 seg
[i
].x1
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
].y1
= y1
;
969 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 1;
970 XDrawSegments(dpy
,main_win
, sgc
, seg
, i
);
973 void RedrawRightButton(GC rgc
, GC sgc
,int x1
,int y1
)
978 seg
[i
].x1
= x1
+1; seg
[i
].y1
= y1
+1;
979 seg
[i
].x2
= x1
+1; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 2;
981 seg
[i
].x1
= x1
; seg
[i
].y1
= y1
;
982 seg
[i
].x2
= x1
; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 1;
984 seg
[i
].x1
= x1
+1; seg
[i
].y1
= y1
+1;
985 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
/2;
987 seg
[i
].x1
= x1
; seg
[i
].y1
= y1
;
988 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
/2;
990 XDrawSegments(dpy
, main_win
, rgc
, seg
, i
);
993 seg
[i
].x1
= x1
; seg
[i
].y1
= y1
+SCROLL_BAR_WIDTH
- 2;
994 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
/2;
996 seg
[i
].x1
= x1
; seg
[i
].y1
= y1
+SCROLL_BAR_WIDTH
- 1;
997 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
/2;
998 XDrawSegments(dpy
,main_win
, sgc
, seg
, i
);
1001 void RedrawTopButton(GC rgc
, GC sgc
,int x1
,int y1
)
1006 seg
[i
].x1
= x1
+SCROLL_BAR_WIDTH
/2; seg
[i
].y1
= y1
+1;
1007 seg
[i
].x2
= x1
+1; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 2;
1009 seg
[i
].x1
= x1
+SCROLL_BAR_WIDTH
/2; seg
[i
].y1
= y1
;
1010 seg
[i
].x2
= x1
+0; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 1;
1011 XDrawSegments(dpy
, main_win
, rgc
, seg
, i
);
1014 seg
[i
].x1
= x1
+SCROLL_BAR_WIDTH
/2; seg
[i
].y1
= y1
+1;
1015 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 2;
1017 seg
[i
].x1
= x1
+SCROLL_BAR_WIDTH
/2; seg
[i
].y1
= y1
;
1018 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 1;
1020 seg
[i
].x1
= x1
+1; seg
[i
].y1
= y1
+SCROLL_BAR_WIDTH
- 2;
1021 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 2;
1023 seg
[i
].x1
= x1
+0; seg
[i
].y1
= y1
+SCROLL_BAR_WIDTH
- 1;
1024 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 1;
1025 XDrawSegments(dpy
,main_win
, sgc
, seg
, i
);
1028 void RedrawBottomButton(GC rgc
, GC sgc
,int x1
, int y1
)
1033 seg
[i
].x1
= x1
+1; seg
[i
].y1
= y1
+1;
1034 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
/2; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 2;
1036 seg
[i
].x1
= x1
; seg
[i
].y1
= y1
+0;
1037 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
/2; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 1;
1039 seg
[i
].x1
= x1
+1; seg
[i
].y1
= y1
+1;
1040 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
++].y2
= y1
+1;
1042 seg
[i
].x1
= x1
; seg
[i
].y1
= y1
+0;
1043 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
++].y2
= y1
+0;
1044 XDrawSegments(dpy
,main_win
, rgc
, seg
, i
);
1047 seg
[i
].x1
= x1
+SCROLL_BAR_WIDTH
- 2; seg
[i
].y1
= y1
+1;
1048 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
/2; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 2;
1050 seg
[i
].x1
= x1
+SCROLL_BAR_WIDTH
- 1; seg
[i
].y1
= y1
+0;
1051 seg
[i
].x2
= x1
+SCROLL_BAR_WIDTH
/2; seg
[i
++].y2
= y1
+SCROLL_BAR_WIDTH
- 1;
1052 XDrawSegments(dpy
, main_win
, sgc
, seg
, i
);