void Done(int restart, char *command) { MenuRoot *mr; #ifndef NON_VIRTUAL MoveViewport(0, 0, False); #endif mr = FindPopup("ExitFunction"); if (mr != NULL) ExecuteFunction("Function ExitFunction", NULL, &Event, C_ROOT, -1); /* Close all my pipes */ ClosePipes(); Reborder(); if (restart) { SaveDesktopState(); /* I wonder why ... */ /* Really make sure that the connection is closed and cleared! */ XSelectInput(dpy, Scr.Root, 0); XSync(dpy, 0); XCloseDisplay(dpy); { char *my_argv[10]; int i, done, j; i = 0; j = 0; done = 0; while ((g_argv[j] != NULL) && (i < 8)) { if (strcmp(g_argv[j], "-s") != 0) { my_argv[i] = g_argv[j]; i++; j++; } else j++; } if (strstr(command, "fvwm") != NULL) my_argv[i++] = "-s"; while (i < 10) my_argv[i++] = NULL; /* really need to destroy all windows, explicitly, * not sleep, but this is adequate for now */ sleep(1); ReapChildren(); execvp(command, my_argv); } fvwm_msg(ERR, "Done", "Call of '%s' failed!!!!", command); execvp(g_argv[0], g_argv); /* that _should_ work */ fvwm_msg(ERR, "Done", "Call of '%s' failed!!!!", g_argv[0]); } else { XCloseDisplay(dpy); exit(0); } }
int main(int argc, char **argv) { unsigned long valuemask; /* mask for create windows */ XSetWindowAttributes attributes; /* attributes for create windows */ void InternUsefulAtoms(void); void InitVariables(void); int i, len; extern int x_fd; char *display_string; char message[255]; Bool single = False; Bool option_error = FALSE; MenuRoot *mr; g_argv = argv; g_argc = argc; OpenConsole(); DBUG("main", "Entered, about to parse args"); for (i = 1; i < argc; i++) { if (strncasecmp(argv[i], "-debug", 6) == 0) { debugging = True; } else if (strncasecmp(argv[i], "-s", 2) == 0) { single = True; } else if (strncasecmp(argv[i], "-d", 2) == 0) { if (++i >= argc) usage(); display_name = argv[i]; } else if (strncasecmp(argv[i], "-f", 2) == 0) { if (++i >= argc) usage(); config_command = (char *) malloc(6 + strlen(argv[i])); strcpy(config_command, "Read "); strcat(config_command, argv[i]); free_config_command = True; } else if (strncasecmp(argv[i], "-cmd", 4) == 0) { if (++i >= argc) usage(); config_command = argv[i]; } else if (strncasecmp(argv[i], "-file", 5) == 0) { if (++i >= argc) usage(); output_file = argv[i]; } else if (strncasecmp(argv[i], "-h", 2) == 0) { usage(); exit(0); } else if (strncasecmp(argv[i], "-blackout", 9) == 0) { Blackout = True; } else if (strncasecmp(argv[i], "-version", 8) == 0) { fvwm_msg(INFO, "main", "Fvwm95 Version %s compiled on %s at %s\n", VERSION, __DATE__, __TIME__); } else { fvwm_msg(ERR, "main", "Unknown option: `%s'\n", argv[i]); option_error = TRUE; } } DBUG("main", "Done parsing args"); if (option_error) { usage(); } DBUG("main", "Installing signal handlers"); newhandler(SIGINT); newhandler(SIGHUP); newhandler(SIGQUIT); newhandler(SIGTERM); signal(SIGUSR1, Restart); signal(SIGPIPE, DeadPipe); ReapChildren(); if (!(dpy = XOpenDisplay(display_name))) { fvwm_msg(ERR, "main", "can't open display %s", XDisplayName(display_name)); exit(1); } Scr.screen = DefaultScreen(dpy); Scr.NumberOfScreens = ScreenCount(dpy); master_pid = getpid(); if (!single) { int myscreen = 0; char *cp; strcpy(message, XDisplayString(dpy)); XCloseDisplay(dpy); for (i = 1; i < Scr.NumberOfScreens; i++) { if (fork() == 0) { myscreen = i; break; } } /* * Truncate the string 'whatever:n.n' to 'whatever:n', * and then append the screen number. */ cp = strchr(message, ':'); if (cp != NULL) { cp = strchr(cp, '.'); if (cp != NULL) *cp = '\0'; /* truncate at display part */ } sprintf(message + strlen(message), ".%d", myscreen); dpy = XOpenDisplay(message); Scr.screen = myscreen; Scr.NumberOfScreens = ScreenCount(dpy); } x_fd = XConnectionNumber(dpy); fd_width = GetFdWidth(); if (fcntl(x_fd, F_SETFD, 1) == -1) { fvwm_msg(ERR, "main", "close-on-exec failed"); exit(1); } /* Add a DISPLAY entry to the environment, in case we were started * with fvwm -display term:0.0 */ len = strlen(XDisplayString(dpy)); display_string = safemalloc(len + 10); sprintf(display_string, "DISPLAY=%s", XDisplayString(dpy)); putenv(display_string); /* Add a HOSTDISPLAY environment variable, which is the same as * DISPLAY, unless display = :0.0 or unix:0.0, in which case the full * host name will be used for ease in networking . */ /* Note: Can't free the rdisplay_string after putenv, because it * becomes part of the environment! */ if (strncmp(display_string, "DISPLAY=:", 9) == 0) { char client[MAXHOSTNAME], *rdisplay_string; mygethostname(client, MAXHOSTNAME); rdisplay_string = safemalloc(len + 14 + strlen(client)); sprintf(rdisplay_string, "HOSTDISPLAY=%s:%s", client, &display_string[9]); putenv(rdisplay_string); } else if (strncmp(display_string, "DISPLAY=unix:", 13) == 0) { char client[MAXHOSTNAME], *rdisplay_string; mygethostname(client, MAXHOSTNAME); rdisplay_string = safemalloc(len + 14 + strlen(client)); sprintf(rdisplay_string, "HOSTDISPLAY=%s:%s", client, &display_string[13]); putenv(rdisplay_string); } else { char *rdisplay_string; rdisplay_string = safemalloc(len + 14); sprintf(rdisplay_string, "HOSTDISPLAY=%s", XDisplayString(dpy)); putenv(rdisplay_string); } Scr.Root = RootWindow(dpy, Scr.screen); if (Scr.Root == None) { fvwm_msg(ERR, "main", "Screen %d is not a valid screen", (char *) Scr.screen); exit(1); } #ifdef SHAPE ShapesSupported = XShapeQueryExtension(dpy, &ShapeEventBase, &ShapeErrorBase); #endif /* SHAPE */ InternUsefulAtoms(); /* Make sure property priority colors is empty */ XChangeProperty(dpy, Scr.Root, _XA_MIT_PRIORITY_COLORS, XA_CARDINAL, 32, PropModeReplace, NULL, 0); XSetErrorHandler((XErrorHandler) CatchRedirectError); XSetIOErrorHandler((XIOErrorHandler) CatchFatal); XSelectInput(dpy, Scr.Root, LeaveWindowMask | EnterWindowMask | PropertyChangeMask | SubstructureRedirectMask | KeyPressMask | SubstructureNotifyMask | ButtonPressMask | ButtonReleaseMask); XSync(dpy, 0); XSetErrorHandler((XErrorHandler) FvwmErrorHandler); BlackoutScreen(); CreateCursors(); InitVariables(); InitEventHandlerJumpTable(); initModules(); InitPictureCMap(dpy, Scr.Root); /* for the pixmap cache... */ Scr.gray_bitmap = XCreateBitmapFromData(dpy, Scr.Root, g_bits, g_width, g_height); DBUG("main", "Setting up rc file defaults..."); SetRCDefaults(); DBUG("main", "Running config_command..."); ExecuteFunction(config_command, NULL, &Event, C_ROOT, -1); DBUG("main", "Done running config_command"); /* CaptureAllWindows(); MakeMenus(); */ #if 0 /* this seems to cause problems for FvwmCpp/M4 startup actually */ /* if not a direct 'Read', we'll capture all windows here, in case cmd fails we'll still have defaults */ if (strncasecmp(config_command, "Read", 4) != 0 && strncasecmp(config_command, "PipeRead", 8) != 0) { /* so if cmd (FvwmM4/Cpp most likely) fails, we can still have borders & stuff... */ StartupStuff(); } #endif /* 0 */ if (free_config_command) { free(config_command); } if (Scr.d_depth < 2) { Scr.gray_pixmap = XCreatePixmapFromBitmapData(dpy, Scr.Root, g_bits, g_width, g_height, Scr.WinColors.fore, Scr.WinColors.back, Scr.d_depth); Scr.light_gray_pixmap = XCreatePixmapFromBitmapData(dpy, Scr.Root, l_g_bits, l_g_width, l_g_height, Scr.WinColors.fore, Scr.WinColors.back, Scr.d_depth); } /* create a window which will accept the keyboard focus when no other windows have it */ attributes.event_mask = KeyPressMask | FocusChangeMask; attributes.override_redirect = True; Scr.NoFocusWin = XCreateWindow(dpy, Scr.Root, -10, -10, 10, 10, 0, 0, InputOnly, CopyFromParent, CWEventMask | CWOverrideRedirect, &attributes); XMapWindow(dpy, Scr.NoFocusWin); SetMWM_INFO(Scr.NoFocusWin); XSetInputFocus(dpy, Scr.NoFocusWin, RevertToParent, CurrentTime); XSync(dpy, 0); if (debugging) XSynchronize(dpy, 1); Scr.SizeStringWidth = XTextWidth(Scr.StdFont.font, " +8888 x +8888 ", 15); attributes.border_pixel = Scr.WinColors.fore; attributes.background_pixel = Scr.WinColors.back; attributes.bit_gravity = NorthWestGravity; attributes.save_under = True; valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity | CWSaveUnder); /* create the window for coordinates */ Scr.SizeWindow = XCreateWindow(dpy, Scr.Root, Scr.MyDisplayWidth / 2 - (Scr.SizeStringWidth + SIZE_HINDENT * 2) / 2, Scr.MyDisplayHeight / 2 - (Scr.StdFont.height + SIZE_VINDENT * 2) / 2, (unsigned int) (Scr.SizeStringWidth + SIZE_HINDENT * 2), (unsigned int) (Scr.StdFont.height + SIZE_VINDENT * 2), (unsigned int) 0, 0, (unsigned int) CopyFromParent, (Visual *) CopyFromParent, valuemask, &attributes); #ifndef NON_VIRTUAL initPanFrames(); #endif XGrabServer(dpy); #ifndef NON_VIRTUAL checkPanFrames(); #endif XUngrabServer(dpy); UnBlackoutScreen(); DBUG("main", "Entering HandleEvents loop..."); HandleEvents(); DBUG("main", "Back from HandleEvents loop? Exiting..."); return 0; }
/*************************************************************************** * * Waits for next X event, or for an auto-raise timeout. * ****************************************************************************/ int My_XNextEvent(Display *dpy, XEvent *event) { extern int fd_width, x_fd; fd_set in_fdset, out_fdset; Window targetWindow; int i; DBUG("My_XNextEvent","Routine Entered"); /* Do this IMMEDIATELY prior to select, to prevent any nasty * queued up X events from just hanging around waiting to be * flushed */ XFlush(dpy); if(XPending(dpy)) { DBUG("My_XNextEvent","taking care of queued up events & returning"); XNextEvent(dpy,event); StashEventTime(event); return 1; } DBUG("My_XNextEvent","no X events waiting - about to reap children"); /* Zap all those zombies! */ /* If we get to here, then there are no X events waiting to be processed. * Just take a moment to check for dead children. */ ReapChildren(); FD_ZERO(&in_fdset); FD_SET(x_fd,&in_fdset); FD_ZERO(&out_fdset); for(i=0; i<npipes; i++) { if(readPipes[i]>=0) { FD_SET(readPipes[i], &in_fdset); } if(pipeQueue[i]!= NULL) { FD_SET(writePipes[i], &out_fdset); } } DBUG("My_XNextEvent","waiting for module input/output"); XFlush(dpy); if (select((SELECT_TYPE_ARG1)fd_width, SELECT_TYPE_ARG234 &in_fdset, SELECT_TYPE_ARG234 &out_fdset, SELECT_TYPE_ARG234 0, SELECT_TYPE_ARG5 NULL) > 0) { /* Check for module input. */ for(i=0;i<npipes;i++) { if(readPipes[i] >= 0) { if(FD_ISSET(readPipes[i], &in_fdset)) { if( read(readPipes[i],&targetWindow, sizeof(Window)) >0 ) { DBUG("My_XNextEvent","calling HandleModuleInput"); HandleModuleInput(targetWindow,i); } else { DBUG("My_XNextEvent","calling KillModule"); KillModule(i,10); } } } if(writePipes[i] >= 0) { if(FD_ISSET(writePipes[i], &out_fdset)) { DBUG("My_XNextEvent","calling FlushQueue"); FlushQueue(i); } } } /* for */ } DBUG("My_XNextEvent","leaving My_XNextEvent"); return 0; }