Copy purify.fvwm2rc to /tmp - add instructions in README.
[fvwm.git] / fvwm / module_interface.c
blob636cc81ada2158c3ee27c6c6a9fd28530ca26397
1 /* -*-c-*- */
2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * This module is all original code
19 * by Rob Nation
20 * Copyright 1993, Robert Nation
21 * You may use this code for any purpose, as long as the original
22 * copyright remains in the source code and all documentation
27 * code for talking with fvwm modules.
30 #include "config.h"
32 #include <stdio.h>
33 #include <stdarg.h>
34 #include <errno.h>
36 #include "libs/ftime.h"
37 #include "libs/fvwmlib.h"
38 #include "libs/FScreen.h"
39 #include "libs/ColorUtils.h"
40 #include "libs/Parse.h"
41 #include "libs/Strings.h"
42 #include "libs/wild.h"
43 #include "fvwm.h"
44 #include "externs.h"
45 #include "functions.h"
46 #include "bindings.h"
47 #include "misc.h"
48 #include "screen.h"
49 #include "module_interface.h"
50 #include "module_list.h"
51 #include "events.h"
52 #include "geometry.h"
53 #include "libs/fvwmsignal.h"
54 #include "decorations.h"
55 #include "commands.h"
57 /* A queue of commands from the modules */
58 static fqueue cqueue = FQUEUE_INIT;
60 static const unsigned long dummy = 0;
62 static unsigned long *
63 make_vpacket(unsigned long *body, unsigned long event_type,
64 unsigned long num, va_list ap)
66 unsigned long *bp = body;
68 /* truncate long packets */
69 if (num > FvwmPacketMaxSize)
71 num = FvwmPacketMaxSize;
73 *(bp++) = START_FLAG;
74 *(bp++) = event_type;
75 *(bp++) = num+FvwmPacketHeaderSize;
76 *(bp++) = fev_get_evtime();
78 for (; num > 0; --num)
80 *(bp++) = va_arg(ap, unsigned long);
83 return body;
89 RBW - 04/16/1999 - new packet builder for GSFR --
90 Arguments are pairs of lengths and argument data pointers.
91 RBW - 05/01/2000 -
92 A length of zero means that an int is being passed which
93 must be stored in the packet as an unsigned long. This is
94 a special hack to accommodate the old CONFIGARGS
95 technique of sending the args for the M_CONFIGURE_WINDOW
96 packet.
98 static unsigned long
99 make_new_vpacket(unsigned char *body, unsigned long event_type,
100 unsigned long num, va_list ap)
102 long arglen;
103 unsigned long addlen;
104 unsigned long bodylen = 0;
105 unsigned long *bp = (unsigned long *)body;
106 unsigned long *bp1 = bp;
107 unsigned long plen = 0;
109 *(bp++) = START_FLAG;
110 *(bp++) = event_type;
111 /* Skip length field, we don't know it yet. */
112 bp++;
113 *(bp++) = fev_get_evtime();
115 for (; num > 0; --num)
117 arglen = va_arg(ap, long);
118 if (arglen <= 0)
120 if (arglen == 0)
122 arglen = -sizeof(int);
124 addlen = sizeof(unsigned long);
126 else
128 addlen = arglen;
130 bodylen += addlen;
131 if (bodylen >= FvwmPacketMaxSize_byte)
133 fvwm_msg(
134 ERR, "make_new_vpacket",
135 "packet too long %ld %ld", (long)bodylen,
136 (long)FvwmPacketMaxSize_byte);
137 break;
139 if (arglen > 0)
141 register char *tmp = (char *)bp;
142 memcpy(tmp, va_arg(ap, char *), arglen);
143 tmp += arglen;
144 bp = (unsigned long *)tmp;
146 else if (arglen == 0 || arglen == -sizeof(int))
148 int *tmp;
150 tmp = va_arg(ap, int *);
151 *bp = (unsigned long) *tmp;
152 bp++;
154 else if (arglen == -sizeof(long))
156 unsigned long *tmp;
158 tmp = va_arg(ap, unsigned long *);
159 *bp = (unsigned long) *tmp;
160 bp++;
162 else if (arglen == -sizeof(short))
164 short *tmp;
166 tmp = va_arg(ap, short *);
167 *bp = (unsigned long) *tmp;
168 bp++;
170 else
172 fvwm_msg(
173 ERR, "make_new_vpacket",
174 "can not handle arglen %ld, please contact"
175 " fvwm-workers@fvwm.org. aborting...", arglen);
176 abort();
181 Round up to a long word boundary. Most of the module interface
182 still thinks in terms of an array of longss, so let's humor it.
184 plen = (unsigned long) ((char *)bp - (char *)bp1);
185 plen = ((plen + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
186 *(((unsigned long*)bp1)+2) = (plen / (sizeof(unsigned long)));
188 return plen;
193 void SendPacket(
194 fmodule *module, unsigned long event_type, unsigned long num_datum,
195 ...)
197 unsigned long body[FvwmPacketMaxSize];
198 va_list ap;
200 va_start(ap, num_datum);
201 make_vpacket(body, event_type, num_datum, ap);
202 va_end(ap);
203 PositiveWrite(
204 module, body,
205 (num_datum+FvwmPacketHeaderSize)*sizeof(body[0]));
207 return;
210 void BroadcastPacket(unsigned long event_type, unsigned long num_datum, ...)
212 unsigned long body[FvwmPacketMaxSize];
213 va_list ap;
214 fmodule_list_itr moditr;
215 fmodule *module;
217 va_start(ap,num_datum);
218 make_vpacket(body, event_type, num_datum, ap);
219 va_end(ap);
220 module_list_itr_init(&moditr);
221 while ( (module = module_list_itr_next(&moditr)) != NULL)
223 PositiveWrite(
224 module, body,
225 (num_datum+FvwmPacketHeaderSize)*sizeof(body[0]));
228 return;
233 RBW - 04/16/1999 - new style packet senders for GSFR --
235 static void SendNewPacket(
236 fmodule *module, unsigned long event_type, unsigned long num_datum,
237 ...)
239 unsigned char body[FvwmPacketMaxSize_byte];
240 va_list ap;
241 unsigned long plen;
243 va_start(ap,num_datum);
244 plen = make_new_vpacket(body, event_type, num_datum, ap);
245 va_end(ap);
246 PositiveWrite(module, (void *) &body, plen);
248 return;
251 static void BroadcastNewPacket(unsigned long event_type,
252 unsigned long num_datum, ...)
254 unsigned char body[FvwmPacketMaxSize_byte];
255 va_list ap;
256 fmodule_list_itr moditr;
257 fmodule *module;
258 unsigned long plen;
260 va_start(ap,num_datum);
261 plen = make_new_vpacket(body, event_type, num_datum, ap);
262 va_end(ap);
263 module_list_itr_init(&moditr);
264 while ( (module = module_list_itr_next(&moditr)) != NULL)
266 PositiveWrite(module, (void *) &body, plen);
269 return;
272 action_flags *__get_allowed_actions(const FvwmWindow *fw)
274 static action_flags act;
275 act.is_movable = is_function_allowed(
276 F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False);
277 act.is_deletable = is_function_allowed(
278 F_DELETE, NULL, fw, RQORIG_PROGRAM_US, False);
279 act.is_destroyable = is_function_allowed(
280 F_DESTROY, NULL, fw, RQORIG_PROGRAM_US, False);
281 act.is_closable = is_function_allowed(
282 F_CLOSE, NULL, fw, RQORIG_PROGRAM_US, False);
283 act.is_maximizable = is_function_allowed(
284 F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False);
285 act.is_resizable = is_function_allowed(
286 F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, False);
287 act.is_iconifiable = is_function_allowed(
288 F_ICONIFY, NULL, fw, RQORIG_PROGRAM_US, False);
290 return &act;
294 RBW - 04/16/1999 - new version for GSFR --
295 - args are now pairs:
296 - length of arg data
297 - pointer to arg data
298 - number of arguments is the number of length/pointer pairs.
299 - the 9th field, where flags used to be, is temporarily left
300 as a dummy to preserve alignment of the other fields in the
301 old packet: we should drop this before the next release.
303 #define CONFIGARGS(_fw) 33, \
304 (unsigned long)(-sizeof(Window)), \
305 &FW_W(*(_fw)), \
306 (unsigned long)(-sizeof(Window)), \
307 &FW_W_FRAME(*(_fw)), \
308 (unsigned long)(-sizeof(void *)), \
309 &(_fw), \
310 (unsigned long)(0), \
311 &(*(_fw))->g.frame.x, \
312 (unsigned long)(0), \
313 &(*(_fw))->g.frame.y, \
314 (unsigned long)(0), \
315 &(*(_fw))->g.frame.width, \
316 (unsigned long)(0), \
317 &(*(_fw))->g.frame.height, \
318 (unsigned long)(0), \
319 &(*(_fw))->Desk, \
320 (unsigned long)(0), \
321 &(*(_fw))->layer, \
322 (unsigned long)(0), \
323 &(*(_fw))->hints.base_width, \
324 (unsigned long)(0), \
325 &(*(_fw))->hints.base_height, \
326 (unsigned long)(0), \
327 &(*(_fw))->hints.width_inc, \
328 (unsigned long)(0), \
329 &(*(_fw))->hints.height_inc, \
330 (unsigned long)(0), \
331 &(*(_fw))->orig_hints.width_inc, \
332 (unsigned long)(0), \
333 &(*(_fw))->orig_hints.height_inc, \
334 (unsigned long)(0), \
335 &(*(_fw))->hints.min_width, \
336 (unsigned long)(0), \
337 &(*(_fw))->hints.min_height, \
338 (unsigned long)(0), \
339 &(*(_fw))->hints.max_width, \
340 (unsigned long)(0), \
341 &(*(_fw))->hints.max_height, \
342 (unsigned long)(-sizeof(Window)), \
343 &FW_W_ICON_TITLE(*(_fw)), \
344 (unsigned long)(-sizeof(Window)), \
345 &FW_W_ICON_PIXMAP(*(_fw)), \
346 (unsigned long)(0), \
347 &(*(_fw))->hints.win_gravity, \
348 (unsigned long)(-sizeof(Pixel)), \
349 &(*(_fw))->colors.fore, \
350 (unsigned long)(-sizeof(Pixel)), \
351 &(*(_fw))->colors.back, \
352 (unsigned long)(0), \
353 &(*(_fw))->ewmh_hint_layer, \
354 (unsigned long)(sizeof(unsigned long)), \
355 &(*(_fw))->ewmh_hint_desktop, \
356 (unsigned long)(0), \
357 &(*(_fw))->ewmh_window_type, \
358 (unsigned long)(sizeof(short)), \
359 &(*(_fw))->title_thickness, \
360 (unsigned long)(sizeof(short)), \
361 &(*(_fw))->boundary_width, \
362 (unsigned long)(sizeof(short)), \
363 &dummy, \
364 (unsigned long)(sizeof(short)), \
365 &dummy, \
366 (unsigned long)(sizeof((*(_fw))->flags)), \
367 &(*(_fw))->flags, \
368 (unsigned long)(sizeof(action_flags)), \
369 __get_allowed_actions((*(_fw)))
371 void SendConfig(fmodule *module, unsigned long event_type, const FvwmWindow *t)
373 const FvwmWindow **t1 = &t;
375 /* RBW- SendPacket(module, event_type, CONFIGARGS(t)); */
376 SendNewPacket(module, event_type, CONFIGARGS(t1));
378 return;
381 void BroadcastConfig(unsigned long event_type, const FvwmWindow *t)
383 const FvwmWindow **t1 = &t;
385 /* RBW- BroadcastPacket(event_type, CONFIGARGS(t)); */
386 BroadcastNewPacket(event_type, CONFIGARGS(t1));
388 return;
391 static unsigned long *make_named_packet(
392 int *len, unsigned long event_type, const char *name, int num, ...)
394 unsigned long *body;
395 va_list ap;
397 /* Packet is the header plus the items plus enough items to hold the
398 * name string. */
399 *len = FvwmPacketHeaderSize + num +
400 (strlen(name) / sizeof(unsigned long)) + 1;
401 /* truncate long packets */
402 if (*len > FvwmPacketMaxSize)
404 *len = FvwmPacketMaxSize;
407 body = (unsigned long *)safemalloc(*len * sizeof(unsigned long));
408 /* Zero out end of memory to avoid uninit memory access. */
409 body[*len-1] = 0;
411 va_start(ap, num);
412 make_vpacket(body, event_type, num, ap);
413 va_end(ap);
415 strncpy((char *)&body[FvwmPacketHeaderSize+num], name,
416 (*len - FvwmPacketHeaderSize - num)*sizeof(unsigned long) - 1);
417 body[2] = *len;
419 return (body);
422 void SendName(
423 fmodule *module, unsigned long event_type,
424 unsigned long data1,unsigned long data2, unsigned long data3,
425 const char *name)
427 unsigned long *body;
428 int l;
430 if (name == NULL)
432 return;
434 body = make_named_packet(&l, event_type, name, 3, data1, data2, data3);
435 PositiveWrite(module, body, l*sizeof(unsigned long));
436 free(body);
438 return;
441 void BroadcastName(
442 unsigned long event_type,
443 unsigned long data1, unsigned long data2, unsigned long data3,
444 const char *name)
446 unsigned long *body;
447 int l;
448 fmodule_list_itr moditr;
449 fmodule *module;
451 if (name == NULL)
453 return;
455 body = make_named_packet(&l, event_type, name, 3, data1, data2, data3);
456 module_list_itr_init(&moditr);
457 while ( (module = module_list_itr_next(&moditr)) != NULL)
459 PositiveWrite(module, body, l*sizeof(unsigned long));
461 free(body);
463 return;
466 void BroadcastWindowIconNames(FvwmWindow *fw, Bool window, Bool icon)
468 if (window)
470 BroadcastName(
471 M_WINDOW_NAME, FW_W(fw), FW_W_FRAME(fw),
472 (unsigned long)fw, fw->name.name);
473 BroadcastName(
474 M_VISIBLE_NAME, FW_W(fw), FW_W_FRAME(fw),
475 (unsigned long)fw, fw->visible_name);
477 if (icon)
479 BroadcastName(
480 M_ICON_NAME, FW_W(fw), FW_W_FRAME(fw),
481 (unsigned long)fw, fw->icon_name.name);
482 BroadcastName(
483 MX_VISIBLE_ICON_NAME, FW_W(fw), FW_W_FRAME(fw),
484 (unsigned long)fw, fw->visible_icon_name);
487 return;
490 void SendFvwmPicture(
491 fmodule *module, unsigned long event_type, unsigned long data1,
492 unsigned long data2, unsigned long data3, FvwmPicture *picture,
493 char *name)
495 unsigned long *body;
496 unsigned long
497 data4 = 0, data5 = 0, data6 = 0,
498 data7 = 0, data8 = 0, data9 = 0;
499 int l;
501 if (!FMiniIconsSupported)
503 return;
505 if ((name == NULL) || (event_type != M_MINI_ICON))
507 return;
510 if (picture != NULL)
512 data4 = picture->width;
513 data5 = picture->height;
514 data6 = picture->depth;
515 data7 = picture->picture;
516 data8 = picture->mask;
517 data9 = picture->alpha;
519 body = make_named_packet(
520 &l, event_type, name, 9, data1, data2, data3, data4, data5,
521 data6, data7, data8, data9);
522 PositiveWrite(module, body, l*sizeof(unsigned long));
523 free(body);
525 return;
528 void BroadcastFvwmPicture(
529 unsigned long event_type, unsigned long data1, unsigned long data2,
530 unsigned long data3, FvwmPicture *picture, char *name)
532 unsigned long *body;
533 unsigned long data4, data5, data6, data7, data8, data9;
534 int l;
535 fmodule_list_itr moditr;
536 fmodule *module;
538 if (!FMiniIconsSupported)
540 return;
542 if (picture != NULL)
544 data4 = picture->width;
545 data5 = picture->height;
546 data6 = picture->depth;
547 data7 = picture->picture;
548 data8 = picture->mask;
549 data9 = picture->alpha;
551 else
553 data4 = 0;
554 data5 = 0;
555 data6 = 0;
556 data7 = 0;
557 data8 = 0;
558 data9 = 0;
560 body = make_named_packet(
561 &l, event_type, name, 9, data1, data2, data3, data4, data5,
562 data6, data7, data8, data9);
563 module_list_itr_init(&moditr);
564 while ( (module = module_list_itr_next(&moditr)) != NULL)
566 PositiveWrite(module, body, l*sizeof(unsigned long));
568 free(body);
570 return;
574 * Reads a colorset command from a module and broadcasts it back out
576 void BroadcastColorset(int n)
578 fmodule_list_itr moditr;
579 fmodule *module;
580 char *buf;
582 buf = DumpColorset(n, &Colorset[n]);
583 module_list_itr_init(&moditr);
584 while ( (module = module_list_itr_next(&moditr)) != NULL)
586 SendName(module, M_CONFIG_INFO, 0, 0, 0, buf);
589 return;
593 * Broadcasts a string to all modules as M_CONFIG_INFO.
595 void BroadcastPropertyChange(
596 unsigned long argument, unsigned long data1, unsigned long data2,
597 char *string)
599 fmodule_list_itr moditr;
600 fmodule *module;
602 module_list_itr_init(&moditr);
603 while ( (module = module_list_itr_next(&moditr)) != NULL)
605 SendName(module, MX_PROPERTY_CHANGE, argument,
606 data1, data2, string);
609 return;
613 * Broadcasts a string to all modules as M_CONFIG_INFO.
615 void BroadcastConfigInfoString(char *string)
617 fmodule_list_itr moditr;
618 fmodule *module;
620 module_list_itr_init(&moditr);
621 while ( (module = module_list_itr_next(&moditr)) != NULL)
623 SendName(module, M_CONFIG_INFO, 0, 0, 0, string);
626 return;
631 * Broadcasts the state of Xinerama support to all modules as M_CONFIG_INFO.
633 void broadcast_xinerama_state(void)
635 BroadcastConfigInfoString((char *)FScreenGetConfiguration());
637 return;
642 * Broadcasts the ignored modifiers to all modules as M_CONFIG_INFO.
644 void broadcast_ignore_modifiers(void)
646 char msg[32];
648 sprintf(msg, "IgnoreModifiers %d", GetUnusedModifiers());
649 BroadcastConfigInfoString(msg);
651 return;
654 /* run the input command as if it cames from a button press or release */
655 void module_input_execute(struct fmodule_input *input)
657 XEvent e;
658 const exec_context_t *exc;
659 exec_context_changes_t ecc;
660 int flags;
662 memset(&e, 0, sizeof(e));
663 if (XFindContext(dpy, input->window, FvwmContext,
664 (caddr_t *)&ecc.w.fw) == XCNOENT)
666 ecc.w.fw = NULL;
667 input->window = None;
669 /* Query the pointer, the pager-drag-out feature doesn't work properly.
670 * This is OK now that the Pager uses "Move pointer"
671 * A real fix would be for the modules to pass the button press coords
673 if (FQueryPointer(
674 dpy, Scr.Root, &JunkRoot, &JunkChild, &JunkX,&JunkY,
675 &e.xbutton.x_root, &e.xbutton.y_root, &e.xbutton.state) ==
676 False)
678 /* pointer is not on this screen */
679 /* If a module does XUngrabPointer(), it can now get proper
680 * Popups */
681 e.xbutton.window = Scr.Root;
682 ecc.w.fw = NULL;
684 else
686 e.xbutton.window = input->window;
688 e.xbutton.subwindow = None;
689 e.xbutton.button = 1;
690 /* If a module does XUngrabPointer(), it can now get proper Popups */
691 if (StrEquals(input->command, "popup"))
693 e.xbutton.type = ButtonPress;
694 e.xbutton.state |= Button1Mask;
696 else
698 e.xbutton.type = ButtonRelease;
699 e.xbutton.state &= (~(Button1Mask));
701 e.xbutton.x = 0;
702 e.xbutton.y = 0;
703 fev_fake_event(&e);
704 ecc.type = EXCT_MODULE;
705 ecc.w.w = input->window;
706 flags = (input->window == None) ? 0 : FUNC_DONT_DEFER;
707 ecc.w.wcontext = GetContext(NULL, ecc.w.fw, &e, &(input->window));
708 ecc.x.etrigger = &e;
709 ecc.m.module = input->module;
710 exc = exc_create_context(
711 &ecc, ECC_TYPE | ECC_ETRIGGER | ECC_FW | ECC_W | ECC_WCONTEXT |
712 ECC_MODULE);
713 execute_function(NULL, exc, input->command, 0);
714 exc_destroy_context(exc);
715 module_input_discard(input);
717 return;
720 /* enqueue a module command on the command queue to be executed later */
721 void module_input_enqueue(struct fmodule_input *input)
723 if (input == NULL)
725 return;
728 DBUG("module_input_enqueue", input->command);
729 fqueue_add_at_end(&cqueue, (void*)input);
734 * Procedure:
735 * ExecuteCommandQueue - runs command from the module command queue
736 * This may be called recursively if a module command runs a function
737 * that does a Wait, so it must be re-entrant
741 void ExecuteCommandQueue(void)
743 fmodule_input *input;
745 while (fqueue_get_first(&cqueue, (void **)&input) == 1)
747 /* remove from queue */
748 fqueue_remove_or_operate_from_front(
749 &cqueue, NULL, NULL, NULL, NULL);
750 /* execute and destroy */
751 if (input->command)
753 DBUG("ExecuteCommandQueue", input->command);
754 module_input_execute(input);
756 else
758 module_input_discard(input);
762 return;
766 ** send an arbitrary string to all instances of a module
768 void CMD_SendToModule(F_CMD_ARGS)
770 char *name,*str;
771 unsigned long data0, data1, data2;
772 fmodule_list_itr moditr;
773 fmodule *module;
774 FvwmWindow * const fw = exc->w.fw;
776 /* FIXME: Without this, popup menus can't be implemented properly in
777 * modules. Olivier: Why ? */
778 /* UngrabEm(); */
779 if (!action)
781 return;
783 str = GetNextToken(action, &name);
784 if (!name)
786 return;
789 if (fw)
791 /* Modules may need to know which window this applies to */
792 data0 = FW_W(fw);
793 data1 = FW_W_FRAME(fw);
794 data2 = (unsigned long)fw;
796 else
798 data0 = 0;
799 data1 = 0;
800 data2 = 0;
803 module_list_itr_init(&moditr);
804 while ( (module = module_list_itr_next(&moditr)) != NULL)
806 if (
807 (MOD_NAME(module) != NULL &&
808 matchWildcards(name,MOD_NAME(module))) ||
809 (MOD_ALIAS(module) &&
810 matchWildcards(name, MOD_ALIAS(module))))
812 SendName(module,M_STRING,data0,data1,data2,str);
813 FlushMessageQueue(module);
817 free(name);
819 return;
823 ** send an arbitrary string back to the calling module
825 void CMD_Send_Reply(F_CMD_ARGS)
827 unsigned long data0, data1, data2;
828 fmodule *module = exc->m.module;
829 FvwmWindow * const fw = exc->w.fw;
831 if (module == NULL)
833 return;
836 if (!action)
838 return;
841 if (fw)
843 /* Modules may need to know which window this applies to */
844 data0 = FW_W(fw);
845 data1 = FW_W_FRAME(fw);
846 data2 = (unsigned long)fw;
848 else
850 data0 = 0;
851 data1 = 0;
852 data2 = 0;
854 SendName(module, MX_REPLY, data0, data1, data2, action);
855 FlushMessageQueue(module);
857 return;
860 void CMD_Send_WindowList(F_CMD_ARGS)
862 FvwmWindow *t;
863 fmodule *mod = exc->m.module;
865 if (mod == NULL)
867 return;
869 SendPacket(mod, M_NEW_DESK, 1, (long)Scr.CurrentDesk);
870 SendPacket(
871 mod, M_NEW_PAGE, 7, (long)Scr.Vx, (long)Scr.Vy,
872 (long)Scr.CurrentDesk, (long)Scr.MyDisplayWidth,
873 (long)Scr.MyDisplayHeight,
874 (long)((Scr.VxMax / Scr.MyDisplayWidth) + 1),
875 (long)((Scr.VyMax / Scr.MyDisplayHeight) + 1));
877 if (Scr.Hilite != NULL)
879 SendPacket(
880 mod, M_FOCUS_CHANGE, 5, (long)FW_W(Scr.Hilite),
881 (long)FW_W_FRAME(Scr.Hilite), (unsigned long)True,
882 (long)Scr.Hilite->hicolors.fore,
883 (long)Scr.Hilite->hicolors.back);
885 else
887 SendPacket(
888 mod, M_FOCUS_CHANGE, 5, 0, 0, (unsigned long)True,
889 (long)GetColor(DEFAULT_FORE_COLOR),
890 (long)GetColor(DEFAULT_BACK_COLOR));
892 if (Scr.DefaultIcon != NULL)
894 SendName(mod, M_DEFAULTICON, 0, 0, 0, Scr.DefaultIcon);
897 for (t = Scr.FvwmRoot.next; t != NULL; t = t->next)
899 SendConfig(mod,M_CONFIGURE_WINDOW,t);
900 SendName(
901 mod, M_WINDOW_NAME, FW_W(t), FW_W_FRAME(t),
902 (unsigned long)t, t->name.name);
903 SendName(
904 mod, M_ICON_NAME, FW_W(t), FW_W_FRAME(t),
905 (unsigned long)t, t->icon_name.name);
906 SendName(
907 mod, M_VISIBLE_NAME, FW_W(t), FW_W_FRAME(t),
908 (unsigned long)t, t->visible_name);
909 SendName(
910 mod, MX_VISIBLE_ICON_NAME, FW_W(t), FW_W_FRAME(t),
911 (unsigned long)t,t->visible_icon_name);
912 if (t->icon_bitmap_file != NULL
913 && t->icon_bitmap_file != Scr.DefaultIcon)
915 SendName(
916 mod, M_ICON_FILE, FW_W(t), FW_W_FRAME(t),
917 (unsigned long)t, t->icon_bitmap_file);
920 SendName(
921 mod, M_RES_CLASS, FW_W(t), FW_W_FRAME(t),
922 (unsigned long)t, t->class.res_class);
923 SendName(
924 mod, M_RES_NAME, FW_W(t), FW_W_FRAME(t),
925 (unsigned long)t, t->class.res_name);
927 if (IS_ICONIFIED(t) && !IS_ICON_UNMAPPED(t))
929 rectangle r;
930 Bool rc;
932 rc = get_visible_icon_geometry(t, &r);
933 if (rc == True)
935 SendPacket(
936 mod, M_ICONIFY, 7, (long)FW_W(t),
937 (long)FW_W_FRAME(t), (unsigned long)t,
938 (long)r.x, (long)r.y,
939 (long)r.width, (long)r.height);
942 if ((IS_ICONIFIED(t))&&(IS_ICON_UNMAPPED(t)))
944 SendPacket(
945 mod, M_ICONIFY, 7, (long)FW_W(t),
946 (long)FW_W_FRAME(t), (unsigned long)t,
947 (long)0, (long)0, (long)0, (long)0);
949 if (FMiniIconsSupported && t->mini_icon != NULL)
951 SendFvwmPicture(
952 mod, M_MINI_ICON, FW_W(t), FW_W_FRAME(t),
953 (unsigned long)t, t->mini_icon,
954 t->mini_pixmap_file);
958 if (Scr.Hilite == NULL)
960 BroadcastPacket(
961 M_FOCUS_CHANGE, 5, (long)0, (long)0,
962 (unsigned long)True,
963 (long)GetColor(DEFAULT_FORE_COLOR),
964 (long)GetColor(DEFAULT_BACK_COLOR));
966 else
968 BroadcastPacket(
969 M_FOCUS_CHANGE, 5, (long)FW_W(Scr.Hilite),
970 (long)FW_W(Scr.Hilite), (unsigned long)True,
971 (long)Scr.Hilite->hicolors.fore,
972 (long)Scr.Hilite->hicolors.back);
975 SendPacket(mod, M_END_WINDOWLIST, 0);
977 return;