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); } }
/************************************************************************** * * Moves focus to specified window * *************************************************************************/ void FocusOn(FvwmWindow *t, Bool FocusByMouse, char *action) { int dx,dy; int cx,cy; Bool do_not_warp; if (t == NULL || HAS_NEVER_FOCUS(t)) { UngrabEm(GRAB_NORMAL); if (t) { /* give the window a chance to take the focus itself */ MoveFocus(t->w, t, FocusByMouse, 1, 0); } return; } if (!(do_not_warp = StrEquals(PeekToken(action, NULL), "NoWarp"))) { if (t->Desk != Scr.CurrentDesk) { goto_desk(t->Desk); } if (IS_ICONIFIED(t)) { cx = t->icon_xl_loc + t->icon_g.width/2; cy = t->icon_g.y + t->icon_p_height + ICON_HEIGHT(t) / 2; } else { cx = t->frame_g.x + t->frame_g.width/2; cy = t->frame_g.y + t->frame_g.height/2; } dx = (cx + Scr.Vx)/Scr.MyDisplayWidth*Scr.MyDisplayWidth; dy = (cy +Scr.Vy)/Scr.MyDisplayHeight*Scr.MyDisplayHeight; MoveViewport(dx,dy,True); /* If the window is still not visible, make it visible! */ if (((t->frame_g.x + t->frame_g.height)< 0)|| (t->frame_g.y + t->frame_g.width < 0)|| (t->frame_g.x >Scr.MyDisplayWidth)||(t->frame_g.y>Scr.MyDisplayHeight)) { SetupFrame(t, 0, 0, t->frame_g.width, t->frame_g.height, False); if (HAS_MOUSE_FOCUS(t) || HAS_SLOPPY_FOCUS(t)) { XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, 2,2); } } } UngrabEm(GRAB_NORMAL); if (t->Desk == Scr.CurrentDesk) { MoveFocus(t->w, t, FocusByMouse, do_not_warp, 0); } return; }
/************************************************************************** * * Moves pointer to specified window * *************************************************************************/ static void warp_to_fvwm_window( XEvent *eventp, FvwmWindow *t, int warp_x, int x_unit, int warp_y, int y_unit) { int dx,dy; int cx,cy; int x,y; if(t == (FvwmWindow *)0 || (IS_ICONIFIED(t) && t->icon_w == None)) return; if(t->Desk != Scr.CurrentDesk) { goto_desk(t->Desk); } if(IS_ICONIFIED(t)) { cx = t->icon_xl_loc + t->icon_g.width/2; cy = t->icon_g.y + t->icon_p_height + ICON_HEIGHT(t) / 2; } else { cx = t->frame_g.x + t->frame_g.width/2; cy = t->frame_g.y + t->frame_g.height/2; } dx = (cx + Scr.Vx) / Scr.MyDisplayWidth * Scr.MyDisplayWidth; dy = (cy + Scr.Vy) / Scr.MyDisplayHeight * Scr.MyDisplayHeight; MoveViewport(dx,dy,True); if(IS_ICONIFIED(t)) { x = t->icon_xl_loc + t->icon_g.width / 2; y = t->icon_g.y + t->icon_p_height + ICON_HEIGHT(t) / 2; } else { if (x_unit != Scr.MyDisplayWidth && warp_x >= 0) x = t->frame_g.x + warp_x; else if (x_unit != Scr.MyDisplayWidth) x = t->frame_g.x + t->frame_g.width + warp_x; else if (warp_x >= 0) x = t->frame_g.x + (t->frame_g.width - 1) * warp_x / 100; else x = t->frame_g.x + (t->frame_g.width - 1) * (100 + warp_x) / 100; if (y_unit != Scr.MyDisplayHeight && warp_y >= 0) y = t->frame_g.y + warp_y; else if (y_unit != Scr.MyDisplayHeight) y = t->frame_g.y + t->frame_g.height + warp_y; else if (warp_y >= 0) y = t->frame_g.y + (t->frame_g.height - 1) * warp_y / 100; else y = t->frame_g.y + (t->frame_g.height - 1) * (100 + warp_y) / 100; } XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, x, y); SetPointerEventPosition(eventp, x, y); RaiseWindow(t); /* If the window is still not visible, make it visible! */ if (t->frame_g.x + t->frame_g.width < 0 || t->frame_g.y + t->frame_g.height < 0 || t->frame_g.x >= Scr.MyDisplayWidth || t->frame_g.y >= Scr.MyDisplayHeight) { SetupFrame(t, 0, 0, t->frame_g.width, t->frame_g.height, False); XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, 2,2); SetPointerEventPosition(eventp, 2, 2); } }
/* * * Moves focus to specified window; only to be called bay Focus and FlipFocus * */ static void __activate_window_by_command( F_CMD_ARGS, int is_focus_by_flip_focus_cmd) { int cx; int cy; Bool do_not_warp; sftfwin_args_t sf_args; FvwmWindow * const fw = exc->w.fw; memset(&sf_args, 0, sizeof(sf_args)); sf_args.do_allow_force_broadcast = 1; sf_args.is_focus_by_flip_focus_cmd = is_focus_by_flip_focus_cmd; sf_args.set_by = FOCUS_SET_BY_FUNCTION; sf_args.client_entered = 0; if (fw == NULL || !FP_DO_FOCUS_BY_FUNCTION(FW_FOCUS_POLICY(fw))) { UngrabEm(GRAB_NORMAL); if (fw) { /* give the window a chance to take the focus itself */ sf_args.do_forbid_warp = 1; sf_args.do_force = 0; set_focus_to_fwin(FW_W(fw), fw, &sf_args); } return; } do_not_warp = StrEquals(PeekToken(action, NULL), "NoWarp"); if (!do_not_warp) { if (fw->Desk != Scr.CurrentDesk) { goto_desk(fw->Desk); } if (IS_ICONIFIED(fw)) { rectangle g; Bool rc; rc = get_visible_icon_title_geometry(fw, &g); if (rc == False) { get_visible_icon_picture_geometry(fw, &g); } cx = g.x + g.width / 2; cy = g.y + g.height / 2; } else { cx = fw->g.frame.x + fw->g.frame.width/2; cy = fw->g.frame.y + fw->g.frame.height/2; } if ( cx < 0 || cx >= Scr.MyDisplayWidth || cy < 0 || cy >= Scr.MyDisplayHeight) { int dx; int dy; dx = ((cx + Scr.Vx) / Scr.MyDisplayWidth) * Scr.MyDisplayWidth; dy = ((cy + Scr.Vy) / Scr.MyDisplayHeight) * Scr.MyDisplayHeight; MoveViewport(dx, dy, True); } #if 0 /* can not happen */ /* If the window is still not visible, make it visible! */ if (fw->g.frame.x + fw->g.frame.width < 0 || fw->g.frame.y + fw->g.frame.height < 0 || fw->g.frame.x >= Scr.MyDisplayWidth || fw->g.frame.y >= Scr.MyDisplayHeight) { frame_setup_window( fw, 0, 0, fw->g.frame.width, fw->g.frame.height, False); if ( FP_DO_WARP_POINTER_ON_FOCUS_FUNC( FW_FOCUS_POLICY(fw))) { FWarpPointerUpdateEvpos( exc->x.elast, dpy, None, Scr.Root, 0, 0, 0, 0, 2, 2); } } #endif } UngrabEm(GRAB_NORMAL); if (fw->Desk == Scr.CurrentDesk) { FvwmWindow *sf; sf = get_focus_window(); sf_args.do_forbid_warp = !!do_not_warp; sf_args.do_force = 0; sf_args.client_entered = 0; set_focus_to_fwin(FW_W(fw), fw, &sf_args); if (sf != get_focus_window()) { /* Ignore EnterNotify event while we are waiting for * this window to be focused. */ Scr.focus_in_pending_window = sf; } } return; }
/* * * Moves pointer to specified window * */ static void warp_to_fvwm_window( const exec_context_t *exc, int warp_x, int x_unit, int warp_y, int y_unit, int do_raise) { int dx,dy; int cx,cy; int x,y; FvwmWindow *t = exc->w.fw; if (t == (FvwmWindow *)0 || (IS_ICONIFIED(t) && FW_W_ICON_TITLE(t) == None)) { return; } if (t->Desk != Scr.CurrentDesk) { goto_desk(t->Desk); } if (IS_ICONIFIED(t)) { rectangle g; Bool rc; rc = get_visible_icon_title_geometry(t, &g); if (rc == False) { get_visible_icon_picture_geometry(t, &g); } cx = g.x + g.width / 2; cy = g.y + g.height / 2; } else { cx = t->g.frame.x + t->g.frame.width/2; cy = t->g.frame.y + t->g.frame.height/2; } dx = (cx + Scr.Vx) / Scr.MyDisplayWidth * Scr.MyDisplayWidth; dy = (cy + Scr.Vy) / Scr.MyDisplayHeight * Scr.MyDisplayHeight; if (dx != Scr.Vx || dy != Scr.Vy) { MoveViewport(dx, dy, True); } if (IS_ICONIFIED(t)) { rectangle g; Bool rc; rc = get_visible_icon_title_geometry(t, &g); if (rc == False) { get_visible_icon_picture_geometry(t, &g); } x = g.x + g.width / 2; y = g.y + g.height / 2; } else { if (x_unit != Scr.MyDisplayWidth && warp_x >= 0) { x = t->g.frame.x + warp_x; } else if (x_unit != Scr.MyDisplayWidth) { x = t->g.frame.x + t->g.frame.width + warp_x; } else if (warp_x >= 0) { x = t->g.frame.x + (t->g.frame.width - 1) * warp_x / 100; } else { x = t->g.frame.x + (t->g.frame.width - 1) * (100 + warp_x) / 100; } if (y_unit != Scr.MyDisplayHeight && warp_y >= 0) { y = t->g.frame.y + warp_y; } else if (y_unit != Scr.MyDisplayHeight) { y = t->g.frame.y + t->g.frame.height + warp_y; } else if (warp_y >= 0) { y = t->g.frame.y + (t->g.frame.height - 1) * warp_y / 100; } else { y = t->g.frame.y + (t->g.frame.height - 1) * (100 + warp_y) / 100; } } FWarpPointerUpdateEvpos( exc->x.elast, dpy, None, Scr.Root, 0, 0, 0, 0, x, y); if (do_raise) { RaiseWindow(t, False); } /* If the window is still not visible, make it visible! */ if (t->g.frame.x + t->g.frame.width < 0 || t->g.frame.y + t->g.frame.height < 0 || t->g.frame.x >= Scr.MyDisplayWidth || t->g.frame.y >= Scr.MyDisplayHeight) { frame_setup_window( t, 0, 0, t->g.frame.width, t->g.frame.height, False); FWarpPointerUpdateEvpos( exc->x.elast, dpy, None, Scr.Root, 0, 0, 0, 0, 2, 2); } return; }
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); }