save.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399
  1. /* $Xorg: save.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */
  2. /******************************************************************************
  3. Copyright 1993, 1998 The Open Group
  4. Permission to use, copy, modify, distribute, and sell this software and its
  5. documentation for any purpose is hereby granted without fee, provided that
  6. the above copyright notice appear in all copies and that both that
  7. copyright notice and this permission notice appear in supporting
  8. documentation.
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  15. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  16. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  17. Except as contained in this notice, the name of The Open Group shall not be
  18. used in advertising or otherwise to promote the sale, use or other dealings
  19. in this Software without prior written authorization from The Open Group.
  20. ******************************************************************************/
  21. /* $XFree86: xc/programs/xsm/save.c,v 3.3 2001/01/17 23:46:30 dawes Exp $ */
  22. #include "xsm.h"
  23. #include "save.h"
  24. #include "saveutil.h"
  25. #include "popup.h"
  26. #include "info.h"
  27. #include "lock.h"
  28. #include "choose.h"
  29. #include <X11/Shell.h>
  30. #include <X11/Xaw/Form.h>
  31. #include <X11/Xaw/List.h>
  32. #include <X11/Xaw/Command.h>
  33. #include <X11/Xaw/Toggle.h>
  34. #include <X11/Xaw/AsciiText.h>
  35. static Widget savePopup;
  36. static Widget saveForm;
  37. static Widget saveMessageLabel;
  38. static Widget saveName;
  39. static Widget saveTypeLabel;
  40. static Widget saveTypeGlobal;
  41. static Widget saveTypeLocal;
  42. static Widget saveTypeBoth;
  43. static Widget interactStyleLabel;
  44. static Widget interactStyleNone;
  45. static Widget interactStyleErrors;
  46. static Widget interactStyleAny;
  47. static Widget saveOkButton;
  48. static Widget helpSaveButton;
  49. static Widget saveCancelButton;
  50. static Widget helpPopup;
  51. static Widget helpForm;
  52. static Widget helpSaveText;
  53. static Widget helpSaveOkButton;
  54. static Widget nameInUsePopup;
  55. static Widget nameInUseForm;
  56. static Widget nameInUseLabel;
  57. static Widget nameInUseOverwriteButton;
  58. static Widget nameInUseCancelButton;
  59. static Widget badSavePopup;
  60. static Widget badSaveForm;
  61. static Widget badSaveLabel;
  62. static Widget badSaveOkButton;
  63. static Widget badSaveCancelButton;
  64. static Widget badSaveListWidget;
  65. static int saveTypeData[] = {
  66. SmSaveLocal,
  67. SmSaveGlobal,
  68. SmSaveBoth
  69. };
  70. static int interactStyleData[] = {
  71. SmInteractStyleNone,
  72. SmInteractStyleErrors,
  73. SmInteractStyleAny
  74. };
  75. static String *failedNames = NULL;
  76. static int numFailedNames = 0;
  77. static Bool help_visible = False;
  78. static String name_in_use = NULL;
  79. static Bool name_locked = False;
  80. static void
  81. MakeCurrentSession(String new_name, Bool name_changed)
  82. {
  83. char title[256];
  84. List *cl;
  85. if (session_name)
  86. {
  87. /*
  88. * In the old session, for any client that was not restarted by the
  89. * session manager (previous ID was NULL), if we did not issue a
  90. * checkpoint to this client after the initial startup, remove the
  91. * client's checkpoint file using the discard command.
  92. */
  93. for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
  94. {
  95. ClientRec *client = (ClientRec *) cl->thing;
  96. if (!client->restarted &&
  97. !client->userIssuedCheckpoint &&
  98. client->discardCommand)
  99. {
  100. execute_system_command (client->discardCommand);
  101. XtFree (client->discardCommand);
  102. client->discardCommand = NULL;
  103. }
  104. }
  105. /*
  106. * Unlock the old session.
  107. */
  108. if (!need_to_name_session)
  109. UnlockSession (session_name);
  110. }
  111. if (name_changed)
  112. {
  113. if (session_name)
  114. XtFree (session_name);
  115. session_name = XtNewString (new_name);
  116. }
  117. LockSession (session_name, True);
  118. snprintf (title, sizeof(title), "xsm: %s", session_name);
  119. XtVaSetValues (topLevel,
  120. XtNtitle, title,
  121. NULL);
  122. set_session_save_file_name (session_name);
  123. /*
  124. * For each client, set the DiscardCommand ptr to NULL.
  125. * This is so when we do a checkpoint with the new session
  126. * name, we don't wipe out the checkpoint files needed by
  127. * the previous session. We also set the userIssuedCheckpoint
  128. * flag to false for each client in the new session.
  129. */
  130. for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
  131. {
  132. ClientRec *client = (ClientRec *) cl->thing;
  133. client->userIssuedCheckpoint = False;
  134. if (client->discardCommand)
  135. {
  136. XtFree (client->discardCommand);
  137. client->discardCommand = NULL;
  138. }
  139. }
  140. need_to_name_session = False;
  141. }
  142. #define NAME_OK 0
  143. #define NAME_EMPTY 1
  144. #define NAME_EXISTS 2
  145. #define NAME_LOCKED 3
  146. static int
  147. GetSaveName(String *nameRet)
  148. {
  149. String new_name = NULL;
  150. Bool name_changed;
  151. /*
  152. * Get the name of the session for the save
  153. */
  154. XtVaGetValues (saveName,
  155. XtNstring, &new_name,
  156. NULL);
  157. *nameRet = new_name;
  158. if (!new_name || *new_name == '\0')
  159. return (NAME_EMPTY);
  160. /*
  161. * See if this is a new session. If not return.
  162. */
  163. name_changed = !session_name ||
  164. (session_name && strcmp (session_name, new_name) != 0);
  165. if (!need_to_name_session && !name_changed)
  166. return (NAME_OK);
  167. /*
  168. * Make sure the session name is unique.
  169. */
  170. if (GetSessionNames (&sessionNameCount,
  171. &sessionNamesShort, NULL, &sessionsLocked))
  172. {
  173. int i, no_good = 0, locked = 0;
  174. for (i = 0; i < sessionNameCount; i++)
  175. if (strcmp (new_name, sessionNamesShort[i]) == 0)
  176. {
  177. no_good = 1;
  178. locked = sessionsLocked[i];
  179. break;
  180. }
  181. FreeSessionNames (sessionNameCount,
  182. sessionNamesShort, NULL, sessionsLocked);
  183. if (no_good)
  184. return (locked ? NAME_LOCKED : NAME_EXISTS);
  185. }
  186. MakeCurrentSession (new_name, name_changed);
  187. return (NAME_OK);
  188. }
  189. static void
  190. GetSaveOptions(int *saveType, int *interactStyle, Bool *fast)
  191. {
  192. XtPointer ptr;
  193. if (help_visible)
  194. {
  195. XtPopdown (helpPopup);
  196. help_visible = 0;
  197. }
  198. ptr = XawToggleGetCurrent (saveTypeLocal /* just 1 of the group */);
  199. *saveType = *((int *) ptr);
  200. ptr = XawToggleGetCurrent (interactStyleNone /* just 1 of the group */);
  201. *interactStyle = *((int *) ptr);
  202. *fast = False;
  203. }
  204. void
  205. DoSave(int saveType, int interactStyle, Bool fast)
  206. {
  207. ClientRec *client;
  208. List *cl;
  209. const char *_saveType;
  210. const char *_shutdown;
  211. const char *_interactStyle;
  212. if (saveType == SmSaveLocal)
  213. _saveType = "Local";
  214. else if (saveType == SmSaveGlobal)
  215. _saveType = "Global";
  216. else
  217. _saveType = "Both";
  218. if (wantShutdown)
  219. _shutdown = "True";
  220. else
  221. _shutdown = "False";
  222. if (interactStyle == SmInteractStyleNone)
  223. _interactStyle = "None";
  224. else if (interactStyle == SmInteractStyleErrors)
  225. _interactStyle = "Errors";
  226. else
  227. _interactStyle = "Any";
  228. SetSaveSensitivity (False);
  229. saveInProgress = True;
  230. shutdownCancelled = False;
  231. phase2InProgress = False;
  232. if (ListCount (RunningList) == 0)
  233. FinishUpSave ();
  234. for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
  235. {
  236. client = (ClientRec *) cl->thing;
  237. SmsSaveYourself (client->smsConn,
  238. saveType, wantShutdown, interactStyle, fast);
  239. ListAddLast (WaitForSaveDoneList, (char *) client);
  240. client->userIssuedCheckpoint = True;
  241. client->receivedDiscardCommand = False;
  242. if (verbose)
  243. {
  244. printf ("Client Id = %s, sent SAVE YOURSELF [", client->clientId);
  245. printf ("Save Type = %s, Shutdown = %s, ", _saveType, _shutdown);
  246. printf ("Interact Style = %s, Fast = False]\n", _interactStyle);
  247. }
  248. }
  249. if (verbose)
  250. {
  251. printf ("\n");
  252. printf ("Sent SAVE YOURSELF to all clients. Waiting for\n");
  253. printf ("SAVE YOURSELF DONE, INTERACT REQUEST, or\n");
  254. printf ("SAVE YOURSELF PHASE 2 REQUEST from each client.\n");
  255. printf ("\n");
  256. }
  257. }
  258. static void
  259. SaveOkAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
  260. {
  261. XtCallCallbacks (saveOkButton, XtNcallback, NULL);
  262. }
  263. static void
  264. DelSaveWinAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
  265. {
  266. XtCallCallbacks (saveCancelButton, XtNcallback, NULL);
  267. }
  268. static void
  269. DelNameInUseWinAction(Widget w, XEvent *event, String *params,
  270. Cardinal *num_params)
  271. {
  272. XtCallCallbacks (nameInUseCancelButton, XtNcallback, NULL);
  273. }
  274. static void
  275. DelBadSaveWinAction(Widget w, XEvent *event, String *params,
  276. Cardinal *num_params)
  277. {
  278. if (XtIsManaged (badSaveCancelButton))
  279. XtCallCallbacks (badSaveCancelButton, XtNcallback, NULL);
  280. else
  281. XtCallCallbacks (badSaveOkButton, XtNcallback, NULL);
  282. }
  283. static void
  284. DelSaveHelpWinAction(Widget w, XEvent *event, String *params,
  285. Cardinal *num_params)
  286. {
  287. XtCallCallbacks (helpSaveOkButton, XtNcallback, NULL);
  288. }
  289. static void
  290. SaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
  291. {
  292. String name = NULL;
  293. char label[256];
  294. int status;
  295. static int first_time = 1;
  296. int saveType;
  297. int interactStyle;
  298. Bool fast;
  299. if ((status = GetSaveName (&name)) != NAME_OK)
  300. {
  301. #ifdef XKB
  302. XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
  303. #else
  304. XBell (XtDisplay (topLevel), 0);
  305. #endif
  306. if (status == NAME_EXISTS || status == NAME_LOCKED)
  307. {
  308. name_in_use = name;
  309. if (status == NAME_LOCKED)
  310. {
  311. name_locked = True;
  312. snprintf (label, sizeof(label), "Another session by the name '%s' is active.\nChoose another name for the session.", name);
  313. XtUnmanageChild (nameInUseOverwriteButton);
  314. XtVaSetValues (nameInUseCancelButton,
  315. XtNlabel, "OK",
  316. XtNfromHoriz, NULL,
  317. NULL);
  318. }
  319. else
  320. {
  321. name_locked = False;
  322. snprintf (label, sizeof(label), "Another session by the name '%s' already exists.\nWould you like to overwrite it?", name);
  323. XtManageChild (nameInUseOverwriteButton);
  324. XtVaSetValues (nameInUseCancelButton,
  325. XtNlabel, "Cancel",
  326. XtNfromHoriz, nameInUseOverwriteButton,
  327. NULL);
  328. }
  329. XtVaSetValues (nameInUseLabel,
  330. XtNlabel, label,
  331. NULL);
  332. XtPopdown (savePopup);
  333. PopupPopup (mainWindow, nameInUsePopup,
  334. True, first_time, 25, 100, "DelNameInUseWinAction()");
  335. if (first_time)
  336. first_time = 0;
  337. }
  338. return;
  339. }
  340. GetSaveOptions (&saveType, &interactStyle, &fast);
  341. DoSave (saveType, interactStyle, fast);
  342. }
  343. void
  344. LetClientInteract(List *cl)
  345. {
  346. ClientRec *client = (ClientRec *) cl->thing;
  347. SmsInteract (client->smsConn);
  348. ListSearchAndFreeOne (WaitForInteractList, (char *) client);
  349. if (verbose)
  350. {
  351. printf ("Client Id = %s, sent INTERACT\n", client->clientId);
  352. }
  353. }
  354. void
  355. StartPhase2(void)
  356. {
  357. List *cl;
  358. if (verbose)
  359. {
  360. printf ("\n");
  361. printf ("Starting PHASE 2 of SAVE YOURSELF\n");
  362. printf ("\n");
  363. }
  364. for (cl = ListFirst (WaitForPhase2List); cl; cl = ListNext (cl))
  365. {
  366. ClientRec *client = (ClientRec *) cl->thing;
  367. SmsSaveYourselfPhase2 (client->smsConn);
  368. if (verbose)
  369. {
  370. printf ("Client Id = %s, sent SAVE YOURSELF PHASE 2",
  371. client->clientId);
  372. }
  373. }
  374. ListFreeAllButHead (WaitForPhase2List);
  375. phase2InProgress = True;
  376. }
  377. void
  378. FinishUpSave(void)
  379. {
  380. ClientRec *client;
  381. List *cl;
  382. if (verbose)
  383. {
  384. printf ("\n");
  385. printf ("All clients issued SAVE YOURSELF DONE\n");
  386. printf ("\n");
  387. }
  388. saveInProgress = False;
  389. phase2InProgress = False;
  390. /*
  391. * Now execute discard commands
  392. */
  393. for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
  394. {
  395. client = (ClientRec *) cl->thing;
  396. if (!client->receivedDiscardCommand)
  397. continue;
  398. if (client->discardCommand)
  399. {
  400. execute_system_command (client->discardCommand);
  401. XtFree (client->discardCommand);
  402. client->discardCommand = NULL;
  403. }
  404. if (client->saveDiscardCommand)
  405. {
  406. client->discardCommand = client->saveDiscardCommand;
  407. client->saveDiscardCommand = NULL;
  408. }
  409. }
  410. /*
  411. * Write the save file
  412. */
  413. WriteSave (sm_id);
  414. if (wantShutdown && shutdownCancelled)
  415. {
  416. shutdownCancelled = False;
  417. }
  418. else if (wantShutdown)
  419. {
  420. if (ListCount (RunningList) == 0)
  421. EndSession (0);
  422. shutdownInProgress = True;
  423. for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
  424. {
  425. client = (ClientRec *) cl->thing;
  426. SmsDie (client->smsConn);
  427. if (verbose)
  428. {
  429. printf ("Client Id = %s, sent DIE\n", client->clientId);
  430. }
  431. }
  432. }
  433. else
  434. {
  435. for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
  436. {
  437. client = (ClientRec *) cl->thing;
  438. SmsSaveComplete (client->smsConn);
  439. if (verbose)
  440. {
  441. printf ("Client Id = %s, sent SAVE COMPLETE\n",
  442. client->clientId);
  443. }
  444. }
  445. }
  446. if (!shutdownInProgress)
  447. {
  448. XtPopdown (savePopup);
  449. SetAllSensitive (1);
  450. if (checkpoint_from_signal)
  451. checkpoint_from_signal = False;
  452. }
  453. }
  454. static void
  455. SaveCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
  456. {
  457. XtPopdown (savePopup);
  458. if (help_visible)
  459. {
  460. XtPopdown (helpPopup);
  461. help_visible = 0;
  462. }
  463. SetAllSensitive (1);
  464. }
  465. /*
  466. * Add toggle button
  467. */
  468. static Widget
  469. AddToggle(char *widgetName, Widget parent, int state, Widget radioGroup,
  470. XtPointer radioData, Widget fromHoriz, Widget fromVert)
  471. {
  472. Widget toggle;
  473. toggle = XtVaCreateManagedWidget (
  474. widgetName, toggleWidgetClass, parent,
  475. XtNstate, state,
  476. XtNradioGroup, radioGroup,
  477. XtNradioData, radioData,
  478. XtNfromHoriz, fromHoriz,
  479. XtNfromVert, fromVert,
  480. NULL);
  481. return (toggle);
  482. }
  483. void
  484. SetSaveSensitivity(Bool on)
  485. {
  486. XtSetSensitive (savePopup, on);
  487. #if 0
  488. /*
  489. * When we turn of sensitivity in the save dialog, we want to keep
  490. * the cancel button sensitive (so the user can cancel in case of
  491. * a problem). Unfortunately, we can not turn off the sensitivity on
  492. * the save popup, and then just turn on sensitivity for the cancel
  493. * button. We must do each widget individually.
  494. */
  495. XtSetSensitive (saveTypeLabel, on);
  496. XtSetSensitive (saveTypeGlobal, on);
  497. XtSetSensitive (saveTypeLocal, on);
  498. XtSetSensitive (saveTypeBoth, on);
  499. XtSetSensitive (interactStyleLabel, on);
  500. XtSetSensitive (interactStyleNone, on);
  501. XtSetSensitive (interactStyleErrors, on);
  502. XtSetSensitive (interactStyleAny, on);
  503. XtSetSensitive (saveOkButton, on);
  504. #endif
  505. }
  506. void
  507. SavePopupStructureNotifyXtHandler(Widget w, XtPointer closure, XEvent *event,
  508. Boolean *continue_to_dispatch)
  509. {
  510. if (event->type == MapNotify)
  511. {
  512. /*
  513. * Now that the Save Dialog is back up, we can do the save.
  514. */
  515. int saveType;
  516. int interactStyle;
  517. Bool fast;
  518. if (name_locked)
  519. {
  520. /* Force shutdown */
  521. }
  522. DeleteSession (name_in_use);
  523. MakeCurrentSession (name_in_use, True);
  524. name_in_use = NULL;
  525. GetSaveOptions (&saveType, &interactStyle, &fast);
  526. DoSave (saveType, interactStyle, fast);
  527. XtRemoveEventHandler (savePopup, StructureNotifyMask, False,
  528. SavePopupStructureNotifyXtHandler, NULL);
  529. }
  530. }
  531. static void
  532. NameInUseOverwriteXtProc(Widget w, XtPointer client_data, XtPointer callData)
  533. {
  534. if (name_locked)
  535. {
  536. /* force shutdown not implemented yet */
  537. return;
  538. }
  539. XtPopdown (nameInUsePopup);
  540. /*
  541. * We want to popup the Save dialog again. In order to avoid a race
  542. * condition with the BadSave handler trying to pop down the Save Dialog,
  543. * we wait for the MapNotify on the Save dialog, and then do the save.
  544. */
  545. XtAddEventHandler (savePopup, StructureNotifyMask, False,
  546. SavePopupStructureNotifyXtHandler, NULL);
  547. XtPopup (savePopup, XtGrabNone);
  548. }
  549. static void
  550. NameInUseCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
  551. {
  552. XtPopdown (nameInUsePopup);
  553. XtPopup (savePopup, XtGrabNone);
  554. name_in_use = NULL;
  555. }
  556. static void
  557. BadSaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
  558. {
  559. ListFreeAllButHead (FailedSaveList);
  560. XtPopdown (badSavePopup);
  561. FinishUpSave ();
  562. }
  563. static void
  564. BadSaveCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
  565. {
  566. ListFreeAllButHead (FailedSaveList);
  567. XtPopdown (badSavePopup);
  568. if (wantShutdown)
  569. {
  570. List *cl;
  571. shutdownCancelled = True;
  572. for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
  573. {
  574. ClientRec *client = (ClientRec *) cl->thing;
  575. SmsShutdownCancelled (client->smsConn);
  576. if (verbose)
  577. {
  578. printf ("Client Id = %s, sent SHUTDOWN CANCELLED\n",
  579. client->clientId);
  580. }
  581. }
  582. }
  583. FinishUpSave ();
  584. }
  585. static void
  586. BadSaveListXtProc(Widget w, XtPointer client_data, XtPointer callData)
  587. {
  588. }
  589. static void
  590. HelpSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
  591. {
  592. static int first_time = 1;
  593. if (help_visible)
  594. {
  595. /* Make sure it is visible */
  596. XMapRaised (XtDisplay (topLevel), XtWindow (helpPopup));
  597. }
  598. else
  599. {
  600. PopupPopup (savePopup, helpPopup,
  601. True, first_time, 50, 50, "DelSaveHelpWinAction()");
  602. help_visible = 1;
  603. if (first_time)
  604. first_time = 0;
  605. }
  606. }
  607. static void
  608. HelpSaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
  609. {
  610. XtPopdown (helpPopup);
  611. help_visible = 0;
  612. }
  613. void
  614. create_save_popup(void)
  615. {
  616. XtTranslations translations;
  617. static XtActionsRec actions[] = {
  618. {"SaveOkAction", SaveOkAction},
  619. {"DelSaveWinAction", DelSaveWinAction},
  620. {"DelNameInUseWinAction", DelNameInUseWinAction},
  621. {"DelBadSaveWinAction", DelBadSaveWinAction},
  622. {"DelSaveHelpWinAction", DelSaveHelpWinAction}
  623. };
  624. /*
  625. * Pop up for Save Yourself button.
  626. */
  627. savePopup = XtVaCreatePopupShell (
  628. "savePopup", transientShellWidgetClass, topLevel,
  629. XtNallowShellResize, True,
  630. NULL);
  631. saveForm = XtCreateManagedWidget (
  632. "saveForm", formWidgetClass, savePopup, NULL, 0);
  633. saveMessageLabel = XtVaCreateManagedWidget (
  634. "saveMessageLabel", labelWidgetClass, saveForm,
  635. XtNfromHoriz, NULL,
  636. XtNfromVert, NULL,
  637. XtNborderWidth, 0,
  638. NULL);
  639. saveName = XtVaCreateManagedWidget (
  640. "saveName", asciiTextWidgetClass, saveForm,
  641. XtNfromVert, NULL,
  642. XtNeditType, XawtextEdit,
  643. XtNresizable, True,
  644. XtNresize, XawtextResizeWidth,
  645. NULL);
  646. saveTypeLabel = XtVaCreateManagedWidget (
  647. "saveTypeLabel", labelWidgetClass, saveForm,
  648. XtNfromHoriz, NULL,
  649. XtNfromVert, saveMessageLabel,
  650. XtNborderWidth, 0,
  651. XtNvertDistance, 20,
  652. NULL);
  653. saveTypeLocal = AddToggle (
  654. "saveTypeLocal", /* widgetName */
  655. saveForm, /* parent */
  656. 0, /* state */
  657. NULL, /* radioGroup */
  658. (XtPointer) &saveTypeData[0], /* radioData */
  659. saveTypeLabel, /* fromHoriz */
  660. saveMessageLabel /* fromVert */
  661. );
  662. saveTypeGlobal = AddToggle (
  663. "saveTypeGlobal", /* widgetName */
  664. saveForm, /* parent */
  665. 0, /* state */
  666. saveTypeLocal, /* radioGroup */
  667. (XtPointer) &saveTypeData[1], /* radioData */
  668. saveTypeLocal, /* fromHoriz */
  669. saveMessageLabel /* fromVert */
  670. );
  671. saveTypeBoth = AddToggle (
  672. "saveTypeBoth", /* widgetName */
  673. saveForm, /* parent */
  674. 1, /* state */
  675. saveTypeLocal, /* radioGroup */
  676. (XtPointer) &saveTypeData[2], /* radioData */
  677. saveTypeGlobal, /* fromHoriz */
  678. saveMessageLabel /* fromVert */
  679. );
  680. XtVaSetValues (saveName, XtNfromHoriz, saveTypeLabel, NULL);
  681. XtVaSetValues (saveTypeLocal, XtNvertDistance, 20, NULL);
  682. XtVaSetValues (saveTypeGlobal, XtNvertDistance, 20, NULL);
  683. XtVaSetValues (saveTypeBoth, XtNvertDistance, 20, NULL);
  684. interactStyleLabel = XtVaCreateManagedWidget (
  685. "interactStyleLabel", labelWidgetClass, saveForm,
  686. XtNfromHoriz, NULL,
  687. XtNfromVert, saveTypeLabel,
  688. XtNborderWidth, 0,
  689. NULL);
  690. interactStyleNone = AddToggle (
  691. "interactStyleNone", /* widgetName */
  692. saveForm, /* parent */
  693. 0, /* state */
  694. NULL, /* radioGroup */
  695. (XtPointer) &interactStyleData[0], /* radioData */
  696. saveTypeLabel, /* fromHoriz */
  697. saveTypeLabel /* fromVert */
  698. );
  699. interactStyleErrors = AddToggle (
  700. "interactStyleErrors", /* widgetName */
  701. saveForm, /* parent */
  702. 0, /* state */
  703. interactStyleNone, /* radioGroup */
  704. (XtPointer) &interactStyleData[1], /* radioData */
  705. interactStyleNone, /* fromHoriz */
  706. saveTypeLabel /* fromVert */
  707. );
  708. interactStyleAny = AddToggle (
  709. "interactStyleAny", /* widgetName */
  710. saveForm, /* parent */
  711. 1, /* state */
  712. interactStyleNone, /* radioGroup */
  713. (XtPointer) &interactStyleData[2], /* radioData */
  714. interactStyleErrors, /* fromHoriz */
  715. saveTypeLabel /* fromVert */
  716. );
  717. saveOkButton = XtVaCreateManagedWidget (
  718. "saveOkButton", commandWidgetClass, saveForm,
  719. XtNfromHoriz, NULL,
  720. XtNfromVert, interactStyleLabel,
  721. XtNvertDistance, 20,
  722. XtNresizable, True,
  723. NULL);
  724. XtAddCallback (saveOkButton, XtNcallback, SaveOkXtProc, NULL);
  725. helpSaveButton = XtVaCreateManagedWidget (
  726. "helpSaveButton", commandWidgetClass, saveForm,
  727. XtNfromHoriz, saveOkButton,
  728. XtNfromVert, interactStyleLabel,
  729. XtNvertDistance, 20,
  730. NULL);
  731. XtAddCallback (helpSaveButton, XtNcallback, HelpSaveXtProc, NULL);
  732. saveCancelButton = XtVaCreateManagedWidget (
  733. "saveCancelButton", commandWidgetClass, saveForm,
  734. XtNfromHoriz, helpSaveButton,
  735. XtNfromVert, interactStyleLabel,
  736. XtNvertDistance, 20,
  737. NULL);
  738. XtAddCallback (saveCancelButton, XtNcallback, SaveCancelXtProc, NULL);
  739. XtSetKeyboardFocus (saveForm, saveName);
  740. XtAppAddActions (appContext, actions, XtNumber (actions));
  741. translations = XtParseTranslationTable
  742. ("<Key>Return: SaveOkAction()\n");
  743. XtOverrideTranslations(saveName, translations);
  744. XtInstallAllAccelerators (saveForm, saveForm);
  745. /*
  746. * Pop up when user tries to save the session under an
  747. * already used name.
  748. */
  749. nameInUsePopup = XtVaCreatePopupShell (
  750. "nameInUsePopup", transientShellWidgetClass, topLevel,
  751. XtNallowShellResize, True,
  752. NULL);
  753. nameInUseForm = XtVaCreateManagedWidget (
  754. "nameInUseForm", formWidgetClass, nameInUsePopup,
  755. NULL);
  756. nameInUseLabel = XtVaCreateManagedWidget (
  757. "nameInUseLabel", labelWidgetClass, nameInUseForm,
  758. XtNresizable, True,
  759. XtNfromHoriz, NULL,
  760. XtNfromVert, NULL,
  761. XtNborderWidth, 0,
  762. XtNtop, XawChainTop,
  763. XtNbottom, XawChainTop,
  764. NULL);
  765. nameInUseOverwriteButton = XtVaCreateManagedWidget (
  766. "nameInUseOverwriteButton", commandWidgetClass, nameInUseForm,
  767. XtNfromHoriz, NULL,
  768. XtNfromVert, nameInUseLabel,
  769. XtNtop, XawChainBottom,
  770. XtNbottom, XawChainBottom,
  771. NULL);
  772. XtAddCallback (nameInUseOverwriteButton, XtNcallback,
  773. NameInUseOverwriteXtProc, NULL);
  774. nameInUseCancelButton = XtVaCreateManagedWidget (
  775. "nameInUseCancelButton", commandWidgetClass, nameInUseForm,
  776. XtNresizable, True,
  777. XtNfromHoriz, nameInUseOverwriteButton,
  778. XtNfromVert, nameInUseLabel,
  779. XtNtop, XawChainBottom,
  780. XtNbottom, XawChainBottom,
  781. NULL);
  782. XtAddCallback (nameInUseCancelButton, XtNcallback,
  783. NameInUseCancelXtProc, NULL);
  784. /*
  785. * Pop up for help.
  786. */
  787. helpPopup = XtVaCreatePopupShell (
  788. "helpPopup", transientShellWidgetClass, topLevel,
  789. NULL);
  790. helpForm = XtVaCreateManagedWidget (
  791. "helpForm", formWidgetClass, helpPopup,
  792. NULL);
  793. helpSaveText = XtVaCreateManagedWidget (
  794. "helpSaveText", labelWidgetClass, helpForm,
  795. XtNfromHoriz, NULL,
  796. XtNfromVert, NULL,
  797. XtNtop, XawChainTop,
  798. XtNbottom, XawChainTop,
  799. NULL);
  800. helpSaveOkButton = XtVaCreateManagedWidget (
  801. "helpSaveOkButton", commandWidgetClass, helpForm,
  802. XtNfromHoriz, NULL,
  803. XtNfromVert, helpSaveText,
  804. XtNtop, XawChainBottom,
  805. XtNbottom, XawChainBottom,
  806. XtNvertDistance, 20,
  807. NULL);
  808. XtAddCallback (helpSaveOkButton, XtNcallback,
  809. HelpSaveOkXtProc, NULL);
  810. /*
  811. * Pop up when not all clients returned SaveSuccess
  812. */
  813. badSavePopup = XtVaCreatePopupShell (
  814. "badSavePopup", transientShellWidgetClass, topLevel,
  815. XtNallowShellResize, True,
  816. NULL);
  817. badSaveForm = XtVaCreateManagedWidget (
  818. "badSaveForm", formWidgetClass, badSavePopup,
  819. NULL);
  820. badSaveLabel = XtVaCreateManagedWidget (
  821. "badSaveLabel", labelWidgetClass, badSaveForm,
  822. XtNfromHoriz, NULL,
  823. XtNfromVert, NULL,
  824. XtNborderWidth, 0,
  825. XtNtop, XawChainTop,
  826. XtNbottom, XawChainTop,
  827. NULL);
  828. badSaveListWidget = XtVaCreateManagedWidget (
  829. "badSaveListWidget", listWidgetClass, badSaveForm,
  830. XtNresizable, True,
  831. XtNdefaultColumns, 1,
  832. XtNforceColumns, True,
  833. XtNfromHoriz, NULL,
  834. XtNfromVert, badSaveLabel,
  835. XtNtop, XawChainTop,
  836. XtNbottom, XawChainBottom,
  837. NULL);
  838. XtAddCallback (badSaveListWidget, XtNcallback, BadSaveListXtProc, NULL);
  839. badSaveOkButton = XtVaCreateManagedWidget (
  840. "badSaveOkButton", commandWidgetClass, badSaveForm,
  841. XtNfromHoriz, NULL,
  842. XtNfromVert, badSaveListWidget,
  843. XtNtop, XawChainBottom,
  844. XtNbottom, XawChainBottom,
  845. NULL);
  846. XtAddCallback (badSaveOkButton, XtNcallback, BadSaveOkXtProc, NULL);
  847. badSaveCancelButton = XtVaCreateManagedWidget (
  848. "badSaveCancelButton", commandWidgetClass, badSaveForm,
  849. XtNfromHoriz, badSaveOkButton,
  850. XtNfromVert, badSaveListWidget,
  851. XtNtop, XawChainBottom,
  852. XtNbottom, XawChainBottom,
  853. NULL);
  854. XtAddCallback (badSaveCancelButton, XtNcallback, BadSaveCancelXtProc, NULL);
  855. XtInstallAllAccelerators (badSaveForm, badSaveForm);
  856. }
  857. void
  858. PopupSaveDialog(void)
  859. {
  860. static int first_time = 1;
  861. XtSetSensitive (mainWindow, 0);
  862. XtSetSensitive (clientInfoPopup, 0);
  863. XtSetSensitive (clientPropPopup, 0);
  864. XawToggleSetCurrent (saveTypeBoth,
  865. (XtPointer) &saveTypeData[2]);
  866. XawToggleSetCurrent (interactStyleAny,
  867. (XtPointer) &interactStyleData[2]);
  868. XtVaSetValues (savePopup,
  869. XtNtitle, wantShutdown ? "Shutdown" : "Checkpoint",
  870. NULL);
  871. XtVaSetValues (saveName,
  872. XtNstring, need_to_name_session ? "" : session_name,
  873. NULL);
  874. XtVaSetValues (saveOkButton,
  875. XtNlabel, wantShutdown ? "Shutdown" : "Checkpoint",
  876. NULL);
  877. PopupPopup (mainWindow, savePopup,
  878. True, first_time, 25, 100, "DelSaveWinAction()");
  879. if (first_time)
  880. first_time = 0;
  881. }
  882. void
  883. CheckPointXtProc(Widget w, XtPointer client_data, XtPointer callData)
  884. {
  885. wantShutdown = False;
  886. PopupSaveDialog ();
  887. }
  888. void
  889. ShutdownSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
  890. {
  891. wantShutdown = True;
  892. PopupSaveDialog ();
  893. }
  894. void
  895. PopupBadSave(void)
  896. {
  897. ClientRec *client;
  898. char *progName, *hostname, *tmp1, *tmp2;
  899. String clientInfo;
  900. int maxlen1, maxlen2;
  901. char extraBuf1[80], extraBuf2[80];
  902. char *restart_service_prop;
  903. List *cl, *pl;
  904. int i, k;
  905. static int first_time = 1;
  906. if (failedNames)
  907. {
  908. /*
  909. * Free the previous list of names. Xaw doesn't make a copy of
  910. * our list, so we need to keep it around.
  911. */
  912. for (i = 0; i < numFailedNames; i++)
  913. XtFree (failedNames[i]);
  914. XtFree ((char *) failedNames);
  915. failedNames = NULL;
  916. }
  917. maxlen1 = maxlen2 = 0;
  918. numFailedNames = 0;
  919. for (cl = ListFirst (FailedSaveList); cl; cl = ListNext (cl))
  920. {
  921. client = (ClientRec *) cl->thing;
  922. progName = NULL;
  923. restart_service_prop = NULL;
  924. for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
  925. {
  926. Prop *pprop = (Prop *) pl->thing;
  927. List *vl = ListFirst (pprop->values);
  928. PropValue *pval = (PropValue *) vl->thing;
  929. if (strcmp (pprop->name, SmProgram) == 0)
  930. {
  931. progName = GetProgramName ((char *) pval->value);
  932. if ((int) strlen (progName) > maxlen1)
  933. maxlen1 = strlen (progName);
  934. }
  935. else if (strcmp (pprop->name, "_XC_RestartService") == 0)
  936. {
  937. restart_service_prop = (char *) pval->value;
  938. }
  939. }
  940. if (!progName)
  941. continue;
  942. if (restart_service_prop)
  943. tmp1 = restart_service_prop;
  944. else if (client->clientHostname)
  945. tmp1 = client->clientHostname;
  946. else
  947. continue;
  948. if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
  949. hostname = tmp1;
  950. else
  951. hostname = tmp2 + 1;
  952. if ((int) strlen (hostname) > maxlen2)
  953. maxlen2 = strlen (hostname);
  954. numFailedNames++;
  955. }
  956. failedNames = (String *) XtMalloc (
  957. numFailedNames * sizeof (String));
  958. i = 0;
  959. for (cl = ListFirst (FailedSaveList); cl; cl = ListNext (cl))
  960. {
  961. ClientRec *client = (ClientRec *) cl->thing;
  962. int extra1, extra2;
  963. progName = NULL;
  964. restart_service_prop = NULL;
  965. for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
  966. {
  967. Prop *pprop = (Prop *) pl->thing;
  968. List *vl = ListFirst (pprop->values);
  969. PropValue *pval = (PropValue *) vl->thing;
  970. if (strcmp (pprop->name, SmProgram) == 0)
  971. {
  972. progName = GetProgramName ((char *) pval->value);
  973. }
  974. else if (strcmp (pprop->name, "_XC_RestartService") == 0)
  975. {
  976. restart_service_prop = (char *) pval->value;
  977. }
  978. }
  979. if (!progName)
  980. continue;
  981. if (restart_service_prop)
  982. tmp1 = restart_service_prop;
  983. else if (client->clientHostname)
  984. tmp1 = client->clientHostname;
  985. else
  986. continue;
  987. if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
  988. hostname = tmp1;
  989. else
  990. hostname = tmp2 + 1;
  991. extra1 = maxlen1 - strlen (progName) + 5;
  992. extra2 = maxlen2 - strlen (hostname);
  993. for (k = 0; k < extra1; k++)
  994. extraBuf1[k] = ' ';
  995. extraBuf1[extra1] = '\0';
  996. for (k = 0; k < extra2; k++)
  997. extraBuf2[k] = ' ';
  998. extraBuf2[extra2] = '\0';
  999. XtAsprintf (&clientInfo, "%s%s (%s%s)", progName, extraBuf1,
  1000. hostname, extraBuf2);
  1001. failedNames[i++] = clientInfo;
  1002. if (client->freeAfterBadSavePopup)
  1003. {
  1004. FreeClient (client, True /* free props */);
  1005. }
  1006. }
  1007. XawListChange (badSaveListWidget,
  1008. failedNames, numFailedNames, 0, True);
  1009. XtPopdown (savePopup);
  1010. if (wantShutdown && !shutdownCancelled)
  1011. XtManageChild (badSaveCancelButton);
  1012. else
  1013. XtUnmanageChild (badSaveCancelButton);
  1014. PopupPopup (mainWindow, badSavePopup,
  1015. True, first_time, 25, 100, "DelBadSaveWinAction()");
  1016. if (first_time)
  1017. first_time = 0;
  1018. }
  1019. void
  1020. ShutdownDontSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
  1021. {
  1022. List *cl;
  1023. ClientRec *client;
  1024. if (ListCount (RunningList) == 0)
  1025. EndSession (0);
  1026. /*
  1027. * For any client that was not restarted by the session
  1028. * manager (previous ID was NULL), if we did not issue a
  1029. * checkpoint to this client, remove the client's checkpoint
  1030. * file using the discard command.
  1031. */
  1032. for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
  1033. {
  1034. client = (ClientRec *) cl->thing;
  1035. if (!client->restarted &&
  1036. !client->userIssuedCheckpoint &&
  1037. client->discardCommand)
  1038. {
  1039. execute_system_command (client->discardCommand);
  1040. XtFree (client->discardCommand);
  1041. client->discardCommand = NULL;
  1042. }
  1043. }
  1044. shutdownInProgress = True;
  1045. for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
  1046. {
  1047. client = (ClientRec *) cl->thing;
  1048. SmsDie (client->smsConn);
  1049. if (verbose)
  1050. {
  1051. printf ("Client Id = %s, sent DIE\n", client->clientId);
  1052. }
  1053. }
  1054. }