2 /* This module, and the entire FvwmCpp program, and the concept for
3 * interfacing this module to the Window Manager, are all original work
6 * Copyright 1994, Robert Nation
7 * No guarantees or warantees or anything
8 * are provided or implied in any way whatsoever. Use this program at your
9 * own risk. Permission to use this program for any purpose is given,
10 * as long as the copyright is kept intact. */
12 /* This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "libs/ftime.h"
37 #include <sys/param.h>
38 #include <sys/types.h>
42 #include <X11/Xutil.h>
43 #include <X11/Xproto.h>
44 #include <X11/Xatom.h>
45 #include <X11/Intrinsic.h>
47 #include "libs/Module.h"
48 #include "libs/fvwm_sys_stat.h"
51 #include "libs/fvwmlib.h"
52 #include "libs/FShape.h"
53 #include "libs/PictureBase.h"
54 #include "libs/FSMlib.h"
55 #include "libs/Strings.h"
56 #include "libs/System.h"
57 #include <X11/StringDefs.h>
58 #include <X11/Shell.h>
59 #define Resolution(pixels, mm) ((((pixels) * 2000 / (mm)) + 1) / 2)
65 static char *MkDef(char *name
, char *def
);
66 static char *MkNum(char *name
,int def
);
67 static char *cpp_defs(Display
*display
, const char *host
, char *m4_options
, char *config_file
);
68 #define MAXHOSTNAME 255
71 char *cpp_prog
= FVWM_CPP
; /* Name of the cpp program */
73 char cpp_options
[BUFSIZ
];
74 char cpp_outfile
[BUFSIZ
]="";
80 * main - start of module
83 int main(int argc
, char **argv
)
85 Display
*dpy
; /* which display are we talking to */
87 char *display_name
= NULL
;
88 char *filename
= NULL
;
96 /* Figure out the working directory and go to it */
97 user_dir
= getenv("FVWM_USERDIR");
100 if (chdir(user_dir
) < 0)
101 fprintf(stderr
, "%s: <<Warning>> chdir to %s failed in cpp_defs",
105 sprintf(cpp_options
, "-I'%s' ", FVWM_DATADIR
);
107 /* Record the program name for error messages */
110 s
=strrchr(argv
[0], '/');
114 MyName
= safemalloc(strlen(temp
)+2);
116 strcat(MyName
, temp
);
120 fprintf(stderr
,"%s Version %s should only be executed by fvwm!\n",MyName
,
125 /* We should exit if our fvwm pipes die */
126 signal (SIGPIPE
, DeadPipe
);
128 fd
[0] = atoi(argv
[1]);
129 fd
[1] = atoi(argv
[2]);
133 /* leaving this in just in case-- any option starting with '-'
134 will get passed on to cpp anyway */
135 if(strcasecmp(argv
[i
],"-cppopt") == 0)
137 strcat(cpp_options
, argv
[++i
]);
138 strcat(cpp_options
, " ");
140 else if (strcasecmp(argv
[i
], "-cppprog") == 0)
142 cpp_prog
= argv
[++i
];
144 else if(strcasecmp(argv
[i
], "-outfile") == 0)
146 strcpy(cpp_outfile
,argv
[++i
]);
148 else if(strcasecmp(argv
[i
], "-debug") == 0)
152 else if(strcasecmp(argv
[i
], "-lock") == 0)
156 else if(strcasecmp(argv
[i
], "-noread") == 0)
160 else if (strncasecmp(argv
[i
],"-",1) == 0)
162 /* pass on any other arguments starting with '-' to cpp */
163 strcat(cpp_options
, argv
[i
]);
164 strcat(cpp_options
, " ");
170 /* If we don't have a cpp, stop right now. */
171 if (!cpp_prog
|| cpp_prog
[0] == '\0') {
172 fprintf(stderr
, "%s: no C preprocessor program specified\n", MyName
);
178 fprintf(stderr
, "%s: no file specified.\n", MyName
);
181 for(i
=0;i
<strlen(filename
);i
++)
182 if((filename
[i
] == '\n')||(filename
[i
] == '\r'))
187 if (!(dpy
= XOpenDisplay(display_name
)))
189 fprintf(stderr
,"%s: can't open display %s",
190 MyName
, XDisplayName(display_name
));
195 PictureInitCMap(dpy
);
197 /* tell fvwm we're running if -lock is not used */
199 SendFinishedStartupNotification(fd
);
201 tmp_file
= cpp_defs(dpy
, display_name
,cpp_options
, filename
);
205 char *read_string
= CatString3("Read '", tmp_file
, "'");
206 SendText(fd
, read_string
, 0);
209 /* tell fvwm to continue if -lock is used */
211 SendFinishedStartupNotification(fd
);
213 /* For a debugging version, we may wish to omit this part. */
214 /* I'll let some cpp advocates clean this up */
218 char *delete_file
= tmp_file
;
219 if (tmp_file
[0] != '/' && user_dir
!= NULL
)
221 delete_file
= safestrdup(CatString3(user_dir
, "/", tmp_file
));
223 delete_string
= CatString3("Exec exec /bin/rm '", delete_file
, "'");
224 SendText(fd
, delete_string
, 0);
232 static char *cpp_defs(Display
*display
, const char *host
, char *cpp_options
, char *config_file
)
236 char client
[MAXHOSTNAME
], server
[MAXHOSTNAME
], *colon
;
238 char options
[BUFSIZ
];
239 static char tmp_name
[BUFSIZ
];
240 struct hostent
*hostname
;
241 char *vc
; /* Visual Class */
243 struct passwd
*pwent
;
245 int ScreenWidth
, ScreenHeight
;
248 /* Generate a temporary filename. Honor the TMPDIR environment variable,
249 if set. Hope nobody deletes this file! */
251 if (strlen(cpp_outfile
) == 0)
253 if ((vc
=getenv("TMPDIR")))
255 strcpy(tmp_name
, vc
);
259 strcpy(tmp_name
, "/tmp");
261 strcat(tmp_name
, "/fvwmrcXXXXXX");
262 fd
= fvwm_mkstemp(tmp_name
);
267 "[FvwmCpp][cpp_def] fvwm_mkstemp failed %s\n",
274 strcpy(tmp_name
,cpp_outfile
);
276 * check to make sure it doesn't exist already, to prevent
279 /* first try to unlink it */
282 tmp_name
, O_WRONLY
|O_EXCL
|O_CREAT
,
283 FVWM_S_IRUSR
| FVWM_S_IWUSR
);
288 "[FvwmCpp][cpp_defs] error opening file %s\n",
296 * Create the appropriate command line to run cpp, and
297 * open a pipe to the command.
300 sprintf(options
, "%s %s >%s\n", cpp_prog
, cpp_options
, tmp_name
);
301 tmpf
= popen(options
, "w");
306 "[FvwmCpp][cpp_defs] Cannot open pipe to cpp\n");
310 gethostname(client
,MAXHOSTNAME
);
312 getostype (ostype
, sizeof ostype
);
314 hostname
= gethostbyname(client
);
315 strcpy(server
, XDisplayName(host
));
316 colon
= strchr(server
, ':');
317 if (colon
!= NULL
) *colon
= '\0';
318 if ((server
[0] == '\0') || (!strcmp(server
, "unix")))
319 strcpy(server
, client
); /* must be connected to :0 or unix:0 */
321 /* TWM_TYPE is fvwm, for completeness */
323 fputs(MkDef("TWM_TYPE", "fvwm"), tmpf
);
325 /* The machine running the X server */
326 fputs(MkDef("SERVERHOST", server
), tmpf
);
327 /* The machine running the window manager process */
328 fputs(MkDef("CLIENTHOST", client
), tmpf
);
330 fputs(MkDef("HOSTNAME", (char *)hostname
->h_name
), tmpf
);
332 fputs(MkDef("HOSTNAME", (char *)client
), tmpf
);
334 fputs(MkDef("OSTYPE", ostype
), tmpf
);
336 pwent
=getpwuid(geteuid());
337 fputs(MkDef("USER", pwent
->pw_name
), tmpf
);
339 fputs(MkDef("HOME", getenv("HOME")), tmpf
);
340 fputs(MkNum("VERSION", ProtocolVersion(display
)), tmpf
);
341 fputs(MkNum("REVISION", ProtocolRevision(display
)), tmpf
);
342 fputs(MkDef("VENDOR", ServerVendor(display
)), tmpf
);
343 fputs(MkNum("RELEASE", VendorRelease(display
)), tmpf
);
345 Mscreen
= DefaultScreen(display
);
346 fputs(MkNum("SCREEN", Mscreen
), tmpf
);
348 ScreenWidth
= DisplayWidth(display
,Mscreen
);
349 ScreenHeight
= DisplayHeight(display
,Mscreen
);
350 fputs(MkNum("WIDTH", DisplayWidth(display
,Mscreen
)), tmpf
);
351 fputs(MkNum("HEIGHT", DisplayHeight(display
,Mscreen
)), tmpf
);
353 screen
= ScreenOfDisplay(display
, Mscreen
);
354 fputs(MkNum("X_RESOLUTION",Resolution(screen
->width
,screen
->mwidth
)),
356 fputs(MkNum("Y_RESOLUTION",Resolution(screen
->height
,screen
->mheight
)),
358 fputs(MkNum("PLANES",DisplayPlanes(display
, Mscreen
)), tmpf
);
360 visual
= DefaultVisualOfScreen(screen
);
361 fputs(MkNum("BITS_PER_RGB", visual
->bits_per_rgb
), tmpf
);
363 switch(visual
->class)
387 fputs(MkDef("CLASS", vc
), tmpf
);
389 switch(Pvisual
->class)
413 fputs(MkDef("FVWM_CLASS", vc
), tmpf
);
415 if (visual
->class != StaticGray
&& visual
->class != GrayScale
)
416 fputs(MkDef("COLOR", "Yes"), tmpf
);
418 fputs(MkDef("COLOR", "No"), tmpf
);
420 if (Pvisual
->class != StaticGray
&& Pvisual
->class != GrayScale
)
421 fputs(MkDef("FVWM_COLOR", "Yes"), tmpf
);
423 fputs(MkDef("FVWM_COLOR", "No"), tmpf
);
425 fputs(MkDef("FVWM_VERSION", VERSION
), tmpf
);
427 /* Add options together */
429 if (FHaveShapeExtension
)
430 strcat(options
, "SHAPE ");
433 strcat(options
, "XPM ");
435 strcat(options
, "Cpp ");
437 fputs(MkDef("OPTIONS", options
), tmpf
);
439 fputs(MkDef("FVWM_MODULEDIR", FVWM_MODULEDIR
), tmpf
);
440 fputs(MkDef("FVWM_DATADIR", FVWM_DATADIR
), tmpf
);
442 if ((vc
= getenv("FVWM_USERDIR")))
443 fputs(MkDef("FVWM_USERDIR", vc
), tmpf
);
445 if (SessionSupport
&& (vc
= getenv("SESSION_MANAGER")))
446 fputs(MkDef("SESSION_MANAGER", vc
), tmpf
);
450 * At this point, we've sent the definitions to cpp. Just include
451 * the fvwmrc file now.
454 fprintf(tmpf
, "#include \"%s\"\n", config_file
);
467 * SIGPIPE handler - SIGPIPE means fvwm is dying
470 RETSIGTYPE
DeadPipe(int nonsense
)
476 static char *MkDef(char *name
, char *def
)
481 /* Get space to hold everything, if needed */
483 n
= EXTRA
+ strlen(name
) + strlen(def
);
486 sprintf(cp
, "#define %s %s\n",name
,def
);
491 static char *MkNum(char *name
,int def
)
495 sprintf(num
, "%d", def
);
497 return(MkDef(name
, num
));