SmSave.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: SmSave.c /main/27 1998/07/23 18:07:58 mgreess $ */
  24. /*************************************<+>*************************************
  25. *****************************************************************************
  26. **
  27. ** File: SmSave.c
  28. **
  29. ** Project: HP DT Session Manager (dtsession)
  30. **
  31. ** Description:
  32. ** -----------
  33. ** This file contains all routines that save off the session at any point
  34. ** in time. The session includes settings, resources, and clients. How
  35. ** the session manager behaves during a save depends on how the user has
  36. ** configured it to behave.
  37. **
  38. **
  39. *****************************************************************************
  40. *************************************<+>*************************************/
  41. /*
  42. * (c) Copyright 1997 The Open Group
  43. * (c) Copyright 1996 Digital Equipment Corporation.
  44. * (c) Copyright 1990, 1993, 1994, 1996 Hewlett-Packard Company.
  45. * (c) Copyright 1993, 1994, 1996 International Business Machines Corp.
  46. * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
  47. * (c) Copyright 1993, 1994, 1996 Novell, Inc.
  48. * (c) Copyright 1996 FUJITSU LIMITED.
  49. * (c) Copyright 1996 Hitachi.
  50. */
  51. #include <stdio.h>
  52. #include <string.h>
  53. #include <dirent.h>
  54. #include <sys/types.h>
  55. #include <sys/stat.h>
  56. #include <sys/param.h>
  57. #include <sys/socket.h>
  58. #include <netinet/in.h>
  59. #include <netdb.h>
  60. #ifdef _SUN_OS
  61. #include <arpa/inet.h>
  62. #include <string.h>
  63. #endif /* _SUN_OS */
  64. #include <X11/Intrinsic.h>
  65. #include <X11/Xutil.h>
  66. #include <X11/Xatom.h>
  67. #include <X11/StringDefs.h>
  68. #include <X11/keysymdef.h>
  69. #include <Dt/DtP.h>
  70. #include <Dt/Connect.h>
  71. #include <Dt/UserMsg.h>
  72. #include <Dt/SessionM.h>
  73. #include <Dt/MsgLog.h>
  74. #include "Sm.h"
  75. #include "SmSave.h"
  76. #include "SmResource.h"
  77. #include "SmError.h"
  78. #include "SmGlobals.h"
  79. #include "SmUI.h"
  80. #include "SmWindow.h"
  81. #include "SmProtocol.h"
  82. #include "SmRestore.h"
  83. #include "SmXSMP.h"
  84. #include "SmDB.h"
  85. #include "SmProperty.h"
  86. #include "SmProp.h"
  87. #include "Srv.h"
  88. #include "SrvFile_io.h"
  89. #ifdef MULTIBYTE
  90. #include <stdlib.h>
  91. #include <limits.h>
  92. #endif
  93. #include <X11/Xlibint.h>
  94. typedef struct _ProxyClientCache {
  95. Window window;
  96. int screen;
  97. } ProxyClientCache, *ProxyClientCachePtr;
  98. static ProxyClientCachePtr proxyList;
  99. static int numProxyClients = 0;
  100. static int numProxyAllocated = 0;
  101. static int proxyCacheAllocIncrement = 10;
  102. /*
  103. * Local Function Declarations
  104. */
  105. static void CacheProxyClient (
  106. Boolean firstClient,
  107. int screenNum,
  108. Window window);
  109. static void PruneSessionDirectory ();
  110. static Boolean WriteClientDatabase ();
  111. static void OutputXSMPClients (
  112. ClientDB outputDB);
  113. static void OutputProxyClients (
  114. ClientDB outputDB);
  115. static Boolean CheckRequiredProperties (
  116. ClientRecPtr pClientRec);
  117. static void PrintStartupInfo(
  118. ClientDB outputDB,
  119. int screen,
  120. Window window);
  121. static int QueryServerSettings( void ) ;
  122. static int SaveCustomizeSettings( void ) ;
  123. static int OutputResource( void ) ;
  124. static void PrintPointerControl(
  125. XrmDatabase *smBase) ;
  126. static void PrintSessionInfo(
  127. XrmDatabase *smBase) ;
  128. static void PrintScreenSaver(
  129. XrmDatabase *smBase) ;
  130. static int PrintFontPaths(
  131. XrmDatabase *smBase,
  132. char **fontPath,
  133. int numPaths) ;
  134. static int PrintKeyboardControl(
  135. XrmDatabase *smBase);
  136. static int PrintPointerMapping(
  137. XrmDatabase *smBase,
  138. char *buttonRet,
  139. int numButton) ;
  140. static void PrintWorkHintString(
  141. FILE *hintFile,
  142. char *hintString) ;
  143. static void PrintCmdHintString(
  144. FILE *hintFile,
  145. char *hintString) ;
  146. static void PrintCmdString(
  147. FILE *cmdFile,
  148. char *cmdString) ;
  149. static void PrintRemoteCmdString(
  150. FILE *cmdFile,
  151. char *cmdString) ;
  152. /*
  153. * Global variables that are exposed
  154. */
  155. SmScreenInfo screenSaverVals;
  156. SmAudioInfo audioVals;
  157. SmKeyboardInfo keyboardVals;
  158. /*
  159. * Variables global to this module only
  160. */
  161. /*
  162. * used as a buffer to write resources into
  163. * before they are written out
  164. */
  165. static int resSize = 10000;
  166. static char *resSpec;
  167. /*
  168. * Vars used to maintain state that is sent to the SaveState
  169. * function.
  170. */
  171. static Boolean saveHome;
  172. int saveMode;
  173. /*************************************<->*************************************
  174. *
  175. * SetupSaveState
  176. *
  177. * Description:
  178. * -----------
  179. * Do all of the preliminary work that must be done before the state
  180. * of a checkpoint can be saved.
  181. *
  182. * Inputs:
  183. * ------
  184. * saveToHome: This session is to be saved to the home session or current
  185. * mode = whether the session is to be reset or restarted
  186. *
  187. *************************************<->***********************************/
  188. void
  189. SetupSaveState(
  190. Boolean saveToHome,
  191. int mode)
  192. {
  193. unsigned char *propData;
  194. /*
  195. * Cache saveToHome and mode - they will be needed after all of
  196. * the XSMP clients are saved and the Proxy clients are saved.
  197. */
  198. saveHome = saveToHome;
  199. saveMode = mode;
  200. /*
  201. * First set up the save paths so we know if we have to do anything here
  202. */
  203. if ((SetSavePath(saveToHome, mode)) == -1)
  204. return;
  205. /*
  206. * Take care of the save mode property on the root window so that the
  207. * clients will know how to save this file (if they save files)
  208. */
  209. if(saveToHome == False)
  210. {
  211. propData = (unsigned char *) SM_CURRENT_DIRECTORY;
  212. }
  213. else
  214. {
  215. propData = (unsigned char *) SM_HOME_DIRECTORY;
  216. }
  217. /*
  218. * Change the save mode to give the subdirectory saved to
  219. *
  220. */
  221. XChangeProperty(smGD.display, RootWindow(smGD.display, 0),
  222. XaSmSaveMode, XA_STRING, 8, PropModeReplace,
  223. propData, strlen((char *)propData));
  224. XFlush(smGD.display);
  225. }
  226. /*************************************<->*************************************
  227. *
  228. * SaveState
  229. *
  230. * Description:
  231. * -----------
  232. * Tells the SM to notify the XSMP clients to save their state.
  233. * The function CompleteSave fill be invoked after the XSMP clients
  234. * have completed their save.
  235. *
  236. * Inputs:
  237. * ------
  238. * saveToHome: This session is to be saved to the home session or current
  239. * mode = whether the session is to be reset or restarted
  240. *
  241. * Comments:
  242. * --------
  243. * As a result of this routine files will be saved in the users .dt directory
  244. * that will allow the session manager to restore the session at a later
  245. * time.
  246. *
  247. * NOTE - this function is called as the result of the following
  248. * events:
  249. *
  250. * 1. User initiates a Save Home Session via the Style Manager
  251. * 2. The Session Manager receives a SM_XSESSION_EXIT message
  252. * 3. The Session Manager receives a SM_SAVE_SESSION message
  253. *
  254. *************************************<->***********************************/
  255. void
  256. SaveState(
  257. Boolean saveToHome,
  258. int mode,
  259. int saveType,
  260. Bool shutdown,
  261. int interactStyle,
  262. Bool fast,
  263. Bool global)
  264. {
  265. /*
  266. * Notify XSMP clients of the save
  267. */
  268. SaveYourselfReqProc (NULL, NULL, saveType, shutdown, interactStyle,
  269. fast, global);
  270. }
  271. /*************************************<->*************************************
  272. *
  273. * CompleteSave
  274. *
  275. * Description:
  276. * -----------
  277. * Called after the XSMP clients have saved their state. In charge of
  278. * calling all routines that save session information for XSMP client
  279. * and Proxy clients as well as settings, resources, etc.
  280. *
  281. * Outputs:
  282. * -------
  283. *
  284. *************************************<->***********************************/
  285. int
  286. CompleteSave (void)
  287. {
  288. FILE *convertFP;
  289. unsigned char *propData;
  290. char *tmpPath, tmpVersion[20];
  291. Boolean saveToHome = saveHome;
  292. int mode = saveMode;
  293. /*
  294. * If this is a Home session and the user is logging out, return
  295. * now - the XSMP clients have all responded to the save and the
  296. * ICCC clients don't save their state when a Home session is
  297. * exited.
  298. */
  299. if (smGD.sessionType == HOME_SESSION &&
  300. smXSMP.saveState.shutdown == True &&
  301. smSettings.startState == DtSM_HOME_STATE)
  302. return (0);
  303. /*
  304. * Start a wait state - don't want anything to happen while
  305. * ICCC clients are being saved
  306. */
  307. ShowWaitState(True);
  308. resSpec = (char *) SM_MALLOC(resSize * sizeof(char));
  309. if (resSpec==NULL)
  310. {
  311. PrintErrnoError(DtError, smNLS.cantMallocErrorString);
  312. return(-1);
  313. }
  314. if (!WriteClientDatabase ()) {
  315. ShowWaitState(False);
  316. SM_FREE(resSpec);
  317. return (-1);
  318. }
  319. /*
  320. * WARNING - THIS VARIABLE MUST BE SET BEFORE THE SETTING INFORMATION IS
  321. * CALLED - SETTINGS MUST BE SAVED BEFORE RESOURCES BECAUSE SETTINGS
  322. * GETS INFORMATION SAVED IN RESOURCES (smToSet.dClickBuf)
  323. */
  324. smToSet.dClickBuf[0] = 0;
  325. /*
  326. * Do the actual output of the X settings information. Output will
  327. * go to the resource database at this point and be written to the
  328. * resource file with the rest of the resources (below).
  329. */
  330. if(smRes.querySettings == True)
  331. {
  332. QueryServerSettings();
  333. }
  334. else
  335. {
  336. SaveCustomizeSettings();
  337. }
  338. /*
  339. * Do the output of resource information.
  340. */
  341. if(OutputResource())
  342. {
  343. ShowWaitState(False);
  344. SM_FREE(resSpec);
  345. return(-1);
  346. }
  347. XDeleteProperty(smGD.display, DefaultRootWindow(smGD.display), XaSmSaveMode);
  348. /*
  349. * Go save the default palette at this time
  350. */
  351. if(saveToHome == True)
  352. SaveDefaultPalette(smGD.display, smGD.savePath, DtSM_HOME_STATE);
  353. else
  354. SaveDefaultPalette(smGD.display, smGD.savePath, mode);
  355. PruneSessionDirectory ();
  356. ShowWaitState(False);
  357. return(0);
  358. }
  359. /*************************************<->*************************************
  360. *
  361. * PruneSessionDirectory -
  362. *
  363. * Description: Removes the oldest session direcotry if the number
  364. * of directories exceeds the smRes.numSessionsBackedup.
  365. *
  366. * Inputs: void
  367. *
  368. *************************************<->***********************************/
  369. static void
  370. PruneSessionDirectory (void)
  371. {
  372. DIR * dirp;
  373. struct dirent * dp;
  374. int numDirs = 0;
  375. struct stat buf;
  376. time_t oldestTime;
  377. char *clientDB;
  378. char *dirPrefix;
  379. char *oldDir; /* the .old dir */
  380. char *oldestDir;
  381. char *saveDir;
  382. char *tmpDir;
  383. if ((dirp = opendir (smGD.savePath)) == NULL)
  384. return;
  385. clientDB = (char*) XtMalloc((2*MAXPATHLEN) + 1);
  386. oldestDir = (char*) XtMalloc(MAXPATHLEN + 1);
  387. saveDir = (char*) XtMalloc(MAXPATHLEN + 1);
  388. tmpDir = (char*) XtMalloc(MAXPATHLEN + 1);
  389. dirPrefix = XtMalloc (strlen (smGD.restoreSession) + 2);
  390. sprintf (dirPrefix, "%s.", smGD.restoreSession);
  391. if (strlen (dirPrefix) > 5) {
  392. dirPrefix[4] = '.';
  393. dirPrefix[5] = '\000';
  394. }
  395. oldDir = XtMalloc (strlen (smGD.restoreSession) +
  396. strlen (SM_OLD_EXTENSION) + 2);
  397. sprintf (oldDir, "%s.%s", smGD.restoreSession, SM_OLD_EXTENSION);
  398. (void) time (&oldestTime);
  399. while ((dp = readdir (dirp)) != NULL) {
  400. /*
  401. * Do some sanity checks to limit the number of * stat()
  402. * calls. Note that for backward compatibility with CDE
  403. * 1.0 if a ".old" directory exists, keep it.
  404. */
  405. if ((!strcmp (dp->d_name, ".")) ||
  406. (!strcmp (dp->d_name, "..")) ||
  407. (!strcmp (dp->d_name, oldDir)) ||
  408. (strncmp (dp->d_name, dirPrefix, strlen (dirPrefix))))
  409. continue;
  410. sprintf (tmpDir, "%s/%s", smGD.savePath, dp->d_name);
  411. if (((stat (tmpDir, &buf)) == 0) && S_ISDIR (buf.st_mode)) {
  412. if (buf.st_mtime < oldestTime) {
  413. /*
  414. * Keep track of the oldest dir in case
  415. * it needs to be removed
  416. */
  417. oldestTime = buf.st_mtime;
  418. strcpy (oldestDir, tmpDir);
  419. }
  420. numDirs++;
  421. }
  422. }
  423. closedir(dirp);
  424. if (numDirs > smRes.numSessionsBackedup) {
  425. /*
  426. * Need to remove the oldest directory. The general
  427. * process (using "home" as an example) is:
  428. *
  429. * mv home home.tmp
  430. * mv oldestDir home
  431. * Execute the DiscardCommand props in the home directory
  432. * rm -rf home
  433. * mv home.tmp home
  434. *
  435. * The reason this is done is because when the
  436. * DiscardCommand were saved, the directory at the time of
  437. * the save contained "home". For example, a DiscardCommand
  438. * may look like:
  439. *
  440. * rm -f /u/somebody/.dt/sessions/home/app.state
  441. *
  442. * yet because of the session archiving, the app.state
  443. * file may actually be in a directory like:
  444. *
  445. * /u/somebody/.dt/sessions/home.<tempnam>
  446. */
  447. char * tmpName;
  448. int len, tfd;
  449. len = strlen(smGD.savePath) + strlen(smGD.restoreSession)
  450. + strlen("XXXXXX") + 3;
  451. tmpName = XtCalloc (1, len);
  452. sprintf(tmpName, "%s/%s.XXXXXX", smGD.savePath,
  453. smGD.restoreSession);
  454. if ((tfd = mkstemp(tmpName)) == -1)
  455. {
  456. PrintErrnoError(DtError, smNLS.cantCreateDirsString);
  457. }
  458. else
  459. {
  460. close(tfd);
  461. unlink(tmpName);
  462. sprintf (saveDir, "%s/%s",
  463. smGD.savePath, smGD.restoreSession);
  464. MoveDirectory (saveDir, tmpName, False);
  465. MoveDirectory (oldestDir, saveDir, False);
  466. sprintf (clientDB, "%s/%s/%s", smGD.savePath,
  467. smGD.restoreSession, SM_CLIENT_FILE2);
  468. ExecuteDiscardCommands (clientDB);
  469. MoveDirectory (tmpName, saveDir, True);
  470. }
  471. XtFree (tmpName);
  472. }
  473. /*
  474. * If exiting and the current session is a Current session
  475. * but smSettings.startState has been set to to a
  476. * Home session (this would be true if a user started a
  477. * Current session but used the Style Manager to set the session
  478. * upon next login to be a Home session), then if a home
  479. * directory exists, mv current to current.old
  480. */
  481. if (smXSMP.saveState.shutdown && smGD.sessionType == CURRENT_SESSION &&
  482. smSettings.startState == DtSM_HOME_STATE) {
  483. sprintf (tmpDir, "%s/%s", smGD.savePath, SM_HOME_DIRECTORY);
  484. if (((stat (tmpDir, &buf)) == 0) && S_ISDIR (buf.st_mode)) {
  485. sprintf (saveDir, "%s/%s", smGD.savePath, oldDir);
  486. if (((stat (saveDir, &buf)) == 0) &&
  487. S_ISDIR (buf.st_mode)) {
  488. sprintf (clientDB, "/bin/rm -rf %s", saveDir);
  489. SystemCmd (clientDB);
  490. sprintf (oldestDir, "%s/%s", smGD.savePath,
  491. SM_CURRENT_DIRECTORY);
  492. MoveDirectory (oldestDir, saveDir, False);
  493. }
  494. }
  495. }
  496. XtFree(clientDB);
  497. XtFree(dirPrefix);
  498. XtFree(oldDir);
  499. XtFree(oldestDir);
  500. XtFree(saveDir);
  501. XtFree(tmpDir);
  502. }
  503. /*************************************<->*************************************
  504. *
  505. * WriteClientDatabase -
  506. *
  507. * Description: Writes the client database (for XSMP and Proxy clients)
  508. *
  509. * Inputs: None
  510. *
  511. * Returns True if the database is wrtten OK; False otherwise
  512. *
  513. *************************************<->***********************************/
  514. static Boolean
  515. WriteClientDatabase (void)
  516. {
  517. char *db;
  518. ClientDB outputDB;
  519. db = (char*) XtMalloc(MAXPATHLEN + 1);
  520. (void) sprintf (db, "%s/%s/%s", smGD.savePath, smGD.restoreSession,
  521. SM_CLIENT_FILE2);
  522. if ((outputDB = OpenOutputClientDB (db, smXSMP.dbVersion,
  523. smXSMP.dbSessionId)) == NULL) {
  524. char * str;
  525. str = strdup ((char *) GETMESSAGE (40, 18,
  526. "The following database file cannot be opened for writing:\n\n %s\n\nThe session will not be saved."));
  527. if (str) {
  528. DtMsgLogMessage (smGD.programName, DtMsgLogError,
  529. str, db);
  530. free (str);
  531. }
  532. XtFree(db);
  533. return (False);
  534. }
  535. XtFree(db);
  536. OutputProxyClients (outputDB);
  537. OutputXSMPClients (outputDB);
  538. CloseClientDB (outputDB, True);
  539. return (True);
  540. }
  541. /*************************************<->*************************************
  542. *
  543. * OutputProxyClients -
  544. *
  545. * Description: Outputs the Proxy clients
  546. *
  547. * Inputs: database pointer
  548. *
  549. * Returns: void
  550. *
  551. *************************************<->***********************************/
  552. static void
  553. OutputProxyClients (
  554. ClientDB outputDB)
  555. {
  556. int i;
  557. for (i = 0; i < numProxyClients; i++)
  558. PrintStartupInfo (outputDB,
  559. proxyList[i].screen,
  560. proxyList[i].window);
  561. }
  562. /*************************************<->*************************************
  563. *
  564. * OutputXSMPClients -
  565. *
  566. * Description: Outputs the XSMP clients
  567. *
  568. * Inputs: database pointer
  569. *
  570. * Returns: void
  571. *
  572. *************************************<->***********************************/
  573. static void
  574. OutputXSMPClients (
  575. ClientDB outputDB)
  576. {
  577. XSMPClientDBRec dbRec;
  578. ClientRecPtr pClientRec;
  579. for (pClientRec = connectedList; pClientRec != NULL;
  580. pClientRec = pClientRec->next) {
  581. dbRec.restartHint = pClientRec->restartHint;
  582. (void) GetCardPropertyValue (pClientRec, SmRestartStyleHint,
  583. &dbRec.restartHint);
  584. if (dbRec.restartHint == SmRestartNever)
  585. continue;
  586. if (!pClientRec->active)
  587. continue;
  588. if (!CheckRequiredProperties (pClientRec))
  589. continue;
  590. dbRec.screenNum = 0;
  591. dbRec.clientId = pClientRec->clientId;
  592. dbRec.clientHost = pClientRec->clientHost;
  593. dbRec.program = GetArrayPropertyValue (pClientRec,
  594. SmProgram);
  595. dbRec.cwd = GetArrayPropertyValue (pClientRec,
  596. SmCurrentDirectory);
  597. dbRec.restartCommand = GetListOfArrayPropertyValue (pClientRec,
  598. SmRestartCommand);
  599. dbRec.cloneCommand = GetListOfArrayPropertyValue (pClientRec,
  600. SmCloneCommand);
  601. dbRec.discardCommand = GetListOfArrayPropertyValue (pClientRec,
  602. SmDiscardCommand);
  603. dbRec.environment = GetListOfArrayPropertyValue (pClientRec,
  604. SmEnvironment);
  605. if (!PutXSMPClientDBRec (outputDB, &dbRec)) {
  606. char *str;
  607. str = strdup ((char *) GETMESSAGE (40, 19,
  608. "Application '%s' cannot be saved."));
  609. if (str) {
  610. DtMsgLogMessage (smGD.programName,
  611. DtMsgLogError, str,
  612. dbRec.program);
  613. free (str);
  614. }
  615. }
  616. if (dbRec.restartCommand)
  617. XtFree ((char *) dbRec.restartCommand);
  618. if (dbRec.cloneCommand)
  619. XtFree ((char *) dbRec.cloneCommand);
  620. if (dbRec.discardCommand)
  621. XtFree ((char *) dbRec.discardCommand);
  622. if (dbRec.environment)
  623. XtFree ((char *) dbRec.environment);
  624. }
  625. }
  626. /*************************************<->*************************************
  627. *
  628. * CheckRequiredProperties -
  629. *
  630. * Description: Check a client's required properties
  631. *
  632. * Inputs: ClientRecPtr
  633. *
  634. * Returns: True if the client has all of the required properties;
  635. * otherwise returns False
  636. *
  637. *************************************<->***********************************/
  638. static Boolean
  639. CheckRequiredProperties (
  640. ClientRecPtr pClientRec)
  641. {
  642. PropertyRecPtr pPropRec;
  643. char * str;
  644. char * program = NULL;
  645. if ((program = GetArrayPropertyValue (pClientRec, SmProgram)) == NULL){
  646. str = strdup ((char *) GETMESSAGE (40, 23,
  647. "The following application did not set the required\nproperty '%s':\n\n %s\n\nThis application will not be saved."));
  648. if (str) {
  649. DtMsgLogMessage (smGD.programName, DtMsgLogError, str,
  650. SmProgram, pClientRec->clientId);
  651. free (str);
  652. }
  653. return (False);
  654. }
  655. if ((pPropRec = GetPropertyRec (pClientRec, SmRestartCommand)) == NULL){
  656. str = strdup ((char *) GETMESSAGE (40, 24,
  657. "24 Application '%s' will not be saved because it did not set\nthe required property '%s'."));
  658. if (str) {
  659. DtMsgLogMessage (smGD.programName, DtMsgLogError,
  660. str, program, SmRestartCommand);
  661. free (str);
  662. }
  663. return (False);
  664. }
  665. if ((pPropRec = GetPropertyRec (pClientRec, SmCloneCommand)) == NULL) {
  666. /*
  667. * This is a warning - still want to save the client
  668. */
  669. str = strdup ((char *) GETMESSAGE (40, 25,
  670. "Application '%s' did not set the required property '%s'."));
  671. if (str) {
  672. DtMsgLogMessage (smGD.programName, DtMsgLogWarning, str,
  673. program, SmCloneCommand);
  674. free (str);
  675. }
  676. }
  677. return (True);
  678. }
  679. /*************************************<->*************************************
  680. *
  681. * NotifyProxyClients -
  682. *
  683. *
  684. * Description:
  685. * -----------
  686. * Notify Proxy clients - calls routines to find top level windows, and
  687. * notifies the Proxy clients about an impending save.
  688. *
  689. * Inputs:
  690. * ------
  691. *
  692. * Outputs:
  693. * -------
  694. *
  695. *************************************<->***********************************/
  696. void
  697. NotifyProxyClients (void)
  698. {
  699. unsigned int topListLength, containedListLength;
  700. WindowInfo * topList; /* list of top-level windows */
  701. WindowInfo topLevelWindowInfo;
  702. Atom actualType;
  703. int actualFormat;
  704. unsigned long nitems;
  705. unsigned long leftover;
  706. unsigned char * data = NULL;
  707. Boolean containedClient;
  708. int i, j;
  709. int numClients = 0;
  710. /*
  711. * Save off the clients currently running. This will be done
  712. * one screen at a time
  713. */
  714. for(j = 0;j < smGD.numSavedScreens;j++)
  715. {
  716. /*
  717. * Get a list of children of the root window. If there are none
  718. * return with an error condition.
  719. */
  720. if(GetTopLevelWindows(j,&topList,&topListLength, &containedListLength))
  721. return;
  722. /*
  723. * Figure out how to restart the client associate with each window.
  724. */
  725. for (i=0 ; i<(topListLength + containedListLength); ++i)
  726. {
  727. topLevelWindowInfo=topList[i];
  728. if(i >= topListLength)
  729. {
  730. containedClient = True;
  731. }
  732. else
  733. {
  734. containedClient = False;
  735. }
  736. /*
  737. * If this window is my window - skip it I don't want to
  738. * save myself because I will be started automatically
  739. */
  740. if (XGetWindowProperty(smGD.display, topLevelWindowInfo.wid,
  741. XA_WM_CLASS,0L,
  742. (long)BUFSIZ,False,XA_STRING,&actualType,
  743. &actualFormat,&nitems,&leftover,
  744. &data)==Success)
  745. {
  746. if (actualType==XA_STRING &&
  747. !strcmp((char *) data, SM_RESOURCE_NAME))
  748. {
  749. SM_FREE((char *)data);
  750. continue;
  751. }
  752. else
  753. {
  754. SM_FREE((char *)data);
  755. }
  756. }
  757. /*
  758. * If the client participates in the WM_SAVE_YOURSELF protocol,
  759. * send the appropriate messages and wait for the proper
  760. * responses.
  761. */
  762. (void) SaveYourself(topLevelWindowInfo);
  763. CacheProxyClient ((numClients == 0), j, topLevelWindowInfo.wid);
  764. numClients++;
  765. }
  766. /*
  767. * Free space malloc'd by GetTopLevelWindowInfo
  768. */
  769. if(topListLength > 0)
  770. {
  771. SM_FREE((char *) topList);
  772. }
  773. }
  774. }
  775. /*************************************<->*************************************
  776. *
  777. * CacheProxyClient -
  778. *
  779. * Description:
  780. * -----------
  781. * Add a Proxy client to the proxy client cache.
  782. *
  783. * Inputs:
  784. * ------
  785. * firstClient - if True, this is the first client in the cache
  786. * screenNum - the client's screen number
  787. * window - the client's window number
  788. *
  789. * Outputs:
  790. * -------
  791. *
  792. *************************************<->***********************************/
  793. static void CacheProxyClient (
  794. Boolean firstClient,
  795. int screenNum,
  796. Window window)
  797. {
  798. if (firstClient)
  799. numProxyClients = 0;
  800. if (numProxyClients >= numProxyAllocated) {
  801. numProxyAllocated += proxyCacheAllocIncrement;
  802. proxyList = (ProxyClientCachePtr) XtRealloc ((char *) proxyList,
  803. numProxyAllocated * sizeof (ProxyClientCache));
  804. }
  805. proxyList[numProxyClients].screen = screenNum;
  806. proxyList[numProxyClients].window = window;
  807. numProxyClients++;
  808. }
  809. /*************************************<->*************************************
  810. *
  811. * PrintStartupInfo -
  812. *
  813. * Description:
  814. * -----------
  815. * Output startup information for one proxy client
  816. *
  817. * Inputs:
  818. * ------
  819. * outputDB = a pointer to the client database
  820. * screen = which screen the client is running on
  821. * window = the top level window of the lient
  822. *
  823. * Outputs:
  824. * -------
  825. *
  826. * Comments:
  827. * --------
  828. *
  829. *************************************<->***********************************/
  830. static void
  831. PrintStartupInfo(
  832. ClientDB outputDB,
  833. int screen,
  834. Window window)
  835. {
  836. Boolean writeStatus;
  837. int wargc;
  838. char ** wargv;
  839. char *clientMachine;
  840. XWindowAttributes windowAttr;
  841. Boolean remoteHost;
  842. Boolean xsmpClient;
  843. ProxyClientDBRec dbRec;
  844. char ** argv;
  845. int i;
  846. Status status;
  847. #ifdef _SUN_OS /* pull out quotes from OpenWindow tools commands */
  848. char * ptr;
  849. #endif
  850. /*
  851. * Get the attributes and properties on the window
  852. */
  853. if ((XGetWindowAttributes(smGD.display, window, &windowAttr)) == 0)
  854. return;
  855. if (GetStandardProperties(window, screen, &wargc, &wargv,
  856. &clientMachine, &xsmpClient)==0)
  857. return;
  858. /*
  859. * If the client doesn't have a WM_COMMAND property, we can't restart it
  860. */
  861. if (!wargv||!wargv[0])
  862. return;
  863. /*
  864. * If the client is an XSMP client, don't save it as a Proxy client.
  865. */
  866. if (xsmpClient)
  867. return;
  868. #ifdef _SUN_OS /* pull out quotes from OpenWindow tools commands */
  869. if (wargc == 1) {
  870. ptr = wargv[0];
  871. /* check for foreground */
  872. if ((ptr = strstr (ptr, "fg \"")) != NULL) {
  873. if (strlen (ptr) > 3)
  874. ptr[3] = ' ';
  875. if ((ptr = strchr (ptr, '"')) != NULL)
  876. ptr[0] = ' ';
  877. }
  878. /* check for background */
  879. if ((ptr = strstr (wargv[0], "bg \"")) != NULL) {
  880. if (strlen (ptr) > 3)
  881. ptr[3] = ' ';
  882. if ((ptr = strchr (ptr, '"')) != NULL)
  883. ptr[0] = ' ';
  884. }
  885. }
  886. #endif
  887. /*
  888. * Find out if the client is running locally
  889. */
  890. dbRec.clientHost = NULL;
  891. if(clientMachine != NULL)
  892. {
  893. if(DtIsLocalHostP(clientMachine) == FALSE)
  894. {
  895. dbRec.clientHost = clientMachine;
  896. }
  897. }
  898. /*
  899. * Must NULL-terminate the WM_COMMAND before writing it
  900. */
  901. argv = (char **) XtMalloc ((wargc + 1) * sizeof (char *));
  902. if (!argv)
  903. return;
  904. for (i = 0; i < wargc; i++)
  905. argv[i] = wargv[i];
  906. argv[wargc] = NULL;
  907. dbRec.command = argv;
  908. dbRec.screenNum = screen;
  909. writeStatus = PutProxyClientDBRec (outputDB, &dbRec);
  910. XtFree ((char *) argv);
  911. if (writeStatus == False)
  912. {
  913. /*
  914. * There should be an error written here - however
  915. * since this means that there already is a write error to
  916. * the disk - no error can be written
  917. */
  918. (void) CloseClientDB (outputDB, True);
  919. /*
  920. * On a write error - move the old session back to
  921. * be used and exit with an error condition
  922. */
  923. XFreeStringList(wargv);
  924. strcat(smGD.savePath, "/");
  925. if(smGD.sessionType == HOME_SESSION)
  926. {
  927. strcat(smGD.savePath, SM_HOME_DIRECTORY);
  928. }
  929. else
  930. {
  931. strcat(smGD.savePath, SM_CURRENT_DIRECTORY);
  932. }
  933. MoveDirectory(smGD.etcPath, smGD.savePath, False);
  934. SM_EXIT(-1);
  935. }
  936. /*
  937. * Free up the argv property
  938. */
  939. XFreeStringList(wargv);
  940. }
  941. /*************************************<->*************************************
  942. *
  943. * QueryServerSettings ()
  944. *
  945. *
  946. * Description:
  947. * -----------
  948. * Query the server for all it's current settings information, and then
  949. * write that information to the session managers settings resource file.
  950. *
  951. * Inputs:
  952. * ------
  953. * smGD.settingPath = (global) pointer to file where
  954. * setting info should be saved.
  955. *
  956. * Outputs:
  957. * -------
  958. *
  959. * Comments:
  960. * --------
  961. * This routine slows down the session manager's shutdown process
  962. * considerably, and is therefore only called when the user specifies
  963. * that all settings should be queried. Otherwise, only settings set in
  964. * the customizer should be saved.
  965. *
  966. *************************************<->***********************************/
  967. static int
  968. QueryServerSettings( void )
  969. {
  970. int i, numLoops;
  971. char **fontPath;
  972. KeySym *tmpSyms, tmpMod;
  973. XModifierKeymap *modMap;
  974. char *buttonRet;
  975. int numButton, numPaths;
  976. int buttonSize = 128;
  977. XrmDatabase smBase = NULL;
  978. char tmpChar[35];
  979. buttonRet = (char *) SM_MALLOC(buttonSize * sizeof(char));
  980. if (buttonRet==NULL)
  981. {
  982. PrintErrnoError(DtError, smNLS.cantMallocErrorString);
  983. return(-1);
  984. }
  985. /*
  986. * First set up all pointer control parameters
  987. * These are simple integer values that get saved
  988. * here, then read into a structure and set at restore
  989. * time
  990. */
  991. XGetPointerControl(smGD.display, &smSettings.accelNum,
  992. &smSettings.accelDenom,
  993. &smSettings.threshold);
  994. PrintPointerControl(&smBase);
  995. /*
  996. * Get all the screen saver values. These are all simple integer
  997. * values that are read back into a structure and set at restore
  998. * time.
  999. */
  1000. XGetScreenSaver(smGD.display, &screenSaverVals.smTimeout,
  1001. &screenSaverVals.smInterval,
  1002. &screenSaverVals.smPreferBlank,
  1003. &screenSaverVals.smAllowExp);
  1004. PrintScreenSaver(&smBase);
  1005. /*
  1006. * Write out all font path information.
  1007. * Write out all the paths one by one concatenated by commas.
  1008. */
  1009. fontPath = XGetFontPath(smGD.display, &numPaths);
  1010. if(fontPath != NULL)
  1011. {
  1012. if(PrintFontPaths(&smBase, fontPath, numPaths) != 0)
  1013. {
  1014. XFreeFontPath(fontPath);
  1015. SM_FREE(buttonRet);
  1016. return(-1);
  1017. }
  1018. }
  1019. /*
  1020. * Write out all the keyboard control information.
  1021. */
  1022. XGetKeyboardControl(smGD.display, &smSettings.kbdState);
  1023. if(PrintKeyboardControl(&smBase) != 0)
  1024. {
  1025. if (fontPath)
  1026. XFreeFontPath(fontPath);
  1027. return(-1);
  1028. }
  1029. /*
  1030. * Put all the button modifier information into the resource database.
  1031. * Find out the number of buttons and then write out the character
  1032. * string for each button.
  1033. */
  1034. numButton = XGetPointerMapping(smGD.display, (unsigned char *)buttonRet, 128);
  1035. if(numButton > 128)
  1036. {
  1037. buttonRet = (char *) SM_REALLOC(buttonRet, numButton * sizeof(char));
  1038. if (buttonRet==NULL)
  1039. {
  1040. if (fontPath)
  1041. XFreeFontPath(fontPath);
  1042. PrintErrnoError(DtError, smNLS.cantMallocErrorString);
  1043. return(-1);
  1044. }
  1045. numButton = XGetPointerMapping(smGD.display, (unsigned char *)buttonRet, numButton);
  1046. }
  1047. if(PrintPointerMapping(&smBase, buttonRet,
  1048. numButton) != 0)
  1049. {
  1050. if (fontPath)
  1051. XFreeFontPath(fontPath);
  1052. SM_FREE(buttonRet);
  1053. return(-1);
  1054. }
  1055. /*
  1056. * Put all keyboard mapping information in the resource database
  1057. * Don't bother putting this in a separate print function because
  1058. * the customizer doesn't do keymap savings this way.
  1059. */
  1060. smSettings.numKeyCode = smGD.display->max_keycode -
  1061. smGD.display->min_keycode;
  1062. tmpSyms = XGetKeyboardMapping(smGD.display,
  1063. (KeyCode) smGD.display->min_keycode,
  1064. smSettings.numKeyCode,
  1065. &smSettings.keySymPerCode);
  1066. if(tmpSyms == NULL)
  1067. {
  1068. if (fontPath)
  1069. XFreeFontPath(fontPath);
  1070. SM_FREE(buttonRet);
  1071. PrintErrnoError(DtError, smNLS.cantMallocErrorString);
  1072. return(-1);
  1073. }
  1074. strcpy(resSpec, SM_RESOURCE_CLASS);
  1075. strcat(resSpec, "*");
  1076. strcat(resSpec, SmCnumKeyCode);
  1077. strcat(resSpec, ":");
  1078. sprintf(tmpChar,"%d", smSettings.numKeyCode);
  1079. strcat(resSpec, tmpChar);
  1080. XrmPutLineResource( &smBase, resSpec);
  1081. strcpy(resSpec, SM_RESOURCE_CLASS);
  1082. strcat(resSpec, "*");
  1083. strcat(resSpec, SmCkeySymsPerKey);
  1084. strcat(resSpec, ":");
  1085. sprintf(tmpChar,"%d", smSettings.keySymPerCode);
  1086. strcat(resSpec, tmpChar);
  1087. XrmPutLineResource( &smBase, resSpec);
  1088. strcpy(resSpec, SM_RESOURCE_CLASS);
  1089. strcat(resSpec, "*");
  1090. strcat(resSpec, SmCkeySyms);
  1091. strcat(resSpec, ":");
  1092. numLoops = smSettings.numKeyCode * smSettings.keySymPerCode;
  1093. sprintf(tmpChar,"%ld", tmpSyms[0]);
  1094. strcat(resSpec, tmpChar);
  1095. for(i = 1;i < numLoops;i++)
  1096. {
  1097. if((strlen(resSpec) + 5) >= resSize)
  1098. {
  1099. resSize += 5000;
  1100. resSpec = (char *) SM_REALLOC(resSpec, resSize * sizeof(char));
  1101. if (resSpec==NULL)
  1102. {
  1103. SM_FREE((char *)tmpSyms);
  1104. if (fontPath)
  1105. SM_FREE((char *)fontPath);
  1106. SM_FREE(buttonRet);
  1107. PrintErrnoError(DtError, smNLS.cantMallocErrorString);
  1108. return(-1);
  1109. }
  1110. }
  1111. strcat(resSpec, ",");
  1112. sprintf(tmpChar,"%ld", tmpSyms[i]);
  1113. strcat(resSpec, tmpChar);
  1114. }
  1115. XrmPutLineResource( &smBase, resSpec);
  1116. /*
  1117. * Write out all keyboard modifier info. This will be a pretty slow
  1118. * process considering that every keycode will have to be turned into
  1119. * a keysym before writing. Don't bother putting print stuff in a
  1120. * separate function because it will not be handled in the customize
  1121. * version.
  1122. */
  1123. modMap = XGetModifierMapping(smGD.display);
  1124. if(modMap == NULL)
  1125. {
  1126. SM_FREE((char *)tmpSyms);
  1127. if (fontPath)
  1128. XFreeFontPath(fontPath);
  1129. SM_FREE(buttonRet);
  1130. PrintErrnoError(DtError, smNLS.cantMallocErrorString);
  1131. return(-1);
  1132. }
  1133. strcpy(resSpec, SM_RESOURCE_CLASS);
  1134. strcat(resSpec, "*");
  1135. strcat(resSpec, SmCmaxKeyPerMod);
  1136. strcat(resSpec, ":");
  1137. sprintf(tmpChar,"%d", modMap->max_keypermod);
  1138. strcat(resSpec, tmpChar);
  1139. XrmPutLineResource( &smBase, resSpec);
  1140. strcpy(resSpec, SM_RESOURCE_CLASS);
  1141. strcat(resSpec, "*");
  1142. strcat(resSpec, SmCmodMap);
  1143. strcat(resSpec, ":");
  1144. numLoops = (8 * modMap->max_keypermod) - 1;
  1145. for(i = 0;i <= numLoops;i++)
  1146. {
  1147. if((strlen(resSpec) + 9) >= resSize)
  1148. {
  1149. resSize += 5000;
  1150. resSpec = (char *) SM_REALLOC(resSpec, resSize * sizeof(char));
  1151. if (resSpec==NULL)
  1152. {
  1153. SM_FREE((char *)tmpSyms);
  1154. XFreeModifiermap(modMap);
  1155. if (fontPath)
  1156. XFreeFontPath(fontPath);
  1157. SM_FREE(buttonRet);
  1158. PrintErrnoError(DtError, smNLS.cantMallocErrorString);
  1159. return(-1);
  1160. }
  1161. }
  1162. tmpMod = XKeycodeToKeysym(smGD.display, modMap->modifiermap[i], 0);
  1163. sprintf(tmpChar,"%ld", tmpMod);
  1164. strcat(resSpec, tmpChar);
  1165. if(i != numLoops)
  1166. {
  1167. strcat(resSpec, ",");
  1168. }
  1169. }
  1170. XrmPutLineResource( &smBase, resSpec);
  1171. /*
  1172. * Print session manager settings
  1173. */
  1174. PrintSessionInfo(&smBase);
  1175. /*
  1176. * Write settings resources out to disk
  1177. */
  1178. XrmPutFileDatabase(smBase, smGD.settingPath);
  1179. /*
  1180. * Free all allocated resources
  1181. */
  1182. if (fontPath)
  1183. XFreeFontPath(fontPath);
  1184. SM_FREE((char *)tmpSyms);
  1185. XFreeModifiermap(modMap);
  1186. SM_FREE(buttonRet);
  1187. XrmDestroyDatabase(smBase);
  1188. return(0);
  1189. }
  1190. /*************************************<->*************************************
  1191. *
  1192. * SaveCustomizeSettings ()
  1193. *
  1194. *
  1195. * Description:
  1196. * ------------
  1197. * Saves those settings that have been set in the customizer during the
  1198. * session to whatever values they were set to during the session.
  1199. *
  1200. *
  1201. * Inputs:
  1202. * ------
  1203. * smGD.resourcePath = (global) a pointer
  1204. * to where the settings should be stored.
  1205. *
  1206. *
  1207. * Outputs:
  1208. * -------
  1209. *
  1210. *
  1211. * Comments:
  1212. * --------
  1213. * This routine is the default saved for saving settings. If the user
  1214. * wants all settings saved, they have to set a resource saying that that
  1215. * will be the case.
  1216. *
  1217. *************************************<->***********************************/
  1218. static int
  1219. SaveCustomizeSettings( void )
  1220. {
  1221. int i,numPaths;
  1222. char **fontPath;
  1223. XrmDatabase smBase = NULL;
  1224. char *tmpChar[20], *ptrRet = NULL, *tmpKey;
  1225. Status newStat;
  1226. char tmpMap[128];
  1227. if(smCust.pointerChange)
  1228. {
  1229. newStat = _DtGetSmPointer(smGD.display, smGD.topLevelWindow,
  1230. XaDtSmPointerInfo, &ptrRet);
  1231. if(newStat != Success)
  1232. {
  1233. smToSet.pointerChange = False;
  1234. smToSet.pointerMapChange = False;
  1235. }
  1236. else
  1237. {
  1238. sscanf(ptrRet, "%d %s %d %d %s",
  1239. &smToSet.numButton,
  1240. &tmpMap,
  1241. &smSettings.accelNum,
  1242. &smSettings.threshold,
  1243. &smToSet.dClickBuf);
  1244. smSettings.accelDenom = 1;
  1245. tmpKey = strtok(tmpMap, "_");
  1246. i = 0;
  1247. while(tmpKey != NULL)
  1248. {
  1249. smToSet.pointerMap[i] = (char) atoi(tmpKey);
  1250. i++;
  1251. tmpKey = strtok(NULL, "_");
  1252. }
  1253. /*
  1254. * append a \n to dClickBuf because it was scanned out
  1255. */
  1256. strcat(smToSet.dClickBuf, "\n");
  1257. }
  1258. if (ptrRet) XFree(ptrRet);
  1259. }
  1260. if(smToSet.pointerChange == True)
  1261. {
  1262. PrintPointerControl(&smBase);
  1263. }
  1264. if(smToSet.pointerMapChange == True)
  1265. {
  1266. if(PrintPointerMapping(&smBase, smToSet.pointerMap,
  1267. smToSet.numButton) != 0)
  1268. {
  1269. return(-1);
  1270. }
  1271. }
  1272. if(smToSet.screenSavChange == True)
  1273. {
  1274. PrintScreenSaver(&smBase);
  1275. }
  1276. if(smCust.audioChange == True)
  1277. {
  1278. newStat = _DtGetSmAudio(smGD.display, smGD.topLevelWindow,
  1279. XaDtSmAudioInfo, &audioVals);
  1280. if(newStat == Success)
  1281. {
  1282. smSettings.kbdState.bell_percent = audioVals.smBellPercent;
  1283. smSettings.kbdState.bell_pitch = audioVals.smBellPitch;
  1284. smSettings.kbdState.bell_duration = audioVals.smBellDuration;
  1285. }
  1286. else
  1287. {
  1288. smToSet.audioChange = False;
  1289. }
  1290. }
  1291. if (smToSet.audioChange)
  1292. {
  1293. strcpy(resSpec, SM_RESOURCE_CLASS);
  1294. strcat(resSpec, "*");
  1295. strcat(resSpec, SmCbellPercent);
  1296. strcat(resSpec, ":");
  1297. sprintf((char *)tmpChar,"%d",smSettings.kbdState.bell_percent);
  1298. strcat(resSpec, (char *)tmpChar);
  1299. XrmPutLineResource(&smBase, resSpec);
  1300. strcpy(resSpec, SM_RESOURCE_CLASS);
  1301. strcat(resSpec, "*");
  1302. strcat(resSpec, SmCbellPitch);
  1303. strcat(resSpec, ":");
  1304. sprintf((char *)tmpChar,"%d",smSettings.kbdState.bell_pitch);
  1305. strcat(resSpec, (char *)tmpChar);
  1306. XrmPutLineResource(&smBase, resSpec);
  1307. strcpy(resSpec, SM_RESOURCE_CLASS);
  1308. strcat(resSpec, "*");
  1309. strcat(resSpec, SmCbellDuration);
  1310. strcat(resSpec, ":");
  1311. sprintf((char *)tmpChar,"%d",smSettings.kbdState.bell_duration);
  1312. strcat(resSpec, (char *)tmpChar);
  1313. XrmPutLineResource(&smBase, resSpec);
  1314. }
  1315. if(smCust.keyboardChange == True)
  1316. {
  1317. newStat = _DtGetSmKeyboard(smGD.display, smGD.topLevelWindow,
  1318. XaDtSmKeyboardInfo, &keyboardVals);
  1319. if(newStat == Success)
  1320. {
  1321. smSettings.kbdState.key_click_percent = keyboardVals.smKeyClickPercent;
  1322. smSettings.kbdState.global_auto_repeat = keyboardVals.smGlobalAutoRepeat;
  1323. }
  1324. else
  1325. {
  1326. smToSet.keyboardChange = False;
  1327. }
  1328. }
  1329. if(smToSet.keyboardChange == True)
  1330. {
  1331. strcpy(resSpec, SM_RESOURCE_CLASS);
  1332. strcat(resSpec, "*");
  1333. strcat(resSpec, SmCkeyClick);
  1334. strcat(resSpec, ":");
  1335. sprintf((char *)tmpChar,"%d", smSettings.kbdState.key_click_percent);
  1336. strcat(resSpec, (char *)tmpChar);
  1337. XrmPutLineResource(&smBase, resSpec);
  1338. strcpy(resSpec, SM_RESOURCE_CLASS);
  1339. strcat(resSpec, "*");
  1340. strcat(resSpec, SmCglobalRepeats);
  1341. strcat(resSpec, ":");
  1342. sprintf((char *)tmpChar,"%d", smSettings.kbdState.global_auto_repeat);
  1343. strcat(resSpec, (char *)tmpChar);
  1344. XrmPutLineResource(&smBase, resSpec);
  1345. }
  1346. /*
  1347. * Write out all font path information.
  1348. * Write out all the paths one by one concatenated by commas.
  1349. */
  1350. fontPath = XGetFontPath(smGD.display, &numPaths);
  1351. if(fontPath != NULL) {
  1352. if(PrintFontPaths(&smBase, fontPath, numPaths) != 0) {
  1353. XFreeFontPath(fontPath);
  1354. return(-1);
  1355. }
  1356. }
  1357. /*
  1358. * Save session manager settings
  1359. */
  1360. PrintSessionInfo(&smBase);
  1361. if (fontPath)
  1362. XFreeFontPath(fontPath);
  1363. /*
  1364. * Write settings resources out to disk
  1365. */
  1366. XrmPutFileDatabase(smBase, smGD.settingPath);
  1367. XrmDestroyDatabase(smBase);
  1368. return(0);
  1369. }
  1370. /*************************************<->*************************************
  1371. *
  1372. * OutputResource ()
  1373. *
  1374. *
  1375. * Description:
  1376. * -----------
  1377. * Save session resources by getting the current RESOURCE_MANAGER property
  1378. * on the root window.
  1379. *
  1380. * Inputs:
  1381. * ------
  1382. * smGD.resourcePath = (global) file name
  1383. * where property contents should be saved.
  1384. *
  1385. * Outputs:
  1386. * -------
  1387. *
  1388. *
  1389. * Comments:
  1390. * --------
  1391. * This method is not a 100% accurate representation of currently active
  1392. * resources in the system. It is however, the best representation (the
  1393. * values with the highest priority) without becoming overly invasive
  1394. * and slow.
  1395. *
  1396. *************************************<->***********************************/
  1397. static int
  1398. OutputResource( void )
  1399. {
  1400. Atom actualType;
  1401. int actualFormat;
  1402. unsigned long nitems, leftover;
  1403. char *data = NULL;
  1404. XrmDatabase db;
  1405. Status newStat;
  1406. char *fontBuf = NULL, *langPtr, tmpChar[20], *sessionRes;
  1407. float fltYRes;
  1408. int intYRes;
  1409. char *preeditBuf = NULL;
  1410. /*
  1411. * Add anything to the Resource Manager property that needs to be added
  1412. */
  1413. /*
  1414. * Write out the LANG variable and the screen's Y resolution
  1415. */
  1416. *resSpec = 0;
  1417. langPtr = getenv("LANG");
  1418. if((langPtr != NULL) && (*langPtr != 0))
  1419. {
  1420. snprintf(resSpec, resSize, "%s*%s: %s\n", SM_RESOURCE_NAME, SmNsessionLang,
  1421. langPtr);
  1422. }
  1423. else
  1424. {
  1425. snprintf(resSpec, resSize, "%s*%s: \n", SM_RESOURCE_NAME, SmNsessionLang);
  1426. }
  1427. fltYRes = ((float) DisplayHeight(smGD.display, 0) /
  1428. (float) DisplayHeightMM(smGD.display, 0)) * 1000;
  1429. intYRes = fltYRes;
  1430. if(*resSpec == 0)
  1431. {
  1432. strcpy(resSpec, SM_RESOURCE_NAME);
  1433. }
  1434. else
  1435. {
  1436. strcat(resSpec, SM_RESOURCE_NAME);
  1437. }
  1438. strcat(resSpec, "*");
  1439. strcat(resSpec, SmNdisplayResolution);
  1440. strcat(resSpec, ":");
  1441. sprintf(tmpChar, "%d",intYRes);
  1442. strcat(resSpec, tmpChar);
  1443. strcat(resSpec, "\n");
  1444. _DtAddToResource(smGD.display, resSpec);
  1445. if(smCust.fontChange == True)
  1446. {
  1447. newStat = _DtGetSmFont(smGD.display, smGD.topLevelWindow,
  1448. XaDtSmFontInfo, &fontBuf);
  1449. if(newStat == Success)
  1450. {
  1451. /*
  1452. * Create the auxillary resource file
  1453. */
  1454. if(SetFontSavePath(langPtr) != -1)
  1455. {
  1456. db = XrmGetStringDatabase(fontBuf);
  1457. if(intYRes < MED_RES_Y_RES)
  1458. {
  1459. sessionRes = SM_LOW_RES_EXT;
  1460. }
  1461. else
  1462. {
  1463. if(intYRes >= HIGH_RES_Y_RES)
  1464. {
  1465. sessionRes = SM_HIGH_RES_EXT;
  1466. }
  1467. else
  1468. {
  1469. sessionRes = SM_MED_RES_EXT;
  1470. }
  1471. }
  1472. strcat(smGD.fontPath, "/");
  1473. strcat(smGD.fontPath, SM_FONT_FILE);
  1474. strcat(smGD.fontPath, ".");
  1475. strcat(smGD.fontPath, sessionRes);
  1476. XrmPutFileDatabase(db, smGD.fontPath);
  1477. XrmDestroyDatabase(db);
  1478. }
  1479. /*
  1480. * Now add this to the resource manager property to be saved
  1481. */
  1482. _DtAddToResource(smGD.display, fontBuf);
  1483. }
  1484. if (fontBuf) XFree(fontBuf);
  1485. }
  1486. if(smCust.preeditChange == True)
  1487. {
  1488. newStat = _DtGetSmPreedit(smGD.display, smGD.topLevelWindow,
  1489. XaDtSmPreeditInfo, &preeditBuf);
  1490. if(newStat == Success)
  1491. {
  1492. _DtAddToResource(smGD.display, preeditBuf);
  1493. }
  1494. if (preeditBuf) XFree(preeditBuf);
  1495. }
  1496. if((smCust.dClickChange == True) && (smToSet.dClickBuf[0] != 0))
  1497. {
  1498. _DtAddToResource(smGD.display, (char *)smToSet.dClickBuf);
  1499. }
  1500. /*
  1501. * Get the contents of the _DT_SM_PREFERENCES property
  1502. */
  1503. data = _DtGetResString(smGD.display, _DT_ATR_PREFS);
  1504. /*
  1505. * Get _DT_SM_PREFERENCES database 'db'.
  1506. */
  1507. db = XrmGetStringDatabase((char *)data);
  1508. XrmPutFileDatabase(db, smGD.resourcePath);
  1509. /*
  1510. * Don't forget to free your data
  1511. */
  1512. SM_FREE((char *)data);
  1513. XrmDestroyDatabase(db);
  1514. return(0);
  1515. }
  1516. /*************************************<->*************************************
  1517. *
  1518. * PrintPointerControl (smBase)
  1519. *
  1520. *
  1521. * Description:
  1522. * -----------
  1523. * A convenience function that is separated out instead of being included
  1524. * in both QueryServerSettings, and SaveCustomizeSettings.
  1525. * Saves pointer control information to the named resource file.
  1526. *
  1527. * Inputs:
  1528. * ------
  1529. * smBase = pointer to newly opened resource db used to store setting info
  1530. * resSpec = a buffer to hold string resource information until it is
  1531. * printed.
  1532. * smSettings = place where settings are stored.
  1533. *
  1534. * Outputs:
  1535. * -------
  1536. *
  1537. * Comments:
  1538. * --------
  1539. *
  1540. *************************************<->***********************************/
  1541. static void
  1542. PrintPointerControl(
  1543. XrmDatabase *smBase)
  1544. {
  1545. char tmpChar[20];
  1546. strcpy(resSpec, SM_RESOURCE_CLASS);
  1547. strcat(resSpec, "*");
  1548. strcat(resSpec, SmCaccelNum);
  1549. strcat(resSpec, ":");
  1550. sprintf(tmpChar, "%d", smSettings.accelNum);
  1551. strcat(resSpec, tmpChar);
  1552. XrmPutLineResource(smBase, resSpec);
  1553. strcpy(resSpec, SM_RESOURCE_CLASS);
  1554. strcat(resSpec, "*");
  1555. strcat(resSpec, SmCaccelDenom);
  1556. strcat(resSpec, ":");
  1557. sprintf(tmpChar, "%d",smSettings.accelDenom);
  1558. strcat(resSpec, tmpChar);
  1559. XrmPutLineResource(smBase, resSpec);
  1560. strcpy(resSpec, SM_RESOURCE_CLASS);
  1561. strcat(resSpec, "*");
  1562. strcat(resSpec, SmCthreshold);
  1563. strcat(resSpec, ":");
  1564. sprintf(tmpChar, "%d",smSettings.threshold);
  1565. strcat(resSpec, tmpChar);
  1566. XrmPutLineResource(smBase, resSpec);
  1567. return;
  1568. }
  1569. /*************************************<->*************************************
  1570. *
  1571. * PrintSessionInfo (smBase)
  1572. *
  1573. *
  1574. * Description:
  1575. * -----------
  1576. * A convenience function that is separated out instead of being included
  1577. * in both QueryServerSettings, and SaveCustomizeSettings.
  1578. * Saves session manager settings to the named resource file.
  1579. *
  1580. * Inputs:
  1581. * ------
  1582. * smBase = pointer to newly opened resource db used to store setting info
  1583. * resSpec = a buffer to hold string resource information until it is
  1584. * printed.
  1585. * smSettings = place where settings are stored.
  1586. *
  1587. * Outputs:
  1588. * -------
  1589. *
  1590. * Comments:
  1591. * --------
  1592. *
  1593. *************************************<->***********************************/
  1594. static void
  1595. PrintSessionInfo(
  1596. XrmDatabase *smBase)
  1597. {
  1598. char tmpChar[20];
  1599. /*
  1600. * Write out the settings for logout confirmation and
  1601. * the correct session to return to
  1602. */
  1603. strcpy(resSpec, SM_RESOURCE_CLASS);
  1604. strcat(resSpec, "*");
  1605. strcat(resSpec, SmCshutDownState);
  1606. strcat(resSpec, ":");
  1607. sprintf(tmpChar, "%d",smSettings.confirmMode);
  1608. strcat(resSpec, tmpChar);
  1609. XrmPutLineResource(smBase, resSpec);
  1610. strcpy(resSpec, SM_RESOURCE_CLASS);
  1611. strcat(resSpec, "*");
  1612. strcat(resSpec, SmCshutDownMode);
  1613. strcat(resSpec, ":");
  1614. sprintf(tmpChar, "%d",smSettings.startState);
  1615. strcat(resSpec, tmpChar);
  1616. XrmPutLineResource(smBase, resSpec);
  1617. return;
  1618. }
  1619. /*************************************<->*************************************
  1620. *
  1621. * PrintScreenSaver (smBase)
  1622. *
  1623. *
  1624. * Description:
  1625. * -----------
  1626. * A convenience function that is separated out instead of being included
  1627. * in both QueryServerSettings, and SaveCustomizeSettings.
  1628. * Saves screen saver information to the named resource file.
  1629. *
  1630. * Inputs:
  1631. * ------
  1632. * smBase = pointer to newly opened resource db used to store setting info
  1633. * resSpec = a buffer to hold string resource information until it is
  1634. * printed.
  1635. *
  1636. * Outputs:
  1637. * -------
  1638. *
  1639. * Comments:
  1640. * --------
  1641. *
  1642. *************************************<->***********************************/
  1643. static void
  1644. PrintScreenSaver(
  1645. XrmDatabase *smBase)
  1646. {
  1647. Status newScreenStat;
  1648. char tmpChar[20];
  1649. if(smCust.screenSavChange == True)
  1650. {
  1651. newScreenStat = _DtGetSmScreen(smGD.display, smGD.topLevelWindow,
  1652. XaDtSmScreenInfo, &screenSaverVals);
  1653. /*
  1654. * If the property has been deleted, it means that we return to
  1655. * the default
  1656. */
  1657. if(newScreenStat != Success)
  1658. {
  1659. return;
  1660. }
  1661. }
  1662. strcpy(resSpec, SM_RESOURCE_CLASS);
  1663. strcat(resSpec, "*");
  1664. strcat(resSpec, SmCtimeout);
  1665. strcat(resSpec, ":");
  1666. sprintf(tmpChar, "%d", screenSaverVals.smTimeout);
  1667. strcat(resSpec, tmpChar);
  1668. XrmPutLineResource(smBase, resSpec);
  1669. strcpy(resSpec, SM_RESOURCE_CLASS);
  1670. strcat(resSpec, "*");
  1671. strcat(resSpec, SmCinterval);
  1672. strcat(resSpec, ":");
  1673. sprintf(tmpChar, "%d", screenSaverVals.smInterval);
  1674. strcat(resSpec, tmpChar);
  1675. XrmPutLineResource(smBase, resSpec);
  1676. strcpy(resSpec, SM_RESOURCE_CLASS);
  1677. strcat(resSpec, "*");
  1678. strcat(resSpec, SmCpreferBlank);
  1679. strcat(resSpec, ":");
  1680. sprintf(tmpChar, "%d", screenSaverVals.smPreferBlank);
  1681. strcat(resSpec, tmpChar);
  1682. XrmPutLineResource(smBase, resSpec);
  1683. strcpy(resSpec, SM_RESOURCE_CLASS);
  1684. strcat(resSpec, "*");
  1685. strcat(resSpec, SmCallowExp);
  1686. strcat(resSpec, ":");
  1687. sprintf(tmpChar, "%d", screenSaverVals.smAllowExp);
  1688. strcat(resSpec, tmpChar);
  1689. XrmPutLineResource(smBase, resSpec);
  1690. return;
  1691. }
  1692. /*************************************<->*************************************
  1693. *
  1694. * PrintFontPaths (smBase, fontPaths, numPaths)
  1695. *
  1696. *
  1697. * Description:
  1698. * -----------
  1699. * A convenience function that is separated out instead of being included
  1700. * in both QueryServerSettings, and SaveCustomizeSettings.
  1701. * Saves pointer control information to the named resource file.
  1702. *
  1703. * Inputs:
  1704. * ------
  1705. * smBase = pointer to newly opened resource db used to store setting info
  1706. * resSpec = a buffer to hold string resource information until it is
  1707. * printed
  1708. * fontPaths = font paths to be saved
  1709. * numPaths = number of font paths to be saved
  1710. *
  1711. * Outputs:
  1712. * -------
  1713. * resSize = made bigger if current buffer is too small to hold all font info
  1714. *
  1715. * Comments:
  1716. * --------
  1717. *
  1718. *************************************<->***********************************/
  1719. static int
  1720. PrintFontPaths(
  1721. XrmDatabase *smBase,
  1722. char **fontPath,
  1723. int numPaths)
  1724. {
  1725. int i;
  1726. /* If no fp save req'd, just pretend we did it */
  1727. if (smRes.saveFontPath == False) return 0;
  1728. strcpy(resSpec, SM_RESOURCE_CLASS);
  1729. strcat(resSpec, "*");
  1730. strcat(resSpec, SmCfontPath);
  1731. strcat(resSpec, ":");
  1732. strcat(resSpec, *fontPath);
  1733. for(i = 1;i < numPaths;i++)
  1734. {
  1735. if((strlen(resSpec) + strlen(fontPath[i]) + 1) >= resSize)
  1736. {
  1737. resSize += 5000;
  1738. resSpec = (char *) SM_REALLOC(resSpec, resSize * sizeof(char));
  1739. if (resSpec==NULL)
  1740. {
  1741. PrintErrnoError(DtError, smNLS.cantMallocErrorString);
  1742. return(-1);
  1743. }
  1744. }
  1745. strcat(resSpec, ",");
  1746. strcat(resSpec, fontPath[i]);
  1747. }
  1748. XrmPutLineResource(smBase, resSpec);
  1749. return(0);
  1750. }
  1751. /*************************************<->*************************************
  1752. *
  1753. * PrintKeyboardControl (smBase)
  1754. *
  1755. *
  1756. * Description:
  1757. * -----------
  1758. * A convenience function that is separated out instead of being included
  1759. * in both QueryServerSettings, and SaveCustomizeSettings.
  1760. * Saves pointer control information to the named resource file.
  1761. *
  1762. * Inputs:
  1763. * ------
  1764. * smBase = pointer to newly opened resource db used to store setting info
  1765. * resSpec = a buffer to hold string resource information until it is
  1766. * printed
  1767. * resSize = size of current resource buffer
  1768. *
  1769. * Outputs:
  1770. * -------
  1771. * resSize = buffer is enlarged if more room is need to hold this info
  1772. *
  1773. * Comments:
  1774. * --------
  1775. *
  1776. *************************************<->***********************************/
  1777. static int
  1778. PrintKeyboardControl(
  1779. XrmDatabase *smBase)
  1780. {
  1781. int i,j;
  1782. char bitTest;
  1783. Bool firstRepeat = True;
  1784. char tmpChar[20];
  1785. strcpy(resSpec, SM_RESOURCE_CLASS);
  1786. strcat(resSpec, "*");
  1787. strcat(resSpec, SmCkeyClick);
  1788. strcat(resSpec, ":");
  1789. sprintf(tmpChar, "%d",smSettings.kbdState.key_click_percent);
  1790. strcat(resSpec, tmpChar);
  1791. XrmPutLineResource(smBase, resSpec);
  1792. strcpy(resSpec, SM_RESOURCE_CLASS);
  1793. strcat(resSpec, "*");
  1794. strcat(resSpec, SmCbellPercent);
  1795. strcat(resSpec, ":");
  1796. sprintf(tmpChar, "%d",smSettings.kbdState.bell_percent);
  1797. strcat(resSpec, tmpChar);
  1798. XrmPutLineResource(smBase, resSpec);
  1799. strcpy(resSpec, SM_RESOURCE_CLASS);
  1800. strcat(resSpec, "*");
  1801. strcat(resSpec, SmCbellPitch);
  1802. strcat(resSpec, ":");
  1803. sprintf(tmpChar, "%d",smSettings.kbdState.bell_pitch);
  1804. strcat(resSpec, tmpChar);
  1805. XrmPutLineResource(smBase, resSpec);
  1806. strcpy(resSpec, SM_RESOURCE_CLASS);
  1807. strcat(resSpec, "*");
  1808. strcat(resSpec, SmCbellDuration);
  1809. strcat(resSpec, ":");
  1810. sprintf(tmpChar, "%d",smSettings.kbdState.bell_duration);
  1811. strcat(resSpec, tmpChar);
  1812. XrmPutLineResource(smBase, resSpec);
  1813. strcpy(resSpec, SM_RESOURCE_CLASS);
  1814. strcat(resSpec, "*");
  1815. strcat(resSpec, SmCledMask);
  1816. strcat(resSpec, ":");
  1817. sprintf(tmpChar, "%ld",smSettings.kbdState.led_mask);
  1818. strcat(resSpec, tmpChar);
  1819. XrmPutLineResource(smBase, resSpec);
  1820. strcpy(resSpec, SM_RESOURCE_CLASS);
  1821. strcat(resSpec, "*");
  1822. strcat(resSpec, SmCglobalRepeats);
  1823. strcat(resSpec, ":");
  1824. sprintf(tmpChar, "%d",smSettings.kbdState.global_auto_repeat);
  1825. strcat(resSpec, tmpChar);
  1826. XrmPutLineResource(smBase, resSpec);
  1827. strcpy(resSpec, SM_RESOURCE_CLASS);
  1828. strcat(resSpec, "*");
  1829. strcat(resSpec, SmCautoRepeats);
  1830. strcat(resSpec, ":");
  1831. /*
  1832. * Now write out which keys need to be auto repeated one at a time
  1833. */
  1834. if(smSettings.kbdState.global_auto_repeat != AutoRepeatModeOn)
  1835. {
  1836. for(i = 0;i < 32;i++)
  1837. {
  1838. bitTest = 0x01;
  1839. for(j = 0;j < 8;j++)
  1840. {
  1841. if((bitTest & smSettings.kbdState.auto_repeats[i]) != 0)
  1842. {
  1843. if(firstRepeat == True)
  1844. {
  1845. firstRepeat = False;
  1846. }
  1847. else
  1848. {
  1849. strcat(resSpec, ",");
  1850. }
  1851. if((strlen(resSpec) + 5) >= resSize)
  1852. {
  1853. resSize += 5000;
  1854. resSpec = (char *) SM_REALLOC(resSpec,
  1855. resSize * sizeof(char));
  1856. if (resSpec==NULL)
  1857. {
  1858. PrintErrnoError(DtError,
  1859. smNLS.cantMallocErrorString);
  1860. return(-1);
  1861. }
  1862. }
  1863. sprintf(tmpChar, "%d", ((8 * i) + j));
  1864. strcat(resSpec, tmpChar);
  1865. }
  1866. bitTest <<= 1;
  1867. }
  1868. }
  1869. }
  1870. else
  1871. {
  1872. strcat(resSpec, "");
  1873. }
  1874. XrmPutLineResource(smBase, resSpec);
  1875. return(0);
  1876. }
  1877. /*************************************<->*************************************
  1878. *
  1879. * PrintPointerMapping (smBase, buttonRet, numButton)
  1880. *
  1881. *
  1882. * Description:
  1883. * -----------
  1884. * A convenience function that is separated out instead of being included
  1885. * in both QueryServerSettings, and SaveCustomizeSettings.
  1886. * Saves pointer mapping information to the named resource file.
  1887. *
  1888. * Inputs:
  1889. * ------
  1890. * smBase = pointer to newly opened resource db used to store setting info
  1891. * resSpec = a buffer to hold string resource information until it is
  1892. * printed
  1893. * resSize = size of resource buffer
  1894. * buttonRet = button mapping to be saved
  1895. * numButton = number of buttons in button mapping
  1896. *
  1897. * Outputs:
  1898. * -------
  1899. * resSize = size of buffer is change if it needs to be enlarged during
  1900. * routine
  1901. *
  1902. * Comments:
  1903. * --------
  1904. *
  1905. *************************************<->***********************************/
  1906. static int
  1907. PrintPointerMapping(
  1908. XrmDatabase *smBase,
  1909. char *buttonRet,
  1910. int numButton )
  1911. {
  1912. int i, numLoops;
  1913. char tmpChar[20];
  1914. strcpy(resSpec, SM_RESOURCE_CLASS);
  1915. strcat(resSpec, "*");
  1916. strcat(resSpec, SmCbuttonMap);
  1917. strcat(resSpec, ":");
  1918. numLoops = numButton - 1;
  1919. for(i = 0;i <= numLoops;i++)
  1920. {
  1921. if((strlen(resSpec) + 5) >= resSize)
  1922. {
  1923. resSize += 5000;
  1924. resSpec = (char *) SM_REALLOC(resSpec, resSize * sizeof(char));
  1925. if (resSpec==NULL)
  1926. {
  1927. PrintErrnoError(DtError, smNLS.cantMallocErrorString);
  1928. return(-1);
  1929. }
  1930. }
  1931. sprintf(tmpChar, "%d",buttonRet[i]);
  1932. strcat(resSpec, tmpChar);
  1933. if(i != numLoops)
  1934. {
  1935. strcat(resSpec, ",");
  1936. }
  1937. XrmPutLineResource(smBase, resSpec);
  1938. }
  1939. return(0);
  1940. }