Initial revision
[wmaker-crm.git] / src / main.c
blob2f87f07285bdd09ca254f2d8b46f9b6237eb058f
1 /*
2 * WindowMaker window manager
3 *
4 * Copyright (c) 1997, 1998 Alfredo K. Kojima
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * USA.
22 #include "wconfig.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <fcntl.h>
32 #include <X11/Xlib.h>
33 #include <X11/Xutil.h>
36 /* Xlocale.h and locale.h are the same if X_LOCALE is undefind in wconfig.h,
37 * and if X_LOCALE is defined, X's locale emulating functions will be used.
38 * See Xlocale.h for more information.
40 #include <X11/Xlocale.h>
42 #include "WindowMaker.h"
43 #include "window.h"
44 #include "funcs.h"
45 #include "menu.h"
46 #include "keybind.h"
47 #include "xmodifier.h"
48 #include "defaults.h"
50 #include <proplist.h>
53 /****** Global Variables ******/
55 /* general info */
57 Display *dpy;
59 char *ProgName;
61 unsigned int ValidModMask = 0xff;
63 /* locale to use. NULL==POSIX or C */
64 char *Locale=NULL;
67 int wScreenCount=0;
69 WPreferences wPreferences;
72 proplist_t wDomainName;
73 proplist_t wAttributeDomainName;
75 WShortKey wKeyBindings[WKBD_LAST];
77 /* defaults domains */
78 WDDomain *WDWindowMaker = NULL;
79 WDDomain *WDRootMenu = NULL;
80 WDDomain *WDWindowAttributes = NULL;
83 /* XContexts */
84 XContext wWinContext;
85 XContext wAppWinContext;
86 XContext wStackContext;
88 /* Atoms */
89 Atom _XA_WM_STATE;
90 Atom _XA_WM_CHANGE_STATE;
91 Atom _XA_WM_PROTOCOLS;
92 Atom _XA_WM_TAKE_FOCUS;
93 Atom _XA_WM_DELETE_WINDOW;
94 Atom _XA_WM_SAVE_YOURSELF;
95 Atom _XA_WM_CLIENT_LEADER;
96 Atom _XA_WM_COLORMAP_WINDOWS;
98 Atom _XA_GNUSTEP_WM_ATTR;
99 Atom _XA_WINDOWMAKER_WM_MINIATURIZE_WINDOW;
100 Atom _XA_GNUSTEP_WM_RESIZEBAR;
102 #ifdef MWM_HINTS
103 /* MWM support */
104 Atom _XA_MOTIF_WM_HINTS;
105 #endif
107 Atom _XA_WINDOWMAKER_MENU;
108 Atom _XA_WINDOWMAKER_WM_PROTOCOLS;
109 Atom _XA_WINDOWMAKER_STATE;
111 Atom _XA_WINDOWMAKER_WM_FUNCTION;
113 #ifdef OFFIX_DND
114 Atom _XA_DND_PROTOCOL;
115 Atom _XA_DND_SELECTION;
116 #endif
119 /* cursors */
120 Cursor wCursor[WCUR_LAST];
122 /* last event timestamp for XSetInputFocus */
123 Time LastTimestamp;
124 /* timestamp on the last time we did XSetInputFocus() */
125 Time LastFocusChange;
127 #ifdef SHAPE
128 int ShapeEventBase;
129 #endif
132 /* special flags */
133 char WRestartASAP = 0;
134 char WExitASAP = 0;
135 char WDelayedActionSet = 0;
137 /* temporary stuff */
138 int wVisualID = -1;
141 /******** End Global Variables *****/
143 static char *DisplayName = NULL;
144 static char **Arguments;
145 static int ArgCount;
147 extern void EventLoop();
148 extern void StartUp();
152 void
153 Restart(char *manager)
155 char *prog=NULL;
156 char *argv[MAX_RESTART_ARGS];
157 int i;
159 if (manager && manager[0]!=0) {
160 prog = argv[0] = strtok(manager, " ");
161 for (i=1; i<MAX_RESTART_ARGS; i++) {
162 argv[i]=strtok(NULL, " ");
163 if (argv[i]==NULL) {
164 break;
169 XCloseDisplay(dpy);
170 if (!prog)
171 execvp(Arguments[0], Arguments);
172 else {
173 execvp(prog, argv);
174 /* fallback */
175 execv(Arguments[0], Arguments);
177 wfatal(_("Restart failed!!!"));
178 exit(-1);
183 void
184 SetupEnvironment(WScreen *scr)
186 char *tmp, *ptr;
187 char buf[16];
189 if (wScreenCount == 1)
190 return;
192 tmp = wmalloc(strlen(DisplayName)+64);
193 sprintf(tmp, "DISPLAY=%s", XDisplayName(DisplayName));
194 ptr = strchr(strchr(DisplayName, ':'), '.');
195 if (ptr)
196 *ptr = 0;
197 sprintf(buf, ".%i", scr->screen);
198 strcat(tmp, buf);
199 putenv(tmp);
204 *---------------------------------------------------------------------
205 * wAbort--
206 * Do a major cleanup and exit the program
208 *----------------------------------------------------------------------
210 void
211 wAbort(Bool dumpCore)
213 int i;
214 WScreen *scr;
216 for (i=0; i<wScreenCount; i++) {
217 scr = wScreenWithNumber(i);
218 if (scr)
219 RestoreDesktop(scr);
221 printf(_("%s aborted.\n"), ProgName);
222 if (dumpCore)
223 abort();
224 else
225 exit(1);
229 void
230 print_help()
232 printf(_("usage: %s [-options]\n"), ProgName);
233 puts(_("options:"));
234 #ifdef USECPP
235 puts(_(" -nocpp disable preprocessing of configuration files"));
236 #endif
237 puts(_(" -nodock do not open the application Dock"));
238 puts(_(" -noclip do not open the workspace Clip"));
240 puts(_(" -locale locale locale to use"));
242 puts(_(" -visualid visualid visual id of visual to use"));
243 puts(_(" -display host:dpy display to use"));
244 puts(_(" -version print version and exit"));
249 void
250 check_defaults()
252 char *path;
254 path = wdefaultspathfordomain("");
255 if (access(path, R_OK)!=0) {
256 wfatal(_("could not find user GNUstep directory.\n"
257 "Make sure you have installed WindowMaker correctly and run wmaker.inst"));
258 exit(1);
261 free(path);
266 static void
267 execInitScript()
269 char *file;
271 file = wfindfile(DEF_CONFIG_PATHS, DEF_INIT_SCRIPT);
272 if (file) {
273 if (fork()==0) {
274 close(ConnectionNumber(dpy));
276 execl("/bin/sh", "/bin/sh", "-c", file, NULL);
277 wsyserror(_("%s:could not execute initialization script"), file);
278 exit(1);
280 free(file);
285 void
286 ExecExitScript()
288 char *file;
290 file = wfindfile(DEF_CONFIG_PATHS, DEF_EXIT_SCRIPT);
291 if (file) {
292 if (fork()==0) {
293 close(ConnectionNumber(dpy));
295 execl("/bin/sh", "/bin/sh", "-c", file, NULL);
296 wsyserror(_("%s:could not execute exit script"), file);
297 exit(1);
299 free(file);
306 main(int argc, char **argv)
308 int i, restart=0;
309 Bool multiHead = True;
310 char *str;
311 int d, s;
313 ArgCount = argc;
314 Arguments = argv;
316 WMInitializeApplication("WindowMaker", &argc, argv);
319 ProgName = strrchr(argv[0],'/');
320 if (!ProgName)
321 ProgName = argv[0];
322 else
323 ProgName++;
326 /* check existence of Defaults DB directory */
327 check_defaults();
329 restart = 0;
331 memset(&wPreferences, 0, sizeof(WPreferences));
333 if (argc>1) {
334 for (i=1; i<argc; i++) {
335 #ifdef USECPP
336 if (strcmp(argv[i], "-nocpp")==0) {
337 wPreferences.flags.nocpp=1;
338 } else
339 #endif
340 if (strcmp(argv[i], "-nodock")==0) {
341 wPreferences.flags.nodock=1;
342 } else if (strcmp(argv[i], "-noclip")==0) {
343 wPreferences.flags.noclip=1;
344 } else if (strcmp(argv[i], "-version")==0) {
345 printf("WindowMaker %s\n", VERSION);
346 exit(0);
347 } else if (strcmp(argv[i], "-global_defaults_path")==0) {
348 printf("%s/Defaults/WindowMaker", PKGDATADIR);
349 exit(0);
350 } else if (strcmp(argv[i], "-locale")==0) {
351 i++;
352 if (i>=argc) {
353 wwarning(_("too few arguments for %s"), argv[i-1]);
354 exit(0);
356 Locale = argv[i];
357 } else if (strcmp(argv[i], "-display")==0) {
358 i++;
359 if (i>=argc) {
360 wwarning(_("too few arguments for %s"), argv[i-1]);
361 exit(0);
363 DisplayName = argv[i];
364 } else if (strcmp(argv[i], "-visualid")==0) {
365 i++;
366 if (i>=argc) {
367 wwarning(_("too few arguments for %s"), argv[i-1]);
368 exit(0);
370 if (sscanf(argv[i], "%d", &wVisualID)!=1) {
371 wwarning(_("bad value for visualid: \"%s\""), argv[i]);
372 exit(0);
374 } else {
375 print_help();
376 exit(0);
380 #if 0
381 tmp = getenv("LANG");
382 if (tmp) {
383 if (setlocale(LC_ALL,"") == NULL) {
384 wwarning("cannot set locale %s", tmp);
385 wwarning("falling back to C locale");
386 setlocale(LC_ALL,"C");
387 Locale = NULL;
388 } else {
389 if (strcmp(tmp, "C")==0 || strcmp(tmp, "POSIX")==0)
390 Locale = NULL;
391 else
392 Locale = tmp;
394 } else {
395 Locale = NULL;
397 #endif
398 if (!Locale) {
399 Locale = getenv("LANG");
401 setlocale(LC_ALL, Locale);
402 if (!Locale || strcmp(Locale, "C")==0 || strcmp(Locale, "POSIX")==0)
403 Locale = NULL;
404 #ifdef I18N
405 if (getenv("NLSPATH"))
406 bindtextdomain("WindowMaker", getenv("NLSPATH"));
407 else
408 bindtextdomain("WindowMaker", NLSDIR);
409 textdomain("WindowMaker");
411 if (!XSupportsLocale()) {
412 wwarning(_("X server does not support locale"));
414 if (XSetLocaleModifiers("") == NULL) {
415 wwarning(_("cannot set locale modifiers"));
417 #endif
419 /* open display */
420 dpy = XOpenDisplay(DisplayName);
421 if (dpy == NULL) {
422 wfatal(_("could not open display \"%s\""), XDisplayName(DisplayName));
423 exit(1);
426 /* check if the user specified a complete display name (with screen).
427 * If so, only manage the specified screen */
428 if (DisplayName)
429 str = strchr(DisplayName, ':');
430 else
431 str = NULL;
432 if (!str)
433 str = "";
434 if (sscanf(str, "%i.%i", &d, &s)==2)
435 multiHead = False;
437 DisplayName = XDisplayName(DisplayName);
438 str = wmalloc(strlen(DisplayName)+64);
439 sprintf(str, "DISPLAY=%s", DisplayName);
440 putenv(str);
442 #ifdef DEBUG
443 XSynchronize(dpy, True);
444 #endif
446 wXModifierInitialize();
448 #ifdef SOUNDS
449 wSoundInitialize();
450 #endif
451 StartUp(!multiHead);
453 execInitScript();
455 EventLoop();
456 return -1;