/* * This should return 0 if process of running external app to draw background completed or killed. * otherwise it returns > 0 */ int check_singleton_child (int singleton_id, Bool kill_it_to_death) { int i; int pid, status; if( as_init_singletons || singleton_id < 0 ) return -1 ; if( singleton_id >= MAX_SINGLETONS_NUM ) singleton_id = MAX_SINGLETONS_NUM-1; DEBUG_OUT("CheckingForDrawChild(%lu)....",time (NULL)); if ( (pid = as_singletons[singleton_id]) > 0) { DEBUG_OUT("checking on singleton child #%d started with PID (%d)", singleton_id, pid); if (kill_it_to_death) { kill (pid, SIGTERM); for (i = 0; i < 100; i++) /* give it 10 sec to terminate */ { sleep_a_millisec (100); if ( WAIT_CHILDREN (&status) == pid || as_singletons[singleton_id] <= 0 ) break; } if (i >= 100) kill (pid, SIGKILL); /* no more mercy */ as_singletons[singleton_id] = 0 ; } } else if (as_singletons[singleton_id] < 0) as_singletons[singleton_id] = 0; DEBUG_OUT ("Done(%lu). Child PID on exit = %d.", time (NULL), as_singletons[singleton_id]); return as_singletons[singleton_id]; }
int next_event (register XEvent * event_return, Bool compress_motion) { register int res; res = (XNextEvent (dpy, event_return) == 0); if (res) { stash_event_time (event_return); #if 0 if (compress_motion && event_return->type == MotionNotify) { if (recursively_find_motion_notify (5)) return (False); XFlush (dpy); if (recursively_find_motion_notify (5)) return (False); sleep_a_millisec (20); /* 0.3 sec delay */ if (recursively_find_motion_notify (10)) return False; } #endif } return res; }
void Done (Bool restart, char *command ) { int restart_screen = get_flags( AfterStepState, ASS_SingleScreen)?Scr.screen:-1; Bool restart_self = False ; char *local_command = NULL ; { static int already_dead = False ; if( already_dead ) return;/* non-reentrant function ! */ already_dead = True ; } /* lets duplicate the string so we don't accidental;y delete it while closing self down */ if( restart ) { int my_name_len = strlen(MyName); if( command ) { if( strncmp(command, MyName, my_name_len )==0 ) restart_self = (command[my_name_len] == ' '|| command[my_name_len] == '\0'); local_command = mystrdup(command); }else { local_command = mystrdup(MyName); restart_self = True ; } if (!is_executable_in_path(local_command)) { if (!restart_self || MyArgs.saved_argv[0] == NULL) { show_error("Cannot restart with command \"%s\" - application is not in PATH!", local_command); return; } free(local_command); if (command) { local_command = safemalloc(strlen(command) + 1+ strlen(MyArgs.saved_argv[0])+1); sprintf( local_command, "%s %s", MyArgs.saved_argv[0], command + my_name_len); }else local_command = mystrdup(MyArgs.saved_argv[0]); } } #ifdef XSHMIMAGE /* may not need to do that as server may still have some of the shared * memory and work in it */ flush_shm_cache(); #endif LOCAL_DEBUG_CALLER_OUT( "%s restart, cmd=\"%s\"", restart?"Do":"Don't", command?command:""); XSelectInput( dpy, Scr.Root, 0 ); SendPacket (-1, M_SHUTDOWN, 0); FlushAllQueues(); sleep_a_millisec(1000); LOCAL_DEBUG_OUT( "local_command = \"%s\", restart_self = %s", local_command, restart_self?"Yes":"No"); set_flags( AfterStepState, ASS_Shutdown ); if( restart ) set_flags( AfterStepState, ASS_Restarting ); clear_flags( AfterStepState, ASS_NormalOperation ); #ifndef NO_VIRTUAL MoveViewport (0, 0, False); #endif #ifndef NO_SAVEWINDOWS if (!restart) { char *fname = make_session_file( Session, AFTER_SAVE, False ); save_aswindow_list( Scr.Windows, NULL ); free( fname ); } #endif /* Close all my pipes */ ShutdownModules(False); desktop_cover_cleanup(); /* remove window frames */ CleanupScreen(); /* Really make sure that the connection is closed and cleared! */ XSync (dpy, 0); if (ASDBus_fd>=0) asdbus_shutdown(); #ifdef XSHMIMAGE flush_shm_cache(); #endif if (restart) { set_flags( MyArgs.flags, ASS_Restarting ); spawn_child( local_command, -1, restart_screen, original_DISPLAY_string, None, C_NO_CONTEXT, False, restart_self, NULL ); } else { XCloseDisplay (dpy); dpy = NULL ; /* freeing up memory */ DestroyPendingFunctionsQueue(); DestroyCategories(); cleanup_default_balloons(); destroy_asdatabase(); destroy_assession( Session ); destroy_asenvironment( &Environment ); /* pixmap references */ build_xpm_colormap (NULL); free_scratch_ids_vector(); free_scratch_layers_vector(); clientprops_cleanup (); wmprops_cleanup (); free_func_hash(); flush_keyword_ids(); purge_asimage_registry(); asxml_var_cleanup(); custom_color_cleanup(); free_as_app_args(); free( ASDefaultScr ); flush_default_asstorage(); flush_asbidirlist_memory_pool(); flush_ashash_memory_pool(); #ifdef DEBUG_ALLOCS print_unfreed_mem (); #endif /*DEBUG_ALLOCS */ #ifdef XSHMIMAGE flush_shm_cache(); #endif } exit(0); }
void asdbus_process_messages (ASDBusFd* fd) { //show_progress ("checking dbus messages for fd = %d", fd->fd); #ifndef ASDBUS_DISPATCH while (ASDBus.session_conn) { DBusMessage *msg; const char *interface, *member; /* non blocking read of the next available message */ dbus_connection_read_write (ASDBus.session_conn, 0); msg = dbus_connection_pop_message (ASDBus.session_conn); if (NULL == msg) { /* show_progress ("no more Dbus messages..."); */ //show_progress("time(%ld):dbus message not received during the timeout - sleeping...", time (NULL)); return; } interface = dbus_message_get_interface (msg); member = dbus_message_get_member (msg); show_debug(__FILE__,__FUNCTION__, __LINE__, "dbus msg iface = \"%s\", member = \"%s\"", interface?interface:"(nil)", member?member:"(nil)"); if (interface == NULL || member == NULL) { show_progress ("time(%ld):dbus message cannot be parsed...", time (NULL)); } else { show_progress ("time(%ld):dbus message received from \"%s\", member \"%s\"", time (NULL), interface, member); if (strcmp (interface, IFACE_SESSION_PRIVATE) == 0) { if (strcmp (member, "QueryEndSession") == 0) { /* must replay yes within 10 seconds */ asdbus_EndSessionOk (); asdbus_Notify ("Session is ending ...", "Checking if it is safe to logout", 0); SaveSession (True); } else if (strcmp (member, "EndSession") == 0) { /*cover_desktop (); display_progress (True, "Session is ending, please wait ..."); */ asdbus_Notify ("Session is ending ...", "Closing apps, please wait.", 0); dbus_connection_read_write (ASDBus.session_conn, 0); /* Yield to let other clients process Session Management requests */ sleep_a_millisec (300); CloseSessionClients (False); /* we want to end to the very end */ } else if (strcmp (member, "Stop") == 0) { asdbus_Notify ("Session is over.", "Bye-bye!", 0); dbus_connection_read_write (ASDBus.session_conn, 0); Done (False, NULL); } } } #if 0 if (dbus_message_is_method_call (msg, "test.method.Type", "Method")) reply_to_method_call (msg, conn); #endif dbus_message_unref (msg); } #else if (ASDBus.session_conn) do { dbus_connection_read_write_dispatch (ASDBus.session_conn, 0); } while (dbus_connection_get_dispatch_status (ASDBus.session_conn) == DBUS_DISPATCH_DATA_REMAINS); #endif }
/*********************************************************************** * Procedure: * main - start of afterstep ************************************************************************/ int main (int argc, char **argv, char **envp) { register int i ; int start_viewport_x = 0 ; int start_viewport_y = 0 ; int start_desk = 0 ; #ifdef LOCAL_DEBUG #if 0 LOCAL_DEBUG_OUT( "calibrating sleep_a_millisec : %s","" ); for( i = 0 ; i < 500 ; ++i ) sleep_a_millisec( 10 ); LOCAL_DEBUG_OUT( "500 sliip_a_millisec(10) completed%s","" ); for( i = 0 ; i < 50 ; ++i ) sleep_a_millisec( 100 ); LOCAL_DEBUG_OUT( "50 sliip_a_millisec(100) completed%s","" ); for( i = 0 ; i < 10 ; ++i ) sleep_a_millisec( 300 ); LOCAL_DEBUG_OUT( "10 sliip_a_millisec(300) completed%s","" ); #endif #endif _as_grab_screen_func = GrabEm; _as_ungrab_screen_func = UngrabEm; original_DISPLAY_string = getenv("DISPLAY"); if (original_DISPLAY_string) original_DISPLAY_string = mystrdup(original_DISPLAY_string); #ifdef DEBUG_TRACE_X trace_window_id2name_hook = &window_id2name; #endif set_DeadPipe_handler(DeadPipe); #if !HAVE_DECL_ENVIRON override_environ( envp ); #endif InitMyApp( CLASS_AFTERSTEP, argc, argv, NULL, AfterStep_usage, 0); LinkAfterStepConfig(); AfterStepState = MyArgs.flags ; clear_flags( AfterStepState, ASS_NormalOperation ); set_flags( AfterStepState, ASS_SuppressDeskBack ); #ifdef __CYGWIN__ CloseOnExec = ASCloseOnExec ; #endif #if defined(LOG_FONT_CALLS) fprintf (stderr, "logging font calls now\n"); #endif /* These signals are mandatory : */ signal (SIGUSR1, Restart); /* These signals we would like to handle only if those are not handled already (by debugger): */ IgnoreSignal(SIGINT); IgnoreSignal(SIGHUP); IgnoreSignal(SIGQUIT); IgnoreSignal(SIGTERM); if( ConnectX( ASDefaultScr, AS_ROOT_EVENT_MASK ) < 0 ) { show_error( "Hostile X server encountered - unable to proceed :-("); return 1;/* failed to accure window management selection - other wm is running */ } ASDBus_fd = asdbus_init(); XSetWindowBackground( dpy, Scr.Root, Scr.asv->black_pixel ); Scr.Look.desktop_animation_tint = get_random_tint_color(); cover_desktop(); if( get_flags( AfterStepState, ASS_Restarting )) { show_progress( "AfterStep v.%s is restarting ...", VERSION ); display_progress( True, "AfterStep v.%s is restarting ...", VERSION ); }else { show_progress( "AfterStep v.%s is starting up ...", VERSION ); display_progress( True, "AfterStep v.%s is starting up ...", VERSION ); } if (ASDBus_fd>=0) { show_progress ("Successfuly accured System DBus connection."); asdbus_RegisterSMClient(SMClientID_string); } SHOW_CHECKPOINT; InitSession(); SHOW_CHECKPOINT; XSync (dpy, 0); SHOW_CHECKPOINT; set_parent_hints_func( afterstep_parent_hints_func ); /* callback for collect_hints() */ SHOW_CHECKPOINT; SetupModules(); SHOW_CHECKPOINT; SetupScreen(); SHOW_CHECKPOINT; event_setup( True /*Bool local*/ ); SHOW_CHECKPOINT; /* * Lets init each and every screen separately : */ for (i = 0; i < Scr.NumberOfScreens; i++) { show_progress( "Initializing screen %d ...", i ); display_progress( True, "Initializing screen %d ...", i ); if (i != Scr.screen) { if( !get_flags(MyArgs.flags, ASS_SingleScreen) ) { int pid = spawn_child( MyName, (i<MAX_USER_SINGLETONS_NUM)?i:-1, i, NULL, None, C_NO_CONTEXT, True, True, NULL ); if( pid >= 0 ) show_progress( "\t instance of afterstep spawned with pid %d.", pid ); else show_error( "failed to launch instance of afterstep to handle screen #%d", i ); } }else { make_screen_envvars(ASDefaultScr); putenv (Scr.rdisplay_string); putenv (Scr.display_string); if( is_output_level_under_threshold( OUTPUT_LEVEL_PROGRESS ) ) { show_progress( "\t screen[%d].size = %ux%u", Scr.screen, Scr.MyDisplayWidth, Scr.MyDisplayHeight ); display_progress( True, " screen[%d].size = %ux%u", Scr.screen, Scr.MyDisplayWidth, Scr.MyDisplayHeight ); show_progress( "\t screen[%d].root = %lX", Scr.screen, Scr.Root ); show_progress( "\t screen[%d].color_depth = %d", Scr.screen, Scr.asv->true_depth ); display_progress( True, " screen[%d].color_depth = %d", Scr.screen, Scr.asv->true_depth ); show_progress( "\t screen[%d].colormap = 0x%lX", Scr.screen, Scr.asv->colormap ); show_progress( "\t screen[%d].visual.id = %X", Scr.screen, Scr.asv->visual_info.visualid ); display_progress( True, " screen[%d].visual.id = %X", Scr.screen, Scr.asv->visual_info.visualid ); show_progress( "\t screen[%d].visual.class = %d", Scr.screen, Scr.asv->visual_info.class ); display_progress( True, " screen[%d].visual.class = %d", Scr.screen, Scr.asv->visual_info.class ); show_progress( "\t screen[%d].visual.red_mask = 0x%8.8lX", Scr.screen, Scr.asv->visual_info.red_mask ); show_progress( "\t screen[%d].visual.green_mask = 0x%8.8lX", Scr.screen, Scr.asv->visual_info.green_mask ); show_progress( "\t screen[%d].visual.blue_mask = 0x%8.8lX", Scr.screen, Scr.asv->visual_info.blue_mask ); show_progress( "\t screen[%d].rdisplay_string = \"%s\"", Scr.screen, Scr.rdisplay_string ); show_progress( "\t screen[%d].display_string = \"%s\"", Scr.screen, Scr.display_string ); display_progress( True, " screen[%d].display_string = \"%s\"", Scr.screen, Scr.display_string ); } } } /* make sure we're on the right desk, and the _WIN_DESK property is set */ Scr.CurrentDesk = INVALID_DESK ; if( get_flags( Scr.wmprops->set_props, WMC_ASDesks ) ) { start_desk = Scr.wmprops->as_current_desk ; }else if( get_flags( Scr.wmprops->set_props, WMC_DesktopCurrent ) ) { int curr = Scr.wmprops->desktop_current ; start_desk = curr; if( get_flags( Scr.wmprops->set_props, WMC_DesktopViewport ) && curr < Scr.wmprops->desktop_viewports_num ) { /* we have to do that prior to capturing any window so that they'll get in * correct position and will not end up outside of the screen */ start_viewport_x = Scr.wmprops->desktop_viewport[curr<<1] ; start_viewport_y = Scr.wmprops->desktop_viewport[(curr<<1)+1] ; } } if( get_flags( Scr.wmprops->set_props, WMC_ASViewport ) ) { start_viewport_x = Scr.wmprops->as_current_vx ; start_viewport_y = Scr.wmprops->as_current_vy ; } /* temporarily setting up desktop 0 */ ChangeDesks(0); /* Load config ... */ /* read config file, set up menus, colors, fonts */ LoadASConfig (0, PARSE_EVERYTHING); /* Reparent all the windows and setup pan frames : */ XSync (dpy, 0); /***********************************************************/ #ifndef DONT_GRAB_SERVER /* grabbed !!!!!*/ grab_server(); /* grabbed !!!!!*/ #endif /* grabbed !!!!!*/ init_screen_panframes(ASDefaultScr); /* grabbed !!!!!*/ display_progress( True, "Capturing all windows ..." ); CaptureAllWindows (ASDefaultScr); /* grabbed !!!!!*/ display_progress( False, "Done." ); check_screen_panframes(ASDefaultScr); /* grabbed !!!!!*/ ASSync( False ); #ifndef DONT_GRAB_SERVER /* grabbed !!!!!*/ ungrab_server(); /* UnGrabbed !!!!!*/ #endif /* UnGrabbed !!!!!*/ /**********************************************************/ XDefineCursor (dpy, Scr.Root, Scr.Feel.cursors[ASCUR_Default]); display_progress( True, "Seting initial viewport to %+d%+d ...", Scr.wmprops->as_current_vx, Scr.wmprops->as_current_vy ); SetupFunctionHandlers(); display_progress( True, "Processing all pending events ..." ); ConfigureNotifyLoop(); display_progress( True, "All done." ); remove_desktop_cover(); if( !get_flags(AfterStepStartupFlags, ASSF_BypassAutoexec)) DoAutoexec(get_flags( AfterStepState, ASS_Restarting)); /* once all the windows are swallowed and placed in its proper desks - we cas restore proper desktop/viewport : */ clear_flags( AfterStepState, ASS_SuppressDeskBack ); ChangeDeskAndViewport ( start_desk, start_viewport_x, start_viewport_y, False); /* all system Go! we are completely Operational! */ set_flags( AfterStepState, ASS_NormalOperation); #if (defined(LOCAL_DEBUG)||defined(DEBUG)) && defined(DEBUG_ALLOCS) LOCAL_DEBUG_OUT( "printing memory%s",""); spool_unfreed_mem( "afterstep.allocs.startup", NULL ); #endif LOCAL_DEBUG_OUT( "entering main loop%s",""); HandleEvents (); return (0); }