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 ----------------------- */
26 #include "libs/Module.h"
27 #include "libs/fvwmlib.h"
28 #include "libs/FRenderInit.h"
29 #include "libs/FRender.h"
30 #include "libs/Colorset.h"
31 #include "libs/Flocale.h"
32 #include "libs/gravity.h"
33 #include "libs/FScreen.h"
34 #include "libs/Picture.h"
35 #include "libs/PictureGraphics.h"
36 #include "libs/charmap.h"
37 #include "libs/modifiers.h"
38 #include "libs/ColorUtils.h"
39 #include "libs/Graphics.h"
40 #include "libs/Parse.h"
41 #include "libs/Strings.h"
42 #include "libs/System.h"
43 #include "libs/wild.h"
45 #include "FvwmProxy.h"
47 /* ---------------------------- local definitions --------------------------- */
49 /* defaults for things we put in a configuration file */
51 #define PROXY_COMMAND_DEBUG False
52 #define PROXY_GROUP_DEBUG False
54 #define PROXY_KEY_POLLING True
55 #define PROXY_MOVE False /* move window when proxy is dragged */
56 #define PROXY_ICONIFIED False /* show proxy when iconified */
57 #define PROXY_WIDTH 180
58 #define PROXY_HEIGHT 60
59 #define PROXY_SEPARATION 10
60 #define PROXY_MINWIDTH 15
61 #define PROXY_MINHEIGHT 10
62 #define PROXY_SLOT_SIZE 16
63 #define PROXY_SLOT_SPACE 4
64 #define PROXY_GROUP_SLOT 2
65 #define PROXY_GROUP_COUNT 6
66 #define PROXY_STAMP_LIMIT 8
68 #define STARTUP_DEBUG False /* store output before log is opened */
70 #define CMD_SELECT "WindowListFunc $[w.id]"
71 #define CMD_CLICK1 "Raise"
72 #define CMD_CLICK3 "Lower"
73 #define CMD_DEFAULT "Nop"
75 /* ---------------------------- local macros -------------------------------- */
77 /* ---------------------------- imports ------------------------------------- */
79 /* ---------------------------- included code files ------------------------- */
81 /* ---------------------------- local types --------------------------------- */
83 /* ---------------------------- forward declarations ------------------------ */
85 /* ---------------------------- local variables ----------------------------- */
87 static char *ImagePath
= NULL
;
90 static fd_set_size_t fd_width
;
93 static unsigned long screen
;
98 static Window rootWindow
;
99 static Window focusWindow
;
100 static XTextProperty windowName
;
101 static int deskNumber
=0;
102 static int mousex
,mousey
;
103 static ProxyWindow
*firstProxy
=NULL
;
104 static ProxyWindow
*lastProxy
=NULL
;
105 static ProxyWindow
*selectProxy
=NULL
;
106 static ProxyWindow
*startProxy
=NULL
;
107 static ProxyWindow
*enterProxy
=NULL
;
108 static ProxyWindow
*last_rotation_instigator
=NULL
;
109 static ProxyGroup
*firstProxyGroup
=NULL
;
110 static FvwmPicture
**pictureArray
=NULL
;
111 static int numSlots
=0;
112 static int miniIconSlot
=0;
113 static XGCValues xgcv
;
114 static int are_windows_shown
= 0;
115 static int watching_modifiers
= 0;
116 static int waiting_to_config
= 0;
117 static int waiting_to_stamp
= 0;
118 static int pending_do
= 0;
119 static unsigned int held_modifiers
=0;
120 static int watched_modifiers
=0;
121 static FlocaleWinString
*FwinString
;
123 static int cset_normal
= 0;
124 static int cset_select
= 0;
125 static int cset_iconified
= 0;
126 static char *font_name
= NULL
;
127 static char *small_font_name
= NULL
;
128 static FlocaleFont
*Ffont
;
129 static FlocaleFont
*Ffont_small
;
130 static int enterSelect
=False
;
131 static int showMiniIcons
=True
;
132 static int proxyIconified
=PROXY_ICONIFIED
;
133 static int proxyMove
=PROXY_MOVE
;
134 static int proxyWidth
=PROXY_WIDTH
;
135 static int proxyHeight
=PROXY_HEIGHT
;
136 static int proxySeparation
=PROXY_SEPARATION
;
137 static int slotWidth
=PROXY_SLOT_SIZE
;
138 static int slotHeight
=PROXY_SLOT_SIZE
;
139 static int slotSpace
=PROXY_SLOT_SPACE
;
140 static int groupSlot
=PROXY_GROUP_SLOT
;
141 static int groupCount
=PROXY_GROUP_COUNT
;
142 static int stampLimit
=PROXY_STAMP_LIMIT
;
144 static GeometryStamp
* stampQueue
=NULL
;
146 static int stampMin
=0;
147 static int stampMax
=0;
149 static char commandBuffer
[256];
150 static char resultBuffer
[256];
154 PROXY_ACTION_SELECT
= 0,
160 PROXY_ACTION_MODIFIER_RELEASE
,
161 /* this one *must* be last */
163 PROXY_ACTION_LAST
= PROXY_ACTION_CLICK
+
164 NUMBER_OF_EXTENDED_MOUSE_BUTTONS
167 #define GROUP_COLORS 7
168 static char* group_color
[GROUP_COLORS
][2] =
170 {"#dddddd", "#777777"},
171 {"#ffcccc", "#ff0000"},
172 {"#ccffcc", "#00ff00"},
173 {"#ccccff", "#0000ff"},
174 {"#ffccff", "#ff00ff"},
175 {"#ffffcc", "#ffff00"},
176 {"#ccffff", "#00ffff"}
179 char *action_list
[PROXY_ACTION_LAST
];
180 char **slot_action_list
[NUMBER_OF_EXTENDED_MOUSE_BUTTONS
];
182 static WindowName
* new_WindowName(void);
183 static ProxyGroup
* FindProxyGroup(char* groupname
);
185 static int (*originalXErrorHandler
)(Display
*,XErrorEvent
*);
186 static int (*originalXIOErrorHandler
)(Display
*);
188 /* ---------------------------- exported variables (globals) ---------------- */
190 /* ---------------------------- local functions (options) ------------------- */
192 static void ExpandSlots(int slots
)
198 pictureArray
=(FvwmPicture
**)realloc(pictureArray
,
199 sizeof(FvwmPicture
*)*(slots
));
200 for(m
=0;m
<NUMBER_OF_EXTENDED_MOUSE_BUTTONS
;m
++)
202 slot_action_list
[m
]=(char**)realloc(
204 sizeof(char*)*(slots
));
205 for(n
=numSlots
;n
<slots
;n
++)
207 slot_action_list
[m
][n
]=NULL
;
210 for(n
=numSlots
;n
<slots
;n
++)
212 pictureArray
[n
]=NULL
;
218 static void LinkSlotAction(char *string
)
223 token
= PeekToken(string
, &string
);
226 token
= PeekToken(string
, &string
);
227 if (strncasecmp(token
, "Click", 5) == 0)
231 i
= sscanf(token
+ 5, "%d", &b
);
232 if (i
> 0 && b
>=1 && b
<= NUMBER_OF_EXTENDED_MOUSE_BUTTONS
)
235 if (slot_action_list
[b
-1][slot
] != NULL
)
237 free(slot_action_list
[b
-1][slot
]);
239 slot_action_list
[b
-1][slot
] = safestrdup(string
);
240 #if PROXY_GROUP_DEBUG
241 fprintf(stderr
,"slot_action_list[%d][%d]=\"%s\"\n",
242 b
-1,slot
,slot_action_list
[b
-1][slot
]);
248 static void LinkAction(char *string
)
252 token
= PeekToken(string
, &string
);
253 if (strncasecmp(token
, "Click", 5) == 0)
257 i
= sscanf(token
+ 5, "%d", &b
);
258 if (i
> 0 && b
>=1 && b
<= NUMBER_OF_EXTENDED_MOUSE_BUTTONS
)
260 if (action_list
[PROXY_ACTION_CLICK
+ b
- 1] != NULL
)
262 free(action_list
[PROXY_ACTION_CLICK
+ b
- 1]);
264 action_list
[PROXY_ACTION_CLICK
+ b
- 1] =
268 else if (StrEquals(token
, "Select"))
270 if (action_list
[PROXY_ACTION_SELECT
] != NULL
)
272 free(action_list
[PROXY_ACTION_SELECT
]);
274 action_list
[PROXY_ACTION_SELECT
] = safestrdup(string
);
276 else if (StrEquals(token
, "Show"))
278 if (action_list
[PROXY_ACTION_SHOW
] != NULL
)
280 free(action_list
[PROXY_ACTION_SHOW
]);
282 action_list
[PROXY_ACTION_SHOW
] = safestrdup(string
);
284 else if (StrEquals(token
, "Hide"))
286 if (action_list
[PROXY_ACTION_HIDE
] != NULL
)
288 free(action_list
[PROXY_ACTION_HIDE
]);
290 action_list
[PROXY_ACTION_HIDE
] = safestrdup(string
);
292 else if (StrEquals(token
, "Abort"))
294 if (action_list
[PROXY_ACTION_ABORT
] != NULL
)
296 free(action_list
[PROXY_ACTION_ABORT
]);
298 action_list
[PROXY_ACTION_ABORT
] = safestrdup(string
);
300 else if (StrEquals(token
, "Mark"))
302 if (action_list
[PROXY_ACTION_MARK
] != NULL
)
304 free(action_list
[PROXY_ACTION_MARK
]);
306 action_list
[PROXY_ACTION_MARK
] = safestrdup(string
);
308 else if (StrEquals(token
, "Unmark"))
310 if (action_list
[PROXY_ACTION_UNMARK
] != NULL
)
312 free(action_list
[PROXY_ACTION_UNMARK
]);
314 action_list
[PROXY_ACTION_UNMARK
] = safestrdup(string
);
316 else if (StrEquals(token
, "ModifierRelease"))
318 token
= PeekToken(string
, &string
);
320 if (action_list
[PROXY_ACTION_MODIFIER_RELEASE
] != NULL
)
322 free(action_list
[PROXY_ACTION_MODIFIER_RELEASE
]);
325 modifiers_string_to_modmask(token
, (int *)&watched_modifiers
);
326 action_list
[PROXY_ACTION_MODIFIER_RELEASE
] = safestrdup(string
);
333 static void parse_cmd(char **ret_cmd
, char *cmd
)
335 if (*ret_cmd
!= NULL
)
342 *ret_cmd
= safestrdup(cmd
);
349 FvwmPicture
* loadPicture(char* name
)
351 FvwmPicture
*picture
=NULL
;
352 FvwmPictureAttributes fpa
;
359 fpa
.mask
= FPAM_NO_COLOR_LIMIT
;
360 picture
= PGetFvwmPicture(dpy
, RootWindow(dpy
,screen
),
361 ImagePath
, name
, fpa
);
364 fprintf(stderr
, "loadPixmap failed to load \"%s\"\n", name
);
369 static Bool
parse_options(void)
374 memset(action_list
, 0, sizeof(action_list
));
375 action_list
[PROXY_ACTION_SELECT
] = strdup(CMD_SELECT
);
376 action_list
[PROXY_ACTION_CLICK
+ 0] = strdup(CMD_CLICK1
);
377 if (NUMBER_OF_EXTENDED_MOUSE_BUTTONS
> 2)
379 action_list
[PROXY_ACTION_CLICK
+ 2] = strdup(CMD_CLICK3
);
381 for (m
=0;m
<PROXY_ACTION_LAST
;m
++)
383 if (action_list
[m
]==NULL
)
385 action_list
[m
] = strdup(CMD_DEFAULT
);
389 InitGetConfigLine(fd
, CatString3("*", MyName
, 0));
390 for (GetConfigLine(fd
, &tline
); tline
!= NULL
;
391 GetConfigLine(fd
, &tline
))
397 token
= PeekToken(tline
, &next
);
398 if (StrEquals(token
, "Colorset"))
403 if (StrEquals(token
, "ImagePath"))
409 CopyString(&ImagePath
, next
);
413 tline
= GetModuleResource(tline
, &resource
, MyName
);
414 if (resource
== NULL
)
419 /* dump leading whitespace */
420 while (*tline
==' ' || *tline
=='\t')
422 if (!strncasecmp(resource
,"Action",6))
426 else if (!strncasecmp(resource
,"SlotAction",10))
428 LinkSlotAction(tline
);
430 else if (StrEquals(resource
, "Colorset"))
432 if (sscanf(tline
, "%d", &cset_normal
) < 1)
437 else if (StrEquals(resource
, "SelectColorset"))
439 if (sscanf(tline
, "%d", &cset_select
) < 1)
444 else if (StrEquals(resource
, "IconifiedColorset"))
446 if (sscanf(tline
, "%d", &cset_iconified
) < 1)
451 else if (StrEquals(resource
, "Font"))
453 if (font_name
!= NULL
)
457 font_name
= safestrdup(tline
);
459 else if (StrEquals(resource
, "SmallFont"))
461 if (small_font_name
!= NULL
)
463 free(small_font_name
);
465 small_font_name
= safestrdup(tline
);
467 else if (StrEquals(resource
, "ShowMiniIcons"))
469 showMiniIcons
= ParseToggleArgument(tline
, NULL
, 0, 1);
471 else if (StrEquals(resource
, "EnterSelect"))
473 enterSelect
= ParseToggleArgument(tline
, NULL
, 0, 1);
475 else if (StrEquals(resource
, "ProxyMove"))
477 proxyMove
= ParseToggleArgument(tline
, NULL
, 0, 1);
479 else if (StrEquals(resource
, "ProxyIconified"))
481 proxyIconified
= ParseToggleArgument(tline
, NULL
, 0, 1);
483 else if (StrEquals(resource
, "Width"))
485 if (sscanf(tline
, "%d", &proxyWidth
) < 1)
486 proxyWidth
=PROXY_MINWIDTH
;
488 else if (StrEquals(resource
, "Height"))
490 if (sscanf(tline
, "%d", &proxyHeight
) < 1)
491 proxyHeight
=PROXY_MINHEIGHT
;
493 else if (StrEquals(resource
, "Separation"))
495 if (sscanf(tline
, "%d", &proxySeparation
) < 1)
496 proxySeparation
=False
;
498 else if (StrEquals(resource
, "UndoLimit"))
500 if (sscanf(tline
, "%d", &stampLimit
) < 1)
501 stampLimit
=PROXY_STAMP_LIMIT
;
503 else if (StrEquals(resource
, "SlotWidth"))
505 if (sscanf(tline
, "%d", &slotWidth
) < 1)
506 slotWidth
=PROXY_SLOT_SIZE
;
508 else if (StrEquals(resource
, "SlotHeight"))
510 if (sscanf(tline
, "%d", &slotHeight
) < 1)
511 slotHeight
=PROXY_SLOT_SIZE
;
513 else if (StrEquals(resource
, "SlotSpace"))
515 if (sscanf(tline
, "%d", &slotSpace
) < 1)
516 slotSpace
=PROXY_SLOT_SPACE
;
518 else if (StrEquals(resource
, "GroupSlot"))
520 if (sscanf(tline
, "%d", &groupSlot
) < 0)
521 groupSlot
=PROXY_GROUP_SLOT
;
523 else if (StrEquals(resource
, "GroupCount"))
525 if (sscanf(tline
, "%d", &groupCount
) < 0)
526 groupCount
=PROXY_GROUP_COUNT
;
528 else if (StrEquals(resource
, "SlotStyle"))
534 int args
= sscanf(tline
, "%d%s%*[^\"]\"%[^\"]\"%n",
535 &slot
,style
,name
,&bytes
);
536 #if PROXY_GROUP_DEBUG
538 "SlotStyle: %d \"%s\" -> %d \"%s\" \"%s\"\n",
539 args
,tline
,slot
,style
,name
);
541 if (args
>=3 && StrEquals(style
, "Pixmap"))
544 pictureArray
[slot
]=loadPicture(name
);
546 else if (args
>=2 && StrEquals(style
, "MiniIcon"))
551 else if (StrEquals(resource
, "Group"))
558 int args
= sscanf(tline
, "\"%[^\"]\"%s%n",
559 groupname
,directive
,&bytes
);
560 ProxyGroup
* proxygroup
;
562 strncpy(tail
,&tline
[bytes
],128);
564 args
= sscanf(tail
, "%*[^\"]\"%[^\"]\"",pattern
);
566 #if PROXY_GROUP_DEBUG
568 "Group: %d \"%s\" -> \"%s\" \"%s\" \"%s\"\n",
569 args
,tline
,groupname
,directive
,pattern
);
572 proxygroup
=FindProxyGroup(groupname
);
573 if (StrEquals(directive
, "IgnoreIDs"))
575 proxygroup
->flags
.ignore_ids
=1;
577 else if (StrEquals(directive
, "AutoInclude"))
579 proxygroup
->flags
.auto_include
=1;
581 else if (StrEquals(directive
, "AutoSoft"))
583 proxygroup
->flags
.auto_include
=1;
584 proxygroup
->flags
.auto_soft
=1;
586 else if (StrEquals(directive
, "Isolated"))
588 proxygroup
->flags
.isolated
=1;
590 else if (StrEquals(directive
, "Include") ||
591 StrEquals(directive
, "SoftInclude"))
593 WindowName
* include
=new_WindowName();
594 include
->name
=strdup(pattern
);
595 include
->flags
.is_soft
=
596 StrEquals(directive
, "SoftInclude");
597 include
->next
=proxygroup
->includes
;
598 proxygroup
->includes
=include
;
599 #if PROXY_GROUP_DEBUG
600 fprintf(stderr
,"Include \"%s\"\n",
604 else if (StrEquals(directive
, "Exclude"))
606 WindowName
* exclude
=new_WindowName();
607 exclude
->name
=strdup(pattern
);
608 exclude
->next
=proxygroup
->excludes
;
609 proxygroup
->excludes
=exclude
;
610 #if PROXY_GROUP_DEBUG
611 fprintf(stderr
,"Exclude \"%s\"\n",
618 fprintf(stderr
,"Unknown: \"%s\"\n",tline
);
627 /* ---------------------------- local functions (classes) ------------------- */
631 static void ProxyWindow_ProxyWindow(ProxyWindow
*p
)
633 memset(p
, 0, sizeof *p
);
636 static ProxyWindow
*new_ProxyWindow(void)
638 ProxyWindow
*p
=(ProxyWindow
*)safemalloc(sizeof(ProxyWindow
));
639 ProxyWindow_ProxyWindow(p
);
643 static void delete_ProxyWindow(ProxyWindow
*p
)
655 if (p
->proxy
!= None
)
657 XDestroyWindow(dpy
, p
->proxy
);
663 static void WindowName_WindowName(WindowName
*p
)
665 memset(p
, 0, sizeof *p
);
668 static WindowName
*new_WindowName(void)
670 WindowName
*p
=(WindowName
*)safemalloc(sizeof(WindowName
));
671 WindowName_WindowName(p
);
675 static void delete_WindowName(WindowName
*p
)
679 delete_WindowName(p
->next
);
685 static void ProxyGroup_ProxyGroup(ProxyGroup
*p
)
687 memset(p
, 0, sizeof *p
);
690 static ProxyGroup
*new_ProxyGroup(void)
692 ProxyGroup
*p
=(ProxyGroup
*)safemalloc(sizeof(ProxyGroup
));
693 ProxyGroup_ProxyGroup(p
);
697 static void delete_ProxyGroup(ProxyGroup
*p
)
701 delete_ProxyGroup(p
->next
);
702 delete_WindowName(p
->includes
);
703 delete_WindowName(p
->excludes
);
709 /* ---------------------------- error handlers ------------------------------ */
711 static int myXErrorHandler(Display
*display
,XErrorEvent
*error_event
)
713 const long messagelen
=256;
714 char buffer
[messagelen
],function
[messagelen
];
715 char request_number
[16];
717 sprintf(request_number
,"%d",error_event
->request_code
);
718 sprintf(buffer
,"UNKNOWN");
719 XGetErrorDatabaseText(display
,"XRequest",
720 request_number
,buffer
,function
,messagelen
);
722 fprintf(stderr
, "non-fatal X error as follows, display %p"
723 " op %d:%d \"%s\" serial %u error %d\n",
725 error_event
->request_code
,error_event
->minor_code
,
726 function
,(unsigned int)error_event
->serial
,
727 error_event
->error_code
);
732 static int myXIOErrorHandler(Display
*display
)
734 fprintf(stderr
, "fatal IO Error on display %p\n", display
);
735 originalXIOErrorHandler(display
);
737 /* should never get this far */
741 /* ---------------------------- local functions ----------------------------- */
743 static void send_command_to_fvwm(char *command
, Window w
)
745 if (command
== NULL
|| *command
== 0)
749 #if PROXY_COMMAND_DEBUG
750 fprintf(stderr
,"SendText: \"%s\"\n", command
);
752 SendText(fd
, command
, w
);
757 static int GetProperty(Window w
,char* propertyname
)
759 Atom atom
,actual_type
;
762 unsigned long nitems
;
763 unsigned long bytes_after
;
770 atom
= XInternAtom(dpy
, propertyname
, True
);
771 atom_name
= XGetAtomName (dpy
,atom
);
773 status
= XGetWindowProperty(dpy
, w
, atom
, 0L, 1024,
774 False
, AnyPropertyType
,
776 &actual_format
, &nitems
,
781 /* fprintf(stderr,"GetProperty: cannot get %s\n",propertyname);
786 /* fprintf(stderr,"GetProperty: no properties\n");
791 bytes
=actual_format
/8;
792 for(byte
=bytes
-1;byte
>=0;byte
--)
794 result
=result
*256+prop
[byte
];
800 static int GetProcessId(Window w
)
802 return GetProperty(w
, "_NET_WM_PID");
805 static int GetLeader(Window w
)
807 int result
=GetProperty(w
, "WM_CLIENT_LEADER");
810 XWMHints
* hints
=XGetWMHints(dpy
,w
);
811 if(hints
&& hints
->flags
&WindowGroupHint
)
813 result
=hints
->window_group
;
820 static int GetParentProcessId(int pid
)
826 sprintf(commandBuffer
,"/proc/%d/stat",pid
);
827 statusfile
=fopen(commandBuffer
,"r");
832 bytes
=fread(resultBuffer
,32,1,statusfile
);
833 sscanf(resultBuffer
,"%*d %*[^)]) %*s %d",&ppid
);
838 static ProxyGroup
* FindProxyGroup(char* groupname
)
840 ProxyGroup
* proxygroup
=firstProxyGroup
;
843 if(StrEquals(proxygroup
->name
, groupname
))
847 proxygroup
=proxygroup
->next
;
849 proxygroup
=new_ProxyGroup();
850 proxygroup
->next
=firstProxyGroup
;
851 proxygroup
->name
=strdup(groupname
);
852 firstProxyGroup
=proxygroup
;
856 static int MatchWindowName(WindowName
* namelist
,char* name
)
858 WindowName
* include
=namelist
;
861 if(matchWildcards(include
->name
, name
))
865 include
=include
->next
;
871 static ProxyGroup
* FindProxyGroupWithWindowName(char* name
)
873 ProxyGroup
* proxygroup
=firstProxyGroup
;
874 #if PROXY_GROUP_DEBUG
875 fprintf(stderr
,"FindProxyGroupWithWindowName(%s)\n",name
);
880 if(MatchWindowName(proxygroup
->includes
, name
))
882 #if PROXY_GROUP_DEBUG
883 fprintf(stderr
," found in %s\n",proxygroup
->name
);
887 proxygroup
=proxygroup
->next
;
893 static ProxyWindow
*FindProxy(Window window
)
895 ProxyWindow
*proxy
=firstProxy
;
897 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
899 if (proxy
->proxy
==window
|| proxy
->window
==window
)
908 static void DrawPicture(
909 Window window
, int x
, int y
, FvwmPicture
*picture
, int cset
)
911 FvwmRenderAttributes fra
;
913 if (!picture
|| picture
->picture
== None
)
916 fra
.mask
= FRAM_DEST_IS_A_WINDOW
;
919 fra
.mask
|= FRAM_HAVE_ICON_CSET
;
920 fra
.colorset
= &Colorset
[cset
];
922 PGraphicsRenderPicture(
923 dpy
, window
, picture
, &fra
, window
, miniIconGC
, None
, None
,
924 0, 0, picture
->width
, picture
->height
,
925 x
, y
, picture
->width
, picture
->height
, False
);
928 static void DrawWindow(
929 ProxyWindow
*proxy
, int x
,int y
,int w
,int h
)
933 FvwmPicture
*picture
= &proxy
->picture
;
934 int drawMiniIcon
=(showMiniIcons
&& proxy
->picture
.picture
!= None
);
941 if (!proxy
|| proxy
->proxy
== None
)
951 texty
=(h
+ Ffont
->ascent
- Ffont
->descent
)/2; /* center */
957 maxy
=h
-Ffont
->descent
-4;
963 cset
= (proxy
==selectProxy
) ? cset_select
:
964 ((proxy
->flags
.is_iconified
) ? cset_iconified
: cset_normal
);
965 XSetForeground(dpy
,fg_gc
,Colorset
[cset
].fg
);
966 XSetBackground(dpy
,fg_gc
,Colorset
[cset
].bg
);
967 XSetForeground(dpy
,sh_gc
,Colorset
[cset
].shadow
);
968 XSetForeground(dpy
,hi_gc
,Colorset
[cset
].hilite
);
970 /* FIXME: use clip redrawing (not really essential here) */
971 if (FLF_FONT_HAS_ALPHA(Ffont
,cset
) || PICTURE_HAS_ALPHA(picture
,cset
))
973 XClearWindow(dpy
,proxy
->proxy
);
975 RelieveRectangle(dpy
,proxy
->proxy
, 0,0, w
- 1,h
- 1, hi_gc
,sh_gc
, 2);
977 big_name
= proxy
->iconname
;
978 if(big_name
==NULL
|| !big_name
[0])
980 big_name
= proxy
->name
;
982 small_name
= proxy
->name
;
983 if(small_name
== NULL
)
987 if (big_name
!= NULL
&& big_name
[0])
989 int text_width
= FlocaleTextWidth(
990 Ffont
,big_name
,strlen(big_name
));
991 int edge
=(w
-text_width
)/2;
1002 FwinString
->str
= big_name
;
1003 FwinString
->win
= proxy
->proxy
;
1004 FwinString
->x
= edge
;
1005 FwinString
->y
= texty
;
1006 FwinString
->gc
= fg_gc
;
1007 FwinString
->flags
.has_colorset
= False
;
1010 FwinString
->colorset
= &Colorset
[cset
];
1011 FwinString
->flags
.has_colorset
= True
;
1013 FlocaleDrawString(dpy
, Ffont
, FwinString
, 0);
1015 if (small_name
!= NULL
&& small_name
[0] &&
1016 (overrun
|| strcmp(small_name
,big_name
)) && Ffont_small
!=NULL
)
1018 int text_width
= FlocaleTextWidth(
1019 Ffont_small
,small_name
,strlen(small_name
));
1020 int edge
=(w
-text_width
)/2;
1024 edge
=w
-text_width
-5;
1027 FwinString
->str
= small_name
;
1028 FwinString
->win
= proxy
->proxy
;
1029 FwinString
->x
= edge
;
1030 FwinString
->y
= h
-Ffont_small
->descent
-3;
1031 FwinString
->gc
= hi_gc
;
1032 FwinString
->flags
.has_colorset
= False
;
1035 FwinString
->colorset
= &Colorset
[cset
];
1036 FwinString
->flags
.has_colorset
= True
;
1038 FlocaleDrawString(dpy
, Ffont_small
, FwinString
, 0);
1040 if (drawMiniIcon
&& miniIconSlot
>0)
1042 int widgetx
=slotSpace
+(slotWidth
+slotSpace
)*(miniIconSlot
-1);
1043 DrawPicture(proxy
->proxy
, widgetx
, slotSpace
, picture
, cset
);
1045 for(group
=1;group
<groupCount
+1;group
++)
1047 int lit
=(proxy
->group
==group
);
1048 int widgetx
=slotSpace
+
1049 (slotWidth
+slotSpace
)*(groupSlot
+group
-2);
1050 int color_index
=group
%GROUP_COLORS
;
1051 int drawsoft
=lit
&& proxy
->flags
.is_soft
;
1052 int drawisolated
=lit
&& proxy
->flags
.is_isolated
;
1056 XSetForeground(dpy
,fg_gc
,GetColor(
1057 group_color
[color_index
][0]));
1058 XFillRectangle(dpy
,proxy
->proxy
,fg_gc
,
1060 slotWidth
,slotHeight
);
1062 XSetForeground(dpy
,sh_gc
,GetColor("black"));
1063 RelieveRectangle(dpy
,proxy
->proxy
,
1065 slotWidth
,slotHeight
/2,
1068 XSetForeground(dpy
,fg_gc
,GetColor(
1069 group_color
[color_index
][proxy
->group
==group
]));
1070 XFillRectangle(dpy
,proxy
->proxy
,fg_gc
,
1073 drawsoft
? slotHeight
/2: slotHeight
);
1075 XSetForeground(dpy
,sh_gc
,GetColor(lit
? "black": "white"));
1076 XSetForeground(dpy
,hi_gc
,GetColor(lit
? "black": "white"));
1077 RelieveRectangle(dpy
,proxy
->proxy
,
1079 slotWidth
,slotHeight
,
1083 RelieveRectangle(dpy
,proxy
->proxy
,
1084 widgetx
+4,slotSpace
+4,
1085 slotWidth
-8,slotHeight
-8,
1089 for(m
=0;m
<numSlots
;m
++)
1091 int widgetx
=slotSpace
+(slotWidth
+slotSpace
)*(m
-1);
1092 DrawPicture(proxy
->proxy
, widgetx
, slotSpace
, pictureArray
[m
],
1097 static void DrawProxy(ProxyWindow
*proxy
)
1102 proxy
, proxy
->proxyx
, proxy
->proxyy
, proxy
->proxyw
,
1107 static void DrawProxyBackground(ProxyWindow
*proxy
)
1111 if (proxy
== NULL
|| proxy
->proxy
== None
)
1115 cset
= (proxy
==selectProxy
) ? cset_select
:
1116 ((proxy
->flags
.is_iconified
) ? cset_iconified
: cset_normal
);
1117 XSetForeground(dpy
,fg_gc
,Colorset
[cset
].fg
);
1118 XSetBackground(dpy
,fg_gc
,Colorset
[cset
].bg
);
1119 SetWindowBackground(
1120 dpy
, proxy
->proxy
, proxy
->proxyw
, proxy
->proxyh
,
1121 &Colorset
[cset
], Pdepth
, fg_gc
, True
);
1124 static void OpenOneWindow(ProxyWindow
*proxy
)
1127 unsigned long valuemask
=CWOverrideRedirect
;
1128 XSetWindowAttributes attributes
;
1134 if (proxy
->desk
!= deskNumber
||
1135 (!proxyIconified
&& proxy
->flags
.is_iconified
) )
1139 if (proxy
->flags
.is_shown
)
1143 if (proxy
->proxy
== None
)
1145 long eventMask
=ButtonPressMask
|ExposureMask
|ButtonMotionMask
;
1149 eventMask
|=EnterWindowMask
;
1151 attributes
.override_redirect
= True
;
1152 proxy
->proxy
= XCreateWindow(
1153 dpy
, rootWindow
, proxy
->proxyx
, proxy
->proxyy
,
1154 proxy
->proxyw
, proxy
->proxyh
,border
,
1155 DefaultDepth(dpy
,screen
), InputOutput
, Pvisual
,
1156 valuemask
, &attributes
);
1157 XSelectInput(dpy
,proxy
->proxy
,eventMask
);
1161 XMoveWindow(dpy
, proxy
->proxy
, proxy
->proxyx
, proxy
->proxyy
);
1163 XMapRaised(dpy
, proxy
->proxy
);
1164 DrawProxyBackground(proxy
);
1165 proxy
->flags
.is_shown
= 1;
1170 static void OpenWindows(void)
1174 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1176 OpenOneWindow(proxy
);
1183 static void CloseOneWindow(ProxyWindow
*proxy
)
1189 if (proxy
->flags
.is_shown
)
1191 XUnmapWindow(dpy
, proxy
->proxy
);
1192 proxy
->flags
.is_shown
= 0;
1198 static void CloseWindows(void)
1202 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1204 CloseOneWindow(proxy
);
1210 static Bool
SortProxiesOnce(void)
1221 for (proxy
=firstProxy
; proxy
!= NULL
&& proxy
->next
!= NULL
;
1225 x2
=proxy
->next
->proxyx
;
1227 y2
=proxy
->next
->proxyy
;
1229 /* sort x, then y, then arbitrarily on pointer */
1230 if ( x1
>x2
|| (x1
==x2
&& y1
>y2
) ||
1231 (x1
==x2
&& y1
==y2
&&
1232 proxy
->window
>proxy
->next
->window
))
1238 lastProxy
->next
=next
;
1241 proxy
->next
=next
->next
;
1249 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1251 proxy
->prev
=lastProxy
;
1258 static void SortProxies(void)
1260 while (SortProxiesOnce() == True
)
1268 static Bool
AdjustOneWindow(ProxyWindow
*proxy
)
1271 ProxyWindow
*other
=proxy
->next
;
1273 for (other
=proxy
->next
; other
; other
=other
->next
)
1278 if(other
->desk
!= deskNumber
)
1282 dx
= abs(proxy
->proxyx
-other
->proxyx
);
1283 dy
= abs(proxy
->proxyy
-other
->proxyy
);
1284 if (dx
<(proxyWidth
+proxySeparation
) &&
1285 dy
<proxyHeight
+proxySeparation
)
1288 if (proxyWidth
-dx
<proxyHeight
-dy
)
1290 if (proxy
->proxyx
<=other
->proxyx
)
1293 proxy
->proxyx
+ proxy
->proxyw
+
1299 other
->proxyx
+ other
->proxyw
+
1305 if (proxy
->proxyy
<=other
->proxyy
)
1308 proxy
->proxyy
+ proxy
->proxyh
+
1314 other
->proxyy
+ other
->proxyh
+
1324 static void AdjustWindows(void)
1326 Bool collision
=True
;
1328 while (collision
== True
)
1333 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1335 if(proxy
->desk
!= deskNumber
)
1338 if (AdjustOneWindow(proxy
) == True
)
1346 static void RecenterProxy(ProxyWindow
*proxy
)
1348 proxy
->proxyx
=proxy
->x
+ (proxy
->w
-proxy
->proxyw
)/2;
1349 proxy
->proxyy
=proxy
->y
+ (proxy
->h
-proxy
->proxyh
)/2;
1352 static void RecalcProxyTweaks(void)
1355 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1357 proxy
->tweakx
=proxy
->proxyx
-
1358 (proxy
->x
+ (proxy
->w
-proxy
->proxyw
)/2);
1359 proxy
->tweaky
=proxy
->proxyy
-
1360 (proxy
->y
+ (proxy
->h
-proxy
->proxyh
)/2);
1363 static void TweakProxy(ProxyWindow
*proxy
)
1365 proxy
->proxyx
+= proxy
->tweakx
;
1366 proxy
->proxyy
+= proxy
->tweaky
;
1369 static void ReshuffleWindows(void)
1373 #if PROXY_GROUP_DEBUG
1374 fprintf(stderr
, "ReshuffleWindows\n");
1377 if (are_windows_shown
)
1381 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1383 RecenterProxy(proxy
);
1387 if (are_windows_shown
)
1391 RecalcProxyTweaks();
1396 static void UpdateOneWindow(ProxyWindow
*proxy
)
1402 if (proxy
->flags
.is_shown
)
1410 static void SendResolve(ProxyWindow
*proxy
)
1412 SendFvwmPipe(fd
, "SendToModule FvwmProxy Resolve",
1416 static void WaitToConfig(ProxyWindow
*proxy
)
1418 proxy
->pending_config
++;
1419 if(!waiting_to_config
)
1421 waiting_to_config
=1;
1426 static void IsolateGroup(ProxyWindow
*instigator
,int isolate
)
1430 #if PROXY_GROUP_DEBUG
1431 fprintf(stderr
, "IsolateGroup %p %d\n",
1432 instigator
,isolate
);
1435 if(!instigator
->group
)
1440 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1442 if(proxy
==instigator
)
1446 if (proxy
->desk
== deskNumber
&&
1447 proxy
->group
==instigator
->group
)
1449 proxy
->flags
.is_isolated
=isolate
;
1451 DrawProxyBackground(proxy
);
1457 static void IconifyGroup(ProxyWindow
*instigator
,int iconify
)
1461 #if PROXY_GROUP_DEBUG
1462 fprintf(stderr
, "IconifyGroup %p %d\n",
1463 instigator
,iconify
);
1466 if(!instigator
->group
)
1471 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1473 if(proxy
==instigator
)
1477 if (proxy
->desk
== deskNumber
&&
1478 proxy
->group
==instigator
->group
)
1480 sprintf(commandBuffer
,"Iconify %s",
1481 iconify
? "On": "Off");
1482 send_command_to_fvwm(commandBuffer
,proxy
->window
);
1487 static void RaiseLowerGroup(Window w
,int raise
)
1489 ProxyWindow
*instigator
;
1492 instigator
= FindProxy(w
);
1493 if(instigator
==NULL
|| instigator
->flags
.is_isolated
)
1499 #if PROXY_GROUP_DEBUG
1500 fprintf(stderr
, "RaiseLowerGroup %p %d %d\n",
1501 instigator
,raise
,instigator
->raised
);
1504 if(abs(instigator
->raised
)>10)
1509 if(instigator
->raised
== (raise
? 1: -1))
1514 instigator
->raised
=0;
1516 if(instigator
->flags
.is_iconified
|| !instigator
->group
)
1521 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1523 if(proxy
==instigator
|| proxy
->raised
== (raise
? 1: -1))
1527 if (proxy
->desk
== deskNumber
&&
1528 proxy
->group
==instigator
->group
)
1532 #if PROXY_GROUP_DEBUG
1533 fprintf(stderr
, "Raise %p\n",proxy
);
1537 XRaiseWindow(dpy
, proxy
->window
);
1541 #if PROXY_GROUP_DEBUG
1542 fprintf(stderr
, "Lower %p\n",proxy
);
1546 XLowerWindow(dpy
, proxy
->window
);
1550 /* make sure instigator ends on on top/bottom */
1553 #if PROXY_GROUP_DEBUG
1554 fprintf(stderr
, "ReRaise %p\n",instigator
);
1557 instigator
->raised
=1;
1558 XRaiseWindow(dpy
, instigator
->window
);
1562 #if PROXY_GROUP_DEBUG
1563 fprintf(stderr
, "ReLower %p\n",instigator
);
1566 instigator
->raised
= -1;
1567 XLowerWindow(dpy
, instigator
->window
);
1571 static void ClearRaised(void)
1575 #if PROXY_GROUP_DEBUG
1576 fprintf(stderr
, "ClearRaised\n");
1579 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1585 static void ShiftWindows(ProxyWindow
*instigator
,int dx
,int dy
)
1589 if((are_windows_shown
&& !instigator
->flags
.is_isolated
) ||
1590 !instigator
->group
|| instigator
->flags
.is_soft
)
1595 #if PROXY_GROUP_DEBUG
1596 fprintf(stderr
, "ShiftWindows %d %d %d\n",
1597 instigator
->group
,dx
,dy
);
1600 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1602 if(proxy
==instigator
)
1606 if (proxy
->desk
== deskNumber
&&
1607 proxy
->group
==instigator
->group
)
1612 XMoveWindow(dpy, proxy->window,
1613 proxy->x+proxy->border_width,
1614 proxy->y+proxy->title_height+
1615 proxy->border_width);
1617 #if PROXY_GROUP_DEBUG
1618 fprintf(stderr
, "shift %d %d (%d %d)\n",
1619 proxy
->x
,proxy
->y
, dx
,dy
);
1621 WaitToConfig(proxy
);
1626 static void CatchWindows(ProxyWindow
*instigator
,int vertical
,int from
,int to
,
1631 if((are_windows_shown
&& !instigator
->flags
.is_isolated
) ||
1632 !instigator
->group
|| instigator
->flags
.is_soft
)
1637 #if PROXY_GROUP_DEBUG
1638 fprintf(stderr
, "CatchWindows %d %d %d %d\n",
1639 instigator
->group
,vertical
,from
,to
);
1642 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1644 if(proxy
==instigator
)
1648 if (proxy
->desk
== deskNumber
&&
1649 proxy
->group
==instigator
->group
&&
1650 !proxy
->flags
.is_soft
)
1655 int neww
=proxy
->goal_width
;
1656 int newh
=proxy
->goal_height
;
1657 const int incx
=proxy
->incx
;
1658 const int incy
=proxy
->incy
;
1659 /* int threshold=(vertical? incy: incx)-1;
1674 #if PROXY_GROUP_DEBUG
1676 "check %p %d %d size %d %d"
1677 " goal %d %d inc %d %d\n",
1678 proxy
,proxy
->x
,proxy
->y
,proxy
->w
,proxy
->h
,
1679 proxy
->goal_width
,proxy
->goal_height
,
1685 if(newy
>=least
&& newy
<=most
)
1691 else if(newy
+newh
>=least
&&
1700 if(newx
>=least
&& newx
<=most
)
1706 else if(newx
+neww
>=least
&&
1715 #if PROXY_GROUP_DEBUG
1716 fprintf(stderr
, "change %d %d %d %d\n",
1717 newx
,newy
,neww
,newh
);
1719 if(newx
!=proxy
->x
|| newy
!=proxy
->y
)
1721 #if PROXY_GROUP_DEBUG
1722 fprintf(stderr
, "move\n");
1725 XMoveWindow(dpy, proxy->window,
1729 WaitToConfig(proxy
);
1731 /* in case more motion of instigator
1732 precedes this window's config */
1737 neww
>=proxy
->w
+incx
||
1739 newh
>=proxy
->h
+incy
)
1741 #if PROXY_GROUP_DEBUG
1742 fprintf(stderr
, "resize\n");
1745 XResizeWindow(dpy, proxy->window,
1749 WaitToConfig(proxy
);
1751 /* in case more motion of instigator
1752 precedes this window's config */
1755 proxy
->w
-=((proxy
->w
-neww
-1)/
1758 else if(neww
>=proxy
->w
+incx
)
1760 proxy
->w
+=(neww
-proxy
->w
)/incx
1765 proxy
->h
-=((proxy
->h
-newh
-1)/
1768 else if(newh
>=proxy
->h
+incy
)
1770 proxy
->h
+=(newh
-proxy
->h
)/incy
1774 proxy
->goal_width
=neww
;
1775 proxy
->goal_height
=newh
;
1782 static void MoveProxiedWindow(ProxyWindow
* proxy
,int x
,int y
,int w
,int h
)
1785 sprintf(commandBuffer
,"ResizeMove frame %dp %dp +%dp +%dp",
1790 send_command_to_fvwm(commandBuffer
,proxy
->window
);
1792 const int bw
=proxy
->border_width
;
1793 const int th
=proxy
->title_height
;
1795 XMoveResizeWindow(dpy
, proxy
->window
,
1803 static void ResolvePendingWindows(void)
1807 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1809 if(proxy
->pending_config
)
1811 MoveProxiedWindow(proxy
,proxy
->x
,proxy
->y
,
1812 proxy
->goal_width
,proxy
->goal_height
);
1817 int FindUniqueGroup(int desk
)
1821 /* find unique group */
1823 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1825 if (proxy
->desk
== desk
&& proxy
->group
==group
)
1832 #if PROXY_GROUP_DEBUG
1833 fprintf(stderr
,"FindUniqueGroup desk %d group %d\n",desk
,group
);
1838 static void MoveGroupToDesk(ProxyWindow
*instigator
,int desk
)
1845 #if PROXY_GROUP_DEBUG
1846 fprintf(stderr
, "MoveGroupToDesk %p %d\n",
1850 if(!instigator
->group
)
1855 old_desk
=instigator
->desk
;
1856 old_group
=instigator
->group
;
1857 group
=FindUniqueGroup(desk
);
1859 sprintf(commandBuffer
, "MoveToDesk 0 %d", desk
);
1860 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1862 if (proxy
->desk
== old_desk
&&
1863 proxy
->group
==old_group
)
1868 send_command_to_fvwm( commandBuffer
, proxy
->window
);
1870 DrawProxyBackground(proxy
);
1877 static ProxyWindow
* FindNeighborInGroup(ProxyWindow
* instigator
,
1887 #if PROXY_GROUP_DEBUG
1888 fprintf(stderr
,"FindNeighborInGroup %p %p desk %d group %d\n",
1889 instigator
,instigator
->proxy_group
,instigator
->desk
,
1893 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1895 #if PROXY_GROUP_DEBUG
1896 fprintf(stderr
," vs %p %p desk %d group %d\n",
1897 proxy
,proxy
->proxy_group
,proxy
->desk
,proxy
->group
);
1899 if (proxy
!= instigator
&& proxy
->desk
== instigator
->desk
&&
1901 proxy
->group
==instigator
->group
&&
1902 (!not_iconified
|| !proxy
->flags
.is_iconified
))
1911 static ProxyWindow
* FindNeighborForProxy(ProxyWindow
* instigator
)
1914 ProxyWindow
*neighbor
=NULL
;
1922 #if PROXY_GROUP_DEBUG
1923 fprintf(stderr
,"FindNeighborForProxy %p %p desk %d\n",
1924 instigator
,instigator
->proxy_group
,instigator
->desk
);
1927 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1929 #if PROXY_GROUP_DEBUG
1930 fprintf(stderr
," vs %p %p desk %d group %d\n",
1931 proxy
,proxy
->proxy_group
,proxy
->desk
,proxy
->group
);
1933 if (proxy
!= instigator
&& proxy
->desk
== instigator
->desk
&&
1934 proxy
->proxy_group
==instigator
->proxy_group
)
1936 if(proxy
->proxy_group
->flags
.isolated
&&
1937 !instigator
->flags
.is_isolated
)
1940 "SendToModule FvwmProxy IsolateToggle",
1953 #if PROXY_GROUP_DEBUG
1954 fprintf(stderr
,"not found\n");
1959 group
=FindUniqueGroup(instigator
->desk
);
1961 /* assign group to all proxies with given pid */
1962 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
1964 if (proxy
->desk
== instigator
->desk
&&
1965 proxy
->proxy_group
==instigator
->proxy_group
)
1967 #if PROXY_GROUP_DEBUG
1968 fprintf(stderr
,"unique group %d reassign %s\n",
1975 #if PROXY_GROUP_DEBUG
1976 fprintf(stderr
,"group %d\n",group
);
1981 static ProxyWindow
* FindNeighborForProcess(ProxyWindow
* proxy
,
1982 int desk
,int pid
,int ppid
)
1985 ProxyWindow
*neighbor
=NULL
;
1994 /* find existing group for pid */
1995 for (other
=firstProxy
; other
!= NULL
; other
=other
->next
)
1997 if (other
->desk
== desk
&& other
->proxy_group
&&
1998 (other
->pid
==pid
|| (ppid
&& other
->pid
==ppid
) ||
1999 other
->ppid
==pid
) &&
2000 (MatchWindowName(other
->proxy_group
->includes
,
2002 (auto_include
=other
->proxy_group
->flags
.auto_include
)))
2004 proxy
->flags
.is_soft
=auto_include
&&
2005 other
->proxy_group
->flags
.auto_soft
;
2006 if(other
->proxy_group
->flags
.isolated
&&
2007 !proxy
->flags
.is_isolated
)
2010 "SendToModule FvwmProxy IsolateToggle",
2013 #if PROXY_GROUP_DEBUG
2015 "pid %d %d found %d %d group %d soft %d\n",
2016 pid
,ppid
,other
->pid
,other
->ppid
,
2017 other
->group
,proxy
->flags
.is_soft
);
2028 #if PROXY_GROUP_DEBUG
2029 fprintf(stderr
,"FindNeighborForProcess pid %d %d not found\n",
2035 group
=FindUniqueGroup(desk
);
2037 /* assign pid to all proxies with given pid */
2038 for (other
=firstProxy
; other
!= NULL
; other
=other
->next
)
2040 if (other
->desk
== desk
&& other
->proxy_group
&&
2041 (other
->pid
==pid
|| (ppid
&& other
->pid
==ppid
) ||
2044 #if PROXY_GROUP_DEBUG
2045 fprintf(stderr
,"unique group %d reassign %s\n",
2052 #if PROXY_GROUP_DEBUG
2053 fprintf(stderr
,"FindNeighborForProcess pid %d new %d\n",pid
,group
);
2058 static ProxyWindow
* FindNeighborForLeader(ProxyWindow
* proxy
,
2059 int desk
,int leader
)
2062 ProxyWindow
*neighbor
=NULL
;
2071 /* find existing group for leader */
2072 for (other
=firstProxy
; other
!= NULL
; other
=other
->next
)
2074 if (other
->desk
== desk
&& other
->proxy_group
&&
2075 other
->leader
==leader
&&
2076 (MatchWindowName(other
->proxy_group
->includes
,
2078 (auto_include
=other
->proxy_group
->flags
.auto_include
)))
2080 proxy
->flags
.is_soft
=auto_include
&&
2081 other
->proxy_group
->flags
.auto_soft
;
2082 if(other
->proxy_group
->flags
.isolated
&&
2083 !proxy
->flags
.is_isolated
)
2086 "SendToModule FvwmProxy IsolateToggle",
2089 #if PROXY_GROUP_DEBUG
2090 fprintf(stderr
,"leader %d found %d group %d soft %d\n",
2091 leader
,other
->leader
,
2092 other
->group
,proxy
->flags
.is_soft
);
2103 #if PROXY_GROUP_DEBUG
2104 fprintf(stderr
,"FindNeighborForLeader leader %d not found\n",
2110 group
=FindUniqueGroup(desk
);
2112 /* assign leader to all proxies with given leader */
2113 for (other
=firstProxy
; other
!= NULL
; other
=other
->next
)
2115 if (other
->desk
== desk
&& other
->leader
==leader
&&
2118 #if PROXY_GROUP_DEBUG
2119 fprintf(stderr
,"unique group %d reassign %s\n",
2126 #if PROXY_GROUP_DEBUG
2127 fprintf(stderr
,"FindNeighborForLeader leader %x new %d\n",
2133 static ProxyWindow
* FindNeighborForApplication(ProxyWindow
* proxy
)
2135 ProxyWindow
* neighbor
=FindNeighborForLeader(proxy
,proxy
->desk
,
2139 neighbor
=FindNeighborForProcess(proxy
,proxy
->desk
,
2140 proxy
->pid
,proxy
->ppid
);
2145 static int ProxyGroupCheckSoft(ProxyGroup
* proxy_group
,
2148 WindowName
* include
=proxy_group
->includes
;
2151 if(matchWildcards(include
->name
, proxy
->name
))
2153 return include
->flags
.is_soft
;
2155 include
=include
->next
;
2160 static void UpdateProxyGroup(ProxyWindow
* proxy
)
2162 ProxyWindow
* neighbor
;
2163 #if PROXY_GROUP_DEBUG
2164 fprintf(stderr
,"UpdateProxyGroup %s\n",proxy
->name
);
2167 if(proxy
->proxy_group
)
2171 if(!proxy
->proxy_group
)
2173 neighbor
=FindNeighborForApplication(proxy
);
2177 proxy
->proxy_group
=NULL
;
2178 if(neighbor
&& neighbor
->proxy_group
)
2180 proxy
->group
=neighbor
->group
;
2181 proxy
->proxy_group
=neighbor
->proxy_group
;
2184 if(!proxy
->proxy_group
)
2187 FindProxyGroupWithWindowName(proxy
->name
);
2189 if(proxy
->proxy_group
&&
2190 MatchWindowName(proxy
->proxy_group
->excludes
,proxy
->name
))
2192 proxy
->proxy_group
=NULL
;
2195 if(proxy
->proxy_group
&& !proxy
->group
&&
2196 proxy
->proxy_group
->flags
.ignore_ids
)
2198 neighbor
=FindNeighborForProxy(proxy
);
2201 proxy
->group
=neighbor
->group
;
2205 if(proxy
->proxy_group
)
2207 #if PROXY_GROUP_DEBUG
2208 fprintf(stderr
," ProxyGroup %s\n",proxy
->proxy_group
->name
);
2211 proxy
->flags
.is_soft
=proxy
->flags
.is_soft
||
2212 ProxyGroupCheckSoft(proxy
->proxy_group
,proxy
);
2216 static void UpdateProxyGroupForAll(void)
2220 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2222 UpdateProxyGroup(proxy
);
2226 static void AdhereGroup(ProxyWindow
*instigator
)
2230 #if PROXY_GROUP_DEBUG
2231 fprintf(stderr
, "AdhereGroup %p\n", instigator
);
2239 if(!instigator
->group
|| instigator
->flags
.is_soft
)
2244 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2246 if(proxy
==instigator
)
2250 if (proxy
->desk
== instigator
->desk
&&
2251 proxy
->group
==instigator
->group
)
2253 if(!proxy
->flags
.is_soft
&&
2254 (proxy
->x
!= instigator
->x
||
2255 proxy
->y
!= instigator
->y
||
2256 proxy
->goal_width
!= instigator
->goal_width
||
2257 proxy
->goal_height
!= instigator
->goal_height
))
2259 proxy
->x
=instigator
->x
;
2260 proxy
->y
=instigator
->y
;
2261 proxy
->goal_width
=instigator
->goal_width
;
2262 proxy
->goal_height
=instigator
->goal_height
;
2264 MoveProxiedWindow(proxy
,proxy
->x
,proxy
->y
,
2265 proxy
->goal_width
,proxy
->goal_height
);
2271 static void SetGroup(ProxyWindow
* proxy
, int group
)
2273 ProxyWindow
*neighbor
;
2278 neighbor
=FindNeighborInGroup(proxy
,0);
2281 proxy
->flags
.is_isolated
= neighbor
->flags
.is_isolated
;
2282 if(proxy
->flags
.is_isolated
)
2284 AdhereGroup(neighbor
);
2287 if(proxy
->flags
.is_isolated
&& !proxy
->flags
.is_iconified
)
2289 IconifyGroup(proxy
,1);
2294 proxy
->flags
.is_soft
=0;
2295 proxy
->flags
.is_isolated
=0;
2299 void DumpStampQueue(void)
2301 #if PROXY_GROUP_DEBUG
2304 fprintf(stderr
,"DumpStampQueue stamp %d min %d max %d\n",
2305 stamp
,stampMin
,stampMax
);
2306 for(m
=0;m
<stampLimit
;m
++)
2308 fprintf(stderr
,"stampQueue[%d] %x %d %d %d %d\n",m
,
2309 (int)(stampQueue
[m
].window
),
2318 void StoreStamp(Window window
,int x
,int y
,int w
,int h
)
2320 #if PROXY_GROUP_DEBUG
2321 fprintf(stderr
,"StoreStamp %x %d %d %d %d\n",(int)window
,x
,y
,w
,h
);
2324 stamp
=(stamp
+1)%stampLimit
;
2326 if(stampMin
==stampMax
)
2328 stampMin
=(stampMax
+1)%stampLimit
;
2331 stampQueue
[stamp
].window
=window
;
2332 stampQueue
[stamp
].x
=x
;
2333 stampQueue
[stamp
].y
=y
;
2334 stampQueue
[stamp
].w
=w
;
2335 stampQueue
[stamp
].h
=h
;
2340 void UndoStamp(void)
2346 #if PROXY_GROUP_DEBUG
2347 fprintf(stderr
,"UndoStamp empty, stamp %d min %d max %d\n",
2348 stamp
,stampMin
,stampMax
);
2352 proxy
= FindProxy(stampQueue
[stamp
].window
);
2355 #if PROXY_GROUP_DEBUG
2356 fprintf(stderr
,"UndoStamp no proxy for window\n");
2362 MoveProxiedWindow(proxy
,
2363 stampQueue
[stamp
].x
,
2364 stampQueue
[stamp
].y
,
2365 stampQueue
[stamp
].w
,
2366 stampQueue
[stamp
].h
);
2368 stampQueue
[stamp
].window
=proxy
->window
;
2369 stampQueue
[stamp
].x
=proxy
->x
;
2370 stampQueue
[stamp
].y
=proxy
->y
;
2371 stampQueue
[stamp
].w
=proxy
->w
;
2372 stampQueue
[stamp
].h
=proxy
->h
;
2374 stamp
=(stamp
-1+stampLimit
)%stampLimit
;
2381 void RedoStamp(void)
2387 #if PROXY_GROUP_DEBUG
2388 fprintf(stderr
,"RedoStamp empty, stamp %d min %d max %d\n",
2389 stamp
,stampMin
,stampMax
);
2394 stamp
=(stamp
+1)%stampLimit
;
2396 proxy
= FindProxy(stampQueue
[stamp
].window
);
2399 #if PROXY_GROUP_DEBUG
2400 fprintf(stderr
,"RedoStamp no proxy for window\n");
2406 MoveProxiedWindow(proxy
,
2407 stampQueue
[stamp
].x
,
2408 stampQueue
[stamp
].y
,
2409 stampQueue
[stamp
].w
,
2410 stampQueue
[stamp
].h
);
2412 stampQueue
[stamp
].window
=proxy
->window
;
2413 stampQueue
[stamp
].x
=proxy
->x
;
2414 stampQueue
[stamp
].y
=proxy
->y
;
2415 stampQueue
[stamp
].w
=proxy
->w
;
2416 stampQueue
[stamp
].h
=proxy
->h
;
2423 static void ConfigureWindow(FvwmPacket
*packet
)
2425 unsigned long* body
= packet
->body
;
2427 struct ConfigWinPacket
*cfgpacket
=(void *)body
;
2428 int wx
=cfgpacket
->frame_x
;
2429 int wy
=cfgpacket
->frame_y
;
2430 int desk
=cfgpacket
->desk
;
2431 int wsx
=cfgpacket
->frame_width
;
2432 int wsy
=cfgpacket
->frame_height
;
2433 int border_width
=cfgpacket
->border_width
;
2434 int title_height
=cfgpacket
->title_height
;
2435 int incx
=cfgpacket
->hints_width_inc
;
2436 int incy
=cfgpacket
->hints_height_inc
;
2437 Window target
=cfgpacket
->w
;
2442 int is_new_window
= 0;
2444 if (DO_SKIP_WINDOW_LIST(cfgpacket
))
2448 #if PROXY_GROUP_DEBUG
2449 fprintf(stderr
,"\n");
2451 leader
=GetLeader(target
);
2452 pid
=GetProcessId(target
);
2453 ppid
=GetParentProcessId(pid
);
2454 proxy
= FindProxy(target
);
2458 proxy
=new_ProxyWindow();
2459 proxy
->next
= firstProxy
;
2461 proxy
->window
=target
;
2463 /* unreliable on existing windows
2464 on 2.5.10, reporting false just after M_ICONIFY */
2465 proxy
->flags
.is_iconified
= !!IS_ICONIFIED(cfgpacket
);
2468 #if PROXY_GROUP_DEBUG
2470 "Config %p %x ld %x pid=%d %d\n"
2471 " pos %d %d sz %d %d"
2472 " was %d %d sz %d %d goal %d %d"
2473 " bdr %d %d pend %d %d\n",
2474 proxy
,(int)target
,leader
,pid
,ppid
,
2478 proxy
->goal_width
,proxy
->goal_height
,
2479 border_width
,title_height
,
2480 proxy
->pending_config
,
2484 if(proxy
->pending_config
)
2486 proxy
->pending_config
=0;
2490 if(!pending_do
&& !waiting_to_stamp
&&
2491 (is_new_window
|| proxy
->x
!=wx
|| proxy
->y
!=wy
||
2492 proxy
->w
!=wsx
|| proxy
->h
!=wsy
))
2495 sprintf(commandBuffer
,
2496 "SendToModule FvwmProxy Stamp %d %d %d %d",
2497 proxy
->x
,proxy
->y
,proxy
->w
,proxy
->h
);
2498 SendFvwmPipe(fd
, commandBuffer
, proxy
->window
);
2503 proxy
->goal_width
=wsx
;
2504 proxy
->goal_height
=wsy
;
2513 int wasgw
=proxy
->goal_width
;
2514 int wasgh
=proxy
->goal_height
;
2515 if(proxy
->x
!=wx
&& proxy
->w
==wsx
)
2517 ShiftWindows(proxy
,wx
-proxy
->x
,wy
-proxy
->y
);
2524 CatchWindows(proxy
,0,proxy
->x
,wx
,-1);
2525 proxy
->goal_width
=wsx
;
2527 if(wasx
+wasw
!=wx
+wsx
)
2529 CatchWindows(proxy
,0,
2532 proxy
->goal_width
=wsx
;
2536 if(proxy
->y
!=wy
&& proxy
->h
==wsy
)
2540 ShiftWindows(proxy
,0,wy
-proxy
->y
);
2547 CatchWindows(proxy
,1,proxy
->y
,wy
,-1);
2548 proxy
->goal_height
=wsy
;
2550 if(wasy
+wash
!=wy
+wsy
)
2552 CatchWindows(proxy
,1,
2555 proxy
->goal_height
=wsy
;
2559 if(wx!=proxy->x || wy!=proxy->y ||
2560 wsx!=proxy->w || wsy!=proxy->h)
2562 StoreStamp(target,proxy->x,proxy->y,
2569 if(!is_new_window
&& proxy
->desk
!=desk
)
2571 MoveGroupToDesk(proxy
,desk
);
2574 proxy
->leader
=leader
;
2582 proxy
->proxyw
=proxyWidth
;
2583 proxy
->proxyh
=proxyHeight
;
2584 proxy
->border_width
=border_width
;
2585 proxy
->title_height
=title_height
;
2589 RecenterProxy(proxy
);
2595 if (are_windows_shown
)
2603 CloseOneWindow(proxy
);
2604 OpenOneWindow(proxy
);
2608 if(proxy
->flags
.is_isolated
)
2616 static void IconifyWindow(ProxyWindow
*proxy
, int is_iconified
)
2622 is_iconified
= !!is_iconified
;
2623 if(proxy
->flags
.is_iconified
!= is_iconified
)
2625 proxy
->flags
.is_iconified
= is_iconified
;
2626 if (!proxyIconified
&& is_iconified
)
2628 if (proxy
->flags
.is_shown
)
2630 CloseOneWindow(proxy
);
2635 if (are_windows_shown
)
2637 /* ReshuffleWindows();
2639 OpenOneWindow(proxy
);
2643 DrawProxyBackground(proxy
);
2645 if(proxy
->flags
.is_isolated
)
2649 IconifyGroup(proxy
, 1);
2654 IconifyGroup(proxy
,is_iconified
);
2661 static void IsolateCheck(ProxyWindow
*instigator
,int force_other
)
2663 if(instigator
->flags
.is_isolated
)
2665 if(!force_other
&& !instigator
->flags
.is_iconified
)
2667 IconifyGroup(instigator
,1);
2668 AdhereGroup(instigator
);
2672 ProxyWindow
*neighbor
=
2673 FindNeighborInGroup(instigator
,1);
2676 IconifyGroup(neighbor
,1);
2680 neighbor
=FindNeighborInGroup(instigator
,0);
2681 if(neighbor
&& force_other
)
2683 sprintf(commandBuffer
,"Iconify Off");
2684 send_command_to_fvwm(commandBuffer
,
2688 AdhereGroup(neighbor
);
2693 static void DestroyWindow(Window w
)
2698 for (proxy
=firstProxy
, prev
= NULL
; proxy
!= NULL
;
2699 prev
= proxy
, proxy
=proxy
->next
)
2701 if (proxy
->proxy
==w
|| proxy
->window
==w
)
2710 firstProxy
= proxy
->next
;
2714 prev
->next
= proxy
->next
;
2716 if (selectProxy
== proxy
)
2720 if (enterProxy
== proxy
)
2724 if(!proxy
->flags
.is_iconified
)
2726 IsolateCheck(proxy
,1);
2728 CloseOneWindow(proxy
);
2729 delete_ProxyWindow(proxy
);
2734 static unsigned int GetModifiers(void)
2736 Window root_return
, child_return
;
2737 int root_x_return
, root_y_return
;
2738 int win_x_return
, win_y_return
;
2739 unsigned int mask_return
;
2742 dpy
,rootWindow
,&root_return
,
2744 &root_x_return
,&root_y_return
,
2745 &win_x_return
,&win_y_return
,
2746 &mask_return
) == False
)
2748 /* pointer is on another screen - ignore */
2761 static void StartProxies(void)
2763 if (are_windows_shown
)
2768 held_modifiers
=GetModifiers();
2772 if(action_list
[PROXY_ACTION_MODIFIER_RELEASE
])
2773 watching_modifiers
=1;
2775 send_command_to_fvwm(action_list
[PROXY_ACTION_SHOW
], None
);
2776 are_windows_shown
= 1;
2784 static void MarkProxy(ProxyWindow
*new_proxy
)
2786 ProxyWindow
*old_proxy
;
2788 old_proxy
= selectProxy
;
2789 selectProxy
= new_proxy
;
2790 if (selectProxy
!= old_proxy
)
2792 if (old_proxy
!= NULL
)
2794 DrawProxyBackground(old_proxy
);
2795 DrawProxy(old_proxy
);
2797 if (selectProxy
!= NULL
)
2799 DrawProxyBackground(selectProxy
);
2800 DrawProxy(selectProxy
);
2803 if (old_proxy
!= NULL
)
2804 send_command_to_fvwm(action_list
[PROXY_ACTION_UNMARK
],
2806 if (selectProxy
!= NULL
)
2807 send_command_to_fvwm(action_list
[PROXY_ACTION_MARK
],
2808 selectProxy
->window
);
2813 static void HideProxies(void)
2815 if (!are_windows_shown
)
2819 are_windows_shown
= 0;
2825 static void SelectProxy(void)
2831 send_command_to_fvwm(action_list
[PROXY_ACTION_SELECT
],
2832 selectProxy
->window
);
2834 send_command_to_fvwm(action_list
[PROXY_ACTION_HIDE
], None
);
2836 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2837 if (proxy
==selectProxy
)
2848 static void AbortProxies(void)
2851 send_command_to_fvwm(action_list
[PROXY_ACTION_ABORT
], None
);
2857 static void RotateIsolated(ProxyWindow
*instigator
,int direction
)
2861 ProxyWindow
*first
=NULL
;
2862 ProxyWindow
*adjacent
=NULL
;
2864 #if PROXY_GROUP_DEBUG
2865 fprintf(stderr
,"RotateIsolated %p %p %d\n",
2866 instigator
,last_rotation_instigator
,direction
);
2869 /* rotation can lose focus, so we store it */
2870 if(!instigator
|| !instigator
->group
||
2871 !instigator
->flags
.is_isolated
)
2873 instigator
=last_rotation_instigator
;
2875 if(!instigator
|| !instigator
->group
||
2876 !instigator
->flags
.is_isolated
)
2880 last_rotation_instigator
=instigator
;
2882 for (proxy
=firstProxy
; proxy
!= NULL
; proxy
=proxy
->next
)
2884 if(proxy
->desk
== instigator
->desk
&&
2885 proxy
->group
==instigator
->group
)
2887 if(!proxy
->flags
.is_iconified
)
2889 if(direction
<0 && adjacent
)
2920 sprintf(commandBuffer
,"Iconify Off");
2921 send_command_to_fvwm(commandBuffer
,adjacent
->window
);
2927 static void change_cset(int cset
)
2929 if (cset
== cset_normal
|| cset
== cset_iconified
)
2933 for (proxy
= firstProxy
; proxy
!= NULL
; proxy
= proxy
->next
)
2935 DrawProxyBackground(proxy
);
2938 else if (cset
== cset_select
&& selectProxy
!= NULL
)
2940 DrawProxyBackground(selectProxy
);
2946 static void ProcessMessage(FvwmPacket
* packet
)
2948 unsigned long type
= packet
->type
;
2949 unsigned long* body
= packet
->body
;
2950 FvwmWinPacketBodyHeader
*bh
= (void *)body
;
2957 if(type
!=M_RAISE_WINDOW
&& type
!=M_LOWER_WINDOW
&&
2958 type
!=M_FOCUS_CHANGE
&& type
!=M_ICON_NAME
&&
2959 type
!=M_MINI_ICON
&& type
!=M_STRING
)
2966 case M_CONFIGURE_WINDOW
:
2968 ConfigureWindow(packet
);
2970 case M_DESTROY_WINDOW
:
2971 DestroyWindow(bh
->w
);
2974 IconifyWindow(FindProxy(bh
->w
), 1);
2977 IconifyWindow(FindProxy(bh
->w
), 0);
2979 case M_RAISE_WINDOW
:
2980 RaiseLowerGroup(bh
->w
,1);
2982 case M_LOWER_WINDOW
:
2983 RaiseLowerGroup(bh
->w
,0);
2986 proxy
= FindProxy(bh
->w
);
2989 if (proxy
->name
!= NULL
)
2993 proxy
->name
= safestrdup((char*)&body
[3]);
2994 #if PROXY_GROUP_DEBUG
2995 fprintf(stderr
,"M_WINDOW_NAME %s\n",proxy
->name
);
2997 UpdateProxyGroup(proxy
);
2998 UpdateProxyGroupForAll();
3002 proxy
= FindProxy(bh
->w
);
3005 if (proxy
->iconname
!= NULL
)
3007 free(proxy
->iconname
);
3009 proxy
->iconname
= safestrdup((char*)&body
[3]);
3010 #if PROXY_GROUP_DEBUG
3011 fprintf(stderr
,"M_ICON_NAME %s\n",proxy
->iconname
);
3013 /* UpdateOneWindow(proxy);
3015 DrawProxyBackground(proxy
);
3020 if (deskNumber
!=body
[0])
3023 if (are_windows_shown
)
3034 proxy
= FindProxy(bh
->w
);
3037 proxy
->picture
.width
=body
[3];
3038 proxy
->picture
.height
=body
[4];
3039 proxy
->picture
.depth
=body
[5];
3040 proxy
->picture
.picture
=body
[6];
3041 proxy
->picture
.mask
=body
[7];
3042 proxy
->picture
.alpha
=body
[8];
3043 UpdateOneWindow(proxy
);
3046 case M_FOCUS_CHANGE
:
3051 last_rotation_instigator
=NULL
;
3057 char *message
=(char*)&body
[3];
3061 int isolate_check
=0;
3064 #if PROXY_GROUP_DEBUG
3065 fprintf(stderr
, "M_STRING \"%s\"\n", message
);
3068 token
= PeekToken(message
, &next
);
3069 prev
=(StrEquals(token
, "Prev"));
3070 if (StrEquals(token
, "Next") || prev
)
3072 ProxyWindow
*lastSelect
=selectProxy
;
3073 ProxyWindow
*newSelect
=selectProxy
;
3074 ProxyWindow
*first
=prev
? lastProxy
: firstProxy
;
3076 /* auto-show if not already shown */
3077 if (!are_windows_shown
)
3080 if (startProxy
&& startProxy
->desk
==deskNumber
)
3082 newSelect
=startProxy
;
3090 newSelect
=newSelect
->prev
;
3092 newSelect
=newSelect
->next
;
3096 while (newSelect
!=lastSelect
&&
3097 newSelect
->desk
!=deskNumber
)
3100 newSelect
=newSelect
->prev
;
3102 newSelect
=newSelect
->next
;
3103 if (!newSelect
&& lastSelect
)
3108 MarkProxy(newSelect
);
3110 else if (StrEquals(token
, "Circulate"))
3114 /* auto-show if not already shown */
3115 if (!are_windows_shown
)
3118 w
= (selectProxy
) ? selectProxy
->window
: focusWindow
;
3120 strcpy(commandBuffer
,next
);
3121 strcat(commandBuffer
," SendToModule FvwmProxy Mark");
3123 SendFvwmPipe(fd
,commandBuffer
,w
);
3125 else if (StrEquals(token
, "Show"))
3129 else if (StrEquals(token
, "Hide"))
3133 else if (StrEquals(token
, "ShowToggle"))
3135 if (are_windows_shown
)
3144 else if (StrEquals(token
, "Abort"))
3148 else if (StrEquals(token
, "Mark"))
3157 else if (sscanf(next
, "0x%x", (int *)&w
) < 1)
3165 proxy
= FindProxy(bh
->w
);
3169 else if (StrEquals(token
, "Resolve"))
3171 waiting_to_config
=0;
3173 ResolvePendingWindows();
3176 else if (StrEquals(token
, "Stamp"))
3178 token
= PeekToken(message
, &next
);
3179 sscanf(next
,"%d%d%d%d",&x
,&y
,&w
,&h
);
3182 proxy
= FindProxy(bh
->w
);
3185 StoreStamp(bh
->w
,x
,y
,w
,h
);
3189 else if (StrEquals(token
, "Undo"))
3194 else if (StrEquals(token
, "Redo"))
3199 else if (StrEquals(token
, "PrevIsolated"))
3201 RotateIsolated(FindProxy(bh
->w
),-1);
3203 else if (StrEquals(token
, "NextIsolated"))
3205 RotateIsolated(FindProxy(bh
->w
),1);
3207 else if (StrEquals(token
, "SoftToggle"))
3209 proxy
= FindProxy(bh
->w
);
3212 proxy
->flags
.is_soft
= proxy
->group
?
3213 !proxy
->flags
.is_soft
: 0;
3216 DrawProxyBackground(proxy
);
3220 else if (StrEquals(token
, "IsolateToggle"))
3222 proxy
= FindProxy(bh
->w
);
3225 proxy
->flags
.is_isolated
= proxy
->group
?
3226 !proxy
->flags
.is_isolated
: 0;
3227 IsolateGroup(proxy
,proxy
->flags
.is_isolated
);
3230 DrawProxyBackground(proxy
);
3237 IsolateCheck(proxy
,0);
3241 /* windows may have moved, so update proxy windows */
3242 if (are_windows_shown
)
3251 char *tline
, *token
;
3253 tline
= (char*)&(body
[3]);
3254 token
= PeekToken(tline
, &tline
);
3255 if (StrEquals(token
, "Colorset"))
3258 cset
= LoadColorset(tline
);
3268 static int My_XNextEvent(Display
*dpy
,XEvent
*event
)
3272 struct timeval timevalue
,*timeout
=&timevalue
;
3273 timevalue
.tv_sec
= 0;
3274 timevalue
.tv_usec
= 100000;
3278 FNextEvent(dpy
,event
);
3283 FD_SET(x_fd
,&in_fdset
);
3284 FD_SET(fd
[1],&in_fdset
);
3286 if ( fvwmSelect(fd_width
, &in_fdset
, 0, 0, timeout
) > 0)
3288 if (FD_ISSET(x_fd
, &in_fdset
))
3292 FNextEvent(dpy
,event
);
3297 if (FD_ISSET(fd
[1], &in_fdset
))
3299 FvwmPacket
* packet
= ReadFvwmPacket(fd
[1]);
3305 ProcessMessage(packet
);
3312 static void DispatchEvent(XEvent
*pEvent
)
3314 Window window
=pEvent
->xany
.window
;
3318 switch(pEvent
->xany
.type
)
3321 proxy
= FindProxy(window
);
3325 proxy
, pEvent
->xexpose
.x
, pEvent
->xexpose
.y
,
3326 pEvent
->xexpose
.width
, pEvent
->xexpose
.height
);
3330 proxy
= FindProxy(window
);
3333 int button
=pEvent
->xbutton
.button
;
3334 int wx
=pEvent
->xbutton
.x
;
3335 int wy
=pEvent
->xbutton
.y
;
3337 button
<= NUMBER_OF_EXTENDED_MOUSE_BUTTONS
)
3339 if(wy
< slotSpace
+slotHeight
)
3341 int index
=(wx
-slotSpace
)/
3342 (slotWidth
+slotSpace
)+1;
3343 int group
=index
-groupSlot
+1;
3347 char* action
=slot_action_list
[
3351 SendFvwmPipe(fd
,action
,
3355 if(group
&& group
<=groupCount
)
3358 proxy
->group
==group
?
3360 DrawProxyBackground(proxy
);
3367 action_list
[PROXY_ACTION_CLICK
3373 mousex
=pEvent
->xbutton
.x_root
;
3374 mousey
=pEvent
->xbutton
.y_root
;
3377 proxy
= FindProxy(window
);
3378 dx
=pEvent
->xbutton
.x_root
-mousex
;
3379 dy
=pEvent
->xbutton
.y_root
-mousey
;
3380 if (proxy
&& proxyMove
)
3382 sprintf(commandBuffer
,"Silent Move w+%dp w+%dp",dx
,dy
);
3383 send_command_to_fvwm(commandBuffer
,proxy
->window
);
3386 mousex
=pEvent
->xbutton
.x_root
;
3387 mousey
=pEvent
->xbutton
.y_root
;
3390 proxy
= FindProxy(pEvent
->xcrossing
.window
);
3391 if (pEvent
->xcrossing
.mode
== NotifyNormal
)
3396 else if (pEvent
->xcrossing
.mode
== NotifyUngrab
&&
3397 proxy
!= NULL
&& proxy
!= selectProxy
&&
3398 proxy
!= enterProxy
)
3405 fprintf(stderr
, "Unrecognized XEvent %d\n", pEvent
->xany
.type
);
3412 static void Loop(int *fd
)
3419 if ((result
=My_XNextEvent(dpy
,&event
))==1)
3421 DispatchEvent(&event
);
3424 #if PROXY_KEY_POLLING
3425 if(are_windows_shown
&& watching_modifiers
)
3427 unsigned int mask_return
=GetModifiers();
3428 if(!(mask_return
&watched_modifiers
))
3430 watching_modifiers
=0;
3431 send_command_to_fvwm(
3433 [PROXY_ACTION_MODIFIER_RELEASE
],
3441 /* ---------------------------- interface functions ------------------------- */
3443 int main(int argc
, char **argv
)
3451 "FvwmProxy should only be executed by fvwm!\n");
3455 FlocaleInit(LC_CTYPE
, "", "", "FvwmProxy");
3456 MyName
= GetFileNameFromPath(argv
[0]);
3458 fd
[0] = atoi(argv
[1]);
3459 fd
[1] = atoi(argv
[2]);
3461 originalXIOErrorHandler
=XSetIOErrorHandler(myXIOErrorHandler
);
3462 originalXErrorHandler
=XSetErrorHandler(myXErrorHandler
);
3464 if (!(dpy
=XOpenDisplay(NULL
)))
3466 fprintf(stderr
,"can't open display\n");
3469 titles
[0]="FvwmProxy";
3470 if (XStringListToTextProperty(titles
,1,&windowName
) == 0)
3472 fprintf(stderr
,"Proxy_CreateBar() could not allocate space"
3473 " for window title");
3476 flib_init_graphics(dpy
);
3477 FlocaleAllocateWinString(&FwinString
);
3478 screen
= DefaultScreen(dpy
);
3479 rootWindow
= RootWindow(dpy
,screen
);
3480 xgcv
.plane_mask
=AllPlanes
;
3481 miniIconGC
=fvwmlib_XCreateGC(dpy
,rootWindow
,GCPlaneMask
,&xgcv
);
3482 fg_gc
= fvwmlib_XCreateGC(dpy
,rootWindow
,GCPlaneMask
,&xgcv
);
3483 hi_gc
= fvwmlib_XCreateGC(dpy
,rootWindow
,GCPlaneMask
,&xgcv
);
3484 sh_gc
= fvwmlib_XCreateGC(dpy
,rootWindow
,GCPlaneMask
,&xgcv
);
3486 x_fd
= XConnectionNumber(dpy
);
3487 fd_width
= GetFdWidth();
3490 fd
, M_STRING
| M_RAISE_WINDOW
| M_LOWER_WINDOW
|
3491 M_CONFIGURE_WINDOW
| M_ADD_WINDOW
| M_FOCUS_CHANGE
|
3492 M_DESTROY_WINDOW
| M_NEW_DESK
| M_NEW_PAGE
| M_ICON_NAME
|
3493 M_WINDOW_NAME
| M_MINI_ICON
| M_ICONIFY
| M_DEICONIFY
|
3494 M_CONFIG_INFO
| M_END_CONFIG_INFO
);
3496 if (parse_options() == False
)
3498 stampQueue
=(GeometryStamp
*)safemalloc(
3499 sizeof(GeometryStamp
)*stampLimit
);
3500 if ((Ffont
= FlocaleLoadFont(dpy
, font_name
, MyName
)) == NULL
)
3502 fprintf(stderr
,"%s: Couldn't load font \"%s\". Exiting!\n",
3506 if (Ffont
->font
!= NULL
)
3508 XSetFont(dpy
,fg_gc
,Ffont
->font
->fid
);
3514 FlocaleLoadFont(dpy
, small_font_name
, MyName
)) == NULL
)
3517 "%s: Couldn't load small font \"%s\"\n",
3518 MyName
, small_font_name
);
3521 if (Ffont_small
!= NULL
&& Ffont_small
->font
!= NULL
)
3523 XSetFont(dpy
,hi_gc
,Ffont_small
->font
->fid
);
3525 SendInfo(fd
,"Send_WindowList",0);
3526 SendFinishedStartupNotification(fd
);