Fix CursorMove command to correctly honour EdgeScroll settings.
[fvwm.git] / modules / FvwmScript / FvwmScript.c
blob23fac70b5d07664ec4e9c1a85663f91a33949cd6
1 /* -*-c-*- */
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.
6 */
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
23 #include "config.h"
25 #include "types.h"
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>
46 #endif
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;
57 #ifdef MEMDEBUG
58 extern int __bounds_debug_no_checking;
59 #endif
61 /* Constante de couleurs utilise dans le tableau TabColor */
62 #define back 0
63 #define fore 1
64 #define shad 2
65 #define hili 3
68 /* Variables globales */
69 char *ScriptName; /* Nom du fichier contenat le script decrivant le GUI */
70 char *ScriptBaseName;
71 char *ScriptPath = "";
72 ModuleArgs *module;
73 int fd[2]; /* pipe pair */
74 int fd_err;
75 int x_fd; /* fd for X */
76 Window ref;
77 FlocaleWinString *FwinString;
79 extern int yyparse(void);
80 extern void (*TabCom[25]) (int NbArg,long *TabArg);
82 Display *dpy;
83 int screen;
84 Window Root;
85 X11base *x11base; /* Pour le serveur X */
86 TypeBuffSend BuffSend; /* Pour les communication entre script */
87 int grab_server = 0;
88 struct XObj *tabxobj[1000];
89 char *Scrapt;
90 Atom propriete,type;
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 */
103 static void
104 ShutdownX(void)
106 int i;
107 static XEvent event;
108 fd_set in_fdset;
109 extern int x_fd;
110 Atom MyAtom;
111 int NbEssai=0;
112 struct timeval tv;
114 #ifdef DEBUG /* For debugging */
115 XSync(dpy,0);
116 #endif
118 /* execute the QuitFunc */
119 if (x11base->quitfunc != NULL)
120 ExecBloc(x11base->quitfunc);
122 if (is_dead_pipe)
123 return;
125 /* On cache la fenetre */
126 XUnmapWindow(dpy,x11base->win);
127 XFlush(dpy);
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) )
136 tv.tv_sec = 1;
137 tv.tv_usec = 0;
138 FD_ZERO(&in_fdset);
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);
146 else
147 NbEssai++;
151 XFlush(dpy);
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]);
158 XFlush(dpy);
159 fsm_close();
160 sleep(2);
161 XCloseDisplay(dpy);
165 void Debug(void)
167 int i,j;
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)
182 extern FILE *yyin;
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);
191 yyin = fopen(s,"r");
192 if (yyin == NULL) { /* file not found yet, */
193 TryToFind(ScriptName); /* look in some other places */
195 if (yyin == NULL)
197 fprintf(stderr,"[%s][ReadConfig]: <<ERROR>> Can't open the script %s\n",
198 module->name,s);
199 exit(1);
201 /* On ne redefini pas yyout qui est la sortie standard */
203 /* Application de l'analyseur syntaxique et lexical */
204 yyparse();
205 /* Fermeture du script */
207 fclose(yyin);
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) {
218 extern FILE *yyin;
219 char path[FILENAME_MAX];
221 if (filename[0] == '/') { /* if absolute path */
222 yyin = fopen(filename,"r");
223 return;
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" );
231 return;
234 /* Quitter par l'option Delete du bouton de la fenetre */
235 RETSIGTYPE DeadPipe(int nonsense)
237 is_dead_pipe = True;
238 Quit (0,NULL);
239 SIGNAL_RETURN;
242 /* Lecture du fichier system.fvwmrc ou .fvwmrc */
243 void ParseOptions(void)
245 char *tline;
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))
301 return 0;
303 PrintXErrorAndCoredump(dpy, event, x11base->title);
305 /* return (*oldErrorHandler)(dpy,event); */
306 return 0;
309 /* Procedure d'initialisation du serveur X et des variables globales*/
310 void Xinit(int IsFather)
312 char *name;
313 Atom myatom;
314 int i = 16;
316 /* Connextion au serveur X */
317 #ifdef MEMDEBUG
318 __bounds_debug_no_checking=True;
319 #endif
321 dpy=XOpenDisplay(NULL);
322 if (dpy == NULL)
324 fprintf(stderr,"[%s]: <<ERROR>> Can't open display %s",
325 ScriptName, XDisplayName(NULL));
326 exit(1);
328 screen = DefaultScreen(dpy);
329 Root = RootWindow(dpy,screen);
330 flib_init_graphics(dpy);
331 FlocaleAllocateWinString(&FwinString);
332 XSetErrorHandler(myErrorHandler);
334 #ifdef MEMDEBUG
335 __bounds_debug_no_checking=False;
336 #endif
338 if (IsFather)
340 name = (char*)safecalloc(sizeof(char),strlen("FvwmScript")+5);
343 sprintf(name,"%c%xFvwmScript",161,i);
344 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 */
357 atexit(ShutdownX);
361 * Lecture d'un icone
363 void LoadIcon(struct XObj *xobj)
365 char *path;
366 int depth;
367 FvwmPictureAttributes fpa;
369 fpa.mask = 0;
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)
391 PictureFreeColors(
392 dpy, Pcmap, xobj->alloc_pixels, xobj->nalloc_pixels, 0,
393 False);
394 xobj->alloc_pixels = NULL;
395 xobj->nalloc_pixels = 0;
397 if ((xobj->icon) == NULL)
398 return;
399 if ((path = PictureFindImageFile(xobj->icon,imagePath,R_OK)) == NULL)
401 return;
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 "
410 "load pixmap %s\n",
411 ScriptName,xobj->icon);
412 free(path);
413 return;
415 if (depth <= 1)
417 XGCValues gcv;
418 GC m_gc;
419 Pixmap temp;
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);
430 XFreeGC(dpy,m_gc);
431 xobj->iconPixmap = temp;
433 free(path);
437 /* Ouvre une fenetre pour l'affichage du GUI */
438 void OpenWindow (void)
440 XTextProperty Name;
441 XWMHints *IndicWM;
442 XSizeHints *IndicNorm;
443 unsigned long mask;
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;
453 } else {
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)
471 SetWindowBackground(
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",
484 ScriptName);
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;
492 else
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)
526 int i;
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)
539 int i;
541 if (scriptprop->font != NULL)
543 /* leak! */
544 x11base->font = scriptprop->font;
547 if (scriptprop->forecolor != NULL)
549 x11base->colorset = -1;
550 /* leak! */
551 x11base->forecolor = scriptprop->forecolor;
553 if (scriptprop->backcolor != NULL)
555 x11base->colorset = -1;
556 /* leak! */
557 x11base->backcolor = scriptprop->backcolor;
559 if (scriptprop->shadcolor != NULL)
561 x11base->colorset=-1;
562 /* leak! */
563 x11base->shadcolor = scriptprop->shadcolor;
565 if (scriptprop->hilicolor != NULL)
567 x11base->colorset=-1;
568 /* leak! */
569 x11base->hilicolor = scriptprop->hilicolor;
571 if (scriptprop->colorset != -1)
572 x11base->colorset = scriptprop->colorset;
574 x11base->icon = scriptprop->icon;
577 int sx;
578 int sy;
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 */
589 OpenWindow();
591 /* Parcour de tous les objets graphiques */
592 nbobj++;
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);
617 else
618 tabxobj[i]->title = (*tabobj)[i].title;
620 if ((*tabobj)[i].font == NULL && x11base->font != NULL)
621 tabxobj[i]->font = (char*)safestrdup(x11base->font);
622 else
623 tabxobj[i]->font = (*tabobj)[i].font;
625 if ((*tabobj)[i].forecolor == NULL)
626 tabxobj[i]->forecolor = (char*)safestrdup(x11base->forecolor);
627 else
628 tabxobj[i]->forecolor = (*tabobj)[i].forecolor;
630 if ((*tabobj)[i].backcolor == NULL)
631 tabxobj[i]->backcolor = (char*)safestrdup(x11base->backcolor);
632 else
633 tabxobj[i]->backcolor = (*tabobj)[i].backcolor;
635 if ((*tabobj)[i].shadcolor == NULL)
636 tabxobj[i]->shadcolor = (char*)safestrdup(x11base->shadcolor);
637 else
638 tabxobj[i]->shadcolor = (*tabobj)[i].shadcolor;
640 if ((*tabobj)[i].hilicolor == NULL)
641 tabxobj[i]->hilicolor = safestrdup(x11base->hilicolor);
642 else
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;
666 /* the QuitFunc */
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);
677 free(tabobj);
678 free(scriptprop);
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)
690 int i;
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)
705 int val[2];
706 char *token = NULL;
707 char *arg1 = NULL;
708 char *arg2 = NULL;
709 char *windowName;
710 int i;
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]);
717 return;
720 i = TabIdObj[val[0]];
721 if (i != -1) {
722 /* skip the integer argument */
723 action = GetNextToken(action, &token);
724 action = GetNextToken(action, &token);
725 if (LastString != NULL) {
726 free(LastString);
727 LastString = NULL;
729 if (action != NULL && strlen(action) > 0)
730 CopyString(&LastString,action);
732 SendMsg(tabxobj[i],val[1]);
733 }else{
734 fprintf(stderr,"[%s][%s]: <<WARNING>> no Widget %i\n",
735 ScriptName,type,val[0]);
737 if (token)
738 free(token);
739 }else{
740 fprintf(stderr,"[%s][%s]: <<WARNING>> Syntax Error: %s\n",
741 ScriptName,type,action);
743 }else{
745 if(StrEquals(type,"ChangeWindowTitle")){
746 action=GetNextToken(action, &arg1);
747 action=GetNextToken(action, &arg2);
749 if(arg2 == NULL){
751 XChangeProperty(
752 dpy, x11base->win, XA_WM_NAME, XA_STRING, 8, PropModeReplace,
753 (unsigned char*)arg1, strlen(arg1));
755 }else{
756 if(XFetchName(dpy, x11base->win, &windowName) == 0){
757 fprintf(
758 stderr,"[%s][SendMsgAndString]: <<ERROR>> "
759 "Can't find the title of a window\n", module->name);
760 }else{
761 if(StrEquals(arg2,windowName)){
762 XChangeProperty(
763 dpy, x11base->win, XA_WM_NAME, XA_STRING, 8,
764 PropModeReplace, (unsigned char*)arg1, strlen(arg1));
769 else
771 fprintf(
772 stderr,"[%s][SendMsgAndString]: <<ERROR>> "
773 "Unknown SendToModule command: %s\n", module->name, type);
776 if(arg1) free(arg1);
777 if(arg2) free(arg2);
783 * Appeler lors d'une demande de selection
785 void SendMsgToScript(XEvent event)
787 Atom Sender,Receiver=None;
788 static XEvent evnt_sel;
789 int i;
791 Sender = XInternAtom(dpy,x11base->TabScriptId[1],True);
793 if (event.xselectionrequest.selection == Sender)
795 i=0;
796 while ((i < BuffSend.NbMsg) && (event.xselectionrequest.target != Receiver))
798 Receiver = XInternAtom(dpy,BuffSend.TabMsg[i].R,True);
799 i++;
801 i--;
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;
812 XChangeProperty(dpy,
813 evnt_sel.xselection.requestor,
814 evnt_sel.xselection.property,
815 evnt_sel.xselection.target,
817 PropModeReplace,
818 (unsigned char *)(BuffSend.TabMsg[i].Msg),
819 strlen(BuffSend.TabMsg[i].Msg)+1);
820 BuffSend.NbMsg--;
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));
828 else
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);
837 static
838 void UpdateRootTransparency(Bool pr_only)
840 int i;
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))
850 SetWindowBackground(
851 dpy, x11base->win, x11base->size.width,
852 x11base->size.height,
853 &Colorset[x11base->colorset], Pdepth,
854 x11base->gc, True);
857 for (i=0; i<nbobj; i++)
859 if (Rectangle == tabxobj[i]->TypeWidget ||
860 SwallowExec == tabxobj[i]->TypeWidget)
862 continue;
864 if (!CSET_IS_TRANSPARENT(tabxobj[i]->colorset) ||
865 (CSET_IS_TRANSPARENT_PR(tabxobj[i]->colorset) &&
866 !CSET_IS_TRANSPARENT(x11base->colorset)))
868 continue;
870 if (CSET_IS_TRANSPARENT_PR_PURE(tabxobj[i]->colorset))
872 XClearArea(dpy, tabxobj[i]->win, 0, 0, 0, 0, True);
874 else if (!pr_only ||
875 CSET_IS_TRANSPARENT_PR(tabxobj[i]->colorset))
877 SetWindowBackground(
878 dpy, tabxobj[i]->win, tabxobj[i]->width,
879 tabxobj[i]->height,
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;
891 int i;
892 int isTab = 0;
893 char *octet;
894 KeySym ks;
895 static unsigned char buf[10]; /* unsigned for international */
896 Bool find = False;
897 char *action;
898 int ex, ey, ex2, ey2;
899 XClassHint tmp;
901 while (FEventsQueued(dpy, QueuedAfterReading))
903 FNextEvent(dpy, &event);
904 switch (event.type)
906 case Expose:
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);
927 break;
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);
938 break;
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);
952 break;
953 case ConfigureNotify:
955 Bool moved = False;
957 moved = event.xconfigure.send_event;
958 while (FCheckTypedEvent(dpy, ConfigureNotify, &event))
960 /* check for movement */
961 if (event.xconfigure.send_event)
962 moved = True;
964 if (moved)
966 UpdateRootTransparency(False);
969 break;
970 case KeyPress:
971 /* Touche presse dans un objet / Key press in an object */
972 isTab = 0;
973 find = False;
974 XLookupString(&event.xkey, (char *)buf, sizeof(buf), &ks, NULL);
975 event.xkey.keycode =
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)) !=
984 NULL)
986 SendMsgAndString(action, "CheckBinding");
987 break;
990 if (ks == XK_Tab) {
991 isTab = 1;
992 if (event.xkey.state & ShiftMask) {
993 /* does not work in general see AddBinding */
994 isTab = 2;
997 else if (ks == shift_tab_ks)
998 isTab = 2;
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)
1006 find = True;
1007 if (isTab == 0 && !HAS_NO_FOCUS(tabxobj[i])) {
1008 tabxobj[i]->EvtKey(tabxobj[i],&event.xkey);
1010 break;
1014 if (isTab > 0) {
1015 Bool loop = False;
1016 if (!find)
1017 i = (isTab == 1)? -1:nbobj;
1018 find = False;
1019 while(!find) {
1020 i = (isTab == 1)? i+1 : i-1;
1021 if (i == nbobj || i == -1) {
1022 i = (isTab == 1)? 0 : nbobj-1;
1023 if (loop) {
1024 i = -1;
1025 break;
1027 loop = True;
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)
1033 find = True;
1035 if (find)
1036 FWarpPointer(dpy, x11base->win, tabxobj[i]->win, 0, 0, 0, 0,
1037 tabxobj[i]->width/2, 10);
1039 break;
1040 case ButtonPress:
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);
1046 break;
1048 break;
1049 case ButtonRelease:
1050 break;
1051 case EnterNotify:
1052 break;
1053 case LeaveNotify:
1054 break;
1055 case MotionNotify:
1056 break;
1057 case MappingNotify:
1058 XRefreshKeyboardMapping((XMappingEvent*)&event);
1059 break;
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)
1071 case XA_STRING:
1072 XChangeProperty(dpy,
1073 evnt_sel.xselection.requestor,
1074 evnt_sel.xselection.property,
1075 evnt_sel.xselection.target,
1077 PropModeReplace,
1078 (unsigned char *)(Scrapt),
1079 strlen(Scrapt)+1);
1080 break;
1081 default:evnt_sel.xselection.property = None;
1083 FSendEvent(dpy,evnt_sel.xselection.requestor,
1084 False,0,&evnt_sel);
1086 else
1087 SendMsgToScript(event);
1088 break;
1089 case SelectionClear:
1090 if (event.xselectionclear.selection == XA_PRIMARY)
1091 UnselectAllTextField(tabxobj);
1092 break;
1093 case ClientMessage:
1094 if ((event.xclient.format == 32) &&
1095 (event.xclient.data.l[0] == wm_del_win))
1096 DeadPipe(1);
1097 break;
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);
1115 else break;
1116 if (i > 0)
1118 Scrapt = (char*)saferealloc((void*)Scrapt,sizeof(char)*(i+1));
1119 Scrapt = strcpy(Scrapt,octet);
1121 break;
1127 /* main event loop */
1128 void MainLoop (void)
1130 fd_set in_fdset;
1131 int i;
1132 struct timeval tv;
1133 struct timeval *ptv;
1134 struct timeval now, last_periodic;
1135 long delta;
1136 fd_set_size_t fd_width = fd[1];
1137 Bool fsm_pending = False;
1139 if (x_fd > fd_width) fd_width = x_fd;
1140 ++fd_width;
1142 tv.tv_sec = 1;
1143 tv.tv_usec = 0;
1144 ptv = NULL;
1145 if (x11base->periodictasks != NULL)
1147 gettimeofday(&last_periodic, NULL);
1148 ptv = &tv;
1151 while ( !isTerminated )
1153 while (FPending(dpy))
1154 ReadXServer();
1156 FD_ZERO(&in_fdset);
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;
1165 if (fsm_pending)
1167 tv.tv_sec = 0;
1168 tv.tv_usec = 10000; /* 10 ms */
1170 else
1172 tv.tv_usec = 1000000 - delta;
1173 if (tv.tv_usec < 0)
1174 tv.tv_usec = 0;
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))
1181 ReadXServer();
1183 if(FD_ISSET(fd[1], &in_fdset))
1185 FvwmPacket* packet = ReadFvwmPacket(fd[1]);
1186 if ( packet == NULL )
1187 exit(0);
1188 if (packet->type == M_CONFIG_INFO) {
1189 char *line, *token;
1190 int n;
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,
1219 x11base->gc, True);
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);
1234 if (token)
1235 free(token);
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)
1248 char *str;
1249 unsigned long u;
1250 Window s;
1251 char cmd[256];
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;
1259 else
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);
1274 SendText(fd,cmd,0);
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);
1287 if (token)
1288 free(token);
1290 else
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)
1311 int i;
1312 Atom myatom;
1313 int FisrtArg;
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);
1324 FisrtArg = 9;
1326 else
1327 { /* Cas du fils */
1328 x11base->TabScriptId[0] = (char*)safecalloc(sizeof(char),strlen(argv[7]));
1329 x11base->TabScriptId[0] = strncpy(x11base->TabScriptId[0],argv[7],
1330 strlen(argv[7])-2);
1331 x11base->TabScriptId[1] = argv[7];
1332 myatom=XInternAtom(dpy, x11base->TabScriptId[1], True);
1333 XSetSelectionOwner(dpy, myatom, x11base->win, CurrentTime);
1334 FisrtArg = 8;
1339 /* signal handler to close down the module */
1340 static RETSIGTYPE
1341 TerminateHandler(int sig)
1343 fvwmSetTerminate(sig);
1344 SIGNAL_RETURN;
1348 /* main procedure */
1349 int main (int argc, char **argv)
1351 int IsFather;
1352 int i;
1354 FlocaleInit(LC_CTYPE, "", "", "FvwmScript");
1356 module = ParseModuleArgs(argc,argv,0); /* no alias */
1357 if (module == NULL)
1359 fprintf(stderr,"FvwmScript must be started by Fvwm.\n");
1360 exit(1);
1363 if (module->user_argc == 0)
1365 fprintf(stderr,"FvwmScript requires the script's name or path.\n");
1366 exit(1);
1369 /* On determine si le script a un pere */
1370 if (module->user_argc >= 2)
1371 IsFather = (module->user_argv[1][0] != (char)161);
1372 else
1373 IsFather = 1;
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 */
1400 Xinit(IsFather);
1402 ParseOptions();
1404 SendText(fd,"Send_WindowList",0);
1406 ReadConfig(ScriptName); /* Lecture et analyse du script */
1408 /* Fonction d'initialisation de TabCom et TabFunc */
1409 InitCom();
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);
1421 #ifdef SA_INTERRUPT
1422 sigact.sa_flags = SA_INTERRUPT;
1423 #else
1424 sigact.sa_flags = 0;
1425 #endif
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);
1433 #else
1434 #ifdef USE_BSD_SIGNALS
1435 fvwmSetSignalMask( sigmask(SIGPIPE) |
1436 sigmask(SIGINT) |
1437 sigmask(SIGHUP) |
1438 sigmask(SIGTERM) |
1439 sigmask(SIGQUIT) );
1440 #endif
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);
1452 #endif
1453 #endif
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 */
1462 BuildGUI(IsFather);
1464 ReadFvwmScriptArg(argc,argv,IsFather);
1466 /* tell fvwm we're running */
1467 SendFinishedStartupNotification(fd);
1469 MainLoop();
1470 return 0;