2 /* vim: set ts=8 shiftwidth=8: */
3 /* This module, FvwmProxy, is an original work by Jason Weber.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* ---------------------------- included header files ----------------------- */
27 #include "libs/Module.h"
28 #include "libs/fvwmlib.h"
29 #include "libs/FRenderInit.h"
30 #include "libs/FRender.h"
31 #include "libs/Colorset.h"
32 #include "libs/Flocale.h"
33 #include "libs/gravity.h"
34 #include "libs/FScreen.h"
35 #include "libs/Picture.h"
36 #include "libs/PictureGraphics.h"
37 #include "libs/charmap.h"
38 #include "libs/modifiers.h"
39 #include "libs/ColorUtils.h"
40 #include "libs/Graphics.h"
41 #include "libs/Parse.h"
42 #include "libs/Strings.h"
43 #include "libs/System.h"
44 #include "libs/wild.h"
46 #include "FvwmProxy.h"
48 /* ---------------------------- local definitions --------------------------- */
50 #define PROXY_COMMAND_DEBUG False
51 #define PROXY_GROUP_DEBUG False
52 #define PROXY_EVENT_DEBUG False
54 #define PROXY_KEY_POLLING True
56 /* defaults for things we put in a configuration file */
58 #define PROXY_WIDTH 180
59 #define PROXY_HEIGHT 60
60 #define PROXY_SEPARATION 10
61 #define PROXY_MINWIDTH 15
62 #define PROXY_MINHEIGHT 10
63 #define PROXY_SLOT_SIZE 16
64 #define PROXY_SLOT_SPACE 4
65 #define PROXY_GROUP_SLOT 2
66 #define PROXY_GROUP_COUNT 6
67 #define PROXY_STAMP_LIMIT 8
69 #define STARTUP_DEBUG False /* store output before log is opened */
71 #define CMD_SELECT "WindowListFunc $[w.id]"
72 #define CMD_CLICK1 "Raise"
73 #define CMD_CLICK3 "Lower"
74 #define CMD_DEFAULT "Nop"
76 /* ---------------------------- local macros -------------------------------- */
78 /* ---------------------------- imports ------------------------------------- */
80 /* ---------------------------- included code files ------------------------- */
82 /* ---------------------------- local types --------------------------------- */
84 /* ---------------------------- forward declarations ------------------------ */
86 /* ---------------------------- local variables ----------------------------- */
88 static char *ImagePath
= NULL
;
91 static fd_set_size_t fd_width
;
94 static unsigned long screen
;
99 static Window rootWindow
;
100 static Window focusWindow
;
101 static XTextProperty windowName
;
102 static int deskNumber
=0;
103 static int mousex
,mousey
;
104 static ProxyWindow
*firstProxy
=NULL
;
105 static ProxyWindow
*lastProxy
=NULL
;
106 static ProxyWindow
*selectProxy
=NULL
;
107 static ProxyWindow
*startProxy
=NULL
;
108 static ProxyWindow
*enterProxy
=NULL
;
109 static ProxyWindow
*last_rotation_instigator
=NULL
;
110 static ProxyGroup
*firstProxyGroup
=NULL
;
111 static FvwmPicture
**pictureArray
=NULL
;
112 static int numSlots
=0;
113 static int miniIconSlot
=0;
114 static XGCValues xgcv
;
115 static int are_windows_shown
= 0;
116 static int watching_modifiers
= 0;
117 static int waiting_to_config
= 0;
118 static int waiting_to_stamp
= 0;
119 static int pending_do
= 0;
120 static unsigned int held_modifiers
=0;
121 static int watched_modifiers
=0;
122 static FlocaleWinString
*FwinString
;
124 static int cset_normal
= 0;
125 static int cset_select
= 0;
126 static int cset_iconified
= 0;
127 static char *font_name
= NULL
;
128 static char *small_font_name
= NULL
;
129 static FlocaleFont
*Ffont
;
130 static FlocaleFont
*Ffont_small
;
131 static int enterSelect
=False
;
132 static int showMiniIcons
=True
;
133 static int proxyIconified
=False
;
134 static int proxyMove
=False
;
135 static int proxyWidth
=PROXY_WIDTH
;
136 static int proxyHeight
=PROXY_HEIGHT
;
137 static int proxySeparation
=PROXY_SEPARATION
;
138 static int slotWidth
=PROXY_SLOT_SIZE
;
139 static int slotHeight
=PROXY_SLOT_SIZE
;
140 static int slotSpace
=PROXY_SLOT_SPACE
;
141 static int groupSlot
=PROXY_GROUP_SLOT
;
142 static int groupCount
=PROXY_GROUP_COUNT
;
143 static int stampLimit
=PROXY_STAMP_LIMIT
;
145 static GeometryStamp
* stampQueue
=NULL
;
147 static int stampMin
=0;
148 static int stampMax
=0;
150 static char commandBuffer
[256];
151 static char resultBuffer
[256];
155 PROXY_ACTION_SELECT
= 0,
161 PROXY_ACTION_MODIFIER_RELEASE
,
162 /* this one *must* be last */
164 PROXY_ACTION_LAST
= PROXY_ACTION_CLICK
+
165 NUMBER_OF_EXTENDED_MOUSE_BUTTONS
170 PROXY_FOLLOW_OFF
= 0,
177 PROXY_PROVOKE_RAISE
= 1,
185 PROXY_SHOWONLY_ALL
= 0,
186 PROXY_SHOWONLY_SELECT
,
187 PROXY_SHOWONLY_COVER
,
190 static proxy_showonly_t showOnly
= PROXY_SHOWONLY_ALL
;
192 #define GROUP_COLORS 7
193 static char* group_color
[GROUP_COLORS
][2] =
195 {"#dddddd", "#777777"},
196 {"#ffcccc", "#ff0000"},
197 {"#ccffcc", "#00ff00"},
198 {"#ccccff", "#0000ff"},
199 {"#ffccff", "#ff00ff"},
200 {"#ffffcc", "#ffff00"},
201 {"#ccffff", "#00ffff"}
204 char *action_list
[PROXY_ACTION_LAST
];
205 char **slot_action_list
[NUMBER_OF_EXTENDED_MOUSE_BUTTONS
];
207 static WindowName
* new_WindowName(void);
208 static ProxyGroup
* FindProxyGroup(char* groupname
);
210 static int (*originalXErrorHandler
)(Display
*,XErrorEvent
*);
211 static int (*originalXIOErrorHandler
)(Display
*);
213 /* ---------------------------- exported variables (globals) ---------------- */
215 /* ---------------------------- local functions (options) ------------------- */
217 static void ExpandSlots(int slots
)
223 pictureArray
=(FvwmPicture
**)realloc(pictureArray
,
224 sizeof(FvwmPicture
*)*(slots
));
225 for(m
=0;m
<NUMBER_OF_EXTENDED_MOUSE_BUTTONS
;m
++)
227 slot_action_list
[m
]=(char**)realloc(
229 sizeof(char*)*(slots
));
230 for(n
=numSlots
;n
<slots
;n
++)
232 slot_action_list
[m
][n
]=NULL
;
235 for(n
=numSlots
;n
<slots
;n
++)
237 pictureArray
[n
]=NULL
;
243 static void LinkSlotAction(char *string
)
248 token
= PeekToken(string
, &string
);
251 token
= PeekToken(string
, &string
);
252 if (strncasecmp(token
, "Click", 5) == 0)
256 i
= sscanf(token
+ 5, "%d", &b
);
257 if (i
> 0 && b
>=1 && b
<= NUMBER_OF_EXTENDED_MOUSE_BUTTONS
)
260 if (slot_action_list
[b
-1][slot
] != NULL
)
262 free(slot_action_list
[b
-1][slot
]);
264 slot_action_list
[b
-1][slot
] = safestrdup(string
);
265 #if PROXY_GROUP_DEBUG
266 fprintf(stderr
,"slot_action_list[%d][%d]=\"%s\"\n",
267 b
-1,slot
,slot_action_list
[b
-1][slot
]);
273 static WindowName
* FindWindowName(WindowName
* namelist
,char* name
)
275 WindowName
* include
=namelist
;
278 if(matchWildcards(include
->name
, name
))
282 include
=include
->next
;
288 static void LinkAction(char *string
)
292 token
= PeekToken(string
, &string
);
293 if (strncasecmp(token
, "Click", 5) == 0)
297 i
= sscanf(token
+ 5, "%d", &b
);
298 if (i
> 0 && b
>=1 && b
<= NUMBER_OF_EXTENDED_MOUSE_BUTTONS
)
300 if (action_list
[PROXY_ACTION_CLICK
+ b
- 1] != NULL
)
302 free(action_list
[PROXY_ACTION_CLICK
+ b
- 1]);
304 action_list
[PROXY_ACTION_CLICK
+ b
- 1] =
308 else if (StrEquals(token
, "Select"))
310 if (action_list
[PROXY_ACTION_SELECT
] != NULL
)
312 free(action_list
[PROXY_ACTION_SELECT
]);
314 action_list
[PROXY_ACTION_SELECT
] = safestrdup(string
);
316 else if (StrEquals(token
, "Show"))
318 if (action_list
[PROXY_ACTION_SHOW
] != NULL
)
320 free(action_list
[PROXY_ACTION_SHOW
]);
322 action_list
[PROXY_ACTION_SHOW
] = safestrdup(string
);
324 else if (StrEquals(token
, "Hide"))
326 if (action_list
[PROXY_ACTION_HIDE
] != NULL
)
328 free(action_list
[PROXY_ACTION_HIDE
]);
330 action_list
[PROXY_ACTION_HIDE
] = safestrdup(string
);
332 else if (StrEquals(token
, "Abort"))
334 if (action_list
[PROXY_ACTION_ABORT
] != NULL
)
336 free(action_list
[PROXY_ACTION_ABORT
]);
338 action_list
[PROXY_ACTION_ABORT
] = safestrdup(string
);
340 else if (StrEquals(token
, "Mark"))
342 if (action_list
[PROXY_ACTION_MARK
] != NULL
)
344 free(action_list
[PROXY_ACTION_MARK
]);
346 action_list
[PROXY_ACTION_MARK
] = safestrdup(string
);
348 else if (StrEquals(token
, "Unmark"))
350 if (action_list
[PROXY_ACTION_UNMARK
] != NULL
)
352 free(action_list
[PROXY_ACTION_UNMARK
]);
354 action_list
[PROXY_ACTION_UNMARK
] = safestrdup(string
);
356 else if (StrEquals(token
, "ModifierRelease"))
358 token
= PeekToken(string
, &string
);
360 if (action_list
[PROXY_ACTION_MODIFIER_RELEASE
] != NULL
)
362 free(action_list
[PROXY_ACTION_MODIFIER_RELEASE
]);
365 modifiers_string_to_modmask(token
, (int *)&watched_modifiers
);
366 action_list
[PROXY_ACTION_MODIFIER_RELEASE
] = safestrdup(string
);
373 static void parse_cmd(char **ret_cmd
, char *cmd
)
375 if (*ret_cmd
!= NULL
)
382 *ret_cmd
= safestrdup(cmd
);
389 FvwmPicture
* loadPicture(char* name
)
391 FvwmPicture
*picture
=NULL
;
392 FvwmPictureAttributes fpa
;
399 fpa
.mask
= FPAM_NO_COLOR_LIMIT
;
400 picture
= PGetFvwmPicture(dpy
, RootWindow(dpy
,screen
),
401 ImagePath
, name
, fpa
);
404 fprintf(stderr
, "loadPixmap failed to load \"%s\"\n", name
);
409 static Bool
parse_options(void)
414 memset(action_list
, 0, sizeof(action_list
));
415 action_list
[PROXY_ACTION_SELECT
] = strdup(CMD_SELECT
);
416 action_list
[PROXY_ACTION_CLICK
+ 0] = strdup(CMD_CLICK1
);
417 if (NUMBER_OF_EXTENDED_MOUSE_BUTTONS
> 2)
419 action_list
[PROXY_ACTION_CLICK
+ 2] = strdup(CMD_CLICK3
);
421 for (m
=0;m
<PROXY_ACTION_LAST
;m
++)
423 if (action_list
[m
]==NULL
)
425 action_list
[m
] = strdup(CMD_DEFAULT
);
429 InitGetConfigLine(fd
, CatString3("*", MyName
, 0));
430 for (GetConfigLine(fd
, &tline
); tline
!= NULL
;
431 GetConfigLine(fd
, &tline
))
437 token
= PeekToken(tline
, &next
);
438 if (StrEquals(token
, "Colorset"))
443 if (StrEquals(token
, "ImagePath"))
449 CopyString(&ImagePath
, next
);
453 tline
= GetModuleResource(tline
, &resource
, MyName
);
454 if (resource
== NULL
)
459 /* dump leading whitespace */
460 while (*tline
==' ' || *tline
=='\t')
462 if (!strncasecmp(resource
,"Action",6))
466 else if (!strncasecmp(resource
,"SlotAction",10))
468 LinkSlotAction(tline
);
470 else if (StrEquals(resource
, "Colorset"))
472 if (sscanf(tline
, "%d", &cset_normal
) < 1)
477 else if (StrEquals(resource
, "SelectColorset"))
479 if (sscanf(tline
, "%d", &cset_select
) < 1)
484 else if (StrEquals(resource
, "IconifiedColorset"))
486 if (sscanf(tline
, "%d", &cset_iconified
) < 1)
491 else if (StrEquals(resource
, "Font"))
493 if (font_name
!= NULL
)
497 font_name
= safestrdup(tline
);
499 else if (StrEquals(resource
, "SmallFont"))
501 if (small_font_name
!= NULL
)
503 free(small_font_name
);
505 small_font_name
= safestrdup(tline
);
507 else if (StrEquals(resource
, "ShowMiniIcons"))
509 showMiniIcons
= ParseToggleArgument(tline
, NULL
, 0, 1);
511 else if (StrEquals(resource
, "EnterSelect"))
513 enterSelect
= ParseToggleArgument(tline
, NULL
, 0, 1);
515 else if (StrEquals(resource
, "ProxyMove"))
517 proxyMove
= ParseToggleArgument(tline
, NULL
, 0, 1);
519 else if (StrEquals(resource
, "ProxyIconified"))
521 proxyIconified
= ParseToggleArgument(tline
, NULL
, 0, 1);
523 else if (StrEquals(resource
, "Width"))
525 if (sscanf(tline
, "%d", &proxyWidth
) < 1)
526 proxyWidth
=PROXY_MINWIDTH
;
528 else if (StrEquals(resource
, "Height"))
530 if (sscanf(tline
, "%d", &proxyHeight
) < 1)
531 proxyHeight
=PROXY_MINHEIGHT
;
533 else if (StrEquals(resource
, "Separation"))
535 if (sscanf(tline
, "%d", &proxySeparation
) < 1)
536 proxySeparation
=False
;
538 else if (StrEquals(resource
, "UndoLimit"))
540 if (sscanf(tline
, "%d", &stampLimit
) < 1)
541 stampLimit
=PROXY_STAMP_LIMIT
;
543 else if (StrEquals(resource
, "ShowOnly"))
545 #if PROXY_GROUP_DEBUG
546 fprintf(stderr
, "ShowOnly: \"%s\"\n", tline
);
548 if(StrEquals(tline
, "All"))
550 showOnly
= PROXY_SHOWONLY_ALL
;
552 else if(StrEquals(tline
, "Selected"))
554 showOnly
= PROXY_SHOWONLY_SELECT
;
556 else if(StrEquals(tline
, "Covered"))
558 showOnly
= PROXY_SHOWONLY_COVER
;
560 else if(StrEquals(tline
, "Grouped"))
562 showOnly
= PROXY_SHOWONLY_GROUP
;
565 else if (StrEquals(resource
, "SlotWidth"))
567 if (sscanf(tline
, "%d", &slotWidth
) < 1)
568 slotWidth
=PROXY_SLOT_SIZE
;
570 else if (StrEquals(resource
, "SlotHeight"))
572 if (sscanf(tline
, "%d", &slotHeight
) < 1)
573 slotHeight
=PROXY_SLOT_SIZE
;
575 else if (StrEquals(resource
, "SlotSpace"))
577 if (sscanf(tline
, "%d", &slotSpace
) < 1)
578 slotSpace
=PROXY_SLOT_SPACE
;
580 else if (StrEquals(resource
, "GroupSlot"))
582 if (sscanf(tline
, "%d", &groupSlot
) < 0)
583 groupSlot
=PROXY_GROUP_SLOT
;
585 else if (StrEquals(resource
, "GroupCount"))
587 if (sscanf(tline
, "%d", &groupCount
) < 0)
588 groupCount
=PROXY_GROUP_COUNT
;
590 else if (StrEquals(resource
, "SlotStyle"))
596 int args
= sscanf(tline
, "%d%s%*[^\"]\"%[^\"]\"%n",
597 &slot
,style
,name
,&bytes
);
598 #if PROXY_GROUP_DEBUG
600 "SlotStyle: %d \"%s\" -> %d \"%s\" \"%s\"\n",
601 args
,tline
,slot
,style
,name
);
603 if (args
>=3 && StrEquals(style
, "Pixmap"))
606 pictureArray
[slot
]=loadPicture(name
);
608 else if (args
>=2 && StrEquals(style
, "MiniIcon"))
613 else if (StrEquals(resource
, "Group"))
620 int args
= sscanf(tline
, "\"%[^\"]\"%s%n",
621 groupname
,directive
,&bytes
);
622 ProxyGroup
* proxygroup
;
624 strncpy(tail
,&tline
[bytes
],128);
627 args
= sscanf(tail
, "%*[^\"]\"%[^\"]\"",pattern
);
629 #if PROXY_GROUP_DEBUG
631 "Group: %d \"%s\" -> \"%s\" \"%s\" \"%s\"\n",
632 args
,tline
,groupname
,directive
,pattern
);
635 proxygroup
=FindProxyGroup(groupname
);
636 if (StrEquals(directive
, "IgnoreIDs"))
638 proxygroup
->flags
.ignore_ids
=1;
640 else if (StrEquals(directive
, "AutoInclude"))
642 proxygroup
->flags
.auto_include
=1;
644 else if (StrEquals(directive
, "AutoSoft"))
646 proxygroup
->flags
.auto_include
=1;
647 proxygroup
->flags
.auto_soft
=1;
649 else if (StrEquals(directive
, "Isolated"))
651 proxygroup
->flags
.isolated
=1;
653 else if (StrEquals(directive
, "Include") ||
654 StrEquals(directive
, "WeakInclude") ||
655 StrEquals(directive
, "SoftInclude") ||
656 StrEquals(directive
, "WeakSoftInclude"))
658 WindowName
* include
=new_WindowName();
659 include
->name
=strdup(pattern
);
660 include
->flags
.is_soft
=
661 (StrEquals(directive
,
665 include
->flags
.is_weak
=
666 (StrEquals(directive
,
670 include
->next
=proxygroup
->includes
;
671 proxygroup
->includes
=include
;
672 #if PROXY_GROUP_DEBUG
673 fprintf(stderr
,"Include \"%s\"\n",
677 else if (StrEquals(directive
, "Exclude"))
679 WindowName
* exclude
=new_WindowName();
680 exclude
->name
=strdup(pattern
);
681 exclude
->next
=proxygroup
->excludes
;
682 proxygroup
->excludes
=exclude
;
683 #if PROXY_GROUP_DEBUG
684 fprintf(stderr
,"Exclude \"%s\"\n",
691 No Soft/Hard Raise/Desk/Drag
693 char* remainder
= directive
;
701 proxy_follow_t setting
= PROXY_FOLLOW_ON
;
702 if(StrHasPrefix(remainder
,"No"))
704 setting
= PROXY_FOLLOW_OFF
;
707 if(StrHasPrefix(remainder
,"Inherit"))
709 setting
= PROXY_FOLLOW_INHERIT
;
715 if(StrHasPrefix(remainder
,"Soft"))
720 if(StrHasPrefix(remainder
,"Hard"))
730 if(StrHasPrefix(remainder
,"Raise"))
737 if(StrHasPrefix(remainder
,"Desk"))
744 if(StrHasPrefix(remainder
,"Drag"))
751 if(StrHasPrefix(remainder
,"Icon"))
758 if(StrHasPrefix(remainder
,"All"))
762 #if PROXY_GROUP_DEBUG
763 fprintf(stderr
,"@@@ ");
764 fprintf(stderr
,"Follow \"%s\"\n",
766 fprintf(stderr
,"@@@ ");
767 fprintf(stderr
," setting %d soft %d hard %d\n",
768 setting
, soft
, hard
);
769 fprintf(stderr
,"@@@ ");
770 fprintf(stderr
," raise %d desk %d",
772 fprintf(stderr
," drag %d icon %d\n",
778 WindowName
* windowName
= FindWindowName(
779 proxygroup
->includes
, pattern
);
784 if(raise
) windowName
->
788 if(desk
) windowName
->
792 if(drag
) windowName
->
796 if(icon
) windowName
->
803 if(raise
) windowName
->
807 if(desk
) windowName
->
811 if(drag
) windowName
->
815 if(icon
) windowName
->
826 if(raise
) proxygroup
->
829 if(desk
) proxygroup
->
832 if(drag
) proxygroup
->
835 if(icon
) proxygroup
->
841 if(raise
) proxygroup
->
844 if(desk
) proxygroup
->
847 if(drag
) proxygroup
->
850 if(icon
) proxygroup
->
859 fprintf(stderr
,"Unknown: \"%s\"\n",tline
);
868 /* ---------------------------- local functions (classes) ------------------- */
872 static void ProxyWindow_ProxyWindow(ProxyWindow
*p
)
874 memset(p
, 0, sizeof *p
);
877 static ProxyWindow
*new_ProxyWindow(void)
879 ProxyWindow
*p
=(ProxyWindow
*)safemalloc(sizeof(ProxyWindow
));
880 ProxyWindow_ProxyWindow(p
);
884 static void delete_ProxyWindow(ProxyWindow
*p
)
896 if (p
->proxy
!= None
)
898 XDestroyWindow(dpy
, p
->proxy
);
904 static void WindowName_WindowName(WindowName
*p
)
906 memset(p
, 0, sizeof *p
);
908 p
->flags
.soft_raise
= PROXY_FOLLOW_INHERIT
;
909 p
->flags
.soft_desk
= PROXY_FOLLOW_INHERIT
;
910 p
->flags
.soft_drag
= PROXY_FOLLOW_INHERIT
;
911 p
->flags
.soft_icon
= PROXY_FOLLOW_INHERIT
;
912 p
->flags
.hard_raise
= PROXY_FOLLOW_INHERIT
;
913 p
->flags
.hard_desk
= PROXY_FOLLOW_INHERIT
;
914 p
->flags
.hard_drag
= PROXY_FOLLOW_INHERIT
;
915 p
->flags
.hard_icon
= PROXY_FOLLOW_INHERIT
;
918 static WindowName
*new_WindowName(void)
920 WindowName
*p
=(WindowName
*)safemalloc(sizeof(WindowName
));
921 WindowName_WindowName(p
);
925 static void ProxyGroup_ProxyGroup(ProxyGroup
*p
)
927 memset(p
, 0, sizeof *p
);
929 p
->flags
.soft_raise
= PROXY_FOLLOW_ON
;
930 p
->flags
.soft_desk
= PROXY_FOLLOW_ON
;
931 p
->flags
.soft_drag
= PROXY_FOLLOW_ON
;
932 p
->flags
.soft_icon
= PROXY_FOLLOW_ON
;
933 p
->flags
.hard_raise
= PROXY_FOLLOW_ON
;
934 p
->flags
.hard_desk
= PROXY_FOLLOW_ON
;
935 p
->flags
.hard_drag
= PROXY_FOLLOW_ON
;
936 p
->flags
.hard_icon
= PROXY_FOLLOW_ON
;
939 static ProxyGroup
*new_ProxyGroup(void)
941 ProxyGroup
*p
=(ProxyGroup
*)safemalloc(sizeof(ProxyGroup
));
942 ProxyGroup_ProxyGroup(p
);
946 /* ---------------------------- error handlers ------------------------------ */
948 static int myXErrorHandler(Display
*display
,XErrorEvent
*error_event
)
950 const long messagelen
=256;
951 char buffer
[messagelen
],function
[messagelen
];
952 char request_number
[16];
954 sprintf(request_number
,"%d",error_event
->request_code
);
955 sprintf(buffer
,"UNKNOWN");
956 XGetErrorDatabaseText(display
,"XRequest",
957 request_number
,buffer
,function
,messagelen
);
959 fprintf(stderr
, "non-fatal X error as follows, display %p"
960 " op %d:%d \"%s\" serial %u error %d\n",
962 error_event
->request_code
,error_event
->minor_code
,
963 function
,(unsigned int)error_event
->serial
,
964 error_event
->error_code
);
969 static int myXIOErrorHandler(Display
*display
)
971 fprintf(stderr
, "fatal IO Error on display %p\n", display
);
972 originalXIOErrorHandler(display
);
974 /* should never get this far */
978 /* ---------------------------- local functions ----------------------------- */
980 static void send_command_to_fvwm(char *command
, Window w
)
982 if (command
== NULL
|| *command
== 0)
986 #if PROXY_COMMAND_DEBUG
987 fprintf(stderr
,"SendText: \"%s\"\n", command
);
989 SendText(fd
, command
, w
);
994 static int GetProperty(Window w
,char* propertyname
)
996 Atom atom
,actual_type
;
999 unsigned long nitems
;
1000 unsigned long bytes_after
;
1001 unsigned char *prop
;
1007 atom
= XInternAtom(dpy
, propertyname
, True
);
1008 atom_name
= XGetAtomName (dpy
,atom
);
1010 status
= XGetWindowProperty(dpy
, w
, atom
, 0L, 1024,
1011 False
, AnyPropertyType
,
1013 &actual_format
, &nitems
,
1018 /* fprintf(stderr,"GetProperty: cannot get %s\n",propertyname);
1023 /* fprintf(stderr,"GetProperty: no properties\n");
1028 bytes
=actual_format
/8;
1029 for(byte
=bytes
-1;byte
>=0;byte
--)
1031 result
=result
*256+prop
[byte
];
1037 static int GetProcessId(Window w
)
1039 return GetProperty(w
, "_NET_WM_PID");
1042 static int GetLeader(Window w
)
1044 int result
=GetProperty(w
, "WM_CLIENT_LEADER");
1047 XWMHints
* hints
=XGetWMHints(dpy
,w
);
1048 if(hints
&& hints
->flags
&WindowGroupHint
)
1050 result
=hints
->window_group
;
1057 static int GetParentProcessId(int pid
)
1063 sprintf(commandBuffer
,"/proc/%d/stat",pid
);
1064 statusfile
=fopen(commandBuffer
,"r");
1069 bytes
=fread(resultBuffer
,32,1,statusfile
);
1070 sscanf(resultBuffer
,"%*d %*[^)]) %*s %d",&ppid
);
1075 static ProxyGroup
* FindProxyGroup(char* groupname
)
1077 ProxyGroup
* proxygroup
=firstProxyGroup
;
1080 if(StrEquals(proxygroup
->name
, groupname
))
1084 proxygroup
=proxygroup
->next
;
1086 proxygroup
=new_ProxyGroup();
1087 proxygroup
->next
=firstProxyGroup
;
1088 proxygroup
->name
=strdup(groupname
);
1089 firstProxyGroup
=proxygroup
;
1093 static int MatchWindowName(WindowName
* namelist
,char* name
)
1095 WindowName
* include
=FindWindowName(namelist
, name
);
1096 return (include
!= NULL
);
1099 static ProxyGroup
* FindProxyGroupWithWindowName(char* name
)
1101 ProxyGroup
* proxygroup
=firstProxyGroup
;
1102 #if PROXY_GROUP_DEBUG
1103 fprintf(stderr
,"FindProxyGroupWithWindowName(%s)\n",name
);
1108 if(MatchWindowName(proxygroup
->includes
, name
))
1110 #if PROXY_GROUP_DEBUG
1111 fprintf(stderr
," found in %s\n",proxygroup
->name
);
1115 proxygroup
=proxygroup
->next
;
1121 static ProxyGroup
* FindProxyGroupOfNeighbor(ProxyWindow
* instigator
)
1125 if(!instigator
->group
)
1130 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1132 if(proxy
==instigator
)
1136 if (proxy
->desk
== deskNumber
&&
1137 proxy
->group
==instigator
->group
&& proxy
->proxy_group
)
1139 return proxy
->proxy_group
;
1145 static ProxyWindow
*FindProxy(Window window
)
1147 ProxyWindow
*proxy
=firstProxy
;
1149 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1151 if (proxy
->proxy
==window
|| proxy
->window
==window
)
1160 static void DrawPicture(
1161 Window window
, int x
, int y
, FvwmPicture
*picture
, int cset
)
1163 FvwmRenderAttributes fra
;
1165 if (!picture
|| picture
->picture
== None
)
1168 fra
.mask
= FRAM_DEST_IS_A_WINDOW
;
1171 fra
.mask
|= FRAM_HAVE_ICON_CSET
;
1172 fra
.colorset
= &Colorset
[cset
];
1174 PGraphicsRenderPicture(
1175 dpy
, window
, picture
, &fra
, window
, miniIconGC
, None
, None
,
1176 0, 0, picture
->width
, picture
->height
,
1177 x
, y
, picture
->width
, picture
->height
, False
);
1180 static void DrawWindow(
1181 ProxyWindow
*proxy
, int x
,int y
,int w
,int h
)
1185 FvwmPicture
*picture
= &proxy
->picture
;
1186 int drawMiniIcon
=(showMiniIcons
&& proxy
->picture
.picture
!= None
);
1193 if (!proxy
|| proxy
->proxy
== None
)
1203 texty
=(h
+ Ffont
->ascent
- Ffont
->descent
)/2; /* center */
1209 maxy
=h
-Ffont
->descent
-4;
1215 cset
= (proxy
==selectProxy
) ? cset_select
:
1216 ((proxy
->flags
.is_iconified
) ? cset_iconified
: cset_normal
);
1217 XSetForeground(dpy
,fg_gc
,Colorset
[cset
].fg
);
1218 XSetBackground(dpy
,fg_gc
,Colorset
[cset
].bg
);
1219 XSetForeground(dpy
,sh_gc
,Colorset
[cset
].shadow
);
1220 XSetForeground(dpy
,hi_gc
,Colorset
[cset
].hilite
);
1222 /* FIXME: use clip redrawing (not really essential here) */
1223 if (FLF_FONT_HAS_ALPHA(Ffont
,cset
) || PICTURE_HAS_ALPHA(picture
,cset
))
1225 XClearWindow(dpy
,proxy
->proxy
);
1227 RelieveRectangle(dpy
,proxy
->proxy
, 0,0, w
- 1,h
- 1, hi_gc
,sh_gc
, 2);
1230 if (proxy
->iconname
!= NULL
)
1232 free(proxy
->iconname
);
1234 proxy
->iconname
= safestrdup(" ");
1235 sprintf(proxy
->iconname
, "%d", proxy
->stack
);
1238 big_name
= proxy
->iconname
;
1239 if(big_name
==NULL
|| !big_name
[0])
1241 big_name
= proxy
->name
;
1243 small_name
= proxy
->name
;
1244 if(small_name
== NULL
)
1246 small_name
=big_name
;
1248 if (big_name
!= NULL
&& big_name
[0])
1250 int text_width
= FlocaleTextWidth(
1251 Ffont
,big_name
,strlen(big_name
));
1252 int edge
=(w
-text_width
)/2;
1263 FwinString
->str
= big_name
;
1264 FwinString
->win
= proxy
->proxy
;
1265 FwinString
->x
= edge
;
1266 FwinString
->y
= texty
;
1267 FwinString
->gc
= fg_gc
;
1268 FwinString
->flags
.has_colorset
= False
;
1271 FwinString
->colorset
= &Colorset
[cset
];
1272 FwinString
->flags
.has_colorset
= True
;
1274 FlocaleDrawString(dpy
, Ffont
, FwinString
, 0);
1276 if (small_name
!= NULL
&& small_name
[0] &&
1277 (overrun
|| strcmp(small_name
,big_name
)) && Ffont_small
!=NULL
)
1279 int text_width
= FlocaleTextWidth(
1280 Ffont_small
,small_name
,strlen(small_name
));
1281 int edge
=(w
-text_width
)/2;
1285 edge
=w
-text_width
-5;
1288 FwinString
->str
= small_name
;
1289 FwinString
->win
= proxy
->proxy
;
1290 FwinString
->x
= edge
;
1291 FwinString
->y
= h
-Ffont_small
->descent
-3;
1292 FwinString
->gc
= hi_gc
;
1293 FwinString
->flags
.has_colorset
= False
;
1296 FwinString
->colorset
= &Colorset
[cset
];
1297 FwinString
->flags
.has_colorset
= True
;
1299 FlocaleDrawString(dpy
, Ffont_small
, FwinString
, 0);
1301 if (drawMiniIcon
&& miniIconSlot
>0)
1303 int widgetx
=slotSpace
+(slotWidth
+slotSpace
)*(miniIconSlot
-1);
1304 DrawPicture(proxy
->proxy
, widgetx
, slotSpace
, picture
, cset
);
1306 for(group
=1;group
<groupCount
+1;group
++)
1308 int lit
=(proxy
->group
==group
);
1309 int widgetx
=slotSpace
+
1310 (slotWidth
+slotSpace
)*(groupSlot
+group
-2);
1311 int color_index
=group
%GROUP_COLORS
;
1312 int drawsoft
=lit
&& proxy
->flags
.is_soft
;
1313 int drawisolated
=lit
&& proxy
->flags
.is_isolated
;
1317 XSetForeground(dpy
,fg_gc
,GetColor(
1318 group_color
[color_index
][0]));
1319 XFillRectangle(dpy
,proxy
->proxy
,fg_gc
,
1321 slotWidth
,slotHeight
);
1323 XSetForeground(dpy
,sh_gc
,GetColor("black"));
1324 RelieveRectangle(dpy
,proxy
->proxy
,
1326 slotWidth
,slotHeight
/2,
1329 XSetForeground(dpy
,fg_gc
,GetColor(
1330 group_color
[color_index
][proxy
->group
==group
]));
1331 XFillRectangle(dpy
,proxy
->proxy
,fg_gc
,
1334 drawsoft
? slotHeight
/2: slotHeight
);
1336 XSetForeground(dpy
,sh_gc
,GetColor(lit
? "black": "white"));
1337 XSetForeground(dpy
,hi_gc
,GetColor(lit
? "black": "white"));
1338 RelieveRectangle(dpy
,proxy
->proxy
,
1340 slotWidth
,slotHeight
,
1344 RelieveRectangle(dpy
,proxy
->proxy
,
1345 widgetx
+4,slotSpace
+4,
1346 slotWidth
-8,slotHeight
-8,
1350 for(m
=0;m
<numSlots
;m
++)
1352 int widgetx
=slotSpace
+(slotWidth
+slotSpace
)*(m
-1);
1353 DrawPicture(proxy
->proxy
, widgetx
, slotSpace
, pictureArray
[m
],
1358 static void DrawProxy(ProxyWindow
*proxy
)
1363 proxy
, proxy
->proxyx
, proxy
->proxyy
, proxy
->proxyw
,
1368 static void DrawProxyBackground(ProxyWindow
*proxy
)
1372 if (proxy
== NULL
|| proxy
->proxy
== None
)
1376 cset
= (proxy
==selectProxy
) ? cset_select
:
1377 ((proxy
->flags
.is_iconified
) ? cset_iconified
: cset_normal
);
1378 XSetForeground(dpy
,fg_gc
,Colorset
[cset
].fg
);
1379 XSetBackground(dpy
,fg_gc
,Colorset
[cset
].bg
);
1380 SetWindowBackground(
1381 dpy
, proxy
->proxy
, proxy
->proxyw
, proxy
->proxyh
,
1382 &Colorset
[cset
], Pdepth
, fg_gc
, True
);
1385 static void OpenOneWindow(ProxyWindow
*proxy
)
1388 unsigned long valuemask
=CWOverrideRedirect
;
1389 XSetWindowAttributes attributes
;
1391 if (proxy
== NULL
||
1392 proxy
->desk
!= deskNumber
||
1393 (!proxyIconified
&& proxy
->flags
.is_iconified
) ||
1394 proxy
->flags
.is_shown
)
1404 if ((!selectProxy
|| proxy
!= selectProxy
) &&
1405 proxy
->window
!= focusWindow
)
1408 if (showOnly
== PROXY_SHOWONLY_SELECT
)
1412 other
= FindProxy(focusWindow
);
1413 #if PROXY_GROUP_DEBUG
1414 fprintf(stderr
, "OpenOneWindow"
1415 " %d %d %d %d %d %d %d %d %d %d\n",
1416 proxy
->proxyx
, proxy
->proxyy
,
1417 proxy
->proxyw
, proxy
->proxyh
,
1420 proxy
->group
, other
->group
);
1422 if ((showOnly
== PROXY_SHOWONLY_COVER
||
1424 proxy
->group
!= other
->group
) &&
1425 (proxy
->proxyx
> other
->x
+other
->w
||
1426 proxy
->proxyx
+proxy
->proxyw
< other
->x
||
1427 proxy
->proxyy
> other
->y
+other
->h
||
1428 proxy
->proxyy
+proxy
->proxyh
< other
->y
))
1434 if (proxy
->proxy
== None
)
1436 long eventMask
=ButtonPressMask
|ExposureMask
|ButtonMotionMask
;
1440 eventMask
|=EnterWindowMask
;
1442 attributes
.override_redirect
= True
;
1443 proxy
->proxy
= XCreateWindow(
1444 dpy
, rootWindow
, proxy
->proxyx
, proxy
->proxyy
,
1445 proxy
->proxyw
, proxy
->proxyh
,border
,
1446 DefaultDepth(dpy
,screen
), InputOutput
, Pvisual
,
1447 valuemask
, &attributes
);
1448 XSelectInput(dpy
,proxy
->proxy
,eventMask
);
1452 XMoveWindow(dpy
, proxy
->proxy
, proxy
->proxyx
, proxy
->proxyy
);
1454 XMapRaised(dpy
, proxy
->proxy
);
1455 DrawProxyBackground(proxy
);
1456 proxy
->flags
.is_shown
= 1;
1461 static void OpenWindows(void)
1465 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1467 OpenOneWindow(proxy
);
1474 static void CloseOneWindow(ProxyWindow
*proxy
)
1480 if (proxy
->flags
.is_shown
)
1482 XUnmapWindow(dpy
, proxy
->proxy
);
1483 proxy
->flags
.is_shown
= 0;
1489 static void CloseWindows(void)
1493 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1495 CloseOneWindow(proxy
);
1501 static Bool
SortProxiesOnce(void)
1512 for (proxy
=firstProxy
; proxy
!= NULL
&& proxy
->next
!= NULL
;
1516 x2
=proxy
->next
->proxyx
;
1518 y2
=proxy
->next
->proxyy
;
1520 /* sort x, then y, then arbitrarily on pointer */
1521 if ( x1
>x2
|| (x1
==x2
&& y1
>y2
) ||
1522 (x1
==x2
&& y1
==y2
&&
1523 proxy
->window
>proxy
->next
->window
))
1529 lastProxy
->next
=next
;
1532 proxy
->next
=next
->next
;
1540 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1542 proxy
->prev
=lastProxy
;
1549 static void SortProxies(void)
1551 while (SortProxiesOnce() == True
)
1559 static Bool
AdjustOneWindow(ProxyWindow
*proxy
)
1562 ProxyWindow
*other
=proxy
->next
;
1564 for (other
=proxy
->next
; other
; other
=other
->next
)
1569 if(other
->desk
!= deskNumber
)
1573 dx
= abs(proxy
->proxyx
-other
->proxyx
);
1574 dy
= abs(proxy
->proxyy
-other
->proxyy
);
1575 if (dx
<(proxyWidth
+proxySeparation
) &&
1576 dy
<proxyHeight
+proxySeparation
)
1579 #if PROXY_GROUP_DEBUG
1581 "AdjustOneWindow %d %d %d %d %d %d %d %d\n",
1582 proxy
->proxyx
, proxy
->proxyy
,
1583 proxy
->proxyw
, proxy
->proxyh
,
1584 other
->proxyx
, other
->proxyy
,
1585 other
->proxyw
, other
->proxyh
);
1587 if (proxyWidth
-dx
<proxyHeight
-dy
)
1589 if (proxy
->proxyx
<=other
->proxyx
)
1591 int delta
= proxy
->proxyx
+
1595 proxy
->proxyx
-= delta
/2;
1596 other
->proxyx
+= delta
- delta
/2;
1597 #if PROXY_GROUP_DEBUG
1598 fprintf(stderr
, "left %d\n", delta
);
1603 int delta
= other
->proxyx
+
1607 other
->proxyx
-= delta
/2;
1608 proxy
->proxyx
+= delta
- delta
/2;
1609 #if PROXY_GROUP_DEBUG
1610 fprintf(stderr
, "right %d\n", delta
);
1616 if (proxy
->proxyy
<=other
->proxyy
)
1618 int delta
= proxy
->proxyy
+
1622 proxy
->proxyy
-= delta
/2;
1623 other
->proxyy
+= delta
- delta
/2;
1624 #if PROXY_GROUP_DEBUG
1625 fprintf(stderr
, "up %d\n", delta
);
1630 int delta
= other
->proxyy
+
1634 other
->proxyy
-= delta
/2;
1635 proxy
->proxyy
+= delta
- delta
/2;
1636 #if PROXY_GROUP_DEBUG
1637 fprintf(stderr
, "down %d\n", delta
);
1642 if (proxyWidth-dx<proxyHeight-dy)
1644 if (proxy->proxyx<=other->proxyx)
1647 proxy->proxyx+ proxy->proxyw+
1653 other->proxyx+ other->proxyw+
1659 if (proxy->proxyy<=other->proxyy)
1662 proxy->proxyy+ proxy->proxyh+
1668 other->proxyy+ other->proxyh+
1679 static void AdjustWindows(void)
1681 Bool collision
=True
;
1683 while (collision
== True
)
1688 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1690 if(proxy
->desk
!= deskNumber
)
1693 if (AdjustOneWindow(proxy
) == True
)
1701 static void RecenterProxy(ProxyWindow
*proxy
)
1703 proxy
->proxyx
=proxy
->x
+ (proxy
->w
-proxy
->proxyw
)/2;
1704 proxy
->proxyy
=proxy
->y
+ (proxy
->h
-proxy
->proxyh
)/2;
1707 static void RecalcProxyTweaks(void)
1710 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1712 proxy
->tweakx
=proxy
->proxyx
-
1713 (proxy
->x
+ (proxy
->w
-proxy
->proxyw
)/2);
1714 proxy
->tweaky
=proxy
->proxyy
-
1715 (proxy
->y
+ (proxy
->h
-proxy
->proxyh
)/2);
1718 static void TweakProxy(ProxyWindow
*proxy
)
1720 proxy
->proxyx
+= proxy
->tweakx
;
1721 proxy
->proxyy
+= proxy
->tweaky
;
1724 static void ReshuffleWindows(void)
1728 #if PROXY_GROUP_DEBUG
1729 fprintf(stderr
, "ReshuffleWindows\n");
1732 if (are_windows_shown
)
1736 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1738 RecenterProxy(proxy
);
1742 if (are_windows_shown
)
1746 RecalcProxyTweaks();
1751 static void UpdateOneWindow(ProxyWindow
*proxy
)
1757 if (proxy
->flags
.is_shown
)
1765 static void SendResolve(ProxyWindow
*proxy
)
1767 SendFvwmPipe(fd
, "SendToModule FvwmProxy Resolve",
1771 static void WaitToConfig(ProxyWindow
*proxy
)
1773 proxy
->pending_config
++;
1774 if(!waiting_to_config
)
1776 waiting_to_config
=1;
1781 static int Provokable(ProxyWindow
*proxy
,proxy_provoke_t provocation
)
1783 int soft
=proxy
->flags
.is_soft
;
1784 ProxyGroup
* proxy_group
=proxy
->proxy_group
;
1785 proxy_follow_t follow
;
1786 WindowName
* include
;
1787 #if PROXY_GROUP_DEBUG
1788 fprintf(stderr
, "Provokable %p %s %x soft %d\n",
1789 proxy
,proxy
->name
,provocation
,soft
);
1793 proxy_group
=FindProxyGroupOfNeighbor(proxy
);
1800 follow
=PROXY_FOLLOW_INHERIT
;
1802 #if PROXY_GROUP_DEBUG
1803 fprintf(stderr
, " group flags %x\n",proxy_group
->flags
);
1805 include
= FindWindowName(proxy_group
->includes
,proxy
->name
);
1808 #if PROXY_GROUP_DEBUG
1809 fprintf(stderr
, " include flags %x\n",include
->flags
);
1814 case PROXY_PROVOKE_RAISE
:
1815 follow
=soft
? include
->flags
.soft_raise
:
1816 include
->flags
.hard_raise
;
1819 case PROXY_PROVOKE_DESK
:
1820 follow
=soft
? include
->flags
.soft_desk
:
1821 include
->flags
.hard_desk
;
1824 case PROXY_PROVOKE_DRAG
:
1825 follow
=soft
? include
->flags
.soft_drag
:
1826 include
->flags
.hard_drag
;
1829 case PROXY_PROVOKE_ICON
:
1830 follow
=soft
? include
->flags
.soft_icon
:
1831 include
->flags
.hard_icon
;
1834 #if PROXY_GROUP_DEBUG
1835 fprintf(stderr
, " include follow %d\n",follow
);
1837 if(follow
!=PROXY_FOLLOW_INHERIT
)
1839 return (follow
!=PROXY_FOLLOW_OFF
);
1843 follow
=PROXY_FOLLOW_INHERIT
;
1846 case PROXY_PROVOKE_RAISE
:
1847 follow
=soft
? proxy_group
->flags
.soft_raise
:
1848 proxy_group
->flags
.hard_raise
;
1851 case PROXY_PROVOKE_DESK
:
1852 follow
=soft
? proxy_group
->flags
.soft_desk
:
1853 proxy_group
->flags
.hard_desk
;
1856 case PROXY_PROVOKE_DRAG
:
1857 follow
=soft
? proxy_group
->flags
.soft_drag
:
1858 proxy_group
->flags
.hard_drag
;
1861 case PROXY_PROVOKE_ICON
:
1862 follow
=soft
? proxy_group
->flags
.soft_icon
:
1863 proxy_group
->flags
.hard_icon
;
1866 #if PROXY_GROUP_DEBUG
1867 fprintf(stderr
, " group follow %d\n",follow
);
1869 return (follow
!=PROXY_FOLLOW_OFF
);
1872 static int Provoked(ProxyWindow
*instigator
,ProxyWindow
*proxy
,
1873 proxy_provoke_t provocation
)
1875 return (Provokable(instigator
,provocation
) &&
1876 Provokable(proxy
,provocation
));
1879 static void IsolateGroup(ProxyWindow
*instigator
,int isolate
)
1883 #if PROXY_GROUP_DEBUG
1884 fprintf(stderr
, "IsolateGroup %p %d\n",
1885 instigator
,isolate
);
1888 if(!instigator
->group
)
1893 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1895 if(proxy
==instigator
)
1899 if (proxy
->desk
== deskNumber
&&
1900 proxy
->group
==instigator
->group
)
1902 proxy
->flags
.is_isolated
=isolate
;
1904 DrawProxyBackground(proxy
);
1910 static void IconifyGroup(ProxyWindow
*instigator
,int iconify
)
1914 #if PROXY_GROUP_DEBUG
1915 fprintf(stderr
, "IconifyGroup %p %d\n",
1916 instigator
,iconify
);
1919 if(!instigator
->group
)
1924 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1926 if(proxy
==instigator
)
1930 if(!Provoked(instigator
,proxy
,PROXY_PROVOKE_ICON
))
1934 if (proxy
->desk
== deskNumber
&&
1935 proxy
->group
==instigator
->group
)
1937 sprintf(commandBuffer
,"Iconify %s",
1938 iconify
? "On": "Off");
1939 send_command_to_fvwm(commandBuffer
,proxy
->window
);
1944 void RefineStack(int desired
)
1947 ProxyWindow
*best
= NULL
;
1949 #if PROXY_GROUP_DEBUG
1950 fprintf(stderr
, "RefineStack %d\n", desired
);
1952 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1954 proxy
->stack_tmp
= -1;
1959 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1961 if(proxy
->stack_tmp
< 0 && (best
== NULL
||
1962 (desired
? proxy
->stack_desired
: proxy
->stack
) <
1963 (desired
? best
->stack_desired
: best
->stack
)))
1972 #if PROXY_GROUP_DEBUG
1973 fprintf(stderr
, "%p %d %d -> %d %s\n", best
,
1974 best
->stack
, best
->stack_desired
,
1977 best
->stack_tmp
= index
++;
1979 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1983 proxy
->stack_desired
= proxy
->stack_tmp
;
1987 proxy
->stack
= proxy
->stack_tmp
;
1992 /* doesn't work: non-fatal X error in X_ConfigureWindow */
1993 void RestackAtomic(int raise
)
2000 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2004 windows
= (Window
*) safemalloc (count
* sizeof (Window
));
2005 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2007 fprintf(stderr
, "RestackAtomic %d %s\n",
2008 proxy
->stack
, proxy
->name
);
2009 windows
[proxy
->stack
] = proxy
->window
;
2011 XRestackWindows(dpy
, windows
, count
);
2015 void RestackIncremental(int raise
)
2026 ProxyWindow
*best
= NULL
;
2030 #if PROXY_GROUP_DEBUG
2031 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2033 fprintf(stderr
, "%2d ", proxy
->stack
);
2035 fprintf(stderr
, "\n");
2036 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2038 fprintf(stderr
, "%2d ", proxy
->stack_desired
);
2040 fprintf(stderr
, "\n");
2042 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2045 proxy
->stack
- proxy
->stack_desired
:
2046 proxy
->stack_desired
- proxy
->stack
;
2048 (best
== NULL
|| delta
> next_delta
))
2056 #if PROXY_GROUP_DEBUG
2058 "RestackIncremental Raise %p %s %d -> %d\n",
2060 best
->stack
, best
->stack_desired
);
2065 XRaiseWindow(dpy
, best
->window
);
2066 best
->stack
= INT_MIN
;
2071 XLowerWindow(dpy
, best
->window
);
2072 best
->stack
= INT_MAX
;
2079 #if PROXY_GROUP_DEBUG
2081 "RestackIncremental excessive changes (%d)\n",
2086 #if PROXY_GROUP_DEBUG
2087 fprintf(stderr
, "*****************************************\n");
2088 fprintf(stderr
, "RestackIncremental(%d) %d changes\n",
2094 void Restack(int raise
)
2096 RestackIncremental(raise
);
2099 void ReadStack(unsigned long *body
, unsigned long length
)
2104 ProxyWindow
*instigator
=NULL
;
2107 #if PROXY_GROUP_DEBUG
2108 fprintf(stderr
, "ReadStack %p %d-%d\n",
2109 body
, (int)length
, FvwmPacketHeaderSize
);
2112 for (i
= 0; i
< (length
- FvwmPacketHeaderSize
); i
+= 3)
2114 instigator
=FindProxy(body
[0]);
2124 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2126 if(proxy
->stack
>instigator
->stack
)
2128 proxy
->stack
+=10000;
2132 index
=instigator
->stack
;
2133 for (i
= 0; i
< (length
- FvwmPacketHeaderSize
); i
+= 3)
2136 #if PROXY_GROUP_DEBUG
2137 fprintf(stderr
, " stack %d %d\n", i
, (int)window
);
2139 proxy
= FindProxy(window
);
2142 #if PROXY_GROUP_DEBUG
2143 fprintf(stderr
, " %p %s",proxy
,proxy
->name
);
2145 proxy
->stack
= index
++;
2147 #if PROXY_GROUP_DEBUG
2148 fprintf(stderr
, "\n");
2154 static void RaiseLowerGroup(Window w
,int raise
)
2156 ProxyWindow
*instigator
;
2159 instigator
= FindProxy(w
);
2160 #if PROXY_GROUP_DEBUG
2161 fprintf(stderr
, "RaiseLowerGroup %d %s\n", raise
,
2162 instigator
? instigator
->name
: "<none>");
2164 if(instigator
==NULL
)
2168 instigator
->stack
= raise
? INT_MIN
: INT_MAX
;
2170 if(instigator
->flags
.is_isolated
)
2174 if(!Provokable(instigator
,PROXY_PROVOKE_RAISE
))
2179 #if PROXY_GROUP_DEBUG
2180 fprintf(stderr
, "RaiseLowerGroup %p %d %d\n",
2181 instigator
,raise
,instigator
->raised
);
2184 if(abs(instigator
->raised
)>10)
2189 if(instigator
->raised
== (raise
? 1: -1))
2194 instigator
->raised
=0;
2196 if(instigator
->flags
.is_iconified
|| !instigator
->group
)
2201 instigator
->stack
= raise
? INT_MIN
: INT_MAX
;
2202 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2204 proxy
->stack_desired
= proxy
->stack
;
2206 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2208 if(proxy
==instigator
)
2212 if(!Provokable(proxy
,PROXY_PROVOKE_RAISE
))
2216 if (proxy
->desk
== deskNumber
&&
2217 proxy
->group
==instigator
->group
)
2221 #if PROXY_GROUP_DEBUG
2222 fprintf(stderr
, "Raise %p\n",proxy
);
2225 proxy
->stack_desired
-=10000;
2229 #if PROXY_GROUP_DEBUG
2230 fprintf(stderr
, "Lower %p\n",proxy
);
2233 proxy
->stack_desired
+=10000;
2241 static void RaiseLowerGroupOld(Window w,int raise)
2243 ProxyWindow *instigator;
2246 instigator = FindProxy(w);
2247 fprintf(stderr, "RaiseLowerGroup %d %s\n", raise,
2248 instigator? instigator->name: "<none>");
2251 instigator->stack = raise? INT_MIN: INT_MAX;
2254 if(instigator==NULL || instigator->flags.is_isolated)
2260 #if PROXY_GROUP_DEBUG
2261 fprintf(stderr, "RaiseLowerGroup %p %d %d\n",
2262 instigator,raise,instigator->raised);
2265 if(abs(instigator->raised)>10)
2270 if(instigator->raised == (raise? 1: -1))
2275 instigator->raised=0;
2277 if(instigator->flags.is_iconified || !instigator->group)
2282 for (proxy=firstProxy; proxy != NULL; proxy=proxy->next)
2284 if(proxy==instigator || proxy->raised == (raise? 1: -1))
2288 if (proxy->desk == deskNumber &&
2289 proxy->group==instigator->group)
2293 #if PROXY_GROUP_DEBUG
2294 fprintf(stderr, "Raise %p\n",proxy);
2298 XRaiseWindow(dpy, proxy->window);
2302 #if PROXY_GROUP_DEBUG
2303 fprintf(stderr, "Lower %p\n",proxy);
2307 XLowerWindow(dpy, proxy->window);
2313 #if PROXY_GROUP_DEBUG
2314 fprintf(stderr, "ReRaise %p\n",instigator);
2317 instigator->raised=1;
2318 XRaiseWindow(dpy, instigator->window);
2322 #if PROXY_GROUP_DEBUG
2323 fprintf(stderr, "ReLower %p\n",instigator);
2326 instigator->raised= -1;
2327 XLowerWindow(dpy, instigator->window);
2332 static void ClearRaised(void)
2336 #if PROXY_GROUP_DEBUG
2337 fprintf(stderr
, "ClearRaised\n");
2340 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2346 static void ShiftWindows(ProxyWindow
*instigator
,int dx
,int dy
)
2350 if((are_windows_shown
&& !instigator
->flags
.is_isolated
) ||
2351 !instigator
->group
|| instigator
->flags
.is_soft
)
2356 #if PROXY_GROUP_DEBUG
2357 fprintf(stderr
, "ShiftWindows %d %d %d\n",
2358 instigator
->group
,dx
,dy
);
2361 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2363 if(proxy
==instigator
)
2367 if(!instigator
->flags
.is_isolated
&&
2368 !Provoked(instigator
,proxy
,PROXY_PROVOKE_DRAG
))
2372 if (proxy
->desk
== deskNumber
&&
2373 proxy
->group
==instigator
->group
)
2378 XMoveWindow(dpy, proxy->window,
2379 proxy->x+proxy->border_width,
2380 proxy->y+proxy->title_height+
2381 proxy->border_width);
2383 #if PROXY_GROUP_DEBUG
2384 fprintf(stderr
, "shift %d %d (%d %d)\n",
2385 proxy
->x
,proxy
->y
, dx
,dy
);
2387 WaitToConfig(proxy
);
2392 static void CatchWindows(ProxyWindow
*instigator
,int vertical
,int from
,int to
,
2397 if((are_windows_shown
&& !instigator
->flags
.is_isolated
) ||
2398 !instigator
->group
|| instigator
->flags
.is_soft
)
2403 #if PROXY_GROUP_DEBUG
2404 fprintf(stderr
, "CatchWindows %d %d %d %d\n",
2405 instigator
->group
,vertical
,from
,to
);
2408 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2410 if(proxy
==instigator
)
2414 if(!Provoked(instigator
,proxy
,PROXY_PROVOKE_DRAG
))
2418 if (proxy
->desk
== deskNumber
&&
2419 proxy
->group
==instigator
->group
&&
2420 !proxy
->flags
.is_soft
)
2425 int neww
=proxy
->goal_width
;
2426 int newh
=proxy
->goal_height
;
2427 const int incx
=proxy
->incx
;
2428 const int incy
=proxy
->incy
;
2429 /* int threshold=(vertical? incy: incx)-1;
2444 #if PROXY_GROUP_DEBUG
2446 "check %p %d %d size %d %d"
2447 " goal %d %d inc %d %d\n",
2448 proxy
,proxy
->x
,proxy
->y
,proxy
->w
,proxy
->h
,
2449 proxy
->goal_width
,proxy
->goal_height
,
2455 if(newy
>=least
&& newy
<=most
)
2461 else if(newy
+newh
>=least
&&
2470 if(newx
>=least
&& newx
<=most
)
2476 else if(newx
+neww
>=least
&&
2485 #if PROXY_GROUP_DEBUG
2486 fprintf(stderr
, "change %d %d %d %d\n",
2487 newx
,newy
,neww
,newh
);
2489 if(newx
!=proxy
->x
|| newy
!=proxy
->y
)
2491 #if PROXY_GROUP_DEBUG
2492 fprintf(stderr
, "move\n");
2495 XMoveWindow(dpy, proxy->window,
2499 WaitToConfig(proxy
);
2501 /* in case more motion of instigator
2502 precedes this window's config */
2507 neww
>=proxy
->w
+incx
||
2509 newh
>=proxy
->h
+incy
)
2511 #if PROXY_GROUP_DEBUG
2512 fprintf(stderr
, "resize\n");
2515 XResizeWindow(dpy, proxy->window,
2519 WaitToConfig(proxy
);
2521 /* in case more motion of instigator
2522 precedes this window's config */
2525 proxy
->w
-=((proxy
->w
-neww
-1)/
2528 else if(neww
>=proxy
->w
+incx
)
2530 proxy
->w
+=(neww
-proxy
->w
)/incx
2535 proxy
->h
-=((proxy
->h
-newh
-1)/
2538 else if(newh
>=proxy
->h
+incy
)
2540 proxy
->h
+=(newh
-proxy
->h
)/incy
2544 proxy
->goal_width
=neww
;
2545 proxy
->goal_height
=newh
;
2552 static void MoveProxiedWindow(ProxyWindow
* proxy
,int x
,int y
,int w
,int h
)
2555 sprintf(commandBuffer
,"ResizeMove frame %dp %dp +%dp +%dp",
2560 send_command_to_fvwm(commandBuffer
,proxy
->window
);
2562 const int bw
=proxy
->border_width
;
2563 const int th
=proxy
->title_height
;
2565 XMoveResizeWindow(dpy
, proxy
->window
,
2573 static void ResolvePendingWindows(void)
2577 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2579 if(proxy
->pending_config
)
2581 MoveProxiedWindow(proxy
,proxy
->x
,proxy
->y
,
2582 proxy
->goal_width
,proxy
->goal_height
);
2587 int FindUniqueGroup(int desk
)
2591 /* find unique group */
2593 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2595 if (proxy
->desk
== desk
&& proxy
->group
==group
)
2602 #if PROXY_GROUP_DEBUG
2603 fprintf(stderr
,"FindUniqueGroup desk %d group %d\n",desk
,group
);
2608 static void MoveGroupToDesk(ProxyWindow
*instigator
,int desk
)
2615 #if PROXY_GROUP_DEBUG
2616 fprintf(stderr
, "MoveGroupToDesk %p %d\n",
2620 if(!instigator
->group
)
2625 old_desk
=instigator
->desk
;
2626 old_group
=instigator
->group
;
2627 group
=FindUniqueGroup(desk
);
2629 sprintf(commandBuffer
, "MoveToDesk 0 %d", desk
);
2630 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2632 if(!Provoked(instigator
,proxy
,PROXY_PROVOKE_DESK
))
2636 if (proxy
->desk
== old_desk
&&
2637 proxy
->group
==old_group
)
2642 send_command_to_fvwm( commandBuffer
, proxy
->window
);
2644 DrawProxyBackground(proxy
);
2651 static ProxyWindow
* FindNeighborInGroup(ProxyWindow
* instigator
,
2661 #if PROXY_GROUP_DEBUG
2662 fprintf(stderr
,"FindNeighborInGroup %p %p desk %d group %d\n",
2663 instigator
,instigator
->proxy_group
,instigator
->desk
,
2667 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2669 #if PROXY_GROUP_DEBUG
2670 fprintf(stderr
," vs %p %p desk %d group %d\n",
2671 proxy
,proxy
->proxy_group
,proxy
->desk
,proxy
->group
);
2673 if (proxy
!= instigator
&& proxy
->desk
== instigator
->desk
&&
2675 proxy
->group
==instigator
->group
&&
2676 (!not_iconified
|| !proxy
->flags
.is_iconified
))
2685 static ProxyWindow
* FindNeighborForProxy(ProxyWindow
* instigator
)
2688 ProxyWindow
*neighbor
=NULL
;
2696 #if PROXY_GROUP_DEBUG
2697 fprintf(stderr
,"FindNeighborForProxy %p %p desk %d\n",
2698 instigator
,instigator
->proxy_group
,instigator
->desk
);
2701 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2703 #if PROXY_GROUP_DEBUG
2704 fprintf(stderr
," vs %p %p desk %d group %d\n",
2705 proxy
,proxy
->proxy_group
,proxy
->desk
,proxy
->group
);
2707 if (proxy
!= instigator
&& proxy
->desk
== instigator
->desk
&&
2708 proxy
->proxy_group
==instigator
->proxy_group
)
2710 if(proxy
->proxy_group
->flags
.isolated
&&
2711 !instigator
->flags
.is_isolated
)
2714 "SendToModule FvwmProxy IsolateToggle",
2727 #if PROXY_GROUP_DEBUG
2728 fprintf(stderr
,"not found\n");
2733 group
=FindUniqueGroup(instigator
->desk
);
2735 /* assign group to all proxies with given pid */
2736 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2738 if (proxy
->desk
== instigator
->desk
&&
2739 proxy
->proxy_group
==instigator
->proxy_group
)
2741 #if PROXY_GROUP_DEBUG
2742 fprintf(stderr
,"unique group %d reassign %s\n",
2749 #if PROXY_GROUP_DEBUG
2750 fprintf(stderr
,"group %d\n",group
);
2755 static ProxyWindow
* FindNeighborForProcess(ProxyWindow
* proxy
,
2756 int desk
,int pid
,int ppid
)
2759 ProxyWindow
*neighbor
=NULL
;
2763 #if PROXY_GROUP_DEBUG
2764 fprintf(stderr
,"FindNeighborForProcess %p desk %d pid %d %d\n",
2765 proxy
, desk
, ppid
, pid
);
2773 /* find existing group for pid */
2774 for (other
=firstProxy
; other
!= NULL
; other
=other
->next
)
2776 if (other
->desk
== desk
&& other
->proxy_group
&&
2777 (other
->pid
==pid
|| (ppid
&& other
->pid
==ppid
) ||
2778 other
->ppid
==pid
) &&
2779 (MatchWindowName(other
->proxy_group
->includes
,
2781 (auto_include
=other
->proxy_group
->flags
.auto_include
)))
2783 proxy
->flags
.is_soft
= (auto_include
&&
2784 other
->proxy_group
->flags
.auto_soft
);
2785 if(other
->proxy_group
->flags
.isolated
&&
2786 !proxy
->flags
.is_isolated
)
2789 "SendToModule FvwmProxy IsolateToggle",
2792 #if PROXY_GROUP_DEBUG
2794 "pid %d %d found %d %d group %d soft %d\n",
2795 pid
,ppid
,other
->pid
,other
->ppid
,
2796 other
->group
,proxy
->flags
.is_soft
);
2807 #if PROXY_GROUP_DEBUG
2808 fprintf(stderr
,"FindNeighborForProcess pid %d %d not found\n",
2814 group
=FindUniqueGroup(desk
);
2816 /* assign pid to all proxies with given pid */
2817 for (other
=firstProxy
; other
!= NULL
; other
=other
->next
)
2819 if (other
->desk
== desk
&& other
->proxy_group
&&
2820 (other
->pid
==pid
|| (ppid
&& other
->pid
==ppid
) ||
2823 #if PROXY_GROUP_DEBUG
2824 fprintf(stderr
,"unique group %d reassign %s\n",
2831 #if PROXY_GROUP_DEBUG
2832 fprintf(stderr
,"FindNeighborForProcess pid %d new %d\n",pid
,group
);
2837 static ProxyWindow
* FindNeighborForLeader(ProxyWindow
* proxy
,
2838 int desk
,int leader
)
2841 ProxyWindow
*neighbor
=NULL
;
2845 #if PROXY_GROUP_DEBUG
2846 fprintf(stderr
,"FindNeighborForLeader %p desk %d leader %d \n",
2847 proxy
, desk
, leader
);
2855 /* find existing group for leader */
2856 for (other
=firstProxy
; other
!= NULL
; other
=other
->next
)
2858 if (other
->desk
== desk
&& other
->proxy_group
&&
2859 other
->leader
==leader
&&
2860 (MatchWindowName(other
->proxy_group
->includes
,
2862 (auto_include
=other
->proxy_group
->flags
.auto_include
)))
2864 proxy
->flags
.is_soft
=auto_include
&&
2865 other
->proxy_group
->flags
.auto_soft
;
2866 if(other
->proxy_group
->flags
.isolated
&&
2867 !proxy
->flags
.is_isolated
)
2870 "SendToModule FvwmProxy IsolateToggle",
2873 #if PROXY_GROUP_DEBUG
2874 fprintf(stderr
,"leader %d found %d group %d soft %d\n",
2875 leader
,other
->leader
,
2876 other
->group
,proxy
->flags
.is_soft
);
2887 #if PROXY_GROUP_DEBUG
2888 fprintf(stderr
,"FindNeighborForLeader leader %d not found\n",
2894 group
=FindUniqueGroup(desk
);
2896 /* assign leader to all proxies with given leader */
2897 for (other
=firstProxy
; other
!= NULL
; other
=other
->next
)
2899 if (other
->desk
== desk
&& other
->leader
==leader
&&
2902 #if PROXY_GROUP_DEBUG
2903 fprintf(stderr
,"unique group %d reassign %s\n",
2910 #if PROXY_GROUP_DEBUG
2911 fprintf(stderr
,"FindNeighborForLeader leader %x new %d\n",
2917 static ProxyWindow
* FindNeighborForApplication(ProxyWindow
* proxy
)
2919 ProxyWindow
* neighbor
=FindNeighborForLeader(proxy
,proxy
->desk
,
2923 neighbor
=FindNeighborForProcess(proxy
,proxy
->desk
,
2924 proxy
->pid
,proxy
->ppid
);
2929 static int ProxyGroupCheckSoft(ProxyGroup
* proxy_group
,
2932 WindowName
* include
=FindWindowName(proxy_group
->includes
,
2934 return include
? include
->flags
.is_soft
: 0;
2937 static int ProxyGroupCheckWeak(ProxyGroup
* proxy_group
,
2940 WindowName
* include
=FindWindowName(proxy_group
->includes
,
2942 return include
? include
->flags
.is_weak
: 0;
2945 static void UpdateProxyGroup(ProxyWindow
* proxy
)
2947 ProxyWindow
* neighbor
;
2948 #if PROXY_GROUP_DEBUG
2949 fprintf(stderr
,"UpdateProxyGroup %s\n",proxy
->name
);
2952 if(proxy
->proxy_group
)
2956 if(!proxy
->proxy_group
)
2958 neighbor
=FindNeighborForApplication(proxy
);
2962 proxy
->proxy_group
=NULL
;
2963 if(neighbor
&& neighbor
->proxy_group
)
2965 proxy
->group
=neighbor
->group
;
2966 proxy
->proxy_group
=neighbor
->proxy_group
;
2969 if(!proxy
->proxy_group
)
2972 FindProxyGroupWithWindowName(proxy
->name
);
2973 if(proxy
->proxy_group
&&
2974 ProxyGroupCheckWeak(proxy
->proxy_group
,proxy
))
2976 proxy
->proxy_group
=NULL
;
2979 if(proxy
->proxy_group
&&
2980 MatchWindowName(proxy
->proxy_group
->excludes
,proxy
->name
))
2982 proxy
->proxy_group
=NULL
;
2985 if(proxy
->proxy_group
&& !proxy
->group
&&
2986 proxy
->proxy_group
->flags
.ignore_ids
)
2988 neighbor
=FindNeighborForProxy(proxy
);
2991 proxy
->group
=neighbor
->group
;
2995 if(proxy
->proxy_group
)
2997 #if PROXY_GROUP_DEBUG
2998 fprintf(stderr
," ProxyGroup %s\n",proxy
->proxy_group
->name
);
3001 proxy
->flags
.is_soft
=proxy
->flags
.is_soft
||
3002 ProxyGroupCheckSoft(proxy
->proxy_group
,proxy
);
3006 static void UpdateProxyGroupForAll(void)
3010 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
3012 UpdateProxyGroup(proxy
);
3016 static void AdhereGroup(ProxyWindow
*instigator
)
3020 #if PROXY_GROUP_DEBUG
3021 fprintf(stderr
, "AdhereGroup %p\n", instigator
);
3029 if(!instigator
->group
|| instigator
->flags
.is_soft
)
3034 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
3036 if(proxy
==instigator
)
3040 if (proxy
->desk
== instigator
->desk
&&
3041 proxy
->group
==instigator
->group
)
3043 if(!proxy
->flags
.is_soft
&&
3044 (proxy
->x
!= instigator
->x
||
3045 proxy
->y
!= instigator
->y
||
3046 proxy
->goal_width
!= instigator
->goal_width
||
3047 proxy
->goal_height
!= instigator
->goal_height
))
3049 proxy
->x
=instigator
->x
;
3050 proxy
->y
=instigator
->y
;
3051 proxy
->goal_width
=instigator
->goal_width
;
3052 proxy
->goal_height
=instigator
->goal_height
;
3054 MoveProxiedWindow(proxy
,proxy
->x
,proxy
->y
,
3055 proxy
->goal_width
,proxy
->goal_height
);
3061 static void SetGroup(ProxyWindow
* proxy
, int group
)
3063 ProxyWindow
*neighbor
;
3068 neighbor
=FindNeighborInGroup(proxy
,0);
3071 proxy
->flags
.is_isolated
= neighbor
->flags
.is_isolated
;
3072 if(proxy
->flags
.is_isolated
)
3074 AdhereGroup(neighbor
);
3077 if(proxy
->flags
.is_isolated
&& !proxy
->flags
.is_iconified
)
3079 IconifyGroup(proxy
,1);
3084 proxy
->flags
.is_soft
=0;
3085 proxy
->flags
.is_isolated
=0;
3089 void DumpStampQueue(void)
3091 #if PROXY_GROUP_DEBUG
3094 fprintf(stderr
,"DumpStampQueue stamp %d min %d max %d\n",
3095 stamp
,stampMin
,stampMax
);
3096 for(m
=0;m
<stampLimit
;m
++)
3098 fprintf(stderr
,"stampQueue[%d] %x %d %d %d %d\n",m
,
3099 (int)(stampQueue
[m
].window
),
3108 void StoreStamp(Window window
,int x
,int y
,int w
,int h
)
3110 #if PROXY_GROUP_DEBUG
3111 fprintf(stderr
,"StoreStamp %x %d %d %d %d\n",(int)window
,x
,y
,w
,h
);
3114 stamp
=(stamp
+1)%stampLimit
;
3116 if(stampMin
==stampMax
)
3118 stampMin
=(stampMax
+1)%stampLimit
;
3121 stampQueue
[stamp
].window
=window
;
3122 stampQueue
[stamp
].x
=x
;
3123 stampQueue
[stamp
].y
=y
;
3124 stampQueue
[stamp
].w
=w
;
3125 stampQueue
[stamp
].h
=h
;
3130 void UndoStamp(void)
3136 #if PROXY_GROUP_DEBUG
3137 fprintf(stderr
,"UndoStamp empty, stamp %d min %d max %d\n",
3138 stamp
,stampMin
,stampMax
);
3142 proxy
= FindProxy(stampQueue
[stamp
].window
);
3145 #if PROXY_GROUP_DEBUG
3146 fprintf(stderr
,"UndoStamp no proxy for window\n");
3152 MoveProxiedWindow(proxy
,
3153 stampQueue
[stamp
].x
,
3154 stampQueue
[stamp
].y
,
3155 stampQueue
[stamp
].w
,
3156 stampQueue
[stamp
].h
);
3158 stampQueue
[stamp
].window
=proxy
->window
;
3159 stampQueue
[stamp
].x
=proxy
->x
;
3160 stampQueue
[stamp
].y
=proxy
->y
;
3161 stampQueue
[stamp
].w
=proxy
->w
;
3162 stampQueue
[stamp
].h
=proxy
->h
;
3164 stamp
=(stamp
-1+stampLimit
)%stampLimit
;
3171 void RedoStamp(void)
3177 #if PROXY_GROUP_DEBUG
3178 fprintf(stderr
,"RedoStamp empty, stamp %d min %d max %d\n",
3179 stamp
,stampMin
,stampMax
);
3184 stamp
=(stamp
+1)%stampLimit
;
3186 proxy
= FindProxy(stampQueue
[stamp
].window
);
3189 #if PROXY_GROUP_DEBUG
3190 fprintf(stderr
,"RedoStamp no proxy for window\n");
3196 MoveProxiedWindow(proxy
,
3197 stampQueue
[stamp
].x
,
3198 stampQueue
[stamp
].y
,
3199 stampQueue
[stamp
].w
,
3200 stampQueue
[stamp
].h
);
3202 stampQueue
[stamp
].window
=proxy
->window
;
3203 stampQueue
[stamp
].x
=proxy
->x
;
3204 stampQueue
[stamp
].y
=proxy
->y
;
3205 stampQueue
[stamp
].w
=proxy
->w
;
3206 stampQueue
[stamp
].h
=proxy
->h
;
3213 static void ConfigureWindow(FvwmPacket
*packet
)
3215 unsigned long* body
= packet
->body
;
3217 struct ConfigWinPacket
*cfgpacket
=(void *)body
;
3218 int wx
=cfgpacket
->frame_x
;
3219 int wy
=cfgpacket
->frame_y
;
3220 int desk
=cfgpacket
->desk
;
3221 int wsx
=cfgpacket
->frame_width
;
3222 int wsy
=cfgpacket
->frame_height
;
3223 int border_width
=cfgpacket
->border_width
;
3224 int title_height
=cfgpacket
->title_height
;
3225 int incx
=cfgpacket
->hints_width_inc
;
3226 int incy
=cfgpacket
->hints_height_inc
;
3227 Window target
=cfgpacket
->w
;
3232 int is_new_window
= 0;
3234 if (DO_SKIP_WINDOW_LIST(cfgpacket
))
3238 #if PROXY_GROUP_DEBUG
3239 fprintf(stderr
,"\n");
3241 leader
=GetLeader(target
);
3242 pid
=GetProcessId(target
);
3243 ppid
=GetParentProcessId(pid
);
3244 proxy
= FindProxy(target
);
3248 proxy
=new_ProxyWindow();
3249 proxy
->next
= firstProxy
;
3251 proxy
->window
=target
;
3253 /* unreliable on existing windows
3254 on 2.5.10, reporting false just after M_ICONIFY */
3255 proxy
->flags
.is_iconified
= !!IS_ICONIFIED(cfgpacket
);
3258 #if PROXY_GROUP_DEBUG
3260 "Config %p %x ld %x pid=%d %d\n"
3261 " pos %d %d sz %d %d"
3262 " was %d %d sz %d %d goal %d %d"
3263 " bdr %d %d pend %d %d\n",
3264 proxy
,(int)target
,leader
,pid
,ppid
,
3268 proxy
->goal_width
,proxy
->goal_height
,
3269 border_width
,title_height
,
3270 proxy
->pending_config
,
3274 if(proxy
->pending_config
)
3276 proxy
->pending_config
=0;
3280 if(!pending_do
&& !waiting_to_stamp
&&
3281 (is_new_window
|| proxy
->x
!=wx
|| proxy
->y
!=wy
||
3282 proxy
->w
!=wsx
|| proxy
->h
!=wsy
))
3285 sprintf(commandBuffer
,
3286 "SendToModule FvwmProxy Stamp %d %d %d %d",
3287 proxy
->x
,proxy
->y
,proxy
->w
,proxy
->h
);
3288 SendFvwmPipe(fd
, commandBuffer
, proxy
->window
);
3293 proxy
->goal_width
=wsx
;
3294 proxy
->goal_height
=wsy
;
3303 int wasgw
=proxy
->goal_width
;
3304 int wasgh
=proxy
->goal_height
;
3305 if(proxy
->x
!=wx
&& proxy
->w
==wsx
)
3307 ShiftWindows(proxy
,wx
-proxy
->x
,wy
-proxy
->y
);
3314 CatchWindows(proxy
,0,proxy
->x
,wx
,-1);
3315 proxy
->goal_width
=wsx
;
3317 if(wasx
+wasw
!=wx
+wsx
)
3319 CatchWindows(proxy
,0,
3322 proxy
->goal_width
=wsx
;
3326 if(proxy
->y
!=wy
&& proxy
->h
==wsy
)
3330 ShiftWindows(proxy
,0,wy
-proxy
->y
);
3337 CatchWindows(proxy
,1,proxy
->y
,wy
,-1);
3338 proxy
->goal_height
=wsy
;
3340 if(wasy
+wash
!=wy
+wsy
)
3342 CatchWindows(proxy
,1,
3345 proxy
->goal_height
=wsy
;
3349 if(wx!=proxy->x || wy!=proxy->y ||
3350 wsx!=proxy->w || wsy!=proxy->h)
3352 StoreStamp(target,proxy->x,proxy->y,
3359 if(!is_new_window
&& proxy
->desk
!=desk
)
3361 MoveGroupToDesk(proxy
,desk
);
3364 proxy
->leader
=leader
;
3372 proxy
->proxyw
=proxyWidth
;
3373 proxy
->proxyh
=proxyHeight
;
3374 proxy
->border_width
=border_width
;
3375 proxy
->title_height
=title_height
;
3379 RecenterProxy(proxy
);
3385 if (are_windows_shown
)
3393 CloseOneWindow(proxy
);
3394 OpenOneWindow(proxy
);
3398 if(proxy
->flags
.is_isolated
)
3406 static void IconifyWindow(ProxyWindow
*proxy
, int is_iconified
)
3412 is_iconified
= !!is_iconified
;
3413 if(proxy
->flags
.is_iconified
!= is_iconified
)
3415 proxy
->flags
.is_iconified
= is_iconified
;
3416 if (!proxyIconified
&& is_iconified
)
3418 if (proxy
->flags
.is_shown
)
3420 CloseOneWindow(proxy
);
3425 if (are_windows_shown
)
3427 /* ReshuffleWindows();
3429 OpenOneWindow(proxy
);
3433 DrawProxyBackground(proxy
);
3435 if(proxy
->flags
.is_isolated
)
3439 IconifyGroup(proxy
, 1);
3444 IconifyGroup(proxy
,is_iconified
);
3451 static void IsolateCheck(ProxyWindow
*instigator
,int force_other
)
3453 if(instigator
->flags
.is_isolated
)
3455 if(!force_other
&& !instigator
->flags
.is_iconified
)
3457 IconifyGroup(instigator
,1);
3458 AdhereGroup(instigator
);
3462 ProxyWindow
*neighbor
=
3463 FindNeighborInGroup(instigator
,1);
3466 IconifyGroup(neighbor
,1);
3470 neighbor
=FindNeighborInGroup(instigator
,0);
3471 if(neighbor
&& force_other
)
3473 sprintf(commandBuffer
,"Iconify Off");
3474 send_command_to_fvwm(commandBuffer
,
3478 AdhereGroup(neighbor
);
3483 static void DestroyWindow(Window w
)
3488 for (proxy
=firstProxy
, prev
= NULL
; proxy
!= NULL
;
3489 prev
= proxy
, proxy
=proxy
->next
)
3491 if (proxy
->proxy
==w
|| proxy
->window
==w
)
3500 firstProxy
= proxy
->next
;
3504 prev
->next
= proxy
->next
;
3506 if (selectProxy
== proxy
)
3510 if (enterProxy
== proxy
)
3514 if(!proxy
->flags
.is_iconified
)
3516 IsolateCheck(proxy
,1);
3518 CloseOneWindow(proxy
);
3519 delete_ProxyWindow(proxy
);
3524 static unsigned int GetModifiers(void)
3526 Window root_return
, child_return
;
3527 int root_x_return
, root_y_return
;
3528 int win_x_return
, win_y_return
;
3529 unsigned int mask_return
;
3532 dpy
,rootWindow
,&root_return
,
3534 &root_x_return
,&root_y_return
,
3535 &win_x_return
,&win_y_return
,
3536 &mask_return
) == False
)
3538 /* pointer is on another screen - ignore */
3551 static void StartProxies(void)
3553 if (are_windows_shown
)
3558 held_modifiers
=GetModifiers();
3562 if(action_list
[PROXY_ACTION_MODIFIER_RELEASE
])
3563 watching_modifiers
=1;
3565 send_command_to_fvwm(action_list
[PROXY_ACTION_SHOW
], None
);
3566 are_windows_shown
= 1;
3574 static void MarkProxy(ProxyWindow
*new_proxy
)
3576 ProxyWindow
*old_proxy
;
3578 old_proxy
= selectProxy
;
3579 selectProxy
= new_proxy
;
3580 if (selectProxy
!= old_proxy
)
3582 if (old_proxy
!= NULL
)
3584 DrawProxyBackground(old_proxy
);
3585 DrawProxy(old_proxy
);
3587 if (selectProxy
!= NULL
)
3589 DrawProxyBackground(selectProxy
);
3590 DrawProxy(selectProxy
);
3593 if (old_proxy
!= NULL
)
3594 send_command_to_fvwm(action_list
[PROXY_ACTION_UNMARK
],
3596 if (selectProxy
!= NULL
)
3597 send_command_to_fvwm(action_list
[PROXY_ACTION_MARK
],
3598 selectProxy
->window
);
3600 if(showOnly
&& are_windows_shown
)
3603 selectProxy
= new_proxy
;
3608 static void HideProxies(void)
3610 if (!are_windows_shown
)
3614 are_windows_shown
= 0;
3620 static void SelectProxy(void)
3626 send_command_to_fvwm(action_list
[PROXY_ACTION_SELECT
],
3627 selectProxy
->window
);
3629 send_command_to_fvwm(action_list
[PROXY_ACTION_HIDE
], None
);
3631 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
3632 if (proxy
==selectProxy
)
3643 static void AbortProxies(void)
3646 send_command_to_fvwm(action_list
[PROXY_ACTION_ABORT
], None
);
3652 static void RotateIsolated(ProxyWindow
*instigator
,int direction
)
3656 ProxyWindow
*first
=NULL
;
3657 ProxyWindow
*adjacent
=NULL
;
3659 #if PROXY_GROUP_DEBUG
3660 fprintf(stderr
,"RotateIsolated %p %p %d\n",
3661 instigator
,last_rotation_instigator
,direction
);
3664 /* rotation can lose focus, so we store it */
3665 if(!instigator
|| !instigator
->group
||
3666 !instigator
->flags
.is_isolated
)
3668 instigator
=last_rotation_instigator
;
3670 if(!instigator
|| !instigator
->group
||
3671 !instigator
->flags
.is_isolated
)
3675 last_rotation_instigator
=instigator
;
3677 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
3679 if(proxy
->desk
== instigator
->desk
&&
3680 proxy
->group
==instigator
->group
)
3682 if(!proxy
->flags
.is_iconified
)
3684 if(direction
<0 && adjacent
)
3715 sprintf(commandBuffer
,"Iconify Off");
3716 send_command_to_fvwm(commandBuffer
,adjacent
->window
);
3722 static void change_cset(int cset
)
3724 if (cset
== cset_normal
|| cset
== cset_iconified
)
3728 for (proxy
= firstProxy
; proxy
!= NULL
; proxy
= proxy
->next
)
3730 DrawProxyBackground(proxy
);
3733 else if (cset
== cset_select
&& selectProxy
!= NULL
)
3735 DrawProxyBackground(selectProxy
);
3741 static void ProcessMessage(FvwmPacket
* packet
)
3743 unsigned long type
= packet
->type
;
3744 unsigned long length
= packet
->size
;
3745 unsigned long* body
= packet
->body
;
3746 FvwmWinPacketBodyHeader
*bh
= (void *)body
;
3754 if(type
!=M_RAISE_WINDOW
&& type
!=M_LOWER_WINDOW
&& type
!=M_RESTACK
&&
3755 type
!=M_FOCUS_CHANGE
&& type
!=M_ICON_NAME
&&
3756 type
!=M_MINI_ICON
&& type
!=M_STRING
)
3763 case M_CONFIGURE_WINDOW
:
3764 #if PROXY_EVENT_DEBUG
3765 fprintf(stderr
, "FvwmProxy ProcessMessage M_CONFIGURE_WINDOW\n");
3768 #if PROXY_EVENT_DEBUG
3769 if(type
!=M_CONFIGURE_WINDOW
)
3772 "FvwmProxy ProcessMessage M_ADD_WINDOW\n");
3775 ConfigureWindow(packet
);
3777 case M_DESTROY_WINDOW
:
3778 #if PROXY_EVENT_DEBUG
3779 fprintf(stderr
, "FvwmProxy ProcessMessage M_DESTROY_WINDOW\n");
3781 DestroyWindow(bh
->w
);
3784 #if PROXY_EVENT_DEBUG
3785 fprintf(stderr
, "FvwmProxy ProcessMessage M_ICONIFY\n");
3787 IconifyWindow(FindProxy(bh
->w
), 1);
3790 #if PROXY_EVENT_DEBUG
3791 fprintf(stderr
, "FvwmProxy ProcessMessage M_DEICONIFY\n");
3793 IconifyWindow(FindProxy(bh
->w
), 0);
3795 case M_RAISE_WINDOW
:
3796 #if PROXY_EVENT_DEBUG
3797 fprintf(stderr
, "FvwmProxy ProcessMessage M_RAISE_WINDOW\n");
3799 RaiseLowerGroup(bh
->w
,1);
3801 case M_LOWER_WINDOW
:
3802 #if PROXY_EVENT_DEBUG
3803 fprintf(stderr
, "FvwmProxy ProcessMessage M_LOWER_WINDOW\n");
3805 RaiseLowerGroup(bh
->w
,0);
3808 #if PROXY_EVENT_DEBUG
3809 fprintf(stderr
, "FvwmProxy ProcessMessage M_RESTACK\n");
3811 ReadStack(body
,length
);
3814 #if PROXY_EVENT_DEBUG
3815 fprintf(stderr
, "FvwmProxy ProcessMessage M_WINDOW_NAME\n");
3817 proxy
= FindProxy(bh
->w
);
3820 if (proxy
->name
!= NULL
)
3824 proxy
->name
= safestrdup((char*)&body
[3]);
3825 #if PROXY_GROUP_DEBUG
3826 fprintf(stderr
,"M_WINDOW_NAME %s\n",proxy
->name
);
3828 UpdateProxyGroup(proxy
);
3829 UpdateProxyGroupForAll();
3833 #if PROXY_EVENT_DEBUG
3834 fprintf(stderr
, "FvwmProxy ProcessMessage M_ICON_NAME\n");
3836 proxy
= FindProxy(bh
->w
);
3839 if (proxy
->iconname
!= NULL
)
3841 free(proxy
->iconname
);
3843 proxy
->iconname
= safestrdup((char*)&body
[3]);
3844 #if PROXY_GROUP_DEBUG
3845 fprintf(stderr
,"M_ICON_NAME %s\n",proxy
->iconname
);
3847 /* UpdateOneWindow(proxy);
3849 DrawProxyBackground(proxy
);
3854 #if PROXY_EVENT_DEBUG
3855 fprintf(stderr
, "FvwmProxy ProcessMessage M_NEW_DESK\n");
3857 if (deskNumber
!=body
[0])
3860 if (are_windows_shown
)
3867 #if PROXY_EVENT_DEBUG
3868 fprintf(stderr
, "FvwmProxy ProcessMessage M_NEW_PAGE\n");
3874 #if PROXY_EVENT_DEBUG
3875 fprintf(stderr
, "FvwmProxy ProcessMessage M_MINI_ICON\n");
3877 proxy
= FindProxy(bh
->w
);
3880 proxy
->picture
.width
=body
[3];
3881 proxy
->picture
.height
=body
[4];
3882 proxy
->picture
.depth
=body
[5];
3883 proxy
->picture
.picture
=body
[6];
3884 proxy
->picture
.mask
=body
[7];
3885 proxy
->picture
.alpha
=body
[8];
3886 UpdateOneWindow(proxy
);
3889 case M_FOCUS_CHANGE
:
3890 #if PROXY_EVENT_DEBUG
3891 fprintf(stderr
, "FvwmProxy ProcessMessage M_FOCUS_CHANGE\n");
3897 last_rotation_instigator
=NULL
;
3899 if(showOnly
&& !selectProxy
)
3906 #if PROXY_EVENT_DEBUG
3907 fprintf(stderr
, "FvwmProxy ProcessMessage M_STRING\n");
3910 char *message
=(char*)&body
[3];
3914 int isolate_check
=0;
3916 #if PROXY_EVENT_DEBUG
3917 fprintf(stderr
, "M_STRING \"%s\"\n", message
);
3920 token
= PeekToken(message
, &next
);
3921 prev
=(StrEquals(token
, "Prev"));
3922 if (StrEquals(token
, "Next") || prev
)
3924 ProxyWindow
*lastSelect
=selectProxy
;
3925 ProxyWindow
*newSelect
=selectProxy
;
3926 ProxyWindow
*first
=prev
? lastProxy
: firstProxy
;
3928 /* auto-show if not already shown */
3929 if (!are_windows_shown
)
3932 if (startProxy
&& startProxy
->desk
==deskNumber
)
3934 newSelect
=startProxy
;
3942 newSelect
=newSelect
->prev
;
3944 newSelect
=newSelect
->next
;
3948 while (newSelect
!=lastSelect
&&
3949 newSelect
->desk
!=deskNumber
)
3952 newSelect
=newSelect
->prev
;
3954 newSelect
=newSelect
->next
;
3955 if (!newSelect
&& lastSelect
)
3960 MarkProxy(newSelect
);
3962 else if (StrEquals(token
, "Circulate"))
3966 /* auto-show if not already shown */
3967 if (!are_windows_shown
)
3970 w
= (selectProxy
) ? selectProxy
->window
: focusWindow
;
3972 strcpy(commandBuffer
,next
);
3973 strcat(commandBuffer
," SendToModule FvwmProxy Mark");
3975 SendFvwmPipe(fd
,commandBuffer
,w
);
3977 else if (StrEquals(token
, "Show"))
3981 else if (StrEquals(token
, "Hide"))
3985 else if (StrEquals(token
, "ShowToggle"))
3987 if (are_windows_shown
)
3996 else if (StrEquals(token
, "Abort"))
4000 else if (StrEquals(token
, "Mark"))
4009 else if (sscanf(next
, "0x%x", (int *)&w
) < 1)
4017 proxy
= FindProxy(bh
->w
);
4021 else if (StrEquals(token
, "Resolve"))
4023 waiting_to_config
=0;
4025 ResolvePendingWindows();
4028 else if (StrEquals(token
, "Stamp"))
4030 token
= PeekToken(message
, &next
);
4031 sscanf(next
,"%d%d%d%d",&x
,&y
,&w
,&h
);
4034 proxy
= FindProxy(bh
->w
);
4037 StoreStamp(bh
->w
,x
,y
,w
,h
);
4041 else if (StrEquals(token
, "Undo"))
4046 else if (StrEquals(token
, "Redo"))
4051 else if (StrEquals(token
, "PrevIsolated"))
4053 RotateIsolated(FindProxy(bh
->w
),-1);
4055 else if (StrEquals(token
, "NextIsolated"))
4057 RotateIsolated(FindProxy(bh
->w
),1);
4059 else if (StrEquals(token
, "SoftToggle"))
4061 proxy
= FindProxy(bh
->w
);
4064 proxy
->flags
.is_soft
= proxy
->group
?
4065 !proxy
->flags
.is_soft
: 0;
4068 DrawProxyBackground(proxy
);
4072 else if (StrEquals(token
, "IsolateToggle"))
4074 proxy
= FindProxy(bh
->w
);
4077 proxy
->flags
.is_isolated
= proxy
->group
?
4078 !proxy
->flags
.is_isolated
: 0;
4079 IsolateGroup(proxy
,proxy
->flags
.is_isolated
);
4082 DrawProxyBackground(proxy
);
4089 IsolateCheck(proxy
,0);
4094 #if PROXY_EVENT_DEBUG
4095 fprintf(stderr
, "FvwmProxy ProcessMessage M_CONFIG_INFO\n");
4098 char *tline
, *token
;
4100 tline
= (char*)&(body
[3]);
4101 token
= PeekToken(tline
, &tline
);
4102 if (StrEquals(token
, "Colorset"))
4105 cset
= LoadColorset(tline
);
4114 /* windows may have moved, so update proxy windows */
4115 if (are_windows_shown
)
4124 static int My_XNextEvent(Display
*dpy
,XEvent
*event
)
4128 struct timeval timevalue
,*timeout
=&timevalue
;
4129 timevalue
.tv_sec
= 0;
4130 timevalue
.tv_usec
= 100000;
4134 FNextEvent(dpy
,event
);
4139 FD_SET(x_fd
,&in_fdset
);
4140 FD_SET(fd
[1],&in_fdset
);
4142 if ( fvwmSelect(fd_width
, &in_fdset
, 0, 0, timeout
) > 0)
4144 if (FD_ISSET(x_fd
, &in_fdset
))
4148 FNextEvent(dpy
,event
);
4153 if (FD_ISSET(fd
[1], &in_fdset
))
4155 FvwmPacket
* packet
= ReadFvwmPacket(fd
[1]);
4161 ProcessMessage(packet
);
4168 static void DispatchEvent(XEvent
*pEvent
)
4170 Window window
=pEvent
->xany
.window
;
4174 switch(pEvent
->xany
.type
)
4177 #if PROXY_EVENT_DEBUG
4178 fprintf(stderr
, "FvwmProxy DispatchEvent Expose\n");
4180 proxy
= FindProxy(window
);
4184 proxy
, pEvent
->xexpose
.x
, pEvent
->xexpose
.y
,
4185 pEvent
->xexpose
.width
, pEvent
->xexpose
.height
);
4189 #if PROXY_EVENT_DEBUG
4190 fprintf(stderr
, "FvwmProxy DispatchEvent ButtonPress\n");
4192 proxy
= FindProxy(window
);
4195 int button
=pEvent
->xbutton
.button
;
4196 int wx
=pEvent
->xbutton
.x
;
4197 int wy
=pEvent
->xbutton
.y
;
4199 button
<= NUMBER_OF_EXTENDED_MOUSE_BUTTONS
)
4201 if(wy
< slotSpace
+slotHeight
)
4203 int index
=(wx
-slotSpace
)/
4204 (slotWidth
+slotSpace
)+1;
4205 int group
=index
-groupSlot
+1;
4209 char* action
=slot_action_list
[
4213 SendFvwmPipe(fd
,action
,
4217 if(group
&& group
<=groupCount
)
4220 proxy
->group
==group
?
4222 DrawProxyBackground(proxy
);
4229 action_list
[PROXY_ACTION_CLICK
4235 mousex
=pEvent
->xbutton
.x_root
;
4236 mousey
=pEvent
->xbutton
.y_root
;
4239 #if PROXY_EVENT_DEBUG
4240 fprintf(stderr
, "FvwmProxy DispatchEvent MotionNotify\n");
4242 proxy
= FindProxy(window
);
4243 dx
=pEvent
->xbutton
.x_root
-mousex
;
4244 dy
=pEvent
->xbutton
.y_root
-mousey
;
4245 if (proxy
&& proxyMove
)
4247 sprintf(commandBuffer
,"Silent Move w+%dp w+%dp",dx
,dy
);
4248 send_command_to_fvwm(commandBuffer
,proxy
->window
);
4251 mousex
=pEvent
->xbutton
.x_root
;
4252 mousey
=pEvent
->xbutton
.y_root
;
4255 #if PROXY_EVENT_DEBUG
4256 fprintf(stderr
, "FvwmProxy DispatchEvent EnterNotify\n");
4258 proxy
= FindProxy(pEvent
->xcrossing
.window
);
4259 if (pEvent
->xcrossing
.mode
== NotifyNormal
)
4264 else if (pEvent
->xcrossing
.mode
== NotifyUngrab
&&
4265 proxy
!= NULL
&& proxy
!= selectProxy
&&
4266 proxy
!= enterProxy
)
4273 fprintf(stderr
, "Unrecognized XEvent %d\n", pEvent
->xany
.type
);
4280 static void Loop(int *fd
)
4287 if ((result
=My_XNextEvent(dpy
,&event
))==1)
4289 DispatchEvent(&event
);
4292 #if PROXY_KEY_POLLING
4293 if(are_windows_shown
&& watching_modifiers
)
4295 unsigned int mask_return
=GetModifiers();
4296 if(!(mask_return
&watched_modifiers
))
4298 watching_modifiers
=0;
4299 send_command_to_fvwm(
4301 [PROXY_ACTION_MODIFIER_RELEASE
],
4309 /* ---------------------------- interface functions ------------------------- */
4311 int main(int argc
, char **argv
)
4319 "FvwmProxy should only be executed by fvwm!\n");
4323 FlocaleInit(LC_CTYPE
, "", "", "FvwmProxy");
4324 MyName
= GetFileNameFromPath(argv
[0]);
4326 fd
[0] = atoi(argv
[1]);
4327 fd
[1] = atoi(argv
[2]);
4329 originalXIOErrorHandler
=XSetIOErrorHandler(myXIOErrorHandler
);
4330 originalXErrorHandler
=XSetErrorHandler(myXErrorHandler
);
4332 if (!(dpy
=XOpenDisplay(NULL
)))
4334 fprintf(stderr
,"can't open display\n");
4337 titles
[0]="FvwmProxy";
4338 if (XStringListToTextProperty(titles
,1,&windowName
) == 0)
4340 fprintf(stderr
,"Proxy_CreateBar() could not allocate space"
4341 " for window title");
4344 flib_init_graphics(dpy
);
4345 FlocaleAllocateWinString(&FwinString
);
4346 screen
= DefaultScreen(dpy
);
4347 rootWindow
= RootWindow(dpy
,screen
);
4348 xgcv
.plane_mask
=AllPlanes
;
4349 miniIconGC
=fvwmlib_XCreateGC(dpy
,rootWindow
,GCPlaneMask
,&xgcv
);
4350 fg_gc
= fvwmlib_XCreateGC(dpy
,rootWindow
,GCPlaneMask
,&xgcv
);
4351 hi_gc
= fvwmlib_XCreateGC(dpy
,rootWindow
,GCPlaneMask
,&xgcv
);
4352 sh_gc
= fvwmlib_XCreateGC(dpy
,rootWindow
,GCPlaneMask
,&xgcv
);
4354 x_fd
= XConnectionNumber(dpy
);
4355 fd_width
= GetFdWidth();
4358 fd
, M_STRING
| M_RAISE_WINDOW
| M_LOWER_WINDOW
|
4359 M_CONFIGURE_WINDOW
| M_ADD_WINDOW
| M_FOCUS_CHANGE
|
4360 M_DESTROY_WINDOW
| M_NEW_DESK
| M_NEW_PAGE
| M_ICON_NAME
|
4361 M_WINDOW_NAME
| M_MINI_ICON
| M_ICONIFY
| M_DEICONIFY
|
4362 M_CONFIG_INFO
| M_END_CONFIG_INFO
| M_RESTACK
);
4364 if (parse_options() == False
)
4366 stampQueue
=(GeometryStamp
*)safemalloc(
4367 sizeof(GeometryStamp
)*stampLimit
);
4368 if ((Ffont
= FlocaleLoadFont(dpy
, font_name
, MyName
)) == NULL
)
4370 fprintf(stderr
,"%s: Couldn't load font \"%s\". Exiting!\n",
4374 if (Ffont
->font
!= NULL
)
4376 XSetFont(dpy
,fg_gc
,Ffont
->font
->fid
);
4382 FlocaleLoadFont(dpy
, small_font_name
, MyName
)) == NULL
)
4385 "%s: Couldn't load small font \"%s\"\n",
4386 MyName
, small_font_name
);
4389 if (Ffont_small
!= NULL
&& Ffont_small
->font
!= NULL
)
4391 XSetFont(dpy
,hi_gc
,Ffont_small
->font
->fid
);
4393 SendInfo(fd
,"Send_WindowList",0);
4394 SendFinishedStartupNotification(fd
);