2 /* FvwmWinList Module for Fvwm.
4 * Copyright 1994, Mike Finger (mfinger@mermaid.micro.umn.edu or
7 * The author makes not guarantees or warantees, either express or
8 * implied. Feel free to use any contained here for any purpose, as long
9 * and this and any other applicible copyrights are kept intact.
11 * The functions in this source file that are based on part of the FvwmIdent
12 * module for Fvwm are noted by a small copyright atop that function, all
13 * others are copyrighted by Mike Finger. For those functions modified/used,
14 * here is the full, origonal copyright:
16 * Copyright 1994, Robert Nation and Nobutaka Suzuki.
17 * No guarantees or warantees or anything
18 * are provided or implied in any way whatsoever. Use this program at your
19 * own risk. Permission to use this program for any purpose is given,
20 * as long as the copyright is kept intact.
22 * Modifications Done to Add Pixmaps, focus highlighting and Current Desk Only
23 * By Don Mahurin, 1996, Some of this Code was taken from FvwmTaskBar
26 /* This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation; either version 2 of the License, or
29 * (at your option) any later version.
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
36 * You should have received a copy of the GNU General Public License
37 * along with this program; if not, write to the Free Software
38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53 #include "libs/ftime.h"
55 #ifdef HAVE_SYS_BSDTYPES_H
56 #include <sys/bsdtypes.h> /* Saul */
59 #include "libs/Module.h"
60 #include "libs/fvwmsignal.h"
61 #include "libs/fvwmlib.h"
62 #include "libs/FScreen.h"
63 #include "libs/FShape.h"
64 #include "libs/FRenderInit.h"
65 #include "libs/Flocale.h"
66 #include "libs/gravity.h"
67 #include "libs/FRender.h"
68 #include "libs/FRenderInterface.h"
69 #include "libs/ColorUtils.h"
70 #include "libs/Graphics.h"
71 #include "libs/Strings.h"
72 #include "libs/System.h"
73 #include "libs/XError.h"
75 #include "FvwmWinList.h"
76 #include "ButtonArray.h"
79 #include "libs/Colorset.h"
81 #define MAX_NO_ICON_ACTION_LENGTH (MAX_MODULE_INPUT_TEXT_LEN - 100)
83 #define GRAB_EVENTS (ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|EnterWindowMask|LeaveWindowMask)
85 #define COMPLEX_WINDOW_PLACEMENT
87 #define SomeButtonDown(a) ((a) & DEFAULT_ALL_BUTTONS_MASK)
89 /* File type information */
91 fd_set_size_t fd_width
;
95 /* X related things */
102 Pixel back
[MAX_COLOUR_SETS
];
103 Pixel fore
[MAX_COLOUR_SETS
];
104 GC graph
[MAX_COLOUR_SETS
];
105 GC shadow
[MAX_COLOUR_SETS
];
106 GC hilite
[MAX_COLOUR_SETS
];
107 GC background
[MAX_COLOUR_SETS
];
109 FlocaleFont
*FButtonFont
;
110 FlocaleWinString
*FwinString
;
113 static Atom wm_del_win
;
116 /* Module related information */
125 #ifdef COMPLEX_WINDOW_PLACEMENT
134 int MinWidth
=DEFMINWIDTH
;
135 int MaxWidth
=DEFMAXWIDTH
;
138 char *ClickAction
[NUMBER_OF_EXTENDED_MOUSE_BUTTONS
] =
145 *BackColor
[MAX_COLOUR_SETS
] = { "white" },
146 *ForeColor
[MAX_COLOUR_SETS
] = { "black" },
148 int colorset
[MAX_COLOUR_SETS
];
149 Pixmap pixmap
[MAX_COLOUR_SETS
];
150 char *font_string
= NULL
;
151 Bool UseSkipList
= False
;
153 Bool UseIconNames
= False
;
154 Bool LeftJustify
= False
;
155 Bool TruncateLeft
= False
;
156 Bool ShowFocus
= True
;
160 long CurrentDesk
= 0;
161 int ShowCurrentDesk
= 0;
165 unsigned is_shaded
: 1;
166 unsigned needs_resize_after_unshade
: 1;
169 rectangle cfg_g
= { 0, 0, 0, 0 }; /* win geometry from M_CONFIGURE_WINDOW */
171 static RETSIGTYPE
TerminateHandler(int sig
);
173 static char *AnimCommand
= NULL
;
176 * TerminateHandler - reentrant signal handler that ends the main event loop
178 static RETSIGTYPE
TerminateHandler(int sig
)
181 * This function might not return - it could "long-jump"
182 * right out, so we need to do everything we need to do
183 * BEFORE we call it ...
185 fvwmSetTerminate(sig
);
189 static void window_shade(unsigned long *body
, int do_shade
)
193 w
= (Window
)(body
[0]);
201 flags
.needs_resize_after_unshade
= 0;
206 if (flags
.needs_resize_after_unshade
)
209 flags
.needs_resize_after_unshade
= 0;
217 Main - Setup the XConnection,request the window list and loop forever
218 Based on main() from FvwmIdent:
219 Copyright 1994, Robert Nation and Nobutaka Suzuki.
221 int main(int argc
, char **argv
)
224 #ifdef HAVE_SIGACTION
225 struct sigaction sigact
;
230 for (i
= 3; i
< NUMBER_OF_EXTENDED_MOUSE_BUTTONS
; i
++)
232 ClickAction
[i
] = "Nop";
235 /* Save the program name for error messages and config parsing */
237 s
=strrchr(argv
[0], '/');
241 /* Open the console for messages */
244 if((argc
!= 6)&&(argc
!= 7)&&(argc
!= 8)) {
245 fprintf(stderr
,"%s Version %s should only be executed by fvwm!\n",temp
,
247 ConsoleMessage("%s Version %s should only be executed by fvwm!\n",temp
,
253 if (argc
== 7 && (strcasecmp(argv
[6],"Transient") == 0 ||
254 strcasecmp(argv
[6],"-Transient") == 0))
260 /* Check for an alias */
261 if (argc
>= opt_num
+ 1 && argv
[opt_num
] != NULL
)
263 Module
= safemalloc(strlen(argv
[opt_num
])+2);
265 strcat(Module
, argv
[opt_num
]);
266 Clength
= strlen(Module
);
270 Module
= safemalloc(strlen(temp
)+2);
272 strcat(Module
, temp
);
273 Clength
= strlen(Module
);
276 FlocaleInit(LC_CTYPE
, "", "", "FvwmWinList");
278 Fvwm_fd
[0] = atoi(argv
[1]);
279 Fvwm_fd
[1] = atoi(argv
[2]);
281 #ifdef HAVE_SIGACTION
283 sigact
.sa_flags
= SA_INTERRUPT
;
287 sigemptyset(&sigact
.sa_mask
);
288 sigaddset(&sigact
.sa_mask
, SIGTERM
);
289 sigaddset(&sigact
.sa_mask
, SIGPIPE
);
290 sigaddset(&sigact
.sa_mask
, SIGINT
);
291 sigact
.sa_handler
= TerminateHandler
;
292 sigaction(SIGPIPE
, &sigact
, NULL
);
293 sigaction(SIGTERM
, &sigact
, NULL
);
294 sigaction(SIGINT
, &sigact
, NULL
);
296 #ifdef USE_BSD_SIGNALS
297 fvwmSetSignalMask( sigmask(SIGPIPE
) |
301 signal(SIGPIPE
, TerminateHandler
);
302 signal(SIGTERM
, TerminateHandler
);
303 signal(SIGINT
, TerminateHandler
);
304 #ifdef HAVE_SIGINTERRUPT
305 siginterrupt(SIGPIPE
, True
);
306 siginterrupt(SIGTERM
, True
);
307 siginterrupt(SIGINT
, True
);
311 /* set default colorsets */
312 colorset
[0] = colorset
[1] = 0;
313 colorset
[2] = colorset
[3] = 1;
315 FlocaleAllocateWinString(&FwinString
);
317 /* Setup the XConnection */
319 /* Parse the config file */
321 /* more initialisations */
323 XSetErrorHandler(ErrorHandler
);
325 InitArray(&buttons
,0,0,win_width
, fontheight
+2, ReliefWidth
);
328 fd_width
= GetFdWidth();
330 /* Request a list of all windows,
331 * wait for ConfigureWindow packets */
332 SetMessageMask(Fvwm_fd
,
334 M_CONFIGURE_WINDOW
| M_ADD_WINDOW
| M_DESTROY_WINDOW
|
335 M_VISIBLE_NAME
| M_DEICONIFY
|
336 M_ICONIFY
| M_END_WINDOWLIST
| M_NEW_DESK
| M_FOCUS_CHANGE
|
337 M_CONFIG_INFO
| M_SENDCONFIG
| M_WINDOWSHADE
|
339 /* extended messages */
340 SetMessageMask(Fvwm_fd
, MX_VISIBLE_ICON_NAME
| MX_PROPERTY_CHANGE
);
342 SendText(Fvwm_fd
, "Send_WindowList",0);
344 /* Recieve all messages from Fvwm */
347 /* tell fvwm we're running */
348 SendFinishedStartupNotification(Fvwm_fd
);
350 /* Lock on send only for iconify and deiconify (for NoIconAction) */
351 SetSyncMask(Fvwm_fd
, M_DEICONIFY
| M_ICONIFY
);
352 SetNoGrabMask(Fvwm_fd
, M_DEICONIFY
| M_ICONIFY
);
360 MainEventLoop - Read and redraw until we die, blocking when can't read
362 void MainEventLoop(void)
366 while( !isTerminated
) {
368 FD_SET(Fvwm_fd
[1],&readset
);
369 FD_SET(x_fd
,&readset
);
371 /* This code restyled after FvwmIconMan, which is simpler.
372 * The biggest advantage over the original approach is
373 * having one fewer select statements
376 if (fvwmSelect(fd_width
, &readset
, NULL
, NULL
, NULL
) > 0) {
378 if (FD_ISSET(x_fd
,&readset
) || FPending(dpy
)) LoopOnEvents();
379 if (FD_ISSET(Fvwm_fd
[1],&readset
)) ReadFvwmPipe();
387 ReadFvwmPipe - Read a single message from the pipe from Fvwm
388 Originally Loop() from FvwmIdent:
389 Copyright 1994, Robert Nation and Nobutaka Suzuki.
391 void ReadFvwmPipe(void)
393 FvwmPacket
* packet
= ReadFvwmPacket(Fvwm_fd
[1]);
394 if ( packet
== NULL
)
397 ProcessMessage( packet
->type
, packet
->body
);
401 ProcessMessage - Process the message coming from Fvwm
402 Skeleton based on processmessage() from FvwmIdent:
403 Copyright 1994, Robert Nation and Nobutaka Suzuki.
405 void ProcessMessage(unsigned long type
,unsigned long *body
)
410 static int current_focus
=-1;
411 struct ConfigWinPacket
*cfgpacket
;
417 case M_CONFIGURE_WINDOW
:
418 cfgpacket
= (void *) body
;
419 /* We get the win_borders only when WinList map it self, this is ok
420 * since we need it only after an unmap */
421 if (cfgpacket
->w
== win
)
423 cfg_g
.x
= cfgpacket
->frame_x
;
424 cfg_g
.y
= cfgpacket
->frame_y
;
425 cfg_g
.width
= cfgpacket
->frame_width
;
426 cfg_g
.height
= cfgpacket
->frame_height
;
427 #ifdef COMPLEX_WINDOW_PLACEMENT
428 win_border_x
= win_border_y
= cfgpacket
->border_width
;
429 if (((win_grav
== NorthWestGravity
|| win_grav
== NorthEastGravity
)
430 && HAS_TITLE_DIR(cfgpacket
, DIR_N
)) ||
431 ((win_grav
== SouthWestGravity
|| win_grav
== SouthEastGravity
)
432 && HAS_TITLE_DIR(cfgpacket
, DIR_S
)))
434 win_border_y
+= cfgpacket
->title_height
;
436 if (((win_grav
== NorthWestGravity
|| win_grav
== SouthWestGravity
)
437 && HAS_TITLE_DIR(cfgpacket
, DIR_W
)) ||
438 ((win_grav
== NorthEastGravity
|| win_grav
== SouthEastGravity
)
439 && HAS_TITLE_DIR(cfgpacket
, DIR_E
)))
441 win_border_x
+= cfgpacket
->title_height
;
445 if ((i
= FindItem(&windows
,cfgpacket
->w
))!=-1)
447 flagitem
=ItemFlags(&windows
,cfgpacket
->w
);
448 if(UpdateItemDesk(&windows
, cfgpacket
) > 0 ||
449 IS_STICKY_ACROSS_DESKS(cfgpacket
) !=
450 IS_STICKY_ACROSS_DESKS(flagitem
) ||
451 DO_SKIP_WINDOW_LIST(cfgpacket
) != DO_SKIP_WINDOW_LIST(flagitem
))
453 UpdateItemGSFRFlags(&windows
, cfgpacket
);
454 UpdateButtonDeskFlags(&buttons
, i
, cfgpacket
->desk
,
455 IS_STICKY_ACROSS_DESKS(cfgpacket
),
456 DO_SKIP_WINDOW_LIST(cfgpacket
));
458 RedrawWindow(True
, True
, NULL
);
461 UpdateItemGSFRFlags(&windows
, cfgpacket
);
466 AddItem(&windows
, cfgpacket
);
467 /* Make sure the lists are synced in order
468 If windows are created during a Send_WindowList strange things might happen
470 AddButton(&buttons
, NULL
, NULL
, 1);
471 i
= FindItem(&windows
,cfgpacket
->w
);
472 UpdateButtonDeskFlags(&buttons
, i
, cfgpacket
->desk
,
473 IS_STICKY_ACROSS_DESKS(cfgpacket
),
474 DO_SKIP_WINDOW_LIST(cfgpacket
));
477 case M_DESTROY_WINDOW
:
478 cfgpacket
= (void *) body
;
479 if ((i
=DeleteItem(&windows
,cfgpacket
->w
))==-1) break;
480 RemoveButton(&buttons
,i
);
487 if (!FMiniIconsSupported
|| (i
=FindItem(&windows
,body
[0]))==-1)
489 if (UpdateButton(&buttons
,i
,NULL
,-1)!=-1)
491 MiniIconPacket
*mip
= (MiniIconPacket
*) body
;
492 p
.picture
= mip
->picture
;
494 p
.alpha
= mip
->alpha
;
495 p
.width
= mip
->width
;
496 p
.height
= mip
->height
;
497 p
.depth
= mip
->depth
;
499 UpdateButtonPicture(&buttons
, i
, &p
);
507 case MX_VISIBLE_ICON_NAME
:
508 if ((type
== MX_VISIBLE_ICON_NAME
) ^ UseIconNames
)
510 string
=(char *)&body
[3];
511 if ((i
=UpdateItemName(&windows
,body
[0],string
))==-1) break;
512 flagitem
= ItemFlags(&windows
,body
[0]);
513 name
=makename(string
, (IS_ICONIFIED(flagitem
)?True
:False
));
515 if (UpdateButton(&buttons
,i
,name
,-1)==-1)
517 AddButton(&buttons
, name
, NULL
, 1);
518 UpdateButtonSet(&buttons
, i
, (IS_ICONIFIED(flagitem
)?1:0));
519 UpdateButtonDeskFlags(&buttons
,i
,ItemDesk(&windows
, body
[0]),
520 IS_STICKY_ACROSS_DESKS(flagitem
),
521 DO_SKIP_WINDOW_LIST(flagitem
));
524 if (WindowState
) AdjustWindow(False
);
529 /* fwvm will wait for an Unlock message before continuing
530 * be careful when changing this construct, make sure unlock happens */
531 if ((i
= FindItem(&windows
, body
[0])) != -1)
533 flagitem
= ItemFlags(&windows
, body
[0]);
534 if ((type
== M_DEICONIFY
&& IS_ICONIFIED(flagitem
))
535 || (type
== M_ICONIFY
&& !IS_ICONIFIED(flagitem
)))
537 if (IS_ICON_SUPPRESSED(flagitem
) && IsItemIndexVisible(&windows
,i
)
538 && AnimCommand
&& WindowState
&& AnimCommand
[0] != 0)
540 char buff
[MAX_MODULE_INPUT_TEXT_LEN
];
544 /* find out where our button is */
545 j
= FindItemVisible(&windows
, body
[0]);
546 XTranslateCoordinates(
547 dpy
, win
, Root
, 0, j
* buttonheight
, &x
, &y
, &child
);
552 if (w
> cfg_g
.width
- win_border_x
)
556 if (h
> cfg_g
.height
- win_border_y
)
560 if (x
< cfg_g
.x
|| x
> cfg_g
.x
+ cfg_g
.width
)
562 x
= cfg_g
.x
+ win_border_x
;
564 if (y
< cfg_g
.y
|| y
> cfg_g
.y
+ cfg_g
.height
)
566 y
= cfg_g
.y
+ win_border_y
;
570 /* tell FvwmAnimate to animate to our button */
571 if (IS_ICONIFIED(flagitem
)) {
572 sprintf(buff
, "%s %d %d %d %d %d %d %d %d", AnimCommand
,
573 x
, y
, w
, h
, (int)body
[7], (int)body
[8],
574 (int)body
[9], (int)body
[10]);
576 sprintf(buff
, "%s %d %d %d %d %d %d %d %d",
577 AnimCommand
, (int)body
[7], (int)body
[8],
578 (int)body
[9], (int)body
[10],
581 SendText(Fvwm_fd
, buff
, 0);
583 SET_ICONIFIED(flagitem
, !IS_ICONIFIED(flagitem
));
584 string
= ItemName(&windows
, i
);
585 name
= makename(string
, IS_ICONIFIED(flagitem
));
586 UpdateButtonIconified(&buttons
, i
, IS_ICONIFIED(flagitem
));
587 if (UpdateButton(&buttons
, i
, name
, -1) != -1) redraw
= 1;
588 if (i
!= current_focus
|| (IS_ICONIFIED(flagitem
)))
589 if (UpdateButtonSet(&buttons
, i
, (IS_ICONIFIED(flagitem
)) ? 1 : 0)
595 SendUnlockNotification(Fvwm_fd
);
599 if ((i
=FindItem(&windows
,body
[0]))!=-1)
601 RadioButton(&buttons
,i
,ButPressed
);
602 if (Follow
&& i
) { /* rearrange order */
603 ReorderList(&windows
,i
,body
[2]);
604 if (WindowState
) ReorderButtons(&buttons
,i
,body
[2]);
608 RadioButton(&buttons
,-1,ButPressed
);
610 case M_END_WINDOWLIST
:
616 CurrentDesk
= body
[0];
620 RedrawWindow(True
, True
, NULL
);
624 window_shade(body
, 1);
626 case M_DEWINDOWSHADE
:
627 window_shade(body
, 0);
629 case MX_PROPERTY_CHANGE
:
630 if (body
[0] == MX_PROPERTY_CHANGE_BACKGROUND
&& body
[2] == 0 &&
631 WindowState
&& win_bg
== ParentRelative
)
633 RedrawWindow(True
, True
, NULL
);
637 ParseConfigLine((char *)&body
[3]);
641 if (redraw
&& WindowState
==1) RedrawWindow(False
, True
, NULL
);
646 RedrawWindow - Update the needed lines and erase any old ones
648 void RedrawWindow(Bool force
, Bool clear_bg
, XEvent
*evp
)
650 DrawButtonArray(&buttons
, force
, clear_bg
, evp
);
651 XFlush(dpy
); /** Put here for VMS; ifdef if causes performance problem **/
652 if (FQLength(dpy
) && !force
) LoopOnEvents();
656 ConsoleMessage - Print a message on the console. Works like printf.
658 void ConsoleMessage(const char *fmt
, ...)
664 if (console
==NULL
) filep
=stderr
;
667 vfprintf(filep
,fmt
,args
);
673 OpenConsole - Open the console as a way of sending messages
675 int OpenConsole(void)
678 if ((console
=fopen("/dev/console","w"))==NULL
) {
679 fprintf(stderr
,"%s: cannot open console\n",Module
);
687 ParseConfig - Parse the configuration file fvwm to us to use
688 Based on part of main() from FvwmIdent:
689 Copyright 1994, Robert Nation and Nobutaka Suzuki.
691 void ParseConfig(void)
695 InitGetConfigLine(Fvwm_fd
,Module
);
696 GetConfigLine(Fvwm_fd
,&tline
);
697 while(tline
!= (char *)0)
699 ParseConfigLine(tline
);
700 GetConfigLine(Fvwm_fd
,&tline
);
705 ParseConfigLine(char *tline
)
707 static Bool has_icon_back
= False
;
708 static Bool has_icon_fore
= False
;
709 static Bool has_icon_cset
= False
;
714 if (strlen(tline
) > 1) {
715 if (strncasecmp(tline
, CatString3(Module
, "Font", ""), Clength
+ 4) == 0)
716 CopyStringWithQuotes(&font_string
, &tline
[Clength
+ 4]);
717 else if (strncasecmp(tline
, CatString3(Module
, "Fore", ""), Clength
+ 4)
719 CopyString(&ForeColor
[0], &tline
[Clength
+ 4]);
724 CopyString(&ForeColor
[1], &tline
[Clength
+ 4]);
725 } else if (strncasecmp(tline
, CatString3(Module
, "IconFore", ""),
727 CopyString(&ForeColor
[1], &tline
[Clength
+ 8]);
728 if (colorset
[0] >= 0)
729 colorset
[1] = colorset
[0];
732 has_icon_fore
= True
;
733 has_icon_cset
= False
;
734 } else if (strncasecmp(tline
, CatString3(Module
, "FocusFore", ""),
736 CopyString(&ForeColor
[2], &tline
[Clength
+ 9]);
737 CopyString(&ForeColor
[3], &tline
[Clength
+ 9]);
738 colorset
[2] = colorset
[3] = -1;
739 } else if (strncasecmp(tline
, CatString3(Module
, "Geometry", ""),
741 CopyString(&geometry
, &tline
[Clength
+ 8]);
742 else if (strncasecmp(tline
, CatString3(Module
, "Back", ""), Clength
+ 4)
744 CopyString(&BackColor
[0], &tline
[Clength
+ 4]);
749 CopyString(&BackColor
[1], &tline
[Clength
+ 4]);
750 } else if (strncasecmp(tline
, CatString3(Module
, "IconBack", ""),
752 CopyString(&BackColor
[1], &tline
[Clength
+ 8]);
753 if (colorset
[0] >= 0)
754 colorset
[1] = colorset
[0];
757 has_icon_fore
= True
;
758 has_icon_cset
= False
;
759 } else if (strncasecmp(tline
, CatString3(Module
, "FocusBack", ""),
761 CopyString(&BackColor
[2], &tline
[Clength
+ 9]);
762 CopyString(&BackColor
[3], &tline
[Clength
+ 9]);
763 colorset
[2] = colorset
[3] = -1;
764 } else if (strncasecmp(tline
, CatString3(Module
, "NoAnchor", ""),
767 else if (strncasecmp(tline
, CatString3(Module
, "Action", ""), Clength
+ 6)
769 LinkAction(&tline
[Clength
+ 6]);
770 else if (strncasecmp(tline
, CatString3(Module
, "UseSkipList", ""),
773 else if (strncasecmp(tline
, CatString3(Module
, "UseIconNames", ""),
776 else if (strncasecmp(tline
, CatString3(Module
, "ShowCurrentDesk", ""),
779 else if (strncasecmp(tline
, CatString3(Module
, "LeftJustify", ""),
782 else if (strncasecmp(tline
, CatString3(Module
, "TruncateLeft", ""),
785 else if (strncasecmp(tline
, CatString3(Module
, "MinWidth", ""),
787 MinWidth
= atoi(&tline
[Clength
+ 8]);
788 else if (strncasecmp(tline
, CatString3(Module
, "MaxWidth", ""),
790 MaxWidth
= atoi(&tline
[Clength
+ 8]);
791 else if (strncasecmp(tline
, CatString3(Module
, "DontDepressFocus", ""),
794 else if (strncasecmp(tline
, CatString3(Module
, "FollowWindowList", ""),
797 else if (strncasecmp(tline
, CatString3(Module
, "ButtonFrameWidth", ""),
798 Clength
+ 16) == 0) {
799 ReliefWidth
= atoi(&tline
[Clength
+ 16]);
800 buttonheight
= fontheight
+ 3 + 2 * ReliefWidth
;
801 } else if (strncasecmp(tline
, CatString3(Module
, "NoIconAction", ""),
802 Clength
+ 12) == 0) {
803 CopyString(&AnimCommand
, &tline
[Clength
+ 12]);
804 if (strlen(AnimCommand
) > MAX_NO_ICON_ACTION_LENGTH
)
805 AnimCommand
[MAX_NO_ICON_ACTION_LENGTH
] = 0;
806 } else if (strncasecmp(tline
, CatString3(Module
, "Colorset", ""),
808 colorset
[0] = atoi(&tline
[Clength
+ 8]);
809 AllocColorset(colorset
[0]);
810 } else if (strncasecmp(tline
, CatString3(Module
, "IconColorset", ""),
813 colorset
[1] = atoi(&tline
[Clength
+ 12]);
814 AllocColorset(colorset
[1]);
815 has_icon_cset
= True
;
817 else if (strncasecmp(tline
, CatString3(Module
, "FocusColorset", ""),
820 colorset
[2] = colorset
[3] = atoi(&tline
[Clength
+ 13]);
821 AllocColorset(colorset
[3]);
822 has_icon_cset
= True
;
824 else if (strncasecmp(tline
, "Colorset", 8) == 0) {
825 int cset
= LoadColorset(&tline
[8]);
827 if (WindowState
&& (cset
>= 0)) {
829 Pixmap old_win_bg
= win_bg
;
831 /* set the window background */
833 for (i
= 0; i
!= MAX_COLOUR_SETS
; i
++)
835 if (CSET_IS_TRANSPARENT_PR(colorset
[i
]))
836 win_bg
= ParentRelative
;
838 if (old_win_bg
!= win_bg
)
839 XSetWindowBackgroundPixmap(dpy
, win
, win_bg
);
840 /* refresh if this colorset is used */
841 for (i
= 0; i
!= MAX_COLOUR_SETS
; i
++) {
842 if (colorset
[i
] == cset
) {
844 RedrawWindow(True
, True
, NULL
);
850 else if (strncasecmp(tline
, XINERAMA_CONFIG_STRING
,
851 sizeof(XINERAMA_CONFIG_STRING
) - 1) == 0) {
852 FScreenConfigureModule(
853 tline
+ sizeof(XINERAMA_CONFIG_STRING
) - 1);
860 LoopOnEvents - Process all the X events we get
862 void LoopOnEvents(void)
868 Window dummyroot
,dummychild
;
869 int x
,xdummy
,y
,ydummy
;
872 if (Transient
&& !Checked
)
877 dpy
, win
, &dummyroot
, &dummychild
, &xdummy
, &ydummy
, &x
, &y
,
880 /* pointer is on a different screen - that's okay here */
882 num
=WhichButton(&buttons
,x
,y
);
887 UpdateButton(&buttons
, num
, NULL
, 0);
900 FNextEvent(dpy
,&Event
);
907 num
=WhichButton(&buttons
,Event
.xbutton
.x
,Event
.xbutton
.y
);
908 if (num
!=-1 && Event
.xbutton
.button
>= 1 &&
909 Event
.xbutton
.button
<= NUMBER_OF_EXTENDED_MOUSE_BUTTONS
)
911 SendFvwmPipe(Fvwm_fd
,
912 ClickAction
[Event
.xbutton
.button
-1],
913 ItemID(&windows
,num
));
914 SwitchButton(&buttons
,num
);
925 num
=WhichButton(&buttons
,Event
.xbutton
.x
,Event
.xbutton
.y
);
928 SwitchButton(&buttons
,num
);
930 } else ButPressed
=-1;
935 int ex
= Event
.xexpose
.x
;
936 int ey
= Event
.xexpose
.y
;
937 int ex2
= Event
.xexpose
.x
+ Event
.xexpose
.width
;
938 int ey2
= Event
.xexpose
.y
+ Event
.xexpose
.height
;
939 while (FCheckTypedWindowEvent(dpy
, win
, Expose
, &Event
))
941 ex
= min(ex
, Event
.xexpose
.x
);
942 ey
= min(ey
, Event
.xexpose
.y
);
943 ex2
= max(ex2
, Event
.xexpose
.x
+ Event
.xexpose
.width
);
944 ey2
= max(ey2
, Event
.xexpose
.y
+ Event
.xexpose
.height
);
946 Event
.xexpose
.x
= ex
;
947 Event
.xexpose
.y
= ey
;
948 Event
.xexpose
.width
= ex2
- ex
;
949 Event
.xexpose
.height
= ey2
- ey
;
950 RedrawWindow(True
, True
, &Event
);
953 case ConfigureNotify
:
957 /* Opaque moves cause lots of these to be sent which causes flickering
958 * It's better to miss out on intermediate steps than to do them all
959 * and take too long. Look down the event queue and do the last one */
960 while (FCheckTypedWindowEvent(dpy
, win
, ConfigureNotify
, &event
))
962 /* if send_event is true it means the user has moved the window or
963 * winlist has mapped itself, take note of the new position.
964 * If it is false it comes from the Xserver and is bogus */
965 if (!event
.xconfigure
.send_event
)
967 Event
.xconfigure
.x
= event
.xconfigure
.x
;
968 Event
.xconfigure
.y
= event
.xconfigure
.y
;
969 Event
.xconfigure
.send_event
= True
;
971 if (Event
.xconfigure
.send_event
&&
972 (win_x
!= Event
.xconfigure
.x
||
973 win_y
!= Event
.xconfigure
.y
|| win_bg
== ParentRelative
))
975 win_x
= Event
.xconfigure
.x
;
976 win_y
= Event
.xconfigure
.y
;
977 DrawTransparentButtonArray(&buttons
);
982 num
=XLookupString(&Event
.xkey
,buffer
,10,NULL
,0);
985 if (buffer
[0]=='q' || buffer
[0]=='Q') exit(0);
986 else if (buffer
[0]=='i' || buffer
[0]=='I') PrintList(&windows
);
987 else if (buffer
[0]=='b' || buffer
[0]=='B') PrintButtons(&buttons
);
991 if ((Event
.xclient
.format
==32) && (Event
.xclient
.data
.l
[0]==wm_del_win
))
994 if (!SomeButtonDown(Event
.xcrossing
.state
)) break;
995 num
=WhichButton(&buttons
,Event
.xcrossing
.x
,Event
.xcrossing
.y
);
998 SwitchButton(&buttons
,num
);
1000 } else ButPressed
=-1;
1004 if (!SomeButtonDown(Event
.xcrossing
.state
)) break;
1005 if (ButPressed
!=-1) SwitchButton(&buttons
,ButPressed
);
1009 if (!Pressed
) break;
1010 num
=WhichButton(&buttons
,Event
.xmotion
.x
,Event
.xmotion
.y
);
1011 if (num
==ButPressed
) break;
1012 if (ButPressed
!=-1) SwitchButton(&buttons
,ButPressed
);
1015 SwitchButton(&buttons
,num
);
1027 AdjustWindow - Resize the window according to maxwidth by number of buttons
1029 void AdjustWindow(Bool force
)
1031 int new_width
=0,new_height
=0,tw
,i
,total
,all
;
1035 total
= ItemCountVisible(&windows
);
1036 all
= ItemCount(&windows
);
1041 XUnmapWindow(dpy
,win
);
1047 if (FMiniIconsSupported
)
1049 for(i
=0; i
<all
; i
++)
1051 if (IsButtonIndexVisible(&buttons
,i
) &&
1052 ButtonPicture(&buttons
,i
)->picture
!= None
)
1054 if (ButtonPicture(&buttons
,i
)->width
> base_miw
)
1055 base_miw
= ButtonPicture(&buttons
,i
)->width
;
1063 temp
=ItemName(&windows
,i
);
1064 if(temp
!= NULL
&& IsItemIndexVisible(&windows
,i
))
1066 tw
= 8 + FlocaleTextWidth(FButtonFont
,temp
,strlen(temp
));
1067 tw
+= FlocaleTextWidth(FButtonFont
,"()",2);
1068 if (FMiniIconsSupported
)
1072 new_width
=max(new_width
,tw
);
1075 new_width
=max(new_width
, MinWidth
);
1076 new_width
=min(new_width
, MaxWidth
);
1077 new_height
=(total
* buttonheight
);
1079 if (WindowState
&& force
) {
1080 for (i
= 0; i
!= MAX_COLOUR_SETS
; i
++) {
1081 int cset
= colorset
[i
];
1084 fore
[i
] = Colorset
[cset
].fg
;
1085 back
[i
] = Colorset
[cset
].bg
;
1086 XSetForeground(dpy
, graph
[i
], fore
[i
]);
1087 XSetForeground(dpy
, background
[i
], back
[i
]);
1088 XSetForeground(dpy
, hilite
[i
], Colorset
[cset
].hilite
);
1089 XSetForeground(dpy
, shadow
[i
], Colorset
[cset
].shadow
);
1093 /* change the pixmap if forced or if width changed (the height is fixed) */
1094 if (WindowState
&& (force
|| new_width
!= win_width
)) {
1095 for (i
= 0; i
!= MAX_COLOUR_SETS
; i
++) {
1096 int cset
= colorset
[i
];
1100 XFreePixmap(dpy
, pixmap
[i
]);
1101 if (Colorset
[cset
].pixmap
&& !CSET_IS_TRANSPARENT_PR(cset
)) {
1102 if (CSET_IS_TRANSPARENT_ROOT(cset
))
1104 pixmap
[i
] = CreateBackgroundPixmap(
1105 dpy
, win
, new_width
, win_height
,
1106 &Colorset
[cset
], Pdepth
,
1107 background
[i
], False
);
1111 pixmap
[i
] = CreateBackgroundPixmap(
1112 dpy
, win
, win_width
, buttonheight
,
1113 &Colorset
[cset
], Pdepth
,
1114 background
[i
], False
);
1116 XSetTile(dpy
, background
[i
], pixmap
[i
]);
1117 XSetFillStyle(dpy
, background
[i
], FillTiled
);
1120 XSetFillStyle(dpy
, background
[i
], FillSolid
);
1126 (new_height
!=win_height
|| new_width
!=win_width
||
1127 (!flags
.is_shaded
&& flags
.needs_resize_after_unshade
)))
1129 #ifdef COMPLEX_WINDOW_PLACEMENT
1132 /* compensate for fvwm borders when going from unmapped to mapped */
1133 int map_x_adjust
= (WindowState
- 1) * win_border_x
;
1134 int map_y_adjust
= (WindowState
- 1) * win_border_y
;
1137 case NorthWestGravity
:
1138 case SouthWestGravity
:
1139 win_x
-= map_x_adjust
;
1141 case NorthEastGravity
:
1142 case SouthEastGravity
:
1143 win_x
+= win_width
- new_width
+ map_x_adjust
;
1148 case NorthWestGravity
:
1149 case NorthEastGravity
:
1150 win_y
-= map_y_adjust
;
1152 case SouthEastGravity
:
1153 case SouthWestGravity
:
1154 win_y
+= win_height
- new_height
+ map_y_adjust
;
1157 /* XMoveResizeWindow(dpy, win, win_x, win_y, new_width, new_height); */
1159 if (flags
.is_shaded
)
1160 flags
.needs_resize_after_unshade
= 1;
1161 else if (Anchor
&& WindowState
== 2)
1162 XMoveResizeWindow(dpy
, win
, win_x
, win_y
, new_width
, new_height
);
1164 XResizeWindow(dpy
, win
, new_width
, new_height
);
1165 /* The new code is sooo much simpler :-) */
1167 if (flags
.is_shaded
)
1168 flags
.needs_resize_after_unshade
= 1;
1170 /* This relies on fvwm honouring South/East gemoetry when resizing. */
1171 XResizeWindow(dpy
, win
, new_width
, new_height
);
1174 UpdateArray(&buttons
,new_width
);
1175 if (new_height
>0) win_height
= new_height
;
1176 if (new_width
>0) win_width
= new_width
;
1179 XMapWindow(dpy
,win
);
1185 makename - Based on the flags return me '(name)' or 'name'
1187 char *makename(const char *string
, Bool iconified
)
1192 return safestrdup(string
);
1193 ptr
=safemalloc(strlen(string
)+3);
1194 sprintf(ptr
, "(%s)", string
);
1199 LinkAction - Link an response to a users action
1201 void LinkAction(char *string
)
1205 while(isspace((unsigned char)*temp
))
1207 if(strncasecmp(temp
, "Click", 5)==0)
1213 i
= sscanf(temp
+ 5, "%d%n", &b
, &n
);
1214 if (i
> 0 && b
>=1 && b
<= NUMBER_OF_EXTENDED_MOUSE_BUTTONS
)
1216 CopyString(&ClickAction
[b
- 1], temp
+ 5 + n
);
1219 else if(strncasecmp(temp
, "Enter", 5)==0)
1220 CopyString(&EnterAction
,&temp
[5]);
1224 MakeMeWindow - Create and setup the window we will need
1226 void MakeMeWindow(void)
1229 XClassHint classhints
;
1231 unsigned long gcmask
;
1232 unsigned int dummy1
, dummy2
;
1233 int x
, y
, ret
, count
;
1236 Window dummyroot
, dummychild
;
1238 XSetWindowAttributes attr
;
1240 if ((count
= ItemCountVisible(&windows
))==0 && Transient
)
1244 AdjustWindow(False
);
1246 hints
.width
=win_width
;
1247 hints
.height
=win_height
;
1248 hints
.win_gravity
=NorthWestGravity
;
1249 hints
.flags
=PSize
|PWinGravity
;
1253 fscreen_scr_arg fscr
;
1256 dpy
, Root
, &dummyroot
, &dummychild
, &wx
, &wy
, &x
, &y
,
1259 /* pointer is on a different screen */
1266 &fscr
, FSCREEN_XYPOS
,
1267 &screen_g
.x
, &screen_g
.y
, &screen_g
.width
, &screen_g
.height
);
1268 wx
-= hints
.width
/ 2;
1269 wy
-= buttonheight
/ 2;
1270 if (wx
+ hints
.width
> screen_g
.x
+ screen_g
.width
)
1272 wx
= screen_g
.x
+ screen_g
.width
- hints
.width
;
1274 if (wx
< screen_g
.x
)
1278 if (wy
+ hints
.height
> screen_g
.y
+ screen_g
.height
)
1280 wy
= screen_g
.y
+ screen_g
.height
- hints
.height
;
1282 if (wy
< screen_g
.y
)
1286 hints
.win_gravity
= NorthWestGravity
;
1287 hints
.flags
|= USPosition
;
1289 else if (geometry
!= NULL
)
1291 /* now evaluate the geometry parsed above */
1292 ret
= FScreenParseGeometry(geometry
, &x
, &y
, &dummy1
, &dummy2
);
1293 hints
.win_gravity
=NorthWestGravity
;
1294 if ((ret
& XValue
) && (ret
& YValue
))
1298 if (ret
& XNegative
)
1300 wx
+= XDisplayWidth(dpy
,screen
) - win_width
;
1301 hints
.win_gravity
=NorthEastGravity
;
1303 if (ret
& YNegative
)
1305 wy
+= XDisplayHeight(dpy
,screen
) - win_height
;
1306 if (ret
& XNegative
)
1308 hints
.win_gravity
=SouthEastGravity
;
1312 hints
.win_gravity
=SouthWestGravity
;
1315 hints
.flags
|= USPosition
;
1318 #ifndef COMPLEX_WINDOW_PLACEMENT
1321 if (hints
.win_gravity
== SouthWestGravity
)
1322 hints
.win_gravity
=NorthWestGravity
;
1323 else if (hints
.win_gravity
== SouthEastGravity
)
1324 hints
.win_gravity
=NorthEastGravity
;
1331 win_grav
= hints
.win_gravity
;
1334 for (i
= 0; i
!= MAX_COLOUR_SETS
; i
++)
1337 back
[i
] = GetColor("white");
1338 fore
[i
] = GetColor("black");
1342 if (colorset
[i
] >= 0) {
1343 back
[i
] = Colorset
[colorset
[i
]].bg
;
1344 fore
[i
] = Colorset
[colorset
[i
]].fg
;
1346 back
[i
] = GetColor(BackColor
[i
] == NULL
? BackColor
[0] : BackColor
[i
]);
1347 fore
[i
] = GetColor(ForeColor
[i
] == NULL
? ForeColor
[0] : ForeColor
[i
]);
1351 /* FvwmWinList paints the entire window and does not rely on the xserver to
1352 * render the background. Setting the background_pixmap to None prevents the
1353 * server from doing anything on expose events. The exception is when one of
1354 * the colorsets is transparent which requires help from the server */
1356 for (i
= 0; i
!= MAX_COLOUR_SETS
; i
++)
1358 if (CSET_IS_TRANSPARENT_PR(colorset
[i
]))
1360 win_bg
= ParentRelative
;
1364 attr
.background_pixmap
= win_bg
;
1365 attr
.border_pixel
= 0;
1366 attr
.colormap
= Pcmap
;
1367 win
=XCreateWindow(dpy
, Root
, wx
, wy
, hints
.width
, hints
.height
, 0,
1368 Pdepth
, InputOutput
, Pvisual
,
1369 CWBackPixmap
| CWBorderPixel
| CWColormap
, &attr
);
1372 XSetTransientForHint(dpy
, win
, Root
);
1375 wm_del_win
=XInternAtom(dpy
,"WM_DELETE_WINDOW",False
);
1376 XSetWMProtocols(dpy
,win
,&wm_del_win
,1);
1378 FwinString
->win
= win
;
1381 XTextProperty nametext
;
1382 char *list
[]={NULL
,NULL
};
1385 classhints
.res_name
=safestrdup(Module
+1);
1386 classhints
.res_class
=safestrdup("FvwmWinList");
1388 if(!XStringListToTextProperty(list
,1,&nametext
))
1390 fprintf(stderr
,"%s: Failed to convert name to XText\n",Module
);
1393 XSetWMProperties(dpy
,win
,&nametext
,&nametext
,
1394 NULL
,0,&hints
,NULL
,&classhints
);
1395 XFree(nametext
.value
);
1400 XGrabButton(dpy
,1,AnyModifier
,win
,True
,GRAB_EVENTS
,GrabModeAsync
,
1401 GrabModeAsync
,None
,None
);
1402 XGrabButton(dpy
,2,AnyModifier
,win
,True
,GRAB_EVENTS
,GrabModeAsync
,
1403 GrabModeAsync
,None
,None
);
1404 XGrabButton(dpy
,3,AnyModifier
,win
,True
,GRAB_EVENTS
,GrabModeAsync
,
1405 GrabModeAsync
,None
,None
);
1407 MWM_DECOR_ALL
|MWM_DECOR_RESIZEH
|MWM_DECOR_MAXIMIZE
|MWM_DECOR_MINIMIZE
,
1408 MWM_FUNC_ALL
|MWM_FUNC_RESIZE
|MWM_FUNC_MAXIMIZE
|MWM_FUNC_MINIMIZE
,
1409 MWM_INPUT_MODELESS
);
1413 SetMwmHints(0,MWM_FUNC_ALL
,MWM_INPUT_MODELESS
);
1416 for (i
= 0; i
!= MAX_COLOUR_SETS
; i
++)
1418 gcval
.foreground
=fore
[i
];
1419 gcval
.background
=back
[i
];
1420 gcmask
=GCForeground
|GCBackground
;
1421 if (FButtonFont
->font
!= NULL
)
1423 gcval
.font
=FButtonFont
->font
->fid
;
1426 graph
[i
]=fvwmlib_XCreateGC(dpy
,win
,gcmask
,&gcval
);
1429 gcval
.foreground
=GetShadow(fore
[i
]);
1431 if (colorset
[i
] < 0)
1432 gcval
.foreground
=GetShadow(back
[i
]);
1434 gcval
.foreground
=Colorset
[colorset
[i
]].shadow
;
1435 gcval
.background
=back
[i
];
1436 gcmask
=GCForeground
|GCBackground
;
1437 shadow
[i
]=fvwmlib_XCreateGC(dpy
,win
,gcmask
,&gcval
);
1439 if (colorset
[i
] < 0)
1440 gcval
.foreground
=GetHilite(back
[i
]);
1442 gcval
.foreground
=Colorset
[colorset
[i
]].hilite
;
1443 gcval
.background
=back
[i
];
1444 gcmask
=GCForeground
|GCBackground
;
1445 hilite
[i
]=fvwmlib_XCreateGC(dpy
,win
,gcmask
,&gcval
);
1447 gcval
.foreground
=back
[i
];
1448 gcmask
=GCForeground
;
1449 background
[i
]=fvwmlib_XCreateGC(dpy
,win
,gcmask
,&gcval
);
1451 if ((colorset
[i
] >= 0) && Colorset
[colorset
[i
]].pixmap
&&
1452 !CSET_IS_TRANSPARENT_PR(colorset
[i
]))
1454 if (CSET_IS_TRANSPARENT_ROOT(colorset
[i
]))
1456 pixmap
[i
] = CreateBackgroundPixmap(
1457 dpy
, win
, win_width
, win_height
,
1458 &Colorset
[colorset
[i
]], Pdepth
,
1459 background
[i
], False
);
1463 pixmap
[i
] = CreateBackgroundPixmap(
1464 dpy
, win
, win_width
, buttonheight
,
1465 &Colorset
[colorset
[i
]], Pdepth
,
1466 background
[i
], False
);
1468 XSetTile(dpy
, background
[i
], pixmap
[i
]);
1469 XSetFillStyle(dpy
, background
[i
], FillTiled
);
1473 XSelectInput(dpy
,win
,(StructureNotifyMask
| ExposureMask
| KeyPressMask
));
1475 if (ItemCountVisible(&windows
) > 0)
1477 XMapRaised(dpy
,win
);
1479 } else WindowState
=2;
1487 XGrabPointer(dpy
, win
, True
,
1488 ButtonPressMask
|ButtonReleaseMask
|ButtonMotionMask
|
1489 PointerMotionMask
|EnterWindowMask
|LeaveWindowMask
,
1490 GrabModeAsync
, GrabModeAsync
, None
,
1491 None
, CurrentTime
) != GrabSuccess
)
1494 /* If you go too fast, other windows may not get a change to release
1495 * any grab that they have. */
1501 fprintf(stderr
,"failed to grab pointer\n");
1504 Pressed
= !!SomeButtonDown(dummy1
);
1509 StartMeUp - Do X initialization things
1511 void StartMeUp_I(void)
1513 if (!(dpy
= XOpenDisplay("")))
1515 fprintf(stderr
,"%s: can't open display %s", Module
,
1519 flib_init_graphics(dpy
);
1521 x_fd
= XConnectionNumber(dpy
);
1522 screen
= DefaultScreen(dpy
);
1523 Root
= RootWindow(dpy
, screen
);
1529 void StartMeUp_II(void)
1534 if (geometry
== NULL
)
1535 UpdateString(&geometry
, "");
1536 /* evaluate further down */
1537 g_hints_rc
= FScreenParseGeometryWithScreen(
1538 geometry
, &g_hints
.x
, &g_hints
.y
, (unsigned int *)&g_hints
.width
,
1539 (unsigned int *)&g_hints
.height
, &fscreen
);
1541 NULL
, fscreen
, &screen_g
.x
, &screen_g
.y
, &screen_g
.width
, &screen_g
.height
);
1543 if ((FButtonFont
= FlocaleLoadFont(dpy
,font_string
,Module
)) == NULL
)
1545 fprintf(stderr
,"%s: Cannot load font, Exitting\n", Module
);
1549 fontheight
= FButtonFont
->height
;
1550 buttonheight
= fontheight
+ 3 + 2 * ReliefWidth
;
1552 win_width
=FlocaleTextWidth(FButtonFont
,"XXXXXXXXXXXXXXX",10);
1557 ShutMeDown - Do X client cleanup
1559 void ShutMeDown(void)
1562 FreeAllButtons(&buttons
);
1563 /* XFreeGC(dpy,graph);*/
1564 if (WindowState
) XDestroyWindow(dpy
,win
);
1569 ChangeWindowName - Self explanitory
1570 Original work from FvwmIdent:
1571 Copyright 1994, Robert Nation and Nobutaka Suzuki.
1573 void ChangeWindowName(char *str
)
1576 if (XStringListToTextProperty(&str
,1,&name
) == 0) {
1577 fprintf(stderr
,"%s: cannot allocate window name.\n",Module
);
1580 XSetWMName(dpy
,win
,&name
);
1581 XSetWMIconName(dpy
,win
,&name
);
1591 * Now, if we (hopefully) have MWW - compatible window manager ,
1592 * say, mwm, ncdwm, or else, we will set useful decoration style.
1593 * Never check for MWM_RUNNING property.May be considered bad.
1596 void SetMwmHints(unsigned int value
, unsigned int funcs
, unsigned int input
)
1602 MwmAtom
=XInternAtom(dpy
,"_MOTIF_WM_HINTS",False
);
1606 /* sh->mwm.decorations contains OR of the MWM_DECOR_XXXXX */
1608 MWM_HINTS_DECORATIONS
| MWM_HINTS_FUNCTIONS
|
1609 MWM_HINTS_INPUT_MODE
;
1610 prop
.props
[1] = funcs
;
1611 prop
.props
[2]= value
;
1612 prop
.props
[3] = input
;
1616 dpy
, win
, MwmAtom
, MwmAtom
, 32, PropModeReplace
,
1617 (unsigned char *)&(prop
.props
[0]),
1618 PROP_MWM_HINTS_ELEMENTS
);
1625 int ErrorHandler(Display
*d
, XErrorEvent
*event
)
1627 /* some errors are OK=ish */
1628 if (event
->error_code
== BadPixmap
)
1630 if (event
->error_code
== BadDrawable
)
1632 if (FRenderGetErrorCodeBase() + FRenderBadPicture
== event
->error_code
)
1635 PrintXErrorAndCoredump(d
, event
, Module
);