WmInitWs.c 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474
  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. /*
  24. * (c) Copyright 1989, 1990, 1991, 1992, 1993, 1994 OPEN SOFTWARE FOUNDATION, INC.
  25. * ALL RIGHTS RESERVED
  26. */
  27. /*
  28. * Motif Release 1.2.4
  29. */
  30. /*
  31. * (c) Copyright 1987, 1988, 1989, 1990, 1993, 1994 HEWLETT-PACKARD COMPANY
  32. * (c) Copyright 1993, 1994 International Business Machines Corp.
  33. * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  34. * (c) Copyright 1993, 1994 Novell, Inc.
  35. */
  36. /*
  37. * Included Files:
  38. */
  39. #include "WmGlobal.h"
  40. #include "WmResNames.h"
  41. #include "WmHelp.h"
  42. #include "WmICCC.h"
  43. #define DTWM_NEED_FNTPL
  44. #include "WmIBitmap.h"
  45. #include "WmOL.h"
  46. #include <X11/Xos.h>
  47. #include <X11/cursorfont.h>
  48. #include <Xm/Xm.h>
  49. #include <Xm/AtomMgr.h>
  50. #include <X11/Shell.h>
  51. #include <X11/Core.h>
  52. #include <X11/keysym.h>
  53. #ifndef NO_HP_KEY_REMAP
  54. #include <Xm/VirtKeysP.h>
  55. typedef struct
  56. {
  57. String default_name ;
  58. String new_name ;
  59. } str_xref_rec, *str_xref ;
  60. #endif /* NO_HP_KEY_REMAP */
  61. #include <Dt/GetDispRes.h>
  62. #include <Dt/SessionP.h>
  63. #include <Dt/SessionM.h>
  64. #include <Dt/DtP.h>
  65. #include <Dt/Message.h>
  66. #include <Dt/WsmM.h>
  67. #include <Dt/EnvControlP.h>
  68. /* Busy is also defined in the BMS -> bms.h. This conflicts with
  69. * /usr/include/X11/Xasync.h on ibm.
  70. */
  71. #ifdef _AIX
  72. #ifdef Busy
  73. #undef Busy
  74. #endif
  75. #endif
  76. #include <X11/Xlibint.h>
  77. /*
  78. * include extern functions
  79. */
  80. #include "WmBackdrop.h"
  81. #include "WmCDInfo.h"
  82. #include "WmColormap.h"
  83. #include "WmError.h"
  84. #include "WmEvent.h"
  85. #include "WmFeedback.h"
  86. #include "WmFunction.h"
  87. #include "WmIDecor.h"
  88. #include "WmIPC.h"
  89. #include "WmIPlace.h"
  90. #include "WmIconBox.h"
  91. #include "WmKeyFocus.h"
  92. #include "WmPanelP.h" /* for typedef in WmManage.h */
  93. #include "WmManage.h"
  94. #include "WmMenu.h"
  95. #include "WmPresence.h"
  96. #include "WmProperty.h"
  97. #include "WmResCvt.h"
  98. #include "WmResource.h"
  99. #include "WmSignal.h"
  100. #include "WmProtocol.h"
  101. #include "WmCDecor.h"
  102. #include "stdio.h"
  103. #include "WmResParse.h"
  104. #include <stdlib.h>
  105. #include "WmXSMP.h"
  106. /*
  107. * Function Declarations:
  108. */
  109. #include "WmInitWs.h"
  110. static void InsureDefaultBackdropDir(char **ppchBackdropDirs);
  111. void InitWmDisplayEnv (void);
  112. #ifndef NO_MESSAGE_CATALOG
  113. void InitNlsStrings (void);
  114. #endif
  115. #ifndef NO_HP_KEY_REMAP
  116. Boolean VirtKeys4DIN(Display *dpy);
  117. #endif /* NO_HP_KEY_REMAP */
  118. /* limited to 3 chars max */
  119. #define UNSPECIFIED_SCREEN_NAME "fbk"
  120. char **dpy2Argv; /* copy for second display */
  121. int dpy2Argc;
  122. /*
  123. * Global Variables:
  124. */
  125. extern int firstTime;
  126. #ifndef NO_MESSAGE_CATALOG
  127. extern char * pWarningStringFile;
  128. extern char * pWarningStringLine;
  129. #endif
  130. /*
  131. * InitMouseBinding
  132. *
  133. * Special case for a two button mouse; move the BMENU binding
  134. * from Button3 to Button2. Fails for one-button mice.
  135. */
  136. static void
  137. InitMouseBinding(void)
  138. {
  139. wmGD.numMouseButtons = XGetPointerMapping(DISPLAY, (unsigned char *)0, 0);
  140. if (wmGD.numMouseButtons < 3) {
  141. wmGD.bMenuButton = Button2;
  142. } else {
  143. wmGD.bMenuButton = Button3;
  144. }
  145. }
  146. /******************************<->*************************************
  147. *
  148. * BuildLockMaskSequence ()
  149. *
  150. * Set up the sequence of modifier masks to use to when grabbing
  151. * key- and button-bindings. This sequence of masks is NULL
  152. * terminated.
  153. *
  154. * Input:
  155. * wmGD.lockingModMask
  156. *
  157. * Output:
  158. * wmGD.pLockMaskSequence
  159. *
  160. *
  161. *************************************<->***********************************/
  162. static void
  163. BuildLockMaskSequence(void)
  164. {
  165. int j, k;
  166. unsigned int mask;
  167. unsigned int thisbit;
  168. Boolean bit_on;
  169. int num_masks;
  170. int num_bits;
  171. int bit;
  172. int run;
  173. /*
  174. * Count the bits to determine the number of elements in
  175. * the mask sequence. The actual number of masks is
  176. * 2^<bitcount> - 1. We're not interested in the case
  177. * where there none of the mask bits are set.
  178. */
  179. mask = wmGD.lockingModMask;
  180. num_bits=0;
  181. while (mask)
  182. {
  183. if (mask & 0x1)
  184. {
  185. num_bits++;
  186. }
  187. mask = mask >> 1;
  188. }
  189. num_masks = (0x1 << num_bits) - 1;
  190. /*
  191. * Allocate the space for the mask sequence + terminator.
  192. */
  193. wmGD.pLockMaskSequence = (unsigned int *)
  194. XtCalloc (num_masks+1, sizeof (unsigned int));
  195. /*
  196. * Fill in the mask sequence
  197. */
  198. mask = wmGD.lockingModMask;
  199. thisbit = 0x1;
  200. bit = 0;
  201. while (mask && thisbit)
  202. {
  203. /* find next bit */
  204. while (!(thisbit & mask))
  205. {
  206. thisbit = thisbit << 1;
  207. }
  208. /* clear it from mask */
  209. mask &= ~thisbit;
  210. bit++;
  211. /*
  212. * Set it in the appropriate slots in the
  213. * mask sequence. The start of the loop is
  214. * funny because we skip the case of all the
  215. * bits cleared.
  216. */
  217. run = (0x1 << bit-1); /* number of consecutive masks to set
  218. bits in */
  219. bit_on = False; /* are we setting bits or not? */
  220. for (j=0, k=run-1; j<num_masks; j++, k--)
  221. {
  222. if (k < 1)
  223. {
  224. if (bit_on)
  225. bit_on = False;
  226. else
  227. bit_on = True;
  228. k = run;
  229. }
  230. if (bit_on) wmGD.pLockMaskSequence[j] |= thisbit;
  231. }
  232. }
  233. }
  234. /******************************<->*************************************
  235. *
  236. * SetupLockingModifierMask ()
  237. *
  238. * Set up the mask used to ignore locking modifier keys (e.g. Shift Lock)
  239. * when processing key- and button-bindings.
  240. *
  241. * We want to try to ignore the set of locking modifers
  242. * such as Shift Lock, Num Lock, Kana Lock, etc. This involves
  243. * some amount of guessing since these things can be mapped
  244. * onto any of the Mod1-Mod5 modifiers. The approach taken is to
  245. * identify the mapping of the locking modifier keysyms to
  246. * Mod1-Mod5 and build the set of masks needed to ignore them.
  247. *
  248. *************************************<->***********************************/
  249. /*
  250. * This is the set of locking modifiers keysyms that might be
  251. * bound to Mod1-Mod5. (Caps Lock is handled independently of
  252. * this set.)
  253. */
  254. static KeySym pksLockingMods[] = {
  255. XK_Scroll_Lock,
  256. XK_Kana_Lock,
  257. XK_Num_Lock,
  258. XK_Mode_switch
  259. };
  260. #define NUM_LOCKING_MODS (sizeof(pksLockingMods)/sizeof(KeySym))
  261. static void
  262. SetupLockingModifierMask(void)
  263. {
  264. int i, j, start_index;
  265. XModifierKeymap *modifier_map = NULL;
  266. static Modifiers mod_masks[] = { None, Mod1Mask, Mod2Mask,
  267. Mod3Mask, Mod4Mask, Mod5Mask };
  268. Display *dpy = wmGD.display;
  269. int pkcLockingMods[NUM_LOCKING_MODS];
  270. int kc;
  271. for (i=0; i<NUM_LOCKING_MODS; i++)
  272. {
  273. pkcLockingMods[i] = XKeysymToKeycode(dpy, pksLockingMods[i]);
  274. }
  275. /*
  276. * Start out with Caps lock and add others we discover.
  277. */
  278. wmGD.lockingModMask = LockMask;
  279. modifier_map = XGetModifierMapping(dpy);
  280. /* just check Mod1 through Mod5 */
  281. start_index = modifier_map->max_keypermod * Mod1MapIndex;
  282. for (i = start_index; i < modifier_map->max_keypermod * 8; i++) {
  283. int this_mod = ((i - start_index) / modifier_map->max_keypermod) + 1;
  284. kc = modifier_map->modifiermap[i];
  285. if (kc)
  286. {
  287. for (j=0; j<NUM_LOCKING_MODS; j++)
  288. {
  289. if (pkcLockingMods[j] == kc)
  290. {
  291. wmGD.lockingModMask |= mod_masks[this_mod];
  292. break;
  293. }
  294. }
  295. }
  296. }
  297. BuildLockMaskSequence();
  298. if(modifier_map != NULL)
  299. XFreeModifiermap(modifier_map);
  300. }
  301. /******************************<->*************************************
  302. *
  303. * MappingEventHandler (Widget, XtPointer, XEvent *, Boolean *)
  304. *
  305. * Catch and handle changes to the mapping of the modifier keys.
  306. *
  307. *************************************<->***********************************/
  308. static void
  309. MappingEventHandler(
  310. Widget w,
  311. XtPointer client_data,
  312. XEvent *event,
  313. Boolean *cont_to_dispatch)
  314. {
  315. if(event->xany.type != MappingNotify ||
  316. event->xmapping.request == MappingPointer)
  317. return;
  318. if(event->xmapping.request == MappingModifier)
  319. SetupLockingModifierMask();
  320. }
  321. /******************************<->*************************************
  322. *
  323. * InitWmGlobal (argc, argv, environ)
  324. *
  325. *
  326. * Description:
  327. * -----------
  328. * This function initializes the workspace manager.
  329. *
  330. *
  331. * Inputs:
  332. * ------
  333. * argc = number of command line arguments (+1)
  334. *
  335. * argv = window manager command line arguments
  336. *
  337. * environ = window manager environment
  338. *
  339. *
  340. * Outputs:
  341. * -------
  342. * wmGD = (initialize the global data structure)
  343. *
  344. *************************************<->***********************************/
  345. void InitWmGlobal (int argc, char *argv [], char *environ [])
  346. {
  347. XSetWindowAttributes sAttributes;
  348. int scr;
  349. int managed = 0;
  350. char pch[80];
  351. Boolean activeSet = False;
  352. Boolean processedGlobalResources = False;
  353. WmScreenData *pSD;
  354. Arg args[20];
  355. int argnum;
  356. char *res_class;
  357. int savedArgc;
  358. wmGD.errorFlag = False;
  359. wmGD.dtSD = NULL;
  360. wmGD.iSlideUpsInProgress = 0;
  361. SetupWmSignalHandlers (0); /* dummy paramater */
  362. /*
  363. * Do (pre-toolkit) initialization:
  364. */
  365. wmGD.windowContextType = XUniqueContext ();
  366. wmGD.screenContextType = XUniqueContext ();
  367. #ifndef IBM_169380
  368. wmGD.cmapWindowContextType = XUniqueContext ();
  369. #endif
  370. wmGD.mwmWindowContextType = XUniqueContext ();
  371. /* copy argv (the XtInititalize changes the original) for use in restart */
  372. savedArgc = argc;
  373. CopyArgv (argc, argv);
  374. wmGD.environ = environ;
  375. wmGD.pWmPB = _DtWmParseNewBuf();
  376. /* set our name */
  377. if ((wmGD.mwmName = (char*)strrchr (wmGD.argv[0], '/')) != NULL)
  378. {
  379. wmGD.mwmName++;
  380. }
  381. else
  382. {
  383. wmGD.mwmName = wmGD.argv[0];
  384. }
  385. if (MwmBehavior)
  386. {
  387. res_class = WM_RESOURCE_CLASS;
  388. }
  389. else
  390. {
  391. res_class = DT_WM_RESOURCE_CLASS;
  392. }
  393. wmGD.statusColorServer = CSERVE_NOT_AVAILABLE;
  394. wmGD.display = (Display *)NULL;
  395. wmGD.topLevelW = (Widget)NULL;
  396. /*
  397. * Do X Tookit initialization:
  398. */
  399. XtToolkitInitialize();
  400. wmGD.mwmAppContext = XtCreateApplicationContext();
  401. AddWmResourceConverters ();
  402. wmGD.display = XtOpenDisplay (wmGD.mwmAppContext,
  403. NULL,
  404. wmGD.mwmName,
  405. res_class,
  406. NULL,
  407. 0,
  408. &argc, /* R5 changed from Cardinal to int*/
  409. argv);
  410. if (!wmGD.display)
  411. {
  412. Warning(((char *)GETMESSAGE(40, 1, "Could not open display.")));
  413. ExitWM (WM_ERROR_EXIT_VALUE);
  414. }
  415. #if defined(sun) && defined(ALLPLANES)
  416. {
  417. int dummy;
  418. wmGD.allplanes = XAllPlanesQueryExtension(wmGD.display,
  419. &dummy, &dummy);
  420. }
  421. #endif /* defined(sun) && defined(ALLPLANES) */
  422. /*
  423. * Setup error handling:
  424. */
  425. WmInitErrorHandler(wmGD.display);
  426. /*
  427. * Initialize cursor size info and
  428. * display the startup cursor.
  429. */
  430. InitCursorInfo ();
  431. InitWmDisplayEnv ();
  432. ShowWaitState (TRUE);
  433. /*
  434. * Initialize support for BMenu virtual mouse binding
  435. */
  436. InitMouseBinding();
  437. /*
  438. * Set up the _MOTIF_BINDINGS property on the root window
  439. * of screen 0. Must do this before we create shells.
  440. */
  441. ProcessMotifBindings ();
  442. #ifndef NO_HP_KEY_REMAP
  443. /* VirtKeys4DIN deals with a shortcoming in the OSF/Motif
  444. * mechanism for selecting a virtual key binding table.
  445. * When a client connects to a display, code inside of libXm
  446. * gets the vendor identifier from the server and uses this
  447. * identifier to select a default virtual key binding table
  448. * from an internal list of possible tables (provided to
  449. * OSF by vendors). A virtual key binding table maps OSF
  450. * virtual keysyms to an "appropriate" set of X keysyms for
  451. * a particular server vendor. The problem with this
  452. * mechanism is that it only allows for a _single_ default
  453. * virtual key binding table per server vendor. If a
  454. * hardware vendor ships more than one distinct keyboard,
  455. * then the single virtual key binding table selected for
  456. * that server might not be appropriate for all keyboards.
  457. * The HP migration from the "ITF" keyboard to the "PC-style"
  458. * keyboard causes this problem to be exposed for Motif
  459. * clients. The default HP virtual key binding table maps
  460. * osfInsert and osfDelete to hpInsertChar and hpDeleteChar,
  461. * respectively. But since hpInsertChar and hpDeleteChar
  462. * are absent from the PC-style keyboard, HP servers with
  463. * this keyboard do not generate key events that map to the
  464. * important osfInsert and osfDelete virtual keys.
  465. * The Motif 1.2 version of libXm installs (one or two)
  466. * properties on the root window, these properties exporting
  467. * the virtual key binding table to be used by all (subsequently
  468. * connected) Motif clients. The VirtKeys4DIN routine attempts
  469. * to ensure that the virtual key binding table exported by
  470. * those properties does not include dependencies on keysyms
  471. * that are not available in the server's current modmap.
  472. * The routine accomplishes this by searching the keyboard
  473. * mapping of the display for the absence of known problematic
  474. * keysyms. For those keysyms that are missing from the
  475. * keyboard map, the corresponding dependencies in the
  476. * virtual key binding table are altered to use pre-determined
  477. * substitutes (which are generic X keysyms that are present
  478. * on the PC-style keyboard mapping).
  479. * The side-effects of this routine are that if there are no
  480. * key binding properties on the root window when this routine
  481. * is called, there will be a property installed (this occurs
  482. * with all Motif 1.2 clients anyway). Since the virtual key
  483. * binding table is only altered if it contains a keysym that
  484. * is missing from the server's keyboard mapping, there is
  485. * little chance of deleterious effects.
  486. */
  487. VirtKeys4DIN(DISPLAY);
  488. #endif /* NO_HP_KEY_REMAP */
  489. argnum = 0;
  490. XtSetArg (args[argnum], XtNgeometry, NULL); argnum++;
  491. XtSetArg (args[argnum], XtNx, 10000); argnum++;
  492. XtSetArg (args[argnum], XtNy, 0); argnum++;
  493. XtSetArg (args[argnum], XtNwidth, 10); argnum++;
  494. XtSetArg (args[argnum], XtNheight, 10); argnum++;
  495. XtSetArg (args[argnum], XtNmappedWhenManaged, False); argnum++;
  496. XtSetArg (args[argnum], XtNjoinSession, True); argnum++;
  497. XtSetArg (args[argnum], XtNrestartStyle, SmRestartNever); argnum++;
  498. XtSetArg (args[argnum], XtNargc, savedArgc); argnum++;
  499. XtSetArg (args[argnum], XtNargv, wmGD.argv); argnum++;
  500. /* create topmost shell (application shell) */
  501. wmGD.topLevelW = XtAppCreateShell (NULL,
  502. res_class,
  503. sessionShellWidgetClass,
  504. DISPLAY,
  505. args,
  506. argnum);
  507. XtAddEventHandler(wmGD.topLevelW, NoEventMask, True,
  508. MappingEventHandler, NULL);
  509. /* Add callbacks used for communication with Session Manager. */
  510. AddSMCallbacks ();
  511. /* allocate namespace for screens */
  512. InitScreenNames();
  513. /*
  514. * Determine the screen management policy (all or none)
  515. * Process command line arguments that we handle
  516. * This could change the number of screens we manage
  517. */
  518. ProcessGlobalScreenResources ();
  519. ProcessCommandLine (argc, argv);
  520. /*
  521. * Make sure backdrops are in our icon search path.
  522. * This call MUST occur before ANY icons are looked up either
  523. * explicitly or through resource processing!!!
  524. * Uses variables set by ProcessGlobalScreenResources and
  525. * ProcessCommandLine.
  526. */
  527. {
  528. int sNum;
  529. Boolean useMaskRtn;
  530. Boolean useMultiColorIcons;
  531. Boolean useIconFileCacheRtn;
  532. String sBdPath;
  533. sNum = (wmGD.numScreens == 1) ? DefaultScreen(DISPLAY) : 0;
  534. XmeGetIconControlInfo(ScreenOfDisplay(DISPLAY, sNum), &useMaskRtn,
  535. &useMultiColorIcons, &useIconFileCacheRtn);
  536. sBdPath = wmGD.backdropDirs;
  537. InsureDefaultBackdropDir ((char **) &sBdPath);
  538. _DtWsmSetBackdropSearchPath(XScreenOfDisplay(DISPLAY, sNum),
  539. sBdPath, useMultiColorIcons);
  540. XtFree(sBdPath);
  541. }
  542. /*
  543. * Allocate data and initialize for screens we manage:
  544. */
  545. if (!(wmGD.Screens = (WmScreenData *)
  546. XtCalloc (wmGD.numScreens, sizeof(WmScreenData))))
  547. {
  548. ShowWaitState (FALSE);
  549. Warning (((char *)GETMESSAGE(40, 2, "Insufficient memory for Screen data")));
  550. ExitWM (WM_ERROR_EXIT_VALUE);
  551. }
  552. else
  553. {
  554. sAttributes.event_mask = SubstructureRedirectMask;
  555. for (scr=0; scr<wmGD.numScreens; scr++)
  556. {
  557. int sNum;
  558. /*
  559. * Gain control of the root windows of each screen:
  560. */
  561. sNum = (wmGD.numScreens == 1) ? DefaultScreen(DISPLAY) : scr;
  562. wmGD.errorFlag = False;
  563. XChangeWindowAttributes (DISPLAY, RootWindow (DISPLAY, sNum),
  564. CWEventMask, &sAttributes);
  565. /*
  566. * Do XSync to force server action and catch errors
  567. * immediately.
  568. */
  569. XSync (DISPLAY, False /* do not discard events */);
  570. if ((wmGD.errorFlag) &&
  571. (RootWindow (DISPLAY, sNum) == (Window) wmGD.errorResource) &&
  572. (wmGD.errorRequestCode == X_ChangeWindowAttributes))
  573. {
  574. sprintf(pch,
  575. ((char *)GETMESSAGE(40, 3, "Another window manager is running on screen %d")), sNum);
  576. Warning ((char *) &pch[0]);
  577. wmGD.Screens[scr].managed = False;
  578. }
  579. else
  580. {
  581. if (!processedGlobalResources)
  582. {
  583. enum {
  584. XA_DT_SESSION_HINTS, XA_DT_SM_WM_PROTOCOL,
  585. XA_DT_SM_START_ACK_WINDOWS, XA_DT_SM_STOP_ACK_WINDOWS,
  586. XA_DT_WM_WINDOW_ACK, XA_DT_WM_EXIT_SESSION,
  587. XA_DT_WM_LOCK_DISPLAY, XA_DT_WM_READY, NUM_ATOMS };
  588. static char *atom_names[] = {
  589. _XA_DT_SESSION_HINTS, _XA_DT_SM_WM_PROTOCOL,
  590. _XA_DT_SM_START_ACK_WINDOWS, _XA_DT_SM_STOP_ACK_WINDOWS,
  591. _XA_DT_WM_WINDOW_ACK, _XA_DT_WM_EXIT_SESSION,
  592. _XA_DT_WM_LOCK_DISPLAY, _XA_DT_WM_READY };
  593. Atom atoms[XtNumber(atom_names)];
  594. XInternAtoms(DISPLAY, atom_names, XtNumber(atom_names),
  595. False, atoms);
  596. wmGD.xa_DT_SESSION_HINTS = atoms[XA_DT_SESSION_HINTS];
  597. wmGD.xa_DT_SM_WM_PROTOCOL = atoms[XA_DT_SM_WM_PROTOCOL];
  598. wmGD.xa_DT_SM_START_ACK_WINDOWS =
  599. atoms[XA_DT_SM_START_ACK_WINDOWS];
  600. wmGD.xa_DT_SM_STOP_ACK_WINDOWS =
  601. atoms[XA_DT_SM_STOP_ACK_WINDOWS];
  602. wmGD.xa_DT_WM_WINDOW_ACK = atoms[XA_DT_WM_WINDOW_ACK];
  603. wmGD.xa_DT_WM_EXIT_SESSION = atoms[XA_DT_WM_EXIT_SESSION];
  604. wmGD.xa_DT_WM_LOCK_DISPLAY = atoms[XA_DT_WM_LOCK_DISPLAY];
  605. wmGD.xa_DT_WM_READY = atoms[XA_DT_WM_READY];
  606. InitOLCompat();
  607. wmGD.hasShape = XShapeQueryExtension (DISPLAY,
  608. &wmGD.shapeEventBase,
  609. &wmGD.shapeErrorBase);
  610. wmGD.replayEnterEvent = False;
  611. wmGD.menuActive = NULL;
  612. wmGD.menuUnpostKeySpec = NULL;
  613. wmGD.F_NextKeySpec = NULL;
  614. wmGD.F_PrevKeySpec = NULL;
  615. wmGD.passKeysActive = False;
  616. wmGD.passKeysKeySpec = NULL;
  617. wmGD.checkHotspot = False;
  618. wmGD.configAction = NO_ACTION;
  619. wmGD.configPart = FRAME_NONE;
  620. wmGD.configSet = False;
  621. wmGD.preMove = False;
  622. wmGD.gadgetClient = NULL;
  623. wmGD.wmTimers = NULL;
  624. wmGD.clientDefaultTitle =
  625. XmStringCreateLocalized(DEFAULT_CLIENT_TITLE);
  626. wmGD.iconDefaultTitle =
  627. XmStringCreateLocalized(DEFAULT_ICON_TITLE);
  628. wmGD.attributesWindow = (Window)NULL;
  629. wmGD.clickData.pCD = NULL;
  630. wmGD.clickData.clickPending = False;
  631. wmGD.clickData.doubleClickPending = False;
  632. wmGD.systemModalActive = False;
  633. wmGD.activeIconTextDisplayed = False;
  634. wmGD.movingIcon = False;
  635. wmGD.queryScreen = True;
  636. wmGD.dataType = GLOBAL_DATA_TYPE;
  637. wmGD.pLockMaskSequence = NULL;
  638. SetupLockingModifierMask ();
  639. wmGD.requestContextWin = (Window) 0L;
  640. wmGD.cppCommand = NULL;
  641. wmGD.evLastButton.button = 0;
  642. wmGD.bReplayedButton = False;
  643. wmGD.bSuspendSecondaryRestack = False;
  644. /*
  645. * Get a second display connection for
  646. * internal WM windows.
  647. */
  648. wmGD.display1 = XtOpenDisplay (wmGD.mwmAppContext,
  649. NULL,
  650. wmGD.mwmName,
  651. res_class,
  652. NULL,
  653. 0,
  654. &dpy2Argc,
  655. dpy2Argv);
  656. if (!wmGD.display1)
  657. {
  658. ShowWaitState (FALSE);
  659. Warning(((char *)GETMESSAGE(40, 4, "Could not open second display connection.")));
  660. ExitWM (WM_ERROR_EXIT_VALUE);
  661. }
  662. _DtGetSmWindow(DISPLAY,
  663. RootWindow(DISPLAY, 0),
  664. &wmGD.dtSmWindow) ;
  665. /* create topmost shell (application shell) */
  666. argnum = 0;
  667. XtSetArg (args[argnum], XtNgeometry, NULL); argnum++;
  668. XtSetArg (args[argnum], XtNx, 10000); argnum++;
  669. XtSetArg (args[argnum], XtNy, 0); argnum++;
  670. XtSetArg (args[argnum], XtNwidth, 10); argnum++;
  671. XtSetArg (args[argnum], XtNheight, 10); argnum++;
  672. XtSetArg (args[argnum],
  673. XtNmappedWhenManaged, False); argnum++;
  674. wmGD.topLevelW1 =
  675. XtAppCreateShell (NULL,
  676. res_class,
  677. applicationShellWidgetClass,
  678. DISPLAY1,
  679. args,
  680. argnum);
  681. /*
  682. * if this is the first screen we can manage,
  683. * process global.
  684. */
  685. processedGlobalResources = True;
  686. /*
  687. * Get the _MOTIF_WM_INFO property and determine
  688. * the startup / restart state.
  689. */
  690. ProcessMotifWmInfo (RootWindow (DISPLAY, sNum));
  691. /*
  692. * Process global window manager resources:
  693. */
  694. #ifndef NO_MESSAGE_CATALOG
  695. InitBuiltinSystemMenu();
  696. #endif
  697. ProcessWmResources ();
  698. }
  699. InitWmScreen (&(wmGD.Screens[scr]), sNum);
  700. wmGD.Screens[scr].managed = True;
  701. managed++;
  702. GetDtSessionHints(&(wmGD.Screens[scr]), sNum);
  703. if (!activeSet)
  704. {
  705. activeSet = True;
  706. ACTIVE_PSD = &wmGD.Screens[scr];
  707. }
  708. }
  709. }
  710. if (managed == 0)
  711. {
  712. /*
  713. * No screens for me to manage, give up.
  714. */
  715. ShowWaitState (FALSE);
  716. Warning (((char *)GETMESSAGE(40, 5, "Unable to manage any screens on display.")));
  717. ExitWM (WM_ERROR_EXIT_VALUE);
  718. }
  719. }
  720. /*
  721. * Initialize the IPC mechanism
  722. */
  723. dtInitialize(argv[0], wmGD.mwmAppContext);
  724. #ifndef NO_MESSAGE_CATALOG
  725. /*
  726. * Set up NLS error messages.
  727. * Must be done after DtInitialize.
  728. */
  729. InitNlsStrings ();
  730. #endif
  731. /*
  732. * For multiple connections to the server, turn off
  733. * the geometry manager's insistence on synchronous
  734. * management.
  735. */
  736. argnum = 0;
  737. XtSetArg (args[argnum], XmNuseAsyncGeometry, True); argnum++;
  738. XtSetValues (wmGD.topLevelW, args, argnum);
  739. XtSetValues (wmGD.topLevelW1, args, argnum);
  740. /*
  741. * Prepare to have child processes (e.g., exec'ed commands).
  742. * The X connection should not be passed on to child processes
  743. * (it should be automatically closed when a fork is done).
  744. */
  745. if (fcntl (ConnectionNumber (DISPLAY), F_SETFD, 1) == -1)
  746. {
  747. ShowWaitState (FALSE);
  748. Warning (((char *)GETMESSAGE(40, 6, "Cannot configure X connection")));
  749. ExitWM (WM_ERROR_EXIT_VALUE);
  750. }
  751. {
  752. enum { XA_DT_WORKSPACE_HINTS, XA_DT_WORKSPACE_PRESENCE,
  753. XA_DT_WORKSPACE_INFO, XA_WmNall,
  754. XA_DT_WORKSPACE_EMBEDDED_CLIENTS, XA_DT_WM_REQUEST,
  755. XA_DT_WORKSPACE_LIST, XA_DT_WORKSPACE_CURRENT, NUM_ATOMS };
  756. static char *atom_names[] = {
  757. _XA_DT_WORKSPACE_HINTS, _XA_DT_WORKSPACE_PRESENCE,
  758. _XA_DT_WORKSPACE_INFO, WmNall,
  759. _XA_DT_WORKSPACE_EMBEDDED_CLIENTS, _XA_DT_WM_REQUEST,
  760. _XA_DT_WORKSPACE_LIST, _XA_DT_WORKSPACE_CURRENT };
  761. Atom atoms[XtNumber(atom_names)];
  762. XInternAtoms(DISPLAY, atom_names, XtNumber(atom_names), False, atoms);
  763. wmGD.xa_DT_WORKSPACE_HINTS = atoms[XA_DT_WORKSPACE_HINTS];
  764. wmGD.xa_DT_WORKSPACE_PRESENCE = atoms[XA_DT_WORKSPACE_PRESENCE];
  765. wmGD.xa_DT_WORKSPACE_INFO = atoms[XA_DT_WORKSPACE_INFO];
  766. wmGD.xa_ALL_WORKSPACES = atoms[XA_WmNall];
  767. wmGD.xa_DT_EMBEDDED_CLIENTS = atoms[XA_DT_WORKSPACE_EMBEDDED_CLIENTS];
  768. wmGD.xa_DT_WM_REQUEST = atoms[XA_DT_WM_REQUEST];
  769. wmGD.xa_DT_WORKSPACE_LIST = atoms[XA_DT_WORKSPACE_LIST];
  770. wmGD.xa_DT_WORKSPACE_CURRENT = atoms[XA_DT_WORKSPACE_CURRENT];
  771. }
  772. /* Initialize properties used in session management. */
  773. wmGD.xa_SM_CLIENT_ID =
  774. XmInternAtom (DISPLAY, _XA_DT_SM_CLIENT_ID, False);
  775. wmGD.xa_WMSAVE_HINT =
  776. XmInternAtom (DISPLAY, _XA_DT_WMSAVE_HINT, False);
  777. /* Load client resource database. */
  778. wmGD.clientResourceDB = LoadClientResourceDB();
  779. /*
  780. * Make the window manager workspace window.
  781. * Setup the _MOTIF_WM_INFO property on the root window.
  782. */
  783. SetupWmWorkspaceWindows ();
  784. /* make the cursors that the window manager uses */
  785. MakeWorkspaceCursors ();
  786. /* Sync the table used by Mwm's modifier parser to actual modMasks used */
  787. SyncModifierStrings();
  788. /*
  789. * Setup screen data and resources (after processing Wm resources.
  790. */
  791. for (scr = 0; scr < wmGD.numScreens; scr++)
  792. {
  793. pSD = &(wmGD.Screens[scr]);
  794. if (pSD->managed)
  795. {
  796. if (XDefaultScreen (wmGD.display) == pSD->screen)
  797. {
  798. wmGD.commandWindow = wmGD.Screens[scr].wmWorkspaceWin;
  799. }
  800. /*
  801. * Initialize workspace colormap data.
  802. */
  803. InitWorkspaceColormap (pSD);
  804. /*
  805. * Process the window manager resource description file (.mwmrc):
  806. */
  807. ProcessWmFile (pSD, False /* not nested */);
  808. /*
  809. * Setup default resources for the system menu and key bindings:
  810. */
  811. SetupDefaultResources (pSD);
  812. /*
  813. * Make global window manager facilities:
  814. */
  815. if(pSD->iconDecoration & ICON_ACTIVE_LABEL_PART)
  816. {
  817. /* create active icon window */
  818. CreateActiveIconTextWindow(pSD);
  819. }
  820. /*
  821. * Make menus and other resources that are used by window manager
  822. * functions that are activated by menus, buttons and keys.
  823. */
  824. MakeWmFunctionResources (pSD);
  825. }
  826. }
  827. /*
  828. * Remove any temp config file we created if we needed to
  829. * convert DT 2.0 syntax to DT 3.0
  830. */
  831. DeleteTempConfigFileIfAny();
  832. /*
  833. * Point second display's resource data base
  834. * to the first display's resource data base
  835. * so dtwm "clients" change colors dynamically.
  836. *
  837. * NEW LOCATION
  838. */
  839. wmGD.display1->db = wmGD.display->db;
  840. /*
  841. * Realize the top level widget, make the window override
  842. * redirect so we don't manage it, and then move it out of the way
  843. */
  844. XtRealizeWidget (wmGD.topLevelW);
  845. XtRealizeWidget (wmGD.topLevelW1);
  846. /*
  847. * Initialize the message handling.
  848. * (This must be done after the realize because a window
  849. * is required for ICCCM-style messaging).
  850. */
  851. dtInitializeMessaging (wmGD.topLevelW);
  852. sAttributes.override_redirect = True;
  853. XChangeWindowAttributes (DISPLAY, XtWindow (wmGD.topLevelW),
  854. CWOverrideRedirect, &sAttributes);
  855. /* setup window manager inter-client communications conventions handling */
  856. SetupWmICCC ();
  857. /*
  858. * Use the WM_SAVE_YOURSELF protocol
  859. * for notification of when to save ourself
  860. */
  861. SetMwmSaveSessionInfo(wmGD.commandWindow);
  862. /*
  863. * Initialize window manager event handling:
  864. */
  865. InitEventHandling ();
  866. /*
  867. * Initialize frame component graphics
  868. */
  869. {
  870. for (scr = 0; scr < wmGD.numScreens; scr++)
  871. {
  872. pSD = &(wmGD.Screens[scr]);
  873. if (pSD->managed)
  874. {
  875. InitClientDecoration (pSD);
  876. /*
  877. * Make an icon box if specificed:
  878. */
  879. if (pSD->useIconBox)
  880. {
  881. InitIconBox (pSD);
  882. }
  883. /*
  884. * Adopt client windows that exist before wm startup:
  885. */
  886. AdoptInitialClients (pSD);
  887. /*
  888. * Setup initial keyboard focus and colormap focus:
  889. */
  890. InitColormapFocus (pSD);
  891. }
  892. }
  893. for (scr = 0; scr < wmGD.numScreens; scr++)
  894. {
  895. int iws;
  896. pSD = &(wmGD.Screens[scr]);
  897. if (pSD->managed)
  898. {
  899. ACTIVE_PSD = &wmGD.Screens[scr];
  900. MapIconBoxes (pSD->pActiveWS);
  901. ChangeBackdrop (pSD->pActiveWS);
  902. SetCurrentWorkspaceProperty (pSD);
  903. SetWorkspaceListProperty (pSD);
  904. for (iws=0; iws < pSD->numWorkspaces; iws++)
  905. {
  906. SetWorkspaceInfoProperty (&(pSD->pWS[iws]));
  907. }
  908. XFlush (DISPLAY);
  909. /* MapWorkspaceBox (); */
  910. /*
  911. * Allocate front panel widgets
  912. */
  913. if (wmGD.useFrontPanel && (pSD == wmGD.dtSD))
  914. {
  915. Pixmap iconBitmap;
  916. Arg al[5];
  917. int ac;
  918. WmPanelistObject pPanelist;
  919. wmGD.dtSD->wPanelist =
  920. WmPanelistAllocate(pSD->screenTopLevelW1,
  921. (XtPointer) &wmGD, (XtPointer) pSD);
  922. pPanelist = (WmPanelistObject) pSD->wPanelist;
  923. if (pPanelist != NULL && O_Shell(pPanelist))
  924. {
  925. /*
  926. * Make a default front panel icon image.
  927. */
  928. iconBitmap = XCreateBitmapFromData (DISPLAY,
  929. pSD->rootWindow,
  930. (char *) fntpl_i_bm_bits,
  931. fntpl_i_bm_width,
  932. fntpl_i_bm_height);
  933. ac = 0;
  934. XtSetArg (al[ac], XmNiconPixmap, iconBitmap); ac++;
  935. XtSetValues (O_Shell(pPanelist), al, ac);
  936. }
  937. }
  938. if (wmGD.useFrontPanel && pSD->wPanelist &&
  939. (pSD == wmGD.dtSD))
  940. {
  941. /*
  942. * Make the front panel visible
  943. */
  944. WmPanelistShow (pSD->wPanelist);
  945. /*
  946. * Find special clients associated with the
  947. * front panel. This needs to be done after
  948. * WmPanelistShow where the data is set up.
  949. */
  950. ScanForPushRecallClients (pSD);
  951. ScanForEmbeddedClients (pSD);
  952. }
  953. RestoreHelpDialogs(pSD);
  954. }
  955. }
  956. firstTime = 0;
  957. }
  958. InitKeyboardFocus ();
  959. ShowWaitState (FALSE);
  960. /*
  961. * Tell the rest of DT that we're up
  962. */
  963. dtReadyNotification();
  964. #ifdef DEBUG_RESOURCE_DATABASE
  965. XrmPutFileDatabase(wmGD.display->db, "/tmp/dtwm.resDB");
  966. #endif /* DEBUG_RESOURCE_DATABASE */
  967. } /* END OF FUNCTION InitWmGlobal */
  968. /******************************<->*************************************
  969. *
  970. * InitWmScreen
  971. *
  972. *
  973. * Description:
  974. * -----------
  975. * This function initializes a screen data block.
  976. *
  977. * Inputs:
  978. * -------
  979. * pSD = pointer to preallocated screen data block
  980. * sNum = screen number for this screen
  981. *
  982. * Outputs:
  983. * -------
  984. *************************************<->***********************************/
  985. void
  986. InitWmScreen (WmScreenData *pSD, int sNum)
  987. {
  988. Arg args[12];
  989. int argnum;
  990. int wsnum;
  991. WmWorkspaceData *pwsI;
  992. int buf_size;
  993. int iwsx;
  994. char *pDisplayName;
  995. #define LENCBUFFER 256
  996. char buffer[LENCBUFFER]; /* screen name & display name! */
  997. char displayName[LENCBUFFER];
  998. char *token1, *token2;
  999. /*
  1000. * Set screen data values
  1001. */
  1002. pSD->rootWindow = RootWindow (DISPLAY, sNum);
  1003. pSD->clientCounter = 0;
  1004. pSD->defaultSystemMenuUseBuiltin = TRUE;
  1005. pSD->displayString = NULL;
  1006. pSD->acceleratorMenuCount = 0;
  1007. pSD->activeIconTextWin = (Window)NULL;
  1008. pSD->focusPriority = 0;
  1009. pSD->inputScreenWindow = (Window)NULL;
  1010. pSD->colormapFocus = NULL;
  1011. pSD->keySpecs = NULL;
  1012. pSD->screen = sNum;
  1013. pSD->confirmboxW[DEFAULT_BEHAVIOR_ACTION] = NULL;
  1014. pSD->confirmboxW[CUSTOM_BEHAVIOR_ACTION] = NULL;
  1015. pSD->confirmboxW[RESTART_ACTION] = NULL;
  1016. pSD->confirmboxW[QUIT_MWM_ACTION] = NULL;
  1017. pSD->feedbackWin = (Window)NULL;
  1018. pSD->fbStyle = FB_OFF;
  1019. pSD->fbWinWidth = 0;
  1020. pSD->fbWinHeight = 0;
  1021. pSD->fbLocation[0] = '\0';
  1022. pSD->fbSize[0] = '\0';
  1023. pSD->fbLocX = 0;
  1024. pSD->fbLocY = 0;
  1025. pSD->fbSizeX = 0;
  1026. pSD->fbSizeY = 0;
  1027. pSD->fbLastX = -1;
  1028. pSD->fbLastY = -1;
  1029. pSD->fbLastWidth = -1;
  1030. pSD->fbLastHeight = -1;
  1031. pSD->fbTop = NULL;
  1032. pSD->fbBottom = NULL;
  1033. pSD->actionNbr = -1;
  1034. pSD->clientList = NULL;
  1035. pSD->lastClient = NULL;
  1036. pSD->lastInstalledColormap = (Colormap)NULL;
  1037. pSD->shrinkWrapGC = NULL;
  1038. pSD->bitmapCache = NULL;
  1039. pSD->bitmapCacheSize = 0;
  1040. pSD->bitmapCacheCount = 0;
  1041. pSD->dataType = SCREEN_DATA_TYPE;
  1042. pSD->managed = False;
  1043. pSD->initialWorkspace=NULL;
  1044. pSD->presence.shellW = NULL;
  1045. pSD->presence.onScreen = False;
  1046. pSD->presence.userDismissed = True;
  1047. pSD->workspaceList = NULL;
  1048. pSD->numWorkspaces = 0;
  1049. pSD->numWsDataAllocated = 0;
  1050. pSD->lastBackdropWin = None;
  1051. pSD->pDtSessionItems = NULL;
  1052. pSD->totalSessionItems = 0;
  1053. pSD->remainingSessionItems = 0;
  1054. pSD->cachedHelp = NULL;
  1055. pSD->dtHelp.shell = (Widget)NULL;
  1056. pSD->dtHelp.dialog = (Widget)NULL;
  1057. pSD->dtHelp.errorDialog = (Widget)NULL;
  1058. pSD->dtHelp.xPos = 0;
  1059. pSD->dtHelp.yPos = 0;
  1060. pSD->dtHelp.restored = False;
  1061. pSD->dtHelp.onScreen = False;
  1062. pSD->dtHelp.userDismissed = False;
  1063. pSD->dtHelp.pCDforClient= NULL;
  1064. pSD->helpResources=NULL;
  1065. pSD->bMarqueeSelectionInitialized = False;
  1066. pSD->woN = (Window) 0L;
  1067. pSD->woS = (Window) 0L;
  1068. pSD->woE = (Window) 0L;
  1069. pSD->woW = (Window) 0L;
  1070. pSD->wPanelist = NULL;
  1071. pSD->pECD = NULL;
  1072. pSD->numPushRecallClients = 0;
  1073. pSD->numEmbeddedClients = 0;
  1074. pSD->pPRCD = NULL;
  1075. pSD->iconBoxControl = False;
  1076. pSD->displayResolutionType = _DtGetDisplayResolution(DISPLAY, sNum);
  1077. /*
  1078. * We've got display resolution type--now, let's get color
  1079. * characteristics.
  1080. */
  1081. ProcessWmColors (pSD);
  1082. if (!(strcmp ((char *)wmGD.screenNames[sNum], UNSPECIFIED_SCREEN_NAME)))
  1083. {
  1084. sprintf (buffer, "%d", sNum);
  1085. buf_size = strlen(buffer) + 1;
  1086. if ((wmGD.screenNames[sNum] =
  1087. (unsigned char *)XtRealloc ((char *)wmGD.screenNames[sNum], buf_size)) == NULL)
  1088. {
  1089. Warning (((char *)GETMESSAGE(40, 7, "Cannot create enough memory for the screen names")));
  1090. ExitWM (WM_ERROR_EXIT_VALUE);
  1091. }
  1092. else
  1093. {
  1094. strcpy((char *)wmGD.screenNames[sNum], buffer);
  1095. }
  1096. } /* if wmGD.screenNames[sNum] == UNSPECIFIED_SCREEN_NAME */
  1097. /*
  1098. * Save screen context
  1099. */
  1100. XSaveContext (DISPLAY, pSD->rootWindow, wmGD.screenContextType,
  1101. (caddr_t)pSD);
  1102. /*
  1103. * Create shell widget for screen resource hierarchy
  1104. */
  1105. argnum = 0;
  1106. XtSetArg (args[argnum], XtNgeometry, NULL); argnum++;
  1107. XtSetArg (args[argnum], XtNx, 10000); argnum++;
  1108. XtSetArg (args[argnum], XtNy, 10000); argnum++;
  1109. XtSetArg (args[argnum], XtNwidth, 10); argnum++;
  1110. XtSetArg (args[argnum], XtNheight, 10); argnum++;
  1111. XtSetArg (args[argnum], XtNoverrideRedirect, True); argnum++;
  1112. XtSetArg (args[argnum], XtNdepth,
  1113. DefaultDepth(DISPLAY, sNum)); argnum++;
  1114. XtSetArg (args[argnum], XtNscreen,
  1115. ScreenOfDisplay(DISPLAY, sNum)); argnum++;
  1116. XtSetArg (args[argnum], XtNcolormap,
  1117. DefaultColormap(DISPLAY, sNum)); argnum++;
  1118. pSD->screenTopLevelW = XtCreatePopupShell ((String) wmGD.screenNames[sNum],
  1119. vendorShellWidgetClass,
  1120. wmGD.topLevelW,
  1121. args,
  1122. argnum);
  1123. argnum = 0;
  1124. XtSetArg (args[argnum], XtNgeometry, NULL); argnum++;
  1125. XtSetArg (args[argnum], XtNx, 10000); argnum++;
  1126. XtSetArg (args[argnum], XtNy, 10000); argnum++;
  1127. XtSetArg (args[argnum], XtNwidth, 10); argnum++;
  1128. XtSetArg (args[argnum], XtNheight, 10); argnum++;
  1129. XtSetArg (args[argnum], XtNoverrideRedirect, True); argnum++;
  1130. XtSetArg (args[argnum], XtNmappedWhenManaged, False); argnum++;
  1131. XtSetArg (args[argnum], XtNdepth,
  1132. DefaultDepth(DISPLAY1, sNum)); argnum++;
  1133. XtSetArg (args[argnum], XtNscreen,
  1134. ScreenOfDisplay(DISPLAY1, sNum)); argnum++;
  1135. XtSetArg (args[argnum], XtNcolormap,
  1136. DefaultColormap(DISPLAY1, sNum)); argnum++;
  1137. pSD->screenTopLevelW1 = XtCreatePopupShell ((String) wmGD.screenNames[sNum],
  1138. vendorShellWidgetClass,
  1139. wmGD.topLevelW1,
  1140. args,
  1141. argnum);
  1142. XtRealizeWidget (pSD->screenTopLevelW1);
  1143. /*
  1144. * Fetch screen based resources
  1145. */
  1146. ProcessScreenResources (pSD, wmGD.screenNames[sNum]);
  1147. /*
  1148. * Initialize other screen resources and parameters
  1149. */
  1150. MakeXorGC (pSD);
  1151. InitIconSize(pSD);
  1152. /*
  1153. * Complete initialization of workspace structures
  1154. */
  1155. for (wsnum = 0,
  1156. pwsI = pSD->pWS; wsnum < pSD->numWorkspaces;
  1157. wsnum++, pwsI++)
  1158. {
  1159. /*
  1160. * Set up workspace for this screen
  1161. */
  1162. InitWmWorkspace (pwsI, pSD);
  1163. }
  1164. if (pSD->initialWorkspace)
  1165. {
  1166. /*
  1167. * restore to the last initialWorkspace saved from
  1168. * Quit, Restart, OR save session
  1169. */
  1170. /*
  1171. * Compare initialWorkspace against workspace name,
  1172. * NOT workspace title.
  1173. */
  1174. for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++)
  1175. {
  1176. if (!strcmp(pSD->pWS[iwsx].name, pSD->initialWorkspace))
  1177. {
  1178. break;
  1179. }
  1180. }
  1181. /* check bounds */
  1182. if (iwsx >= pSD->numWorkspaces)
  1183. {
  1184. /* make first workspace in list the active one to start with */
  1185. pSD->pActiveWS = pSD->pWS;
  1186. }
  1187. else
  1188. {
  1189. pSD->pActiveWS = &pSD->pWS[iwsx];
  1190. }
  1191. }
  1192. else
  1193. {
  1194. /* make first workspace in list the active one to start with */
  1195. pSD->pActiveWS = pSD->pWS;
  1196. }
  1197. pDisplayName = DisplayString (DISPLAY);
  1198. /*
  1199. * Construct displayString for this string.
  1200. *
  1201. * NOTE: The variable buffer is reused here. It was
  1202. * used earlier to generate a screen name.
  1203. */
  1204. strcpy(displayName, pDisplayName);
  1205. token1 = (char*)strtok(displayName, ":"); /* parse of hostname */
  1206. if((token2 = (char*)strtok(NULL, ".")) || /* parse off dpy & scr # */
  1207. (token2 = (char*)strtok(NULL, "")) ||
  1208. (displayName[0] == ':'))
  1209. {
  1210. if (displayName[0] == ':') /* local dpy (special case) */
  1211. {
  1212. if ((token2 = (char*)strtok(token1, ".")) != NULL) /* parse dpy# */
  1213. sprintf(buffer, "DISPLAY=:%s.%d",
  1214. token2, sNum);
  1215. } else { /* otherwise process normally */
  1216. sprintf(buffer, "DISPLAY=%s:%s.%d",
  1217. token1, token2, sNum);
  1218. }
  1219. /*
  1220. * Allocate space for the display string
  1221. */
  1222. if ((pSD->displayString =
  1223. (String)XtMalloc ((unsigned int) (strlen(buffer) + 1))) == NULL)
  1224. {
  1225. Warning (((char *)GETMESSAGE(40, 9,
  1226. "Insufficient memory for displayString")));
  1227. }
  1228. else
  1229. {
  1230. strcpy(pSD->displayString, buffer);
  1231. }
  1232. }
  1233. } /* END OF FUNCTION InitWmScreen */
  1234. /*************************************<->*************************************
  1235. *
  1236. * InitWmWorkspace
  1237. *
  1238. *
  1239. * Description:
  1240. * -----------
  1241. * This function initializes a workspace data block.
  1242. *
  1243. * Inputs:
  1244. * -------
  1245. * pWS = pointer to preallocated workspace data block
  1246. * pSD = ptr to parent screen data block
  1247. *
  1248. * Outputs:
  1249. * -------
  1250. *************************************<->***********************************/
  1251. void InitWmWorkspace (WmWorkspaceData *pWS, WmScreenData *pSD)
  1252. {
  1253. Arg args[10];
  1254. int argnum;
  1255. pWS->pSD = pSD;
  1256. pWS->pIconBox = NULL;
  1257. pWS->dataType = WORKSPACE_DATA_TYPE;
  1258. pWS->backdrop.window = 0;
  1259. pWS->backdrop.nameAtom = 0;
  1260. pWS->backdrop.image = NULL;
  1261. pWS->numClients = 0;
  1262. pWS->sizeClientList = 0;
  1263. pWS->ppClients = 0;
  1264. pWS->buttonW = NULL;
  1265. /*
  1266. * Create widget for workspace resource hierarchy
  1267. */
  1268. argnum = 0;
  1269. XtSetArg (args[argnum], XtNdepth,
  1270. DefaultDepth(DISPLAY, pSD->screen)); argnum++;
  1271. XtSetArg (args[argnum], XtNscreen,
  1272. ScreenOfDisplay(DISPLAY, pSD->screen)); argnum++;
  1273. XtSetArg (args[argnum], XtNcolormap,
  1274. DefaultColormap(DISPLAY, pSD->screen)); argnum++;
  1275. XtSetArg (args[argnum], XtNwidth, 5); argnum++;
  1276. XtSetArg (args[argnum], XtNheight, 5); argnum++;
  1277. pWS->workspaceTopLevelW = XtCreateWidget ( pWS->name,
  1278. xmPrimitiveWidgetClass,
  1279. pSD->screenTopLevelW,
  1280. args,
  1281. argnum);
  1282. /* internalize the workspace name */
  1283. pWS->id = XInternAtom (DISPLAY, pWS->name, False);
  1284. /*
  1285. * Process workspace based resources
  1286. */
  1287. ProcessWorkspaceResources (pWS);
  1288. /* setup icon placement */
  1289. if (wmGD.iconAutoPlace)
  1290. {
  1291. InitIconPlacement (pWS);
  1292. }
  1293. } /* END OF FUNCTION InitWmWorkspace */
  1294. /******************************<->*************************************
  1295. *
  1296. * InsureDefaultBackdropDir(char **ppchBackdropDirs)
  1297. *
  1298. *
  1299. * Description:
  1300. * -----------
  1301. * This function checks and edits a directory path to insure
  1302. * that the system backdrop directroy (/usr/dt/backdrops) is in the
  1303. * path. If not it adds it to the end. Further, it always adds the user's
  1304. * backdrop directory ($HOME/.dt/backdrops) to the beginning of the path
  1305. * and the system admin directory (/etc/dt/backdrops) before the system
  1306. * directory.
  1307. *
  1308. * Inputs:
  1309. * -------
  1310. * ppchBackdropDirs - Pointer to a pointer to a directory path
  1311. * (must be allocated memory)
  1312. *
  1313. * Outputs:
  1314. * -------
  1315. * *ppchBackdropDirs - Directory path may be modified, path
  1316. * pointer may be realloc'ed.
  1317. *
  1318. * Comments:
  1319. * --------
  1320. * Assumes that the default directory does not start with a
  1321. * multi-byte character.
  1322. *
  1323. ******************************<->***********************************/
  1324. static void
  1325. InsureDefaultBackdropDir(char **ppchBackdropDirs)
  1326. {
  1327. int len;
  1328. Boolean bFound = False;
  1329. char *pch, *pchEnd, *pch2, *tmpptr;
  1330. char *pchD = DEFAULT_BACKDROP_DIR;
  1331. unsigned int chlen;
  1332. char * homeDir;
  1333. /*
  1334. * Set up initial stuff
  1335. */
  1336. pch = *ppchBackdropDirs;
  1337. len = strlen (pchD);
  1338. pchEnd = pch + strlen(pch);
  1339. while (!bFound && (pch != NULL) && (*pch != 0))
  1340. {
  1341. if (strncmp (pch, pchD, len) == 0)
  1342. {
  1343. /* found partial match, confirm complete match ...
  1344. * complete match if char off end of partial match
  1345. * is a NULL or a colon
  1346. */
  1347. pch2 = pch + len;
  1348. if ((pch2 <= pchEnd) &&
  1349. ((*pch2 == 0) ||
  1350. (((mblen (pch2, MB_CUR_MAX) == 1) &&
  1351. (*pch2 == ':')))))
  1352. {
  1353. bFound = True;
  1354. }
  1355. }
  1356. else
  1357. {
  1358. /* find next path component */
  1359. pch = strchr (pch, (int) ':');
  1360. if ((pch != NULL) && (*pch != 0))
  1361. {
  1362. /* skip path separator */
  1363. chlen = mblen (pch, MB_CUR_MAX);
  1364. pch += chlen;
  1365. }
  1366. }
  1367. }
  1368. /*
  1369. * Always add the user's home directory to the beginning of the string
  1370. */
  1371. homeDir = (char *) XmeGetHomeDirName();
  1372. /*
  1373. * If found add the user's home directory ($HOME/.dt/backdrops) and the
  1374. * admin directory /etc/dt/backdrops to the beginning of the string
  1375. */
  1376. if (bFound)
  1377. {
  1378. len = strlen (homeDir) + strlen("/.dt/backdrops") +
  1379. strlen (*ppchBackdropDirs) + strlen("/etc/dt/backdrops") + 3;
  1380. tmpptr = XtMalloc (len * sizeof (char *));
  1381. strcpy (tmpptr, homeDir);
  1382. strcat (tmpptr, "/.dt/backdrops");
  1383. strcat (tmpptr, ":");
  1384. strcat (tmpptr, "/etc/dt/backdrops");
  1385. strcat (tmpptr, ":");
  1386. strcat (tmpptr, *ppchBackdropDirs);
  1387. *ppchBackdropDirs = tmpptr;
  1388. }
  1389. else
  1390. /*
  1391. * If string not found, then add home directory to the beginning of
  1392. * string and the admin directory and system directory to the end.
  1393. */
  1394. {
  1395. len = strlen (homeDir) + strlen("/.dt/backdrops") +
  1396. strlen (*ppchBackdropDirs) + strlen(pchD) +
  1397. strlen("/etc/dt/backdrops") + 4;
  1398. tmpptr = XtMalloc (len * sizeof (char *));
  1399. strcpy (tmpptr, homeDir);
  1400. strcat (tmpptr, "/.dt/backdrops");
  1401. strcat (tmpptr, ":");
  1402. strcat (tmpptr, *ppchBackdropDirs);
  1403. strcat (tmpptr, ":");
  1404. strcat (tmpptr, "/etc/dt/backdrops");
  1405. strcat (tmpptr, ":");
  1406. strcat (tmpptr, pchD);
  1407. *ppchBackdropDirs = tmpptr;
  1408. }
  1409. } /* END OF FUNCTION InsureDefaultBackdropDirs */
  1410. /*************************************<->*************************************
  1411. *
  1412. * ProcessMotifWmInfo (rootWindowOfScreen)
  1413. *
  1414. *
  1415. * Description:
  1416. * -----------
  1417. * This function is used retrieve and save the information in the
  1418. * _MOTIF_WM_INFO property. If the property does not exist then
  1419. * the start / restart state is set to initial startup with the
  1420. * user specified (not standard) configuration.
  1421. *
  1422. *
  1423. * Outputs:
  1424. * -------
  1425. * wmGD.useStandardBehavior = True if set indicated in property
  1426. *
  1427. * wmGD.wmRestarted = True if the window manager was restarted
  1428. *
  1429. *************************************<->***********************************/
  1430. void ProcessMotifWmInfo (Window rootWindowOfScreen)
  1431. {
  1432. MwmInfo *pMwmInfo;
  1433. wmGD.xa_MWM_INFO = XInternAtom (DISPLAY, _XA_MWM_INFO, False);
  1434. if ((pMwmInfo = (MotifWmInfo *)GetMwmInfo (rootWindowOfScreen)) != NULL)
  1435. {
  1436. wmGD.useStandardBehavior =
  1437. (pMwmInfo->flags & MWM_INFO_STARTUP_STANDARD) ? True : False;
  1438. wmGD.wmRestarted = True;
  1439. XFree ((char *)pMwmInfo);
  1440. }
  1441. else
  1442. {
  1443. wmGD.useStandardBehavior = False;
  1444. wmGD.wmRestarted = False;
  1445. }
  1446. } /* END OF FUNCTION ProcessMotifWmInfo */
  1447. /*************************************<->*************************************
  1448. *
  1449. * SetupWmWorkspaceWindows ()
  1450. *
  1451. *
  1452. * Description:
  1453. * -----------
  1454. * This function is used to setup a window that can be used in doing window
  1455. * management functions. This window is not visible on the screen.
  1456. *
  1457. *
  1458. * Outputs:
  1459. * -------
  1460. * pSD->wmWorkspaceWin = window that is used to hold wm properties
  1461. *
  1462. *************************************<->***********************************/
  1463. void SetupWmWorkspaceWindows (void)
  1464. {
  1465. int scr;
  1466. WmScreenData *pSD;
  1467. XSetWindowAttributes sAttributes;
  1468. for (scr = 0; scr < wmGD.numScreens; scr++)
  1469. {
  1470. pSD = &(wmGD.Screens[scr]);
  1471. if (pSD->managed)
  1472. {
  1473. sAttributes.override_redirect = True;
  1474. sAttributes.event_mask = FocusChangeMask | PropertyChangeMask;
  1475. pSD->wmWorkspaceWin = XCreateWindow (DISPLAY, pSD->rootWindow,
  1476. -100, -100, 10, 10, 0, 0,
  1477. InputOnly, CopyFromParent,
  1478. (CWOverrideRedirect |CWEventMask),
  1479. &sAttributes);
  1480. XMapWindow (DISPLAY, pSD->wmWorkspaceWin);
  1481. SetMwmInfo (pSD->rootWindow,
  1482. (long) ((wmGD.useStandardBehavior) ?
  1483. MWM_INFO_STARTUP_STANDARD : MWM_INFO_STARTUP_CUSTOM),
  1484. pSD->wmWorkspaceWin);
  1485. XSaveContext (DISPLAY, pSD->wmWorkspaceWin,
  1486. wmGD.mwmWindowContextType, (caddr_t)pSD);
  1487. }
  1488. }
  1489. } /* END OF FUNCTION SetupWmWorkspaceWindow */
  1490. /*************************************<->*************************************
  1491. *
  1492. * MakeWorkspaceCursors ()
  1493. *
  1494. *
  1495. * Description:
  1496. * -----------
  1497. * This function makes the cursors that the window manager uses.
  1498. *
  1499. *
  1500. * Inputs:
  1501. * ------
  1502. * XXinput = ...
  1503. *
  1504. * XXinput = ...
  1505. *
  1506. *
  1507. * Outputs:
  1508. * -------
  1509. * wmGD = (stretchCursors ...)
  1510. *
  1511. *************************************<->***********************************/
  1512. void MakeWorkspaceCursors (void)
  1513. {
  1514. wmGD.workspaceCursor = XCreateFontCursor (DISPLAY, XC_left_ptr);
  1515. wmGD.stretchCursors[STRETCH_NORTH_WEST] =
  1516. XCreateFontCursor (DISPLAY, XC_top_left_corner);
  1517. wmGD.stretchCursors[STRETCH_NORTH] =
  1518. XCreateFontCursor (DISPLAY, XC_top_side);
  1519. wmGD.stretchCursors[STRETCH_NORTH_EAST] =
  1520. XCreateFontCursor (DISPLAY, XC_top_right_corner);
  1521. wmGD.stretchCursors[STRETCH_EAST] =
  1522. XCreateFontCursor (DISPLAY, XC_right_side);
  1523. wmGD.stretchCursors[STRETCH_SOUTH_EAST] =
  1524. XCreateFontCursor (DISPLAY, XC_bottom_right_corner);
  1525. wmGD.stretchCursors[STRETCH_SOUTH] =
  1526. XCreateFontCursor (DISPLAY, XC_bottom_side);
  1527. wmGD.stretchCursors[STRETCH_SOUTH_WEST] =
  1528. XCreateFontCursor (DISPLAY, XC_bottom_left_corner);
  1529. wmGD.stretchCursors[STRETCH_WEST] =
  1530. XCreateFontCursor (DISPLAY, XC_left_side);
  1531. wmGD.configCursor = XCreateFontCursor (DISPLAY, XC_fleur);
  1532. wmGD.movePlacementCursor = XCreateFontCursor (DISPLAY, XC_ul_angle);
  1533. wmGD.sizePlacementCursor = XCreateFontCursor (DISPLAY, XC_lr_angle);
  1534. } /* END OF FUNCTION MakeWorkspaceCursors */
  1535. /*************************************<->*************************************
  1536. *
  1537. * MakeWmFunctionResources (pSD)
  1538. *
  1539. *
  1540. * Description:
  1541. * -----------
  1542. * This function makes menus and other resources that are used by window
  1543. * manager functions.
  1544. *
  1545. *
  1546. * Inputs:
  1547. * ------
  1548. * wmGD = (menuSpecs, keySpecs, buttonSpecs)
  1549. *
  1550. *
  1551. * Outputs:
  1552. * -------
  1553. * wmGD (menuSpecs) = new menu panes, protocol atoms
  1554. *
  1555. *************************************<->***********************************/
  1556. void MakeWmFunctionResources (WmScreenData *pSD)
  1557. {
  1558. ButtonSpec *buttonSpec;
  1559. KeySpec *keySpec;
  1560. MenuSpec *menuSpec;
  1561. Context menuContext;
  1562. /*
  1563. * Scan through the menu specifications and make wm protocol atoms.
  1564. */
  1565. /*
  1566. * Scan through the button binding specifications making menus if the
  1567. * f.menu function is invoked.
  1568. */
  1569. buttonSpec = pSD->buttonSpecs;
  1570. while (buttonSpec)
  1571. {
  1572. if (buttonSpec->wmFunction == F_Menu)
  1573. {
  1574. if (buttonSpec->context & F_CONTEXT_WINDOW)
  1575. {
  1576. menuContext = F_CONTEXT_WINDOW;
  1577. }
  1578. else if (buttonSpec->context & F_CONTEXT_ICON)
  1579. {
  1580. menuContext = F_CONTEXT_ICON;
  1581. }
  1582. else
  1583. {
  1584. menuContext = F_CONTEXT_ROOT;
  1585. }
  1586. menuSpec = MAKE_MENU (pSD, NULL, buttonSpec->wmFuncArgs,
  1587. menuContext,
  1588. buttonSpec->context,
  1589. (MenuItem *) NULL, FALSE);
  1590. if (menuSpec)
  1591. /*
  1592. * If successful, save in pSD->acceleratorMenuSpecs
  1593. * Note: these accelerators have nonzero contexts.
  1594. */
  1595. {
  1596. SaveMenuAccelerators (pSD, menuSpec);
  1597. }
  1598. else
  1599. {
  1600. buttonSpec->wmFunction = F_Nop;
  1601. }
  1602. }
  1603. buttonSpec = buttonSpec->nextButtonSpec;
  1604. }
  1605. /*
  1606. * Scan through the key binding specifications making menus if the
  1607. * f.menu function is invoked.
  1608. */
  1609. keySpec = pSD->keySpecs;
  1610. while (keySpec)
  1611. {
  1612. if (keySpec->wmFunction == F_Menu)
  1613. {
  1614. if (keySpec->context & F_CONTEXT_WINDOW)
  1615. {
  1616. menuContext = F_CONTEXT_WINDOW;
  1617. }
  1618. else if (keySpec->context & F_CONTEXT_ICON)
  1619. {
  1620. menuContext = F_CONTEXT_ICON;
  1621. }
  1622. else
  1623. {
  1624. menuContext = F_CONTEXT_ROOT;
  1625. }
  1626. menuSpec = MAKE_MENU (pSD, NULL, keySpec->wmFuncArgs, menuContext,
  1627. keySpec->context,
  1628. (MenuItem *) NULL, FALSE);
  1629. if (menuSpec)
  1630. /*
  1631. * If successful, save in pSD->acceleratorMenuSpecs
  1632. * Note: these accelerators have nonzero contexts.
  1633. */
  1634. {
  1635. SaveMenuAccelerators (pSD, menuSpec);
  1636. }
  1637. else
  1638. {
  1639. keySpec->wmFunction = F_Nop;
  1640. }
  1641. }
  1642. keySpec = keySpec->nextKeySpec;
  1643. }
  1644. } /* END OF FUNCTION MakeWmFunctionResources */
  1645. /*************************************<->*************************************
  1646. *
  1647. * MakeXorGC (pSD)
  1648. *
  1649. *
  1650. * Description:
  1651. * -----------
  1652. * Make an XOR graphic context for resizing and moving
  1653. *
  1654. *
  1655. * Inputs:
  1656. * ------
  1657. * pSD = pointer to screen data
  1658. *
  1659. * Outputs:
  1660. * -------
  1661. * Modifies global data
  1662. *
  1663. * Comments:
  1664. * --------
  1665. *
  1666. *
  1667. *************************************<->***********************************/
  1668. void MakeXorGC (WmScreenData *pSD)
  1669. {
  1670. XGCValues gcv;
  1671. XtGCMask mask;
  1672. mask = GCFunction | GCLineWidth | GCSubwindowMode | GCCapStyle;
  1673. gcv.function = GXinvert;
  1674. gcv.line_width = 0;
  1675. gcv.cap_style = CapNotLast;
  1676. gcv.subwindow_mode = IncludeInferiors;
  1677. /* Fix so that the rubberbanding for resize and move will
  1678. * have more contrasting colors.
  1679. */
  1680. gcv.plane_mask = BlackPixelOfScreen( DefaultScreenOfDisplay( DISPLAY )) ^
  1681. WhitePixelOfScreen( DefaultScreenOfDisplay( DISPLAY ));
  1682. mask = mask | GCPlaneMask;
  1683. pSD->xorGC = XCreateGC (DISPLAY, pSD->rootWindow, mask, &gcv);
  1684. } /* END OF FUNCTION MakeXorGC */
  1685. /*************************************<->*************************************
  1686. *
  1687. * CopyArgv (argc, argv)
  1688. *
  1689. *
  1690. * Description:
  1691. * -----------
  1692. * This function makes a copy of the window manager's argv for use by
  1693. * the f.restart function. A copy must be kept because XtInitialize
  1694. * changes argv.
  1695. *
  1696. *
  1697. * Inputs:
  1698. * ------
  1699. * argc = the number of strings in argv
  1700. *
  1701. * argv = window manager parameters
  1702. *
  1703. *
  1704. * Outputs:
  1705. * -------
  1706. * Return = a copy of argv
  1707. *
  1708. *************************************<->***********************************/
  1709. void CopyArgv (int argc, char *argv [])
  1710. {
  1711. int i;
  1712. if ((wmGD.argv = (char **)XtMalloc ((argc + 1) * sizeof (char *))) == NULL)
  1713. {
  1714. Warning (((char *)GETMESSAGE(40, 10, "Insufficient memory for window manager data")));
  1715. wmGD.argv = argv;
  1716. dpy2Argv = argv;
  1717. }
  1718. else
  1719. {
  1720. for (i = 0; i < argc; i++)
  1721. {
  1722. wmGD.argv[i] = argv[i];
  1723. }
  1724. wmGD.argv[i] = NULL;
  1725. if ((dpy2Argv = (char **)XtMalloc((argc + 1) * sizeof(char *))) == NULL)
  1726. {
  1727. Warning (((char *)GETMESSAGE(40, 11, "Insufficient memory for window manager data")));
  1728. dpy2Argv = argv;
  1729. }
  1730. else
  1731. {
  1732. for (i = 0; i < argc; i++)
  1733. {
  1734. dpy2Argv[i] = argv[i];
  1735. }
  1736. dpy2Argc = argc;
  1737. dpy2Argv[i] = NULL;
  1738. }
  1739. }
  1740. } /* END OF FUNCTION CopyArgv */
  1741. /*************************************<->*************************************
  1742. *
  1743. * InitScreenNames ()
  1744. *
  1745. *
  1746. * Description:
  1747. * -----------
  1748. * Initializes the name space for screen names
  1749. *
  1750. * Outputs:
  1751. * -------
  1752. * Modifies global data
  1753. * + screenNames
  1754. *
  1755. * Comments:
  1756. * --------
  1757. * Initializes screenNames to contain a numeric name for each screen
  1758. *
  1759. *************************************<->***********************************/
  1760. void InitScreenNames (void)
  1761. {
  1762. int num, numScreens;
  1763. numScreens = ScreenCount (wmGD.display);
  1764. if (!(wmGD.screenNames =
  1765. (unsigned char **) XtMalloc (numScreens * sizeof(char *))))
  1766. {
  1767. ShowWaitState (FALSE);
  1768. Warning (((char *)GETMESSAGE(40, 12, "Insufficient memory for screen names")));
  1769. ExitWM (WM_ERROR_EXIT_VALUE);
  1770. }
  1771. for (num=0; num<numScreens; num++)
  1772. {
  1773. if (!(wmGD.screenNames[num] =
  1774. (unsigned char *) XtMalloc (4*sizeof(char))))
  1775. {
  1776. ShowWaitState (FALSE);
  1777. Warning (((char *)GETMESSAGE(40, 13, "Insufficient memory for screen names")));
  1778. ExitWM (WM_ERROR_EXIT_VALUE);
  1779. }
  1780. /* default name is left justified, 3-chars max, zero terminated */
  1781. sprintf((char *)wmGD.screenNames[num], UNSPECIFIED_SCREEN_NAME);
  1782. }
  1783. }
  1784. #ifndef NO_MESSAGE_CATALOG
  1785. void InitNlsStrings (void)
  1786. {
  1787. char * tmpString;
  1788. /*
  1789. * Initialize messages
  1790. */
  1791. wmGD.okLabel=XmStringCreateLocalized((String)_DtOkString);
  1792. wmGD.cancelLabel=XmStringCreateLocalized((String)_DtCancelString);
  1793. wmGD.helpLabel=XmStringCreateLocalized((String)_DtHelpString);
  1794. /*
  1795. * catgets returns a pointer to an area that is over written
  1796. * on each call to catgets.
  1797. */
  1798. tmpString = ((char *)GETMESSAGE(40, 14, "Icons"));
  1799. if ((wmNLS.default_icon_box_title =
  1800. (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
  1801. {
  1802. Warning (((char *)GETMESSAGE(40, 15, "Insufficient memory for local message string")));
  1803. wmNLS.default_icon_box_title = "Icons";
  1804. }
  1805. else
  1806. {
  1807. strcpy(wmNLS.default_icon_box_title, tmpString);
  1808. }
  1809. tmpString = ((char *)GETMESSAGE(40, 20, "%s: %s on line %d of configuration file %s\n"));
  1810. if ((pWarningStringFile =
  1811. (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
  1812. {
  1813. Warning (((char *)GETMESSAGE(40, 17, "Insufficient memory for local message string")));
  1814. pWarningStringFile = "%s: %s on line %d of configuration file %s\n";
  1815. }
  1816. else
  1817. {
  1818. strcpy(pWarningStringFile, tmpString);
  1819. }
  1820. tmpString = ((char *)GETMESSAGE(40, 21, "%s: %s on line %d of specification string\n"));
  1821. if ((pWarningStringLine =
  1822. (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
  1823. {
  1824. Warning (((char *)GETMESSAGE(40, 19, "Insufficient memory for local message string")));
  1825. pWarningStringLine = "%s: %s on line %d of specification string\n";
  1826. }
  1827. else
  1828. {
  1829. strcpy(pWarningStringLine, tmpString);
  1830. }
  1831. tmpString = ((char *)GETMESSAGE(40, 22, "About Workspace Manager"));
  1832. if ((wmNLS.defaultVersionTitle =
  1833. (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
  1834. {
  1835. Warning (((char *)GETMESSAGE(40, 15, "Insufficient memory for local message string")));
  1836. wmNLS.defaultVersionTitle = "About Workspace Manager";
  1837. }
  1838. else
  1839. {
  1840. strcpy(wmNLS.defaultVersionTitle, tmpString);
  1841. }
  1842. tmpString = ((char *)GETMESSAGE(40, 23, "Workspace Manager - Help"));
  1843. if ((wmNLS.defaultDtwmHelpTitle =
  1844. (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
  1845. {
  1846. Warning (((char *)GETMESSAGE(40, 15, "Insufficient memory for local message string")));
  1847. wmNLS.defaultDtwmHelpTitle = "Workspace Manager - Help";
  1848. }
  1849. else
  1850. {
  1851. strcpy(wmNLS.defaultDtwmHelpTitle, tmpString);
  1852. }
  1853. tmpString = ((char *)GETMESSAGE(40, 24, "Workspace Manager - Help"));
  1854. if ((wmNLS.defaultHelpTitle =
  1855. (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
  1856. {
  1857. Warning (((char *)GETMESSAGE(40, 15, "Insufficient memory for local message string")));
  1858. wmNLS.defaultHelpTitle = "Workspace Manager - Help";
  1859. }
  1860. else
  1861. {
  1862. strcpy(wmNLS.defaultHelpTitle, tmpString);
  1863. }
  1864. } /* InitNlsStrings */
  1865. #endif
  1866. /******************************<->*************************************
  1867. *
  1868. * InitWmDisplayEnv
  1869. *
  1870. *
  1871. * Description:
  1872. * -----------
  1873. * This function saves the display string for putenv in F_Exec.
  1874. *
  1875. * Inputs:
  1876. * -------
  1877. *
  1878. * Outputs:
  1879. * -------
  1880. *************************************<->***********************************/
  1881. void
  1882. InitWmDisplayEnv (void)
  1883. {
  1884. char *pDisplayName;
  1885. char buffer[256];
  1886. char displayName[256];
  1887. pDisplayName = DisplayString (DISPLAY);
  1888. /*
  1889. * Construct displayString for this string.
  1890. */
  1891. strcpy(displayName, pDisplayName);
  1892. sprintf(buffer, "DISPLAY=%s",displayName);
  1893. /*
  1894. * Allocate space for the display string
  1895. */
  1896. if ((wmGD.displayString =
  1897. (String)XtMalloc ((unsigned int) (strlen(buffer) + 1))) == NULL)
  1898. {
  1899. wmGD.displayString = NULL;
  1900. Warning (((char *)GETMESSAGE(40, 9,
  1901. "Insufficient memory for displayString")));
  1902. }
  1903. else
  1904. {
  1905. strcpy(wmGD.displayString, buffer);
  1906. putenv(wmGD.displayString);
  1907. }
  1908. } /* END OF FUNCTION InitWmDisplayEnv */
  1909. #ifndef NO_HP_KEY_REMAP
  1910. static str_xref
  1911. GetReplacementList(
  1912. Display *dsp,
  1913. str_xref std_xref,
  1914. int count)
  1915. {
  1916. int min_kc ;
  1917. int max_kc ;
  1918. int ks_per_kc ;
  1919. int kc_count ;
  1920. KeySym *key_map ;
  1921. unsigned i ;
  1922. str_xref xref_rtn = NULL ;
  1923. unsigned num_xref = 0 ;
  1924. XDisplayKeycodes( dsp, &min_kc, &max_kc) ;
  1925. kc_count = max_kc + 1 - min_kc ;
  1926. key_map = XGetKeyboardMapping( dsp, min_kc, kc_count, &ks_per_kc) ;
  1927. if( key_map == NULL )
  1928. {
  1929. return NULL ;
  1930. }
  1931. kc_count *= ks_per_kc ;
  1932. i = 0 ;
  1933. while( i < count )
  1934. {
  1935. KeySym ks = XStringToKeysym( std_xref[i].default_name) ;
  1936. unsigned j = 0 ;
  1937. while( j < kc_count )
  1938. {
  1939. if( key_map[j] == ks )
  1940. {
  1941. /* Found keysym used in virtkey table in keymap,
  1942. * so break -> j != kc_count
  1943. */
  1944. break ;
  1945. }
  1946. ++j ;
  1947. }
  1948. if( j == kc_count )
  1949. {
  1950. /* Didn't find keysym of virtkey table, so add record to
  1951. * returned list which will later cause replacement in
  1952. * virtkeys table.
  1953. */
  1954. xref_rtn = (str_xref) XtRealloc( (char *) xref_rtn,
  1955. sizeof( str_xref_rec) * (num_xref + 2)) ;
  1956. xref_rtn[num_xref++] = std_xref[i] ;
  1957. xref_rtn[num_xref].default_name = NULL ;
  1958. }
  1959. ++i ;
  1960. }
  1961. XFree( (char *) key_map) ;
  1962. return xref_rtn ;
  1963. }
  1964. static Boolean
  1965. GetBindingsProperty(
  1966. Display *dsp,
  1967. Atom property,
  1968. String *binding)
  1969. {
  1970. Atom actual_type ;
  1971. int actual_format ;
  1972. unsigned long num_items ;
  1973. unsigned long bytes_after ;
  1974. unsigned char *prop = NULL ;
  1975. XGetWindowProperty( dsp, RootWindow( dsp, 0), property, 0, 1000000L,
  1976. FALSE, XA_STRING, &actual_type, &actual_format, &num_items, &bytes_after,
  1977. &prop) ;
  1978. if( (actual_type != XA_STRING)
  1979. || (actual_format != 8)
  1980. || (num_items == 0) )
  1981. {
  1982. if( prop != NULL )
  1983. {
  1984. XFree( prop) ;
  1985. }
  1986. return FALSE ;
  1987. }
  1988. *binding = (String) prop ;
  1989. return TRUE ;
  1990. }
  1991. static void
  1992. SetBindingsProperty(
  1993. Display *dsp,
  1994. Atom property,
  1995. String binding)
  1996. {
  1997. XChangeProperty( dsp, RootWindow( dsp, 0), property, XA_STRING, 8,
  1998. PropModeReplace, (unsigned char *) binding, strlen( binding)) ;
  1999. }
  2000. static String
  2001. FixupBindingsString(
  2002. String bindingsString,
  2003. str_xref repl_xref)
  2004. {
  2005. String fixed_str = XtNewString( bindingsString) ;
  2006. String ptr_next = fixed_str ;
  2007. while( repl_xref->default_name != NULL )
  2008. {
  2009. String ks_ptr = strstr( ptr_next, repl_xref->default_name) ;
  2010. unsigned orig_len = strlen( repl_xref->default_name) ;
  2011. if( ks_ptr == NULL )
  2012. {
  2013. /* Only increment to next replacement when no other instances
  2014. * are found in fixed_str.
  2015. */
  2016. ++repl_xref ;
  2017. ptr_next = fixed_str ;
  2018. continue ;
  2019. }
  2020. if( (strpbrk( (ks_ptr - 1), " \t>") == (ks_ptr - 1))
  2021. && (strpbrk( ks_ptr, " \t\n") == (ks_ptr + orig_len)) )
  2022. {
  2023. unsigned new_len = strlen( repl_xref->new_name) ;
  2024. unsigned suffix_len = strlen( ks_ptr + orig_len) ;
  2025. if( new_len > orig_len )
  2026. {
  2027. unsigned new_ttl_len = strlen( fixed_str) + new_len - orig_len ;
  2028. unsigned prefix_len ;
  2029. *ks_ptr = '\0' ;
  2030. prefix_len = strlen( fixed_str) ;
  2031. fixed_str = XtRealloc( fixed_str, (new_ttl_len + 1)) ;
  2032. ks_ptr = fixed_str + prefix_len ;
  2033. }
  2034. memmove( (ks_ptr + new_len), (ks_ptr + orig_len), (suffix_len + 1)) ;
  2035. memcpy( ks_ptr, repl_xref->new_name, new_len) ;
  2036. ptr_next = ks_ptr + new_len ;
  2037. }
  2038. else
  2039. {
  2040. ptr_next = ks_ptr + 1 ;
  2041. }
  2042. }
  2043. return fixed_str ;
  2044. }
  2045. Boolean
  2046. VirtKeys4DIN(
  2047. Display *dsp)
  2048. {
  2049. /* This routine examines the X server's key map table to determine
  2050. * if certain HP-specific keysyms are missing. If they are, then
  2051. * the Motif virtual binding table properties are updated to utilize
  2052. * generic X keysyms instead of the missing HP vendor keysyms.
  2053. * In particular, this fixes the Motif virtual key binding table for
  2054. * correct operation on HP systems using the AT2/DIN style keyboard.
  2055. */
  2056. static char *prop_names[] = { "_MOTIF_BINDINGS",
  2057. "_MOTIF_DEFAULT_BINDINGS" } ;
  2058. static str_xref_rec std_xref[] = { { "hpInsertChar", "Insert" },
  2059. { "hpDeleteChar", "Delete" },
  2060. { "End", "F7" },
  2061. } ;
  2062. Boolean PropChanged4DIN = FALSE ;
  2063. unsigned i ;
  2064. char *bindingsString ;
  2065. unsigned prop_existed ;
  2066. Atom *prop_atoms ;
  2067. str_xref vkeysym_xref ;
  2068. unsigned num_props = XtNumber( prop_names) ;
  2069. vkeysym_xref = GetReplacementList( dsp, std_xref, XtNumber(std_xref)) ;
  2070. if( vkeysym_xref == NULL )
  2071. {
  2072. return PropChanged4DIN ;
  2073. }
  2074. prop_atoms = (Atom *) XtMalloc( sizeof( Atom) * num_props) ;
  2075. XInternAtoms(dsp, prop_names, num_props, FALSE, prop_atoms);
  2076. prop_existed = FALSE ;
  2077. i = 0 ;
  2078. while( i < num_props )
  2079. {
  2080. if( GetBindingsProperty( dsp, prop_atoms[i], &bindingsString) )
  2081. {
  2082. String new_bstring = FixupBindingsString( bindingsString,
  2083. vkeysym_xref) ;
  2084. prop_existed = TRUE ;
  2085. XFree( bindingsString) ;
  2086. if( new_bstring != NULL )
  2087. {
  2088. SetBindingsProperty( dsp, prop_atoms[i], new_bstring) ;
  2089. XtFree( new_bstring) ;
  2090. }
  2091. }
  2092. ++i ;
  2093. }
  2094. if( !prop_existed )
  2095. {
  2096. bindingsString = NULL ;
  2097. /* FIXME: this is an unexported openmotif procedure */
  2098. extern void _XmVirtKeysLoadFallbackBindings(Display *dsp, String *binding);
  2099. _XmVirtKeysLoadFallbackBindings( dsp, &bindingsString) ;
  2100. XtFree( bindingsString) ;
  2101. i = 0 ;
  2102. while( i < num_props )
  2103. {
  2104. if( GetBindingsProperty( dsp, prop_atoms[i], &bindingsString) )
  2105. {
  2106. String new_bstring = FixupBindingsString( bindingsString,
  2107. vkeysym_xref) ;
  2108. XtFree( bindingsString) ;
  2109. if( new_bstring != NULL )
  2110. {
  2111. PropChanged4DIN = TRUE ;
  2112. SetBindingsProperty( dsp, prop_atoms[i], new_bstring) ;
  2113. XtFree( new_bstring) ;
  2114. }
  2115. XFree( bindingsString) ;
  2116. }
  2117. ++i ;
  2118. }
  2119. }
  2120. XtFree( (char *) vkeysym_xref) ;
  2121. XtFree( (char *) prop_atoms) ;
  2122. return PropChanged4DIN ;
  2123. }
  2124. #endif /* NO_HP_KEY_REMAP */
  2125. /**************************** eof ***************************/