2 /* Copyright May 1996, Frederic Cordier. No guarantees or warantees are
3 * provided or implied in any way whatsoever. Use this program at your own
4 * risk. Permission to use, modify, and redistribute this program is hereby
5 * given, provided that this copyright is kept intact.
8 /* This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "libs/fvwmlib.h"
27 #include "libs/FScreen.h"
28 #include "libs/FShape.h"
29 #include "libs/fvwmsignal.h"
30 #include "libs/Picture.h"
31 #include "libs/PictureGraphics.h"
32 #include "libs/FRender.h"
33 #include "libs/FRenderInit.h"
34 #include "libs/FGettext.h"
35 #include "libs/Bindings.h"
36 #include "libs/charmap.h"
37 #include "libs/wcontext.h"
38 #include "libs/ColorUtils.h"
39 #include "libs/Graphics.h"
40 #include "libs/Parse.h"
41 #include "libs/Strings.h"
42 #include "libs/XError.h"
44 #ifdef MEMDEBUG /* For debugging */
45 #include <unchecked.h>
48 /* Variables utilise par l'analyseur syntaxique */
49 extern ScriptProp
*scriptprop
;
50 extern int nbobj
; /* Nombre d'objets */
51 extern int numligne
; /* Numero de ligne */
52 extern TabObj
*tabobj
; /* Tableau d'objets, limite=1000 */
53 extern char **TabVVar
; /* Tableau des variables du sript */
54 extern int TabIdObj
[1001];
55 extern Bloc
**TabIObj
;
56 extern CaseObj
*TabCObj
;
58 extern int __bounds_debug_no_checking
;
61 /* Constante de couleurs utilise dans le tableau TabColor */
68 /* Variables globales */
69 char *ScriptName
; /* Nom du fichier contenat le script decrivant le GUI */
71 char *ScriptPath
= "";
73 int fd
[2]; /* pipe pair */
75 int x_fd
; /* fd for X */
77 FlocaleWinString
*FwinString
;
79 extern int yyparse(void);
80 extern void (*TabCom
[25]) (int NbArg
,long *TabArg
);
85 X11base
*x11base
; /* Pour le serveur X */
86 TypeBuffSend BuffSend
; /* Pour les communication entre script */
88 struct XObj
*tabxobj
[1000];
91 static Atom wm_del_win
;
92 char *imagePath
= NULL
;
93 static Bool is_dead_pipe
= False
;
94 KeySym shift_tab_ks
; /* shift-Tab keysym */
95 char *LastString
= NULL
; /* last string send by a SendString ot Key cmd */
96 Binding
*BindingsList
;
98 extern void InitCom(void);
99 static void TryToFind(char *filename
);
102 /* Exit procedure - called whenever we call exit(), or when main() ends */
114 #ifdef DEBUG /* For debugging */
118 /* execute the QuitFunc */
119 if (x11base
->quitfunc
!= NULL
)
120 ExecBloc(x11base
->quitfunc
);
125 /* On cache la fenetre */
126 XUnmapWindow(dpy
,x11base
->win
);
129 /* Le script ne possede plus la propriete */
130 MyAtom
= XInternAtom(dpy
, x11base
->TabScriptId
[1], False
);
131 XSetSelectionOwner(dpy
, MyAtom
, x11base
->root
, CurrentTime
);
133 /* On verifie si tous les messages ont ete envoyes */
134 while(!isTerminated
&& (BuffSend
.NbMsg
> 0) && (NbEssai
< 10000) )
139 FD_SET(x_fd
,&in_fdset
);
140 if ( fvwmSelect(x_fd
+1, &in_fdset
, NULL
, NULL
, &tv
) > 0 )
142 if (FD_ISSET(x_fd
, &in_fdset
))
144 if (FCheckTypedEvent(dpy
, SelectionRequest
, &event
))
145 SendMsgToScript(event
);
153 /* Attente de deux secondes afin d'etre sur que tous */
154 /* les messages soient arrives a destination */
155 /* On quitte proprement le serveur X */
156 for (i
=0; i
<nbobj
; i
++)
157 tabxobj
[i
]->DestroyObj(tabxobj
[i
]);
169 for (j
=1;j
<=nbobj
;j
++)
170 for (i
=0; i
<=TabCObj
[TabIdObj
[j
]].NbCase
; i
++)
172 /* Execution du bloc d'instruction */
173 fprintf(stderr
,"Id de l'objet %d\n",TabIdObj
[j
]);
174 fprintf(stderr
,"Nb Instruction %d\n",TabIObj
[TabIdObj
[j
]][i
].NbInstr
);
179 /* Lecture du fichier contenant le script */
180 void ReadConfig (char *ScriptName
)
183 char s
[FILENAME_MAX
];
185 /* This is legacy support. The first try is the command line file name
186 with the scriptfile directory. If the scriptfile directory wasn't set
187 it ends up trying the command line file name undecorated, which
188 could be a full path, or it could be relative to the current directory.
189 Not very pretty, dje 12/26/99 */
190 sprintf(s
,"%s%s%s",ScriptPath
,(!*ScriptPath
? "" : "/"),ScriptName
);
192 if (yyin
== NULL
) { /* file not found yet, */
193 TryToFind(ScriptName
); /* look in some other places */
197 fprintf(stderr
,"[%s][ReadConfig]: <<ERROR>> Can't open the script %s\n",
201 /* On ne redefini pas yyout qui est la sortie standard */
203 /* Application de l'analyseur syntaxique et lexical */
205 /* Fermeture du script */
210 /* Original method for finding the config file didn't work,
211 try using the same strategy fvwm uses in its read command.
212 1. If the file name starts with a slash, just try it.
213 2. Look in the home directory, using FVWM_USERDIR.
214 3. If that doesn't work, look in FVWM_DATADIR.
215 The extern "yyin" indicates success or failure.
217 static void TryToFind(char *filename
) {
219 char path
[FILENAME_MAX
];
221 if (filename
[0] == '/') { /* if absolute path */
222 yyin
= fopen(filename
,"r");
225 sprintf(path
,"%s/%s",getenv("FVWM_USERDIR"),filename
);
226 yyin
= fopen( path
, "r" );
227 if ( yyin
== NULL
) {
228 sprintf(path
,"%s/%s",FVWM_DATADIR
, filename
);
229 yyin
= fopen( path
, "r" );
234 /* Quitter par l'option Delete du bouton de la fenetre */
235 RETSIGTYPE
DeadPipe(int nonsense
)
242 /* Lecture du fichier system.fvwmrc ou .fvwmrc */
243 void ParseOptions(void)
247 InitGetConfigLine(fd
,"*FvwmScript");
248 GetConfigLine(fd
,&tline
);
249 while(tline
!= (char *)0) {
250 if (strlen(tline
) > 1) {
251 if (strncasecmp(tline
,"ImagePath",9) == 0)
252 CopyString(&imagePath
,&tline
[9]);
253 else if (strncasecmp(tline
,"*FvwmScriptPath",15) == 0)
254 CopyString(&ScriptPath
,&tline
[15]);
255 else if (strncasecmp(tline
,"*FvwmScriptDefaultColorset",26) == 0)
257 LoadColorset(&tline
[26]);
258 x11base
->colorset
= atoi(&tline
[26]);
260 else if (strncasecmp(tline
,"*FvwmScriptDefaultBack",22) == 0)
262 x11base
->colorset
= -1;
263 CopyString(&x11base
->backcolor
,&tline
[22]);
265 else if (strncasecmp(tline
,"*FvwmScriptDefaultFore",22) == 0)
267 x11base
->colorset
= -1;
268 CopyString(&x11base
->forecolor
,&tline
[22]);
270 else if (strncasecmp(tline
,"*FvwmScriptDefaultHilight",25) == 0)
272 x11base
->colorset
= -1;
273 CopyString(&x11base
->hilicolor
,&tline
[25]);
275 else if (strncasecmp(tline
,"*FvwmScriptDefaultShadow",24) == 0)
277 x11base
->colorset
= -1;
278 CopyString(&x11base
->shadcolor
,&tline
[24]);
280 else if (strncasecmp(tline
,"*FvwmScriptDefaultFont",22) == 0)
281 CopyStringWithQuotes(&x11base
->font
,&tline
[22]);
282 else if (strncasecmp(tline
,"Colorset",8) == 0)
283 LoadColorset(&tline
[8]);
284 else if (strncasecmp(tline
, XINERAMA_CONFIG_STRING
,
285 sizeof(XINERAMA_CONFIG_STRING
) - 1) == 0)
286 FScreenConfigureModule(
287 tline
+ sizeof(XINERAMA_CONFIG_STRING
) - 1);
290 GetConfigLine(fd
,&tline
);
294 static int myErrorHandler(Display
*dpy
, XErrorEvent
*event
)
296 /* some errors are acceptable, mostly they're caused by
297 * trying to use a deleted pixmap */
298 if((event
->error_code
== BadDrawable
) || (event
->error_code
== BadPixmap
) ||
299 (event
->error_code
== BadWindow
) ||
300 (event
->error_code
== FRenderGetErrorCodeBase() + FRenderBadPicture
))
303 PrintXErrorAndCoredump(dpy
, event
, x11base
->title
);
305 /* return (*oldErrorHandler)(dpy,event); */
309 /* Procedure d'initialisation du serveur X et des variables globales*/
310 void Xinit(int IsFather
)
316 /* Connextion au serveur X */
318 __bounds_debug_no_checking
=True
;
321 dpy
=XOpenDisplay(NULL
);
324 fprintf(stderr
,"[%s]: <<ERROR>> Can't open display %s",
325 ScriptName
, XDisplayName(NULL
));
328 screen
= DefaultScreen(dpy
);
329 Root
= RootWindow(dpy
,screen
);
330 flib_init_graphics(dpy
);
331 FlocaleAllocateWinString(&FwinString
);
332 XSetErrorHandler(myErrorHandler
);
335 __bounds_debug_no_checking
=False
;
340 name
= (char*)safecalloc(sizeof(char),strlen("FvwmScript")+5);
343 sprintf(name
,"%c%xFvwmScript",161,i
);
345 myatom
= XInternAtom(dpy
, name
, False
);
347 while (XGetSelectionOwner(dpy
,myatom
) != None
)
349 x11base
->TabScriptId
[1] = name
;
350 x11base
->TabScriptId
[0] = NULL
;
352 x11base
->NbChild
= 0;
353 x11base
->root
= RootWindow(dpy
,screen
);
354 x_fd
= XConnectionNumber(dpy
);
356 /* install exit procedure to close X down again */
363 void LoadIcon(struct XObj
*xobj
)
367 FvwmPictureAttributes fpa
;
370 if (xobj
->colorset
>= 0 && Colorset
[xobj
->colorset
].do_dither_icon
)
372 fpa
.mask
|= FPAM_DITHER
;
374 if (xobj
->iconPixmap
!= None
)
376 XFreePixmap(dpy
, xobj
->iconPixmap
);
377 xobj
->iconPixmap
= None
;
379 if (xobj
->icon_maskPixmap
!= None
)
381 XFreePixmap(dpy
, xobj
->icon_maskPixmap
);
382 xobj
->icon_maskPixmap
= None
;
384 if (xobj
->icon_alphaPixmap
!= None
)
386 XFreePixmap(dpy
, xobj
->icon_alphaPixmap
);
387 xobj
->icon_alphaPixmap
= None
;
389 if (xobj
->alloc_pixels
!= NULL
&& xobj
->nalloc_pixels
> 0)
392 dpy
, Pcmap
, xobj
->alloc_pixels
, xobj
->nalloc_pixels
, 0,
394 xobj
->alloc_pixels
= NULL
;
395 xobj
->nalloc_pixels
= 0;
397 if ((xobj
->icon
) == NULL
)
399 if ((path
= PictureFindImageFile(xobj
->icon
,imagePath
,R_OK
)) == NULL
)
403 if (!PImageLoadPixmapFromFile(
404 dpy
, x11base
->win
, path
, &xobj
->iconPixmap
,
405 &xobj
->icon_maskPixmap
, &xobj
->icon_alphaPixmap
, &xobj
->icon_w
,
406 &xobj
->icon_h
, &depth
, &xobj
->nalloc_pixels
,
407 &xobj
->alloc_pixels
, 0, fpa
))
409 fprintf(stderr
,"[%s][LoadIcon]: <<WARNING>> Unable to "
411 ScriptName
,xobj
->icon
);
421 gcv
.background
= WhitePixel(dpy
, screen
);
422 gcv
.foreground
= BlackPixel(dpy
, screen
);
423 m_gc
= fvwmlib_XCreateGC(dpy
, x11base
->win
,
424 GCForeground
| GCBackground
, &gcv
);
425 temp
= XCreatePixmap(dpy
, x11base
->win
,
426 xobj
->icon_w
, xobj
->icon_h
, Pdepth
);
427 XCopyPlane(dpy
, xobj
->iconPixmap
, temp
, m_gc
,
428 0,0,xobj
->icon_w
, xobj
->icon_h
, 0,0,1);
429 XFreePixmap(dpy
, xobj
->iconPixmap
);
431 xobj
->iconPixmap
= temp
;
437 /* Ouvre une fenetre pour l'affichage du GUI */
438 void OpenWindow (void)
442 XSizeHints
*IndicNorm
;
444 XClassHint classHints
;
445 XSetWindowAttributes Attr
;
447 /* Allocation des couleurs */
448 if (x11base
->colorset
>= 0) {
449 x11base
->TabColor
[fore
] = Colorset
[x11base
->colorset
].fg
;
450 x11base
->TabColor
[back
] = Colorset
[x11base
->colorset
].bg
;
451 x11base
->TabColor
[shad
] = Colorset
[x11base
->colorset
].shadow
;
452 x11base
->TabColor
[hili
] = Colorset
[x11base
->colorset
].hilite
;
454 x11base
->TabColor
[fore
] = GetColor(x11base
->forecolor
);
455 x11base
->TabColor
[back
] = GetColor(x11base
->backcolor
);
456 x11base
->TabColor
[shad
] = GetColor(x11base
->shadcolor
);
457 x11base
->TabColor
[hili
] = GetColor(x11base
->hilicolor
);
460 /* Definition des caracteristiques de la fentre */
461 mask
= CWBackPixel
| CWBorderPixel
| CWColormap
;
462 Attr
.background_pixel
= x11base
->TabColor
[back
];
463 Attr
.border_pixel
= 0;
464 Attr
.colormap
= Pcmap
;
466 x11base
->win
=XCreateWindow(
467 dpy
, x11base
->root
, x11base
->size
.x
,x11base
->size
.y
, x11base
->size
.width
,
468 x11base
->size
.height
, 0, Pdepth
, InputOutput
, Pvisual
, mask
, &Attr
);
469 x11base
->gc
=fvwmlib_XCreateGC(dpy
,x11base
->win
,0,NULL
);
470 if (x11base
->colorset
>= 0)
472 dpy
, x11base
->win
, x11base
->size
.width
, x11base
->size
.height
,
473 &Colorset
[x11base
->colorset
], Pdepth
, x11base
->gc
, True
);
475 /* Choix des evts recus par la fenetre */
476 XSelectInput(dpy
,x11base
->win
, KeyPressMask
|ButtonPressMask
|
477 ExposureMask
|ButtonReleaseMask
|EnterWindowMask
|LeaveWindowMask
|
478 ButtonMotionMask
|StructureNotifyMask
);
479 XSelectInput(dpy
, x11base
->root
, PropertyChangeMask
);
481 /* Specification des parametres utilises par le gestionnaire de fenetre */
482 if (XStringListToTextProperty(&x11base
->title
,1,&Name
) == 0)
483 fprintf(stderr
,"[%s][OpenWindow]: <<WARNING>> Can't use icon name\n",
485 IndicNorm
= XAllocSizeHints();
486 if (x11base
->size
.x
!=-1)
488 IndicNorm
->x
= x11base
->size
.x
;
489 IndicNorm
->y
= x11base
->size
.y
;
490 IndicNorm
->flags
= PSize
|PMinSize
|PMaxSize
|PBaseSize
|PPosition
;
493 IndicNorm
->flags
= PSize
|PMinSize
|PMaxSize
|PBaseSize
;
494 IndicNorm
->width
= x11base
->size
.width
;
495 IndicNorm
->height
= x11base
->size
.height
;
496 IndicNorm
->min_width
= x11base
->size
.width
;
497 IndicNorm
->min_height
= x11base
->size
.height
;
498 IndicNorm
->max_width
= x11base
->size
.width
;
499 IndicNorm
->max_height
= x11base
->size
.height
;
500 IndicWM
= XAllocWMHints();
501 IndicWM
->input
= True
;
502 IndicWM
->initial_state
= NormalState
;
503 IndicWM
->flags
= InputHint
|StateHint
;
505 classHints
.res_name
= safestrdup(ScriptBaseName
);
506 classHints
.res_class
= safestrdup(module
->name
);
508 XSetWMProperties(dpy
, x11base
->win
, &Name
,
509 &Name
, NULL
, 0, IndicNorm
, IndicWM
, &classHints
);
510 Scrapt
= (char*)safecalloc(sizeof(char),1);
512 /* Construction des atomes pour la communication inter-application */
513 propriete
= XInternAtom(dpy
,"Prop_selection",False
);
514 wm_del_win
= XInternAtom(dpy
,"WM_DELETE_WINDOW",False
);
515 XSetWMProtocols(dpy
,x11base
->win
,&wm_del_win
,1);
517 free(classHints
.res_class
);
518 free(classHints
.res_name
);
522 * Execution d'une sequence d'instruction
524 void ExecBloc(Bloc
*bloc
)
528 for (i
= 0; i
<= bloc
->NbInstr
; i
++)
530 TabCom
[bloc
->TabInstr
[i
].Type
](bloc
->TabInstr
[i
].NbArg
,
531 bloc
->TabInstr
[i
].TabArg
);
536 /* Construction de l'interface graphique */
537 void BuildGUI(int IsFather
)
541 if (scriptprop
->font
!= NULL
)
544 x11base
->font
= scriptprop
->font
;
547 if (scriptprop
->forecolor
!= NULL
)
549 x11base
->colorset
= -1;
551 x11base
->forecolor
= scriptprop
->forecolor
;
553 if (scriptprop
->backcolor
!= NULL
)
555 x11base
->colorset
= -1;
557 x11base
->backcolor
= scriptprop
->backcolor
;
559 if (scriptprop
->shadcolor
!= NULL
)
561 x11base
->colorset
=-1;
563 x11base
->shadcolor
= scriptprop
->shadcolor
;
565 if (scriptprop
->hilicolor
!= NULL
)
567 x11base
->colorset
=-1;
569 x11base
->hilicolor
= scriptprop
->hilicolor
;
571 if (scriptprop
->colorset
!= -1)
572 x11base
->colorset
= scriptprop
->colorset
;
574 x11base
->icon
= scriptprop
->icon
;
580 FScreenGetScrRect(NULL
, FSCREEN_CURRENT
, &sx
, &sy
, NULL
, NULL
);
581 x11base
->size
.x
= scriptprop
->x
+ sx
;
582 x11base
->size
.y
= scriptprop
->y
+ sy
;
584 x11base
->size
.width
= scriptprop
->width
;
585 x11base
->size
.height
= scriptprop
->height
;
586 x11base
->title
= scriptprop
->titlewin
;
588 /* Initialisation de la fenetre */
591 /* Parcour de tous les objets graphiques */
593 for (i
=0; i
<nbobj
; i
++)
595 tabxobj
[i
] = (struct XObj
*)safecalloc(1,sizeof(struct XObj
));
596 tabxobj
[i
]->id
= (*tabobj
)[i
].id
;
597 tabxobj
[i
]->x
= (*tabobj
)[i
].x
;
598 tabxobj
[i
]->y
= (*tabobj
)[i
].y
;
599 tabxobj
[i
]->width
= (*tabobj
)[i
].width
;
600 tabxobj
[i
]->height
= (*tabobj
)[i
].height
;
601 if (tabxobj
[i
]->width
== 0)
602 tabxobj
[i
]->width
= 1;
603 if (tabxobj
[i
]->height
== 0)
604 tabxobj
[i
]->height
= 1;
605 tabxobj
[i
]->value
= (*tabobj
)[i
].value
;
606 tabxobj
[i
]->value2
= (*tabobj
)[i
].value2
;
607 tabxobj
[i
]->value3
= (*tabobj
)[i
].value3
;
608 tabxobj
[i
]->flags
[0] = (*tabobj
)[i
].flags
[0];
609 tabxobj
[i
]->flags
[1] = (*tabobj
)[i
].flags
[1];
610 tabxobj
[i
]->flags
[2] = (*tabobj
)[i
].flags
[2];
611 tabxobj
[i
]->flags
[3] = (*tabobj
)[i
].flags
[3];
612 tabxobj
[i
]->icon
= (*tabobj
)[i
].icon
;
613 tabxobj
[i
]->swallow
= (*tabobj
)[i
].swallow
;
615 if ((*tabobj
)[i
].title
== NULL
)
616 tabxobj
[i
]->title
= (char*)safecalloc(1,200);
618 tabxobj
[i
]->title
= (*tabobj
)[i
].title
;
620 if ((*tabobj
)[i
].font
== NULL
&& x11base
->font
!= NULL
)
621 tabxobj
[i
]->font
= (char*)safestrdup(x11base
->font
);
623 tabxobj
[i
]->font
= (*tabobj
)[i
].font
;
625 if ((*tabobj
)[i
].forecolor
== NULL
)
626 tabxobj
[i
]->forecolor
= (char*)safestrdup(x11base
->forecolor
);
628 tabxobj
[i
]->forecolor
= (*tabobj
)[i
].forecolor
;
630 if ((*tabobj
)[i
].backcolor
== NULL
)
631 tabxobj
[i
]->backcolor
= (char*)safestrdup(x11base
->backcolor
);
633 tabxobj
[i
]->backcolor
= (*tabobj
)[i
].backcolor
;
635 if ((*tabobj
)[i
].shadcolor
== NULL
)
636 tabxobj
[i
]->shadcolor
= (char*)safestrdup(x11base
->shadcolor
);
638 tabxobj
[i
]->shadcolor
= (*tabobj
)[i
].shadcolor
;
640 if ((*tabobj
)[i
].hilicolor
== NULL
)
641 tabxobj
[i
]->hilicolor
= safestrdup(x11base
->hilicolor
);
643 tabxobj
[i
]->hilicolor
= (*tabobj
)[i
].hilicolor
;
645 if ((*tabobj
)[i
].colorset
>= 0)
646 tabxobj
[i
]->colorset
=(*tabobj
)[i
].colorset
;
647 else if ((*tabobj
)[i
].backcolor
== NULL
&& (*tabobj
)[i
].forecolor
== NULL
&&
648 (*tabobj
)[i
].shadcolor
== NULL
&& (*tabobj
)[i
].hilicolor
== NULL
)
649 tabxobj
[i
]->colorset
= x11base
->colorset
;
650 else tabxobj
[i
]->colorset
= -1;
653 ChooseFunction(tabxobj
[i
],(*tabobj
)[i
].type
);
654 tabxobj
[i
]->gc
= x11base
->gc
;
655 tabxobj
[i
]->ParentWin
= &(x11base
->win
);
656 tabxobj
[i
]->iconPixmap
= None
;
657 tabxobj
[i
]->icon_maskPixmap
= None
;
659 LoadIcon(tabxobj
[i
]); /* Chargement de l'icone du widget */
661 tabxobj
[i
]->InitObj(tabxobj
[i
]);
664 /* Enregistrement du bloc de taches periodic */
665 x11base
->periodictasks
= scriptprop
->periodictasks
;
667 x11base
->quitfunc
= scriptprop
->quitfunc
;
669 /*Si un bloc d'initialisation du script existe, on l'execute ici */
670 if (scriptprop
->initbloc
!= NULL
)
672 ExecBloc(scriptprop
->initbloc
);
673 free(scriptprop
->initbloc
->TabInstr
);
674 free(scriptprop
->initbloc
);
679 XMapRaised(dpy
,x11base
->win
);
680 for (i
=0; i
<nbobj
; i
++)
681 if (tabxobj
[i
]->flags
[0] != True
)
682 XMapWindow(dpy
,tabxobj
[i
]->win
);
686 * Fonction de traitement des msg entre objets
688 void SendMsg(struct XObj
*xobj
,int TypeMsg
)
692 for (i
=0; i
<= TabCObj
[TabIdObj
[xobj
->id
]].NbCase
; i
++)
693 if (TabCObj
[TabIdObj
[xobj
->id
]].LstCase
[i
] == TypeMsg
)
695 /* Execution du bloc d'instruction */
696 ExecBloc(&TabIObj
[TabIdObj
[xobj
->id
]][i
]);
701 * Fonction de traitement des msg entre objets
703 void SendMsgAndString(char *action
, char *type
)
712 if(StrEquals(type
,"SendString") || StrEquals(type
,"CheckBinding")){
713 if (GetIntegerArguments(action
, NULL
, val
, 2) == 2){
714 if (val
[0] > 1000 || val
[0] < 1){
715 fprintf(stderr
,"[%s][%s]: <<WARNING>> Widget id out of range: %i\n",
716 ScriptName
,type
,val
[0]);
720 i
= TabIdObj
[val
[0]];
722 /* skip the integer argument */
723 action
= GetNextToken(action
, &token
);
724 action
= GetNextToken(action
, &token
);
725 if (LastString
!= NULL
) {
729 if (action
!= NULL
&& strlen(action
) > 0)
730 CopyString(&LastString
,action
);
732 SendMsg(tabxobj
[i
],val
[1]);
734 fprintf(stderr
,"[%s][%s]: <<WARNING>> no Widget %i\n",
735 ScriptName
,type
,val
[0]);
740 fprintf(stderr
,"[%s][%s]: <<WARNING>> Syntax Error: %s\n",
741 ScriptName
,type
,action
);
745 if(StrEquals(type
,"ChangeWindowTitle")){
746 action
=GetNextToken(action
, &arg1
);
747 action
=GetNextToken(action
, &arg2
);
752 dpy
, x11base
->win
, XA_WM_NAME
, XA_STRING
, 8, PropModeReplace
,
753 (unsigned char*)arg1
, strlen(arg1
));
756 if(XFetchName(dpy
, x11base
->win
, &windowName
) == 0){
758 stderr
,"[%s][SendMsgAndString]: <<ERROR>> "
759 "Can't find the title of a window\n", module
->name
);
761 if(StrEquals(arg2
,windowName
)){
763 dpy
, x11base
->win
, XA_WM_NAME
, XA_STRING
, 8,
764 PropModeReplace
, (unsigned char*)arg1
, strlen(arg1
));
772 stderr
,"[%s][SendMsgAndString]: <<ERROR>> "
773 "Unknown SendToModule command: %s\n", module
->name
, type
);
783 * Appeler lors d'une demande de selection
785 void SendMsgToScript(XEvent event
)
787 Atom Sender
,Receiver
=None
;
788 static XEvent evnt_sel
;
791 Sender
= XInternAtom(dpy
,x11base
->TabScriptId
[1],True
);
793 if (event
.xselectionrequest
.selection
== Sender
)
796 while ((i
< BuffSend
.NbMsg
) && (event
.xselectionrequest
.target
!= Receiver
))
798 Receiver
= XInternAtom(dpy
,BuffSend
.TabMsg
[i
].R
,True
);
803 evnt_sel
.type
= SelectionNotify
;
804 evnt_sel
.xselection
.requestor
= event
.xselectionrequest
.requestor
;
805 evnt_sel
.xselection
.selection
= event
.xselectionrequest
.selection
;
806 evnt_sel
.xselection
.target
= Receiver
;
807 evnt_sel
.xselection
.time
= event
.xselectionrequest
.time
;
808 /* On a trouve le recepteur */
809 if (event
.xselectionrequest
.target
== Receiver
)
811 evnt_sel
.xselection
.property
= event
.xselectionrequest
.property
;
813 evnt_sel
.xselection
.requestor
,
814 evnt_sel
.xselection
.property
,
815 evnt_sel
.xselection
.target
,
818 (unsigned char *)(BuffSend
.TabMsg
[i
].Msg
),
819 strlen(BuffSend
.TabMsg
[i
].Msg
)+1);
821 free(BuffSend
.TabMsg
[i
].Msg
);
822 if (BuffSend
.NbMsg
> 0)
824 memmove(&BuffSend
.TabMsg
[i
],
825 &BuffSend
.TabMsg
[i
+1],(BuffSend
.NbMsg
-i
)*sizeof(TypeName
));
830 /* Cas ou le recepteur demande un message et qu'il n'y en a pas */
831 evnt_sel
.xselection
.property
= None
;
833 FSendEvent(dpy
,evnt_sel
.xselection
.requestor
, False
, 0, &evnt_sel
);
838 void UpdateRootTransparency(Bool pr_only
)
842 if (CSET_IS_TRANSPARENT(x11base
->colorset
))
844 if (CSET_IS_TRANSPARENT_PR_PURE(x11base
->colorset
))
846 XClearArea(dpy
, x11base
->win
, 0, 0, 0, 0, True
);
848 else if (!pr_only
|| CSET_IS_TRANSPARENT_PR(x11base
->colorset
))
851 dpy
, x11base
->win
, x11base
->size
.width
,
852 x11base
->size
.height
,
853 &Colorset
[x11base
->colorset
], Pdepth
,
857 for (i
=0; i
<nbobj
; i
++)
859 if (Rectangle
== tabxobj
[i
]->TypeWidget
||
860 SwallowExec
== tabxobj
[i
]->TypeWidget
)
864 if (!CSET_IS_TRANSPARENT(tabxobj
[i
]->colorset
) ||
865 (CSET_IS_TRANSPARENT_PR(tabxobj
[i
]->colorset
) &&
866 !CSET_IS_TRANSPARENT(x11base
->colorset
)))
870 if (CSET_IS_TRANSPARENT_PR_PURE(tabxobj
[i
]->colorset
))
872 XClearArea(dpy
, tabxobj
[i
]->win
, 0, 0, 0, 0, True
);
875 CSET_IS_TRANSPARENT_PR(tabxobj
[i
]->colorset
))
878 dpy
, tabxobj
[i
]->win
, tabxobj
[i
]->width
,
880 &Colorset
[tabxobj
[i
]->colorset
], Pdepth
,
881 tabxobj
[i
]->gc
, True
);
887 /* read an X event */
888 void ReadXServer (void)
890 static XEvent event
,evnt_sel
;
895 static unsigned char buf
[10]; /* unsigned for international */
898 int ex
, ey
, ex2
, ey2
;
901 while (FEventsQueued(dpy
, QueuedAfterReading
))
903 FNextEvent(dpy
, &event
);
907 ex
= event
.xexpose
.x
;
908 ey
= event
.xexpose
.y
;
909 ex2
= event
.xexpose
.x
+ event
.xexpose
.width
;
910 ey2
= event
.xexpose
.y
+ event
.xexpose
.height
;
911 while (FCheckTypedWindowEvent(dpy
, event
.xany
.window
, Expose
, &event
))
913 ex
= min(ex
, event
.xexpose
.x
);
914 ey
= min(ey
, event
.xexpose
.y
);
915 ex2
= max(ex2
, event
.xexpose
.x
+ event
.xexpose
.width
);
916 ey2
= max(ey2
, event
.xexpose
.y
+ event
.xexpose
.height
);
918 event
.xexpose
.x
= ex
;
919 event
.xexpose
.y
= ey
;
920 event
.xexpose
.width
= ex2
- ex
;
921 event
.xexpose
.height
= ey2
- ey
;
922 for (i
=0; i
<nbobj
; i
++)
924 if (event
.xexpose
.window
== tabxobj
[i
]->win
)
926 tabxobj
[i
]->DrawObj(tabxobj
[i
], &event
);
929 /* handle exposes on x11base that need an object to render */
930 if (event
.xexpose
.window
== x11base
->win
)
932 /* redraw first menu item to get the 3d menubar */
933 for (i
=0; i
<nbobj
; i
++)
935 if (Menu
== tabxobj
[i
]->TypeWidget
)
937 tabxobj
[i
]->DrawObj(tabxobj
[i
], &event
);
941 /* redraw all Rectangles and SwallowExec's */
942 for (i
=0; i
<nbobj
; i
++)
944 if ((Rectangle
== tabxobj
[i
]->TypeWidget
)
945 ||(SwallowExec
== tabxobj
[i
]->TypeWidget
))
947 tabxobj
[i
]->DrawObj(tabxobj
[i
], &event
);
953 case ConfigureNotify
:
957 moved
= event
.xconfigure
.send_event
;
958 while (FCheckTypedEvent(dpy
, ConfigureNotify
, &event
))
960 /* check for movement */
961 if (event
.xconfigure
.send_event
)
966 UpdateRootTransparency(False
);
971 /* Touche presse dans un objet / Key press in an object */
974 XLookupString(&event
.xkey
, (char *)buf
, sizeof(buf
), &ks
, NULL
);
976 XKeysymToKeycode(dpy
,XKeycodeToKeysym(dpy
,event
.xkey
.keycode
,0));
978 /* check for bindings defined by the Key instruction */
979 tmp
.res_class
= tmp
.res_name
= "root";
980 if ((action
= CheckBinding(
981 BindingsList
, STROKE_ARG(0) event
.xkey
.keycode
,
982 event
.xkey
.state
, LockMask
, C_WINDOW
, BIND_KEYPRESS
,
983 &tmp
, tmp
.res_class
)) !=
986 SendMsgAndString(action
, "CheckBinding");
992 if (event
.xkey
.state
& ShiftMask
) {
993 /* does not work in general see AddBinding */
997 else if (ks
== shift_tab_ks
)
999 if (event
.xkey
.subwindow
!=0)
1001 /* Envoi de l'evt à l'objet */
1002 for (i
=0; i
<nbobj
; i
++)
1004 if (tabxobj
[i
]->win
== event
.xkey
.subwindow
)
1007 if (isTab
== 0 && !HAS_NO_FOCUS(tabxobj
[i
])) {
1008 tabxobj
[i
]->EvtKey(tabxobj
[i
],&event
.xkey
);
1017 i
= (isTab
== 1)? -1:nbobj
;
1020 i
= (isTab
== 1)? i
+1 : i
-1;
1021 if (i
== nbobj
|| i
== -1) {
1022 i
= (isTab
== 1)? 0 : nbobj
-1;
1029 if (!IS_HIDDEN(tabxobj
[i
]) && !HAS_NO_FOCUS(tabxobj
[i
]) &&
1030 tabxobj
[i
]->TypeWidget
!= Rectangle
&&
1031 tabxobj
[i
]->TypeWidget
!= HDipstick
&&
1032 tabxobj
[i
]->TypeWidget
!= VDipstick
)
1036 FWarpPointer(dpy
, x11base
->win
, tabxobj
[i
]->win
, 0, 0, 0, 0,
1037 tabxobj
[i
]->width
/2, 10);
1041 /* Clique dans quel fenetre? */
1042 if (event
.xbutton
.subwindow
!= 0)
1043 for (i
=0; i
<nbobj
; i
++)
1044 if (tabxobj
[i
]->win
== event
.xbutton
.subwindow
) {
1045 tabxobj
[i
]->EvtMouse(tabxobj
[i
],&event
.xbutton
);
1058 XRefreshKeyboardMapping((XMappingEvent
*)&event
);
1060 case SelectionRequest
:
1061 if (event
.xselectionrequest
.selection
== XA_PRIMARY
)
1063 evnt_sel
.type
= SelectionNotify
;
1064 evnt_sel
.xselection
.requestor
= event
.xselectionrequest
.requestor
;
1065 evnt_sel
.xselection
.selection
= event
.xselectionrequest
.selection
;
1066 evnt_sel
.xselection
.target
= event
.xselectionrequest
.target
;
1067 evnt_sel
.xselection
.time
= event
.xselectionrequest
.time
;
1068 evnt_sel
.xselection
.property
= event
.xselectionrequest
.property
;
1069 switch (event
.xselectionrequest
.target
)
1072 XChangeProperty(dpy
,
1073 evnt_sel
.xselection
.requestor
,
1074 evnt_sel
.xselection
.property
,
1075 evnt_sel
.xselection
.target
,
1078 (unsigned char *)(Scrapt
),
1081 default:evnt_sel
.xselection
.property
= None
;
1083 FSendEvent(dpy
,evnt_sel
.xselection
.requestor
,
1087 SendMsgToScript(event
);
1089 case SelectionClear
:
1090 if (event
.xselectionclear
.selection
== XA_PRIMARY
)
1091 UnselectAllTextField(tabxobj
);
1094 if ((event
.xclient
.format
== 32) &&
1095 (event
.xclient
.data
.l
[0] == wm_del_win
))
1098 case PropertyNotify
:
1099 if (event
.xproperty
.atom
== XA_CUT_BUFFER0
)
1100 octet
= XFetchBuffer(dpy
,&i
,0);
1101 else if (event
.xproperty
.atom
== XA_CUT_BUFFER1
)
1102 octet
= XFetchBuffer(dpy
,&i
,1);
1103 else if (event
.xproperty
.atom
== XA_CUT_BUFFER2
)
1104 octet
= XFetchBuffer(dpy
,&i
,2);
1105 else if (event
.xproperty
.atom
== XA_CUT_BUFFER3
)
1106 octet
= XFetchBuffer(dpy
,&i
,3);
1107 else if (event
.xproperty
.atom
== XA_CUT_BUFFER4
)
1108 octet
= XFetchBuffer(dpy
,&i
,4);
1109 else if (event
.xproperty
.atom
== XA_CUT_BUFFER5
)
1110 octet
= XFetchBuffer(dpy
,&i
,5);
1111 else if (event
.xproperty
.atom
== XA_CUT_BUFFER6
)
1112 octet
= XFetchBuffer(dpy
,&i
,6);
1113 else if (event
.xproperty
.atom
== XA_CUT_BUFFER7
)
1114 octet
= XFetchBuffer(dpy
,&i
,7);
1118 Scrapt
= (char*)saferealloc((void*)Scrapt
,sizeof(char)*(i
+1));
1119 Scrapt
= strcpy(Scrapt
,octet
);
1127 /* main event loop */
1128 void MainLoop (void)
1133 struct timeval
*ptv
;
1134 struct timeval now
, last_periodic
;
1136 fd_set_size_t fd_width
= fd
[1];
1137 Bool fsm_pending
= False
;
1139 if (x_fd
> fd_width
) fd_width
= x_fd
;
1145 if (x11base
->periodictasks
!= NULL
)
1147 gettimeofday(&last_periodic
, NULL
);
1151 while ( !isTerminated
)
1153 while (FPending(dpy
))
1157 FD_SET(x_fd
,&in_fdset
);
1158 FD_SET(fd
[1],&in_fdset
);
1159 fsm_fdset(&in_fdset
);
1161 gettimeofday(&now
, NULL
);
1162 delta
= (now
.tv_sec
- last_periodic
.tv_sec
) * 1000000;
1163 delta
+= now
.tv_usec
- last_periodic
.tv_usec
;
1168 tv
.tv_usec
= 10000; /* 10 ms */
1172 tv
.tv_usec
= 1000000 - delta
;
1175 tv
.tv_sec
= delta
? 0 : 1;
1178 if (fvwmSelect(fd_width
, &in_fdset
, NULL
, NULL
, ptv
) > 0)
1180 if (FD_ISSET(x_fd
, &in_fdset
))
1183 if(FD_ISSET(fd
[1], &in_fdset
))
1185 FvwmPacket
* packet
= ReadFvwmPacket(fd
[1]);
1186 if ( packet
== NULL
)
1188 if (packet
->type
== M_CONFIG_INFO
) {
1192 line
= (char*)&(packet
->body
[3]);
1193 line
= GetNextToken(line
, &token
);
1194 if (StrEquals(token
, "Colorset")) {
1195 /* track all colorset changes and update display if necessary */
1196 n
= LoadColorset(line
);
1197 for (i
=0; i
<nbobj
; i
++) {
1198 if (n
== tabxobj
[i
]->colorset
) {
1199 tabxobj
[i
]->TabColor
[fore
] = Colorset
[n
].fg
;
1200 tabxobj
[i
]->TabColor
[back
] = Colorset
[n
].bg
;
1201 tabxobj
[i
]->TabColor
[shad
] = Colorset
[n
].shadow
;
1202 tabxobj
[i
]->TabColor
[hili
] = Colorset
[n
].hilite
;
1203 if (tabxobj
[i
]->TypeWidget
!= SwallowExec
) {
1204 SetWindowBackground(dpy
, tabxobj
[i
]->win
, tabxobj
[i
]->width
,
1205 tabxobj
[i
]->height
, &Colorset
[n
], Pdepth
,
1206 tabxobj
[i
]->gc
, False
);
1207 XClearWindow(dpy
, tabxobj
[i
]->win
);
1209 tabxobj
[i
]->DrawObj(tabxobj
[i
],NULL
);
1212 if (n
== x11base
->colorset
) {
1213 x11base
->TabColor
[fore
] = Colorset
[n
].fg
;
1214 x11base
->TabColor
[back
] = Colorset
[n
].bg
;
1215 x11base
->TabColor
[shad
] = Colorset
[n
].shadow
;
1216 x11base
->TabColor
[hili
] = Colorset
[n
].hilite
;
1217 SetWindowBackground(dpy
, x11base
->win
, x11base
->size
.width
,
1218 x11base
->size
.height
, &Colorset
[n
], Pdepth
,
1220 for (i
=0; i
<nbobj
; i
++)
1222 if (Rectangle
!= tabxobj
[i
]->TypeWidget
&&
1223 SwallowExec
!= tabxobj
[i
]->TypeWidget
&&
1224 CSET_IS_TRANSPARENT_PR(tabxobj
[i
]->colorset
))
1226 XClearArea(dpy
, tabxobj
[i
]->win
, 0, 0, 0, 0, True
);
1231 else if (StrEquals(token
, XINERAMA_CONFIG_STRING
)) {
1232 FScreenConfigureModule(line
);
1237 else if (packet
->type
== MX_PROPERTY_CHANGE
)
1239 if (packet
->body
[0] == MX_PROPERTY_CHANGE_BACKGROUND
&&
1240 ((!x11base
->swallowed
&& packet
->body
[2] == 0) ||
1241 (x11base
->swallowed
&& packet
->body
[2] == x11base
->win
)))
1243 UpdateRootTransparency(True
);
1245 else if (packet
->body
[0] == MX_PROPERTY_CHANGE_SWALLOW
&&
1246 packet
->body
[2] == x11base
->win
)
1253 x11base
->swallowed
= packet
->body
[1];
1254 str
= (char *)&(packet
->body
[3]);
1255 if (x11base
->swallowed
&& str
&& sscanf(str
,"%lu",&u
) == 1)
1257 x11base
->swallower_win
= (Window
)u
;
1261 x11base
->swallower_win
= 0;
1263 /* update the swallower */
1264 s
= ((x11base
->swallower_win
&& x11base
->swallowed
)?
1265 x11base
->swallower_win
:x11base
->win
);
1266 for (i
=0; i
<nbobj
; i
++)
1268 if (tabxobj
[i
]->TypeWidget
== SwallowExec
&&
1269 tabxobj
[i
]->win
!= None
)
1271 sprintf(cmd
,"PropertyChange %u %u %lu %lu",
1272 MX_PROPERTY_CHANGE_SWALLOW
, 1,
1273 tabxobj
[i
]->win
, s
);
1277 UpdateRootTransparency(False
);
1280 else if (packet
->type
== M_STRING
) {
1281 char *action
, *token
;
1282 action
= (char*)&(packet
->body
[3]);
1283 action
= GetNextToken(action
, &token
);
1285 SendMsgAndString(action
, token
);
1291 for (i
=0; i
<nbobj
; i
++)
1292 tabxobj
[i
]->ProcessMsg(tabxobj
[i
], packet
->type
, packet
->body
);
1295 fsm_pending
= fsm_process(&in_fdset
);
1298 if (!isTerminated
&& x11base
->periodictasks
!=NULL
&& delta
>= 1000000)
1300 /* Execution des taches periodics */
1301 last_periodic
.tv_sec
= now
.tv_sec
;
1302 last_periodic
.tv_usec
= now
.tv_usec
;
1303 ExecBloc(x11base
->periodictasks
);
1304 usleep(10000); /* slight delay, not the whole second */
1309 void ReadFvwmScriptArg(int argc
, char **argv
,int IsFather
)
1315 BuffSend
.NbMsg
=0; /* Aucun message dans le buffer */
1317 for (i
=2; i
<98; i
++)
1318 x11base
->TabScriptId
[i
]=NULL
;
1320 if (IsFather
) /* Cas du pere */
1322 myatom
= XInternAtom(dpy
,x11base
->TabScriptId
[1],True
);
1323 XSetSelectionOwner(dpy
, myatom
, x11base
->win
, CurrentTime
);
1328 x11base
->TabScriptId
[0] = (char*)safecalloc(sizeof(char),strlen(argv
[7]));
1329 x11base
->TabScriptId
[0] = strncpy(x11base
->TabScriptId
[0],argv
[7],
1331 x11base
->TabScriptId
[1] = argv
[7];
1332 myatom
=XInternAtom(dpy
, x11base
->TabScriptId
[1], True
);
1333 XSetSelectionOwner(dpy
, myatom
, x11base
->win
, CurrentTime
);
1339 /* signal handler to close down the module */
1341 TerminateHandler(int sig
)
1343 fvwmSetTerminate(sig
);
1348 /* main procedure */
1349 int main (int argc
, char **argv
)
1354 FlocaleInit(LC_CTYPE
, "", "", "FvwmScript");
1356 module
= ParseModuleArgs(argc
,argv
,0); /* no alias */
1359 fprintf(stderr
,"FvwmScript must be started by Fvwm.\n");
1363 if (module
->user_argc
== 0)
1365 fprintf(stderr
,"FvwmScript requires the script's name or path.\n");
1369 /* On determine si le script a un pere */
1370 if (module
->user_argc
>= 2)
1371 IsFather
= (module
->user_argv
[1][0] != (char)161);
1375 ScriptName
= module
->user_argv
[0];
1376 ScriptBaseName
= GetFileNameFromPath(ScriptName
);
1377 ref
= strtol(argv
[4], NULL
, 16);
1378 if (ref
== 0) ref
= None
;
1379 fd
[0] = module
->to_fvwm
;
1380 fd
[1] = module
->from_fvwm
;
1381 SetMessageMask(fd
, M_NEW_DESK
| M_END_WINDOWLIST
| M_STRING
|
1382 M_MAP
| M_RES_NAME
| M_RES_CLASS
| M_CONFIG_INFO
|
1383 M_END_CONFIG_INFO
| M_WINDOW_NAME
| M_SENDCONFIG
);
1384 SetMessageMask(fd
, MX_PROPERTY_CHANGE
);
1385 /* Enregistrement des arguments du script */
1386 x11base
= (X11base
*) safecalloc(1,sizeof(X11base
));
1387 x11base
->TabArg
[0] = module
->name
;
1388 for (i
=2-IsFather
; i
< module
->user_argc
; i
++)
1389 x11base
->TabArg
[i
-1+IsFather
] = module
->user_argv
[i
];
1390 /* Couleurs et fontes par defaut */
1391 x11base
->font
= NULL
;
1392 x11base
->forecolor
= safestrdup("black");
1393 x11base
->backcolor
= safestrdup("grey85");
1394 x11base
->shadcolor
= safestrdup("grey55");
1395 x11base
->hilicolor
= safestrdup("grey100");
1396 x11base
->colorset
= -1;
1397 x11base
->swallowed
= False
;
1399 /* Initialisation du serveur X et de la fenetre */
1404 SendText(fd
,"Send_WindowList",0);
1406 ReadConfig(ScriptName
); /* Lecture et analyse du script */
1408 /* Fonction d'initialisation de TabCom et TabFunc */
1411 #ifdef HAVE_SIGACTION
1413 struct sigaction sigact
;
1415 sigemptyset(&sigact
.sa_mask
);
1416 sigaddset(&sigact
.sa_mask
, SIGPIPE
);
1417 sigaddset(&sigact
.sa_mask
, SIGINT
);
1418 sigaddset(&sigact
.sa_mask
, SIGHUP
);
1419 sigaddset(&sigact
.sa_mask
, SIGTERM
);
1420 sigaddset(&sigact
.sa_mask
, SIGQUIT
);
1422 sigact
.sa_flags
= SA_INTERRUPT
;
1424 sigact
.sa_flags
= 0;
1426 sigact
.sa_handler
= TerminateHandler
;
1427 sigaction(SIGPIPE
, &sigact
, NULL
);
1428 sigaction(SIGINT
, &sigact
, NULL
);
1429 sigaction(SIGHUP
, &sigact
, NULL
);
1430 sigaction(SIGTERM
, &sigact
, NULL
);
1431 sigaction(SIGQUIT
, &sigact
, NULL
);
1434 #ifdef USE_BSD_SIGNALS
1435 fvwmSetSignalMask( sigmask(SIGPIPE
) |
1441 signal (SIGPIPE
, TerminateHandler
);
1442 signal (SIGINT
, TerminateHandler
); /* cleanup on other ways of closing too */
1443 signal (SIGHUP
, TerminateHandler
);
1444 signal (SIGQUIT
, TerminateHandler
);
1445 signal (SIGTERM
, TerminateHandler
);
1446 #ifdef HAVE_SIGINTERRUPT
1447 siginterrupt(SIGPIPE
, 1);
1448 siginterrupt(SIGINT
, 1);
1449 siginterrupt(SIGHUP
, 1);
1450 siginterrupt(SIGQUIT
, 1);
1451 siginterrupt(SIGTERM
, 1);
1455 /* Compute the Shift-Tab keysym */
1457 KeyCode tab
= XKeysymToKeycode(dpy
, XK_Tab
);
1458 shift_tab_ks
= XKeycodeToKeysym(dpy
, tab
, ShiftMask
);
1461 /* Construction des boutons et de la fenetre */
1464 ReadFvwmScriptArg(argc
,argv
,IsFather
);
1466 /* tell fvwm we're running */
1467 SendFinishedStartupNotification(fd
);