Backdrop.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251
  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: Backdrop.c /main/7 1998/11/25 14:48:36 samborn $ */
  24. /************************************<+>*************************************
  25. ****************************************************************************
  26. **
  27. ** File: Backdrop.c
  28. **
  29. ** Project: DT 3.0
  30. **
  31. ** Description: Controls the Dtstyle Backdrop dialog
  32. **
  33. **
  34. ** (c) Copyright Hewlett-Packard Company, 1990, 1993.
  35. **
  36. **
  37. **
  38. ****************************************************************************
  39. ************************************<+>*************************************/
  40. /*+++++++++++++++++++++++++++++++++++++++*/
  41. /* include files */
  42. /*+++++++++++++++++++++++++++++++++++++++*/
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include <stdlib.h>
  46. #include <sys/types.h>
  47. #include <errno.h>
  48. #if defined(_AIX)
  49. #include <sys/dir.h>
  50. #else
  51. #include <dirent.h> /* opendir(), directory(3C) */
  52. #endif /* _AIX */
  53. #include <locale.h>
  54. #include <X11/Xlib.h>
  55. #include <Xm/MwmUtil.h>
  56. #include <Xm/Xm.h>
  57. #include <Xm/XmP.h>
  58. #include <Xm/DrawnB.h>
  59. #include <Xm/Form.h>
  60. #include <Xm/List.h>
  61. #include <Xm/VendorSEP.h>
  62. #include <Xm/AtomMgr.h>
  63. #include <Dt/DialogBox.h>
  64. #include <Dt/Message.h>
  65. #include <Dt/SessionM.h>
  66. #include <Dt/HourGlass.h>
  67. #include <Dt/Wsm.h>
  68. #include <Dt/UserMsg.h>
  69. #include "Help.h"
  70. #include "Main.h"
  71. #include "SaveRestore.h"
  72. /*+++++++++++++++++++++++++++++++++++++++*/
  73. /* include extern functions */
  74. /*+++++++++++++++++++++++++++++++++++++++*/
  75. #include "Backdrop.h"
  76. /*+++++++++++++++++++++++++++++++++++++++*/
  77. /* Local #defines */
  78. /*+++++++++++++++++++++++++++++++++++++++*/
  79. #define MAX_STR_LEN 128
  80. #define B_OK_BUTTON 1
  81. #define B_APPLY_BUTTON 2
  82. #define B_CANCEL_BUTTON 3
  83. #define B_HELP_BUTTON 4
  84. #define ERR2 ((char *)GETMESSAGE(11, 2, "The backdrop portion of the Style Manager\n\
  85. will not operate because there are no backdrop\nfiles available. Check $HOME/.dt/errorlog."))
  86. /*+++++++++++++++++++++++++++++++++++++++*/
  87. /* Internal Functions */
  88. /*+++++++++++++++++++++++++++++++++++++++*/
  89. static int CreateBackdropDialog( Widget parent) ;
  90. static void MoreBitmaps( void ) ;
  91. static ReadBitmaps( void ) ;
  92. static Boolean CreatePixmaps( void ) ;
  93. static ReadBitmapDirectory( char *dir ) ;
  94. static void DrawBitmap(
  95. Widget w,
  96. XtPointer client_data,
  97. XtPointer call_data) ;
  98. static void SizeBitmap(
  99. Widget w,
  100. XtPointer client_data,
  101. XtPointer call_data) ;
  102. static XmString * MakeListStrings( void ) ;
  103. static void FreeListStrings( XmString *listPtr) ;
  104. static void ListCB(
  105. Widget w,
  106. XtPointer client_data,
  107. XtPointer call_data) ;
  108. static void ButtonCB(
  109. Widget w,
  110. XtPointer client_data,
  111. XtPointer call_data) ;
  112. static void GetColors( void ) ;
  113. static void FreeAll( void ) ;
  114. static void _DtMapCB(
  115. Widget w,
  116. XtPointer client_data,
  117. XtPointer call_data) ;
  118. /*+++++++++++++++++++++++++++++++++++++++*/
  119. /* Internal Variables */
  120. /*+++++++++++++++++++++++++++++++++++++++*/
  121. typedef struct {
  122. Widget drawnButton;
  123. char **dirList;
  124. int dirCount;
  125. char **tmpBitmapNames;
  126. int tmpNumBitmaps;
  127. int tmpMaxNumBitmaps;
  128. char **bitmapNames;
  129. char **bitmapDescs;
  130. Pixmap *bitmaps;
  131. int numBitmaps;
  132. int maxNumBitmaps;
  133. int selected;
  134. GC gc;
  135. int width, height;
  136. int shadow;
  137. Pixel fg, bg;
  138. char *errStr;
  139. char noBitmaps;
  140. Boolean newColors;
  141. } Backdrops, *BackdropsPtr;
  142. static Backdrops backdrops;
  143. static saveRestore save = {FALSE, 0, };
  144. char *BACKDROPSDLG = "backdropsDialog";
  145. /*
  146. * copy of the system backdrop description file for the
  147. * current locale in xrm form
  148. */
  149. static XrmDatabase sys_bd_DB = NULL;
  150. /*
  151. * copy of the admin backdrop description file for the
  152. * current locale in xrm form
  153. */
  154. static XrmDatabase adm_bd_DB = NULL;
  155. /*
  156. * copy of the user's home backdrop description file for the
  157. * current locale in xrm form
  158. */
  159. static XrmDatabase hm_bd_DB = NULL;
  160. /*
  161. * final combination of the admin & system data bases
  162. */
  163. static XrmDatabase bd_DB = NULL;
  164. /*+++++++++++++++++++++++++++++++++++++++*/
  165. /* build_dirList */
  166. /*+++++++++++++++++++++++++++++++++++++++*/
  167. char **
  168. build_dirList(char * dirStr,
  169. int * count)
  170. {
  171. char tokenSep[] = ":";
  172. char * token;
  173. char ** dirList = NULL;
  174. int i = 0;
  175. char * tmpStr;
  176. int len = strlen(dirStr);
  177. *count = 0;
  178. tmpStr = (char *)XtCalloc(1, len + 1);
  179. strcpy(tmpStr, dirStr);
  180. token = strtok(tmpStr, tokenSep);
  181. while(token != NULL)
  182. {
  183. ++(i);
  184. token = strtok(NULL, tokenSep);
  185. }
  186. if (i == 0)
  187. return (NULL);
  188. dirList = (char **) XtCalloc(1, i * sizeof(char *));
  189. if( dirList )
  190. {
  191. strcpy(tmpStr, dirStr);
  192. token = strtok(tmpStr, tokenSep);
  193. *count=0;
  194. while(token != NULL)
  195. {
  196. dirList[*count] = (char *) XtCalloc(1, strlen( token ) + 1);
  197. strcpy(dirList[*count], token);
  198. token = strtok(NULL, tokenSep);
  199. ++(*count);
  200. }
  201. }
  202. XtFree ((char *) tmpStr);
  203. return(dirList);
  204. }
  205. /*+++++++++++++++++++++++++++++++++++++++*/
  206. /* free_dirList */
  207. /*+++++++++++++++++++++++++++++++++++++++*/
  208. void
  209. free_dirList(char ** dirList,
  210. int count)
  211. {
  212. int i;
  213. if (dirList == NULL)
  214. return;
  215. for (i=0; i<count; i++)
  216. XtFree((char *) dirList[i]);
  217. XtFree ((char *) dirList);
  218. }
  219. /************************************************************************
  220. * SelectCurrentBackdrop() - Selects current backdrop in list
  221. *
  222. ************************************************************************/
  223. void SelectCurrentBackdrop(int callback)
  224. {
  225. DtWsmWorkspaceInfo *wInfo=NULL;
  226. Atom aWS;
  227. Widget list;
  228. char *backdropName;
  229. int i;
  230. if ((DtWsmGetCurrentWorkspace (style.display, style.root, &aWS)
  231. != Success) ||
  232. (DtWsmGetWorkspaceInfo (style.display, style.root, aWS, &wInfo)
  233. != Success))
  234. {
  235. return;
  236. }
  237. list = XtNameToWidget(style.backdropDialog, "*bitmapList");
  238. backdropName = XmGetAtomName(style.display, wInfo->backdropName);
  239. for (i = 0; i < backdrops.numBitmaps; i++) {
  240. if (strcmp(backdrops.bitmapNames[i], backdropName) == 0) {
  241. XmListSelectPos (list, i + 1, callback);
  242. XmListSetPos(list, i + 1);
  243. backdrops.selected = i;
  244. }
  245. }
  246. XtFree((char *) backdropName);
  247. XtFree((char *) wInfo);
  248. }
  249. /************************************************************************
  250. * BackdropDialog() - Create backdrop selection dialog first time up.
  251. * If it has already been created, map it.
  252. ************************************************************************/
  253. void
  254. BackdropDialog(
  255. Widget parent )
  256. {
  257. int i;
  258. if (style.backdropDialog == NULL)
  259. {
  260. _DtTurnOnHourGlass(parent);
  261. if (!CreateBackdropDialog(parent)) {
  262. _DtTurnOffHourGlass(parent);
  263. return;
  264. }
  265. SelectCurrentBackdrop(False);
  266. XtManageChild(style.backdropDialog);
  267. XSync(style.display, 0);
  268. XmUpdateDisplay(style.backdropDialog);
  269. _DtTurnOffHourGlass(parent);
  270. }
  271. else
  272. {
  273. SelectCurrentBackdrop(True);
  274. XtManageChild(style.backdropDialog);
  275. raiseWindow(XtWindow(XtParent(style.backdropDialog)));
  276. XmUpdateDisplay(style.backdropDialog);
  277. }
  278. }
  279. /************************************************************************
  280. * CreateBackdropDialog()
  281. * Create the Backdrop Dialog
  282. ************************************************************************/
  283. static int
  284. CreateBackdropDialog(
  285. Widget parent )
  286. {
  287. int i, n;
  288. Arg args[20];
  289. Widget mainForm;
  290. Widget list;
  291. XmString strings[NUM_LABELS+1];
  292. XmString *listStrings;
  293. char *bd_desc;
  294. char *lang;
  295. if (backdrops.noBitmaps)
  296. {
  297. ErrDialog (backdrops.errStr, style.shell);
  298. return 0;
  299. }
  300. /* initialize backdrop data */
  301. backdrops.bitmapNames = NULL;
  302. backdrops.bitmaps = NULL;
  303. backdrops.numBitmaps = 0;
  304. backdrops.maxNumBitmaps = 100;
  305. backdrops.selected = -1;
  306. backdrops.gc = NULL;
  307. backdrops.errStr = NULL;
  308. backdrops.shadow = 2;
  309. backdrops.width = 200 - 2*backdrops.shadow;
  310. backdrops.height = 200 - 2*backdrops.shadow;
  311. backdrops.newColors = True;
  312. /* load the backdrop description data base for the given locale*/
  313. /* from that locale's description file from the system location */
  314. lang = setlocale (LC_CTYPE,NULL);
  315. #ifdef hpux /* hpux-specific parsing of the locale string */
  316. /* The following code is identical to the
  317. ExtractLocaleName function in WmResParse.c
  318. from dtwm
  319. */
  320. #define MAXLOCALE 64 /* buffer size of locale name */
  321. { char *start;
  322. char *end;
  323. int len;
  324. static char buf[MAXLOCALE];
  325. /* If lang has a substring ":<category>;", extract <category>
  326. * from the first such occurrence as the locale name.
  327. */
  328. start = lang;
  329. if (start = strchr (lang, ':')) {
  330. start++;
  331. if (end = strchr (start, ';')) {
  332. len = end - start;
  333. strncpy(buf, start, len);
  334. *(buf + len) = '\0';
  335. lang = buf;
  336. }
  337. }
  338. }
  339. #endif /* hpux */
  340. bd_desc = (char *)XtMalloc(strlen("/usr/dt/backdrops/desc.") + strlen(lang) + 1);
  341. strcpy (bd_desc,"/usr/dt/backdrops/desc.");
  342. strcat (bd_desc, lang);
  343. if(sys_bd_DB = XrmGetFileDatabase (bd_desc))
  344. XrmMergeDatabases(sys_bd_DB, &bd_DB);
  345. XtFree(bd_desc);
  346. /* load the backdrop description data base for the given locale*/
  347. /* from that locale's description file from the admin location */
  348. bd_desc = (char *)XtMalloc(strlen("/etc/dt/backdrops/desc.") + strlen(lang) + 1);
  349. strcpy (bd_desc,"/etc/dt/backdrops/desc.");
  350. strcat (bd_desc, lang);
  351. if (adm_bd_DB = XrmGetFileDatabase (bd_desc))
  352. XrmMergeDatabases(adm_bd_DB, &bd_DB);
  353. XtFree(bd_desc);
  354. /* load the backdrop description from the user's .dt/backdrops directory */
  355. /* regardless of locale */
  356. bd_desc = (char *)XtMalloc(strlen(style.home) + strlen("/.dt/backdrops/desc.backdrops") + 1);
  357. strcpy (bd_desc, style.home);
  358. strcat (bd_desc, "/.dt/backdrops/desc.backdrops");
  359. if (hm_bd_DB = XrmGetFileDatabase (bd_desc))
  360. XrmMergeDatabases(hm_bd_DB, &bd_DB);
  361. XtFree(bd_desc);
  362. /* Set up DialogBox button labels. */
  363. strings[0] = XmStringCreateLocalized ((String) _DtOkString);
  364. strings[1] = XmStringCreateLocalized ((String) _DtApplyString);
  365. strings[2] = XmStringCreateLocalized ((String) _DtCloseString);
  366. strings[3] = XmStringCreateLocalized ((String) _DtHelpString);
  367. /* saveRestore
  368. * Note that save.poscnt has been initialized elsewhere.
  369. * save.posArgs may contain information from restoreBackdrop().*/
  370. /* create the dialog box with shell */
  371. XtSetArg (save.posArgs[save.poscnt], XmNbuttonCount, NUM_LABELS+1);
  372. save.poscnt++;
  373. XtSetArg (save.posArgs[save.poscnt], XmNbuttonLabelStrings, strings);
  374. save.poscnt++;
  375. XtSetArg (save.posArgs[save.poscnt], XmNdefaultPosition, False);
  376. save.poscnt++;
  377. XtSetArg (save.posArgs[save.poscnt], XmNallowOverlap, False);
  378. save.poscnt++;
  379. style.backdropDialog = __DtCreateDialogBoxDialog (parent, BACKDROPSDLG,
  380. save.posArgs, save.poscnt);
  381. XtAddCallback(style.backdropDialog, XmNcallback, ButtonCB, NULL);
  382. XtAddCallback(style.backdropDialog, XmNmapCallback, _DtMapCB, parent);
  383. XtAddCallback(style.backdropDialog, XmNhelpCallback,
  384. (XtCallbackProc)HelpRequestCB, (XtPointer)HELP_BACKDROP_DIALOG);
  385. /* free compound strings now */
  386. XmStringFree (strings[0]);
  387. XmStringFree (strings[1]);
  388. XmStringFree (strings[2]);
  389. XmStringFree (strings[3]);
  390. n = 0;
  391. XtSetArg (args[n], XmNtitle, ((char *)GETMESSAGE(11, 12, "Style Manager - Backdrop"))); n++;
  392. XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
  393. XtSetValues (XtParent(style.backdropDialog), args, n);
  394. /* get bitmap data */
  395. if (!ReadBitmaps()) return 0; /* uses style.backdropDialog */
  396. /* create the form to go in to dialog box as the work area */
  397. n = 0;
  398. XtSetArg(args[n], XmNhorizontalSpacing, style.horizontalSpacing); n++;
  399. XtSetArg(args[n], XmNverticalSpacing, style.verticalSpacing); n++;
  400. XtSetArg (args[n], XmNchildType, XmWORK_AREA); n++;
  401. XtSetArg (args[n], XmNallowOverlap, False); n++;
  402. mainForm = XmCreateForm (style.backdropDialog, "backdropsForm", args, n);
  403. /* create the scrolled list of bitmap names... first create XmStrings */
  404. listStrings = MakeListStrings ();
  405. n = 0;
  406. XtSetArg (args[n], XmNautomaticSelection, True); n++;
  407. XtSetArg (args[n], XmNselectionPolicy, XmBROWSE_SELECT); n++;
  408. XtSetArg (args[n], XmNitems, listStrings); n++;
  409. XtSetArg (args[n], XmNitemCount, backdrops.numBitmaps); n++;
  410. list = XmCreateScrolledList (mainForm, "bitmapList", args, n);
  411. XtAddCallback (list, XmNbrowseSelectionCallback, ListCB, (XtPointer)NULL);
  412. FreeListStrings (listStrings); /* after list has copied */
  413. /* set up attachments for scrolled list itself */
  414. n = 0;
  415. XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  416. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  417. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  418. XtSetValues (XtParent(list), args, n);
  419. /* Create drawing area for the bitmap */
  420. n = 0;
  421. XtSetArg (args[n], XmNshadowType, XmSHADOW_IN); n++;
  422. XtSetArg (args[n], XmNshadowThickness, backdrops.shadow); n++;
  423. XtSetArg (args[n], XmNhighlightThickness, 0); n++;
  424. XtSetArg (args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  425. XtSetArg (args[n], XmNrightWidget, XtParent(list)); n++;
  426. XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  427. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  428. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  429. XtSetArg (args[n], XmNborderWidth, 0); n++;
  430. XtSetArg (args[n], XmNwidth, backdrops.width+2*backdrops.shadow); n++;
  431. XtSetArg (args[n], XmNheight, backdrops.height+2*backdrops.shadow); n++;
  432. XtSetArg (args[n], XmNtraversalOn, False); n++;
  433. backdrops.drawnButton = XmCreateDrawnButton (mainForm, "bitmap", args, n);
  434. XtAddCallback (backdrops.drawnButton, XmNexposeCallback, DrawBitmap, NULL);
  435. XtAddCallback (backdrops.drawnButton, XmNresizeCallback, SizeBitmap, NULL);
  436. /* manage all of the widgets */
  437. XtManageChild (mainForm);
  438. XtManageChild (backdrops.drawnButton);
  439. XtManageChild (list);
  440. return 1;
  441. }
  442. /************************************************************************
  443. * MoreBitmaps()
  444. * Create space for more bitmap entries
  445. ************************************************************************/
  446. static void
  447. MoreBitmaps( void )
  448. {
  449. int newSize;
  450. /* allocate space for icon names */
  451. newSize = (backdrops.maxNumBitmaps + 100) * sizeof(char *);
  452. backdrops.bitmapNames = (char **) XtRealloc((char *)backdrops.bitmapNames,
  453. newSize);
  454. /* now allocate new bitmap space */
  455. newSize = (backdrops.maxNumBitmaps + 100) * sizeof(Pixmap);
  456. backdrops.bitmaps = (Pixmap *)XtRealloc((char *)backdrops.bitmaps, newSize);
  457. backdrops.maxNumBitmaps += 100;
  458. }
  459. /************************************************************************
  460. * cmpstringp()
  461. * qsort() sort function, used for sorting bitmap names into alphabetical order
  462. * can't use strcmp() due to char** rather than char*
  463. ************************************************************************/
  464. static int
  465. cmpstringp(const void *p1, const void *p2)
  466. {
  467. return strcmp(*(char * const *) p1, *(char * const *) p2);
  468. }
  469. /************************************************************************
  470. * ReadBitmaps()
  471. * Create an array of bitmaps by reading backdrop directories in the
  472. * following order overriding any duplicates:
  473. * 1) Read the system location /usr/dt/backdrops
  474. * 2) Read the admin location /etc/dt/backdrops
  475. * 3) Read the directories specified by the backdropDirectories
  476. * resource.
  477. * 4) Read the user's home directory /$HOME/.dt/backdrops.
  478. ************************************************************************/
  479. static
  480. ReadBitmaps( void )
  481. {
  482. int status;
  483. Pixmap tmpPix = 0;
  484. int width, height, x, y;
  485. Window win;
  486. int num;
  487. int i;
  488. char *string;
  489. /* allocate space for temporary bitmap info */
  490. backdrops.tmpBitmapNames = (char **)XtCalloc(100, sizeof(char *));
  491. backdrops.tmpMaxNumBitmaps = 100;
  492. backdrops.tmpNumBitmaps = 0;
  493. /* read system backdrop directory */
  494. ReadBitmapDirectory("/usr/dt/backdrops");
  495. /* read sys admin backdrop directory */
  496. ReadBitmapDirectory("/etc/dt/backdrops");
  497. /* Parse the backdropDirectories resource to get the individual directories */
  498. if (style.xrdb.backdropDir)
  499. {
  500. backdrops.dirList = build_dirList(style.xrdb.backdropDir, &backdrops.dirCount);
  501. /* compile the list of bitmaps */
  502. for (i=0; i<backdrops.dirCount; i++)
  503. ReadBitmapDirectory(backdrops.dirList[i]);
  504. }
  505. /* read the directory $HOME/.dt/backdrops */
  506. string = (char *)XtMalloc(strlen(style.home) + strlen("/.dt/backdrops") + 1);
  507. if (string != NULL)
  508. {
  509. sprintf(string, "%s/.dt/backdrops", style.home);
  510. ReadBitmapDirectory(string);
  511. XtFree(string);
  512. }
  513. if (backdrops.tmpNumBitmaps == 0)
  514. {
  515. /* give error dialog, free space, and return */
  516. backdrops.errStr = (char *)XtMalloc(strlen(ERR2) + 1);
  517. sprintf(backdrops.errStr, "%s", ERR2);
  518. ErrDialog (backdrops.errStr, style.shell);
  519. FreeAll();
  520. free_dirList(backdrops.dirList, backdrops.dirCount);
  521. return 0;
  522. }
  523. /* Sort the list into alphanetical order */
  524. qsort(backdrops.tmpBitmapNames, backdrops.tmpNumBitmaps, sizeof(char *), cmpstringp);
  525. /* get the fg/bg colors from Dtwm */
  526. if (backdrops.newColors)
  527. {
  528. GetColors();
  529. backdrops.newColors = False;
  530. }
  531. /* create all the pixmaps */
  532. if (!CreatePixmaps())
  533. {
  534. /* give error dialog, free space, and return */
  535. backdrops.errStr = (char *)XtMalloc(strlen(ERR2) + 1);
  536. sprintf(backdrops.errStr, "%s", ERR2);
  537. ErrDialog (backdrops.errStr, style.shell);
  538. FreeAll();
  539. free_dirList(backdrops.dirList, backdrops.dirCount);
  540. return 0;
  541. }
  542. if (backdrops.selected == -1) backdrops.selected = 0;
  543. return 1;
  544. }
  545. /************************************************************************
  546. * CreatePixmaps()
  547. * Create the pixmpas in the backdrop list
  548. with workprocs 10 at a time
  549. ************************************************************************/
  550. static Boolean
  551. CreatePixmaps( void )
  552. {
  553. static int pixmapsCreated=0;
  554. int i;
  555. Pixmap tmpPixmap;
  556. backdrops.numBitmaps = 0;
  557. /* allocate space for real bitmap info */
  558. backdrops.bitmapNames = (char **)XtCalloc(100, sizeof(char *));
  559. backdrops.bitmaps = (Pixmap *)XtCalloc(100, sizeof(Pixmap));
  560. for (i=0; i<backdrops.tmpNumBitmaps; i++)
  561. {
  562. tmpPixmap = XmGetPixmap (style.screen,
  563. backdrops.tmpBitmapNames[i],
  564. backdrops.fg, backdrops.bg);
  565. if (tmpPixmap != XmUNSPECIFIED_PIXMAP)
  566. {
  567. if (backdrops.numBitmaps == backdrops.maxNumBitmaps)
  568. MoreBitmaps();
  569. backdrops.bitmapNames[backdrops.numBitmaps] =
  570. backdrops.tmpBitmapNames[i];
  571. backdrops.bitmaps[backdrops.numBitmaps] = tmpPixmap;
  572. backdrops.numBitmaps++;
  573. }
  574. }
  575. if (backdrops.numBitmaps)
  576. return(True);
  577. else
  578. return(False);
  579. }
  580. /************************************************************************
  581. * ReadBitmapDirectory()
  582. * Create an array of bitmap names overriding duplicates
  583. ************************************************************************/
  584. static
  585. ReadBitmapDirectory(
  586. char *dir )
  587. {
  588. DIR *dirp;
  589. struct dirent *filep;
  590. int i;
  591. Boolean duplicate;
  592. char *name;
  593. int stat_result;
  594. struct stat stat_buf;
  595. char *statPath, *pStatPath;
  596. int newSize;
  597. /* open the backdrops directory */
  598. if ((dirp = opendir(dir)) == NULL)
  599. {
  600. /* print message to errorlog, free space, and return */
  601. return 0;
  602. }
  603. /* create string to contain complete path */
  604. statPath = (char *) XtMalloc(strlen(dir) + MAX_STR_LEN + 2);
  605. strcpy (statPath, dir);
  606. strcat (statPath, "/");
  607. pStatPath = statPath + strlen(statPath);
  608. filep = readdir(dirp);
  609. while (filep != NULL)
  610. {
  611. /* append filename to stat path */
  612. strcpy (pStatPath, filep->d_name);
  613. /* stat the file */
  614. if ((stat_result = stat (statPath, &stat_buf)) != 0)
  615. {
  616. filep = readdir(dirp);
  617. continue;
  618. }
  619. /* skip directories */
  620. if ((stat_buf.st_mode & S_IFMT) == S_IFDIR)
  621. {
  622. filep = readdir(dirp);
  623. continue;
  624. }
  625. name = (char *) XtMalloc(strlen(filep->d_name) + 1);
  626. strcpy (name, filep->d_name);
  627. /* strip suffix off filename if it's a .pm or .bm
  628. * motif requires other formats like jpg, png etc to
  629. * have the extension on to work with the XmGetPixmap() calls */
  630. if(strlen(name) > 3
  631. && (0 == strcmp(name + strlen(name) - 3, ".pm")
  632. || 0 == strcmp(name + strlen(name) - 3, ".bm")))
  633. {
  634. (void)strtok(name, ".");
  635. }
  636. /* check for duplicates */
  637. duplicate = 0;
  638. for (i=0; i<backdrops.tmpNumBitmaps; i++)
  639. {
  640. if (!strcmp(backdrops.tmpBitmapNames[i], name))
  641. {
  642. duplicate = 1;
  643. break;
  644. }
  645. }
  646. if (!duplicate)
  647. {
  648. /* add to the temporary bitmap list */
  649. if (backdrops.tmpNumBitmaps == backdrops.tmpMaxNumBitmaps)
  650. {
  651. /* allocate space for more temporary bitmap info */
  652. newSize = (backdrops.tmpMaxNumBitmaps + 100) * sizeof(char *);
  653. backdrops.tmpBitmapNames =
  654. (char **)XtRealloc((char *)backdrops.tmpBitmapNames, newSize);
  655. backdrops.tmpMaxNumBitmaps += 100;
  656. }
  657. backdrops.tmpBitmapNames[backdrops.tmpNumBitmaps] =
  658. (char *) XtMalloc(strlen(name)+1);
  659. strcpy (backdrops.tmpBitmapNames[backdrops.tmpNumBitmaps], name);
  660. backdrops.tmpNumBitmaps++;
  661. }
  662. filep = readdir(dirp);
  663. XtFree(name);
  664. }
  665. XtFree(statPath);
  666. closedir (dirp);
  667. return 1;
  668. }
  669. /************************************************************************
  670. * DrawBitmap()
  671. * This is the exposeCallback for the bitmap drawing area.
  672. ************************************************************************/
  673. static void
  674. DrawBitmap(
  675. Widget w,
  676. XtPointer client_data,
  677. XtPointer call_data )
  678. {
  679. XGCValues gcValues;
  680. Arg args[3];
  681. if (backdrops.selected == -1)
  682. return;
  683. if (backdrops.newColors)
  684. {
  685. GetColors();
  686. /* we could keep track of which tile pixmaps need to be updated
  687. since the last workspace change, but for now simply regenerate
  688. each pixmap as it is selected after a workspace change has
  689. occurred */
  690. /* backdrops.newColors = False; */
  691. }
  692. if (backdrops.gc == NULL)
  693. {
  694. gcValues.background = backdrops.bg;
  695. gcValues.foreground = backdrops.fg;
  696. gcValues.fill_style = FillTiled;
  697. gcValues.tile = backdrops.bitmaps[backdrops.selected];
  698. backdrops.gc = XCreateGC (style.display, XtWindow(w),
  699. GCForeground | GCBackground |
  700. GCTile | GCFillStyle, &gcValues);
  701. }
  702. XFillRectangle (style.display, XtWindow(w), backdrops.gc, backdrops.shadow,
  703. backdrops.shadow, backdrops.width, backdrops.height);
  704. }
  705. /************************************************************************
  706. * SizeBitmap()
  707. * This is the resizeCallback for the bitmap drawing area.
  708. ************************************************************************/
  709. static void
  710. SizeBitmap(
  711. Widget w,
  712. XtPointer client_data,
  713. XtPointer call_data )
  714. {
  715. backdrops.width = XtWidth(w) - 2*backdrops.shadow;
  716. backdrops.height = XtHeight(w) - 2*backdrops.shadow;
  717. }
  718. /************************************************************************
  719. * MakeListStrings()
  720. * Make XmStrings from the bitmap descriptions, to pass into list.
  721. *
  722. ************************************************************************/
  723. static XmString *
  724. MakeListStrings( void )
  725. {
  726. int i;
  727. XmString *list;
  728. char *name_str;
  729. char *class_str;
  730. char *str_type_return;
  731. XrmValue value_return;
  732. /* allocate space for bitmap descriptions */
  733. backdrops.bitmapDescs = (char **)XtCalloc(backdrops.numBitmaps, sizeof(char *));
  734. for (i=0; i<backdrops.numBitmaps; i++)
  735. {
  736. if (bd_DB !=NULL)
  737. {
  738. name_str = (char *) XtMalloc(strlen("backdrops.") +
  739. strlen(backdrops.bitmapNames[i]) +
  740. strlen(".desc") + 1);
  741. class_str = (char *) XtMalloc(strlen("Backdrops.") +
  742. strlen(backdrops.bitmapNames[i]) +
  743. strlen(".Desc") + 1);
  744. strcpy(name_str, "backdrops.");
  745. strcpy(class_str, "Backdrops.");
  746. strcat(name_str, backdrops.bitmapNames[i]);
  747. strcat(class_str, backdrops.bitmapNames[i]);
  748. strcat(name_str, ".desc");
  749. strcat(class_str, ".Desc");
  750. if (XrmGetResource (bd_DB, name_str, class_str, &str_type_return, &value_return))
  751. {
  752. /* make copy of resource value */
  753. backdrops.bitmapDescs[i] = (char *) XtMalloc(value_return.size + 1);
  754. strcpy (backdrops.bitmapDescs[i], value_return.addr);
  755. }
  756. else
  757. {
  758. backdrops.bitmapDescs[i] = (char *) XtMalloc(strlen(backdrops.bitmapNames[i]) + 1);
  759. strcpy(backdrops.bitmapDescs[i], backdrops.bitmapNames[i]);
  760. }
  761. }
  762. else
  763. {
  764. backdrops.bitmapDescs[i] = (char *) XtMalloc(strlen(backdrops.bitmapNames[i]) + 1);
  765. strcpy(backdrops.bitmapDescs[i], backdrops.bitmapNames[i]);
  766. }
  767. }
  768. list = (XmString *) XtCalloc(backdrops.numBitmaps, sizeof(XmString));
  769. for (i = 0; i < backdrops.numBitmaps; i++)
  770. {
  771. list[i] = XmStringCreateLocalized (backdrops.bitmapDescs[i]);
  772. }
  773. return (list);
  774. }
  775. /************************************************************************
  776. * FreeListStrings()
  777. * Free XmStrings from the bitmap names, passed into list.
  778. ************************************************************************/
  779. static void
  780. FreeListStrings(
  781. XmString *listPtr )
  782. {
  783. int i;
  784. int n;
  785. XmString *list = listPtr;
  786. for (i = 0; i < backdrops.numBitmaps; i++)
  787. {
  788. if (list[i]) XmStringFree(list[i]);
  789. }
  790. XtFree ((char *)list);
  791. }
  792. /************************************************************************
  793. * ListCB()
  794. * Get the bitmap selected from the list
  795. ************************************************************************/
  796. static void
  797. ListCB(
  798. Widget w,
  799. XtPointer client_data,
  800. XtPointer call_data )
  801. {
  802. XmListCallbackStruct *cb = (XmListCallbackStruct *)call_data;
  803. backdrops.selected = cb->item_position - 1;
  804. XSetTile (style.display, backdrops.gc,
  805. backdrops.bitmaps[backdrops.selected]);
  806. DrawBitmap (backdrops.drawnButton, NULL, NULL);
  807. }
  808. /************************************************************************
  809. * ButtonCB()
  810. *
  811. ************************************************************************/
  812. static void
  813. ButtonCB(
  814. Widget w,
  815. XtPointer client_data,
  816. XtPointer call_data )
  817. {
  818. int n, num;
  819. Arg args[MAX_ARGS];
  820. DtDialogBoxCallbackStruct *cb = (DtDialogBoxCallbackStruct *) call_data;
  821. switch (cb->button_position)
  822. {
  823. case B_APPLY_BUTTON:
  824. /* send message to update backdrop */
  825. num = backdrops.selected;
  826. _DtWsmChangeBackdrop(style.display, style.root,
  827. backdrops.bitmapNames[num],
  828. backdrops.bitmaps[num]);
  829. break;
  830. case B_OK_BUTTON:
  831. /* send message to update backdrop */
  832. num = backdrops.selected;
  833. _DtWsmChangeBackdrop(style.display, style.root,
  834. backdrops.bitmapNames[num],
  835. backdrops.bitmaps[num]);
  836. XtUnmanageChild(w);
  837. break;
  838. case B_CANCEL_BUTTON: /* close */
  839. XtUnmanageChild(w);
  840. break;
  841. case B_HELP_BUTTON:
  842. XtCallCallbacks(style.backdropDialog, XmNhelpCallback, (XtPointer)NULL);
  843. break;
  844. default:
  845. break;
  846. }
  847. }
  848. /************************************************************************
  849. * CheckWorkspace()
  850. * Workspace may have changed, so get current workspace
  851. * colors and draw the backdrop bitmap
  852. *
  853. ************************************************************************/
  854. void
  855. CheckWorkspace( void )
  856. {
  857. backdrops.newColors = True; /* need to get new colors */
  858. if (style.backdropDialog && XtIsManaged(style.backdropDialog))
  859. {
  860. DrawBitmap (backdrops.drawnButton, NULL, NULL);
  861. }
  862. }
  863. /************************************************************************
  864. * GetColors()
  865. * Get current workspace colors, and update GC if needed
  866. *
  867. ************************************************************************/
  868. static void
  869. GetColors( void )
  870. {
  871. DtWsmWorkspaceInfo *wInfo=NULL;
  872. unsigned long num=0;
  873. Pixel fg, bg;
  874. XGCValues gcValues;
  875. Atom aWS;
  876. if ((DtWsmGetCurrentWorkspace (style.display, style.root, &aWS)
  877. == Success) &&
  878. (DtWsmGetWorkspaceInfo (style.display, style.root, aWS, &wInfo)
  879. == Success))
  880. {
  881. backdrops.bg = wInfo->bg;
  882. backdrops.fg = wInfo->fg;
  883. DtWsmFreeWorkspaceInfo (wInfo);
  884. }
  885. else
  886. {
  887. backdrops.bg = 0;
  888. backdrops.fg = 1;
  889. }
  890. if (backdrops.gc) /* update the gc if there is one */
  891. {
  892. gcValues.background = backdrops.bg;
  893. gcValues.foreground = backdrops.fg;
  894. /* free old pixmap */
  895. XmDestroyPixmap(style.screen,
  896. backdrops.bitmaps[backdrops.selected]);
  897. /* allocate new pixmap */
  898. backdrops.bitmaps[backdrops.selected] =
  899. XmGetPixmap (style.screen,
  900. backdrops.bitmapNames[backdrops.selected],
  901. backdrops.fg, backdrops.bg);
  902. gcValues.tile = backdrops.bitmaps[backdrops.selected];
  903. XChangeGC (style.display, backdrops.gc,
  904. GCForeground | GCBackground | GCTile, &gcValues);
  905. }
  906. }
  907. /************************************************************************
  908. * FreeAll()
  909. * Free some space that was allocated for backdrops
  910. ************************************************************************/
  911. static void
  912. FreeAll( void )
  913. {
  914. int i;
  915. /* set no bitmaps flag, so we won't try to get them next time */
  916. backdrops.noBitmaps = 1;
  917. /* free temporary list of backdrop names */
  918. for (i = 0; i < backdrops.tmpNumBitmaps; i++)
  919. if (backdrops.tmpBitmapNames[i])
  920. XtFree(backdrops.tmpBitmapNames[i]);
  921. XtFree ((char *)backdrops.tmpBitmapNames);
  922. XtFree ((char *)backdrops.bitmapNames);
  923. /* free backdrop bitmaps */
  924. for (i = 0; i < backdrops.numBitmaps; i++) {
  925. if (backdrops.bitmaps[i])
  926. XFreePixmap (style.display, backdrops.bitmaps[i]);
  927. if (backdrops.numBitmaps)
  928. XtFree((char *)backdrops.bitmaps);
  929. }
  930. /* destory widgets (via first parent) */
  931. XtDestroyWidget (XtParent(style.backdropDialog));
  932. style.backdropDialog = NULL;
  933. }
  934. /************************************************************************
  935. * _DtMapCB
  936. *
  937. ************************************************************************/
  938. static void
  939. _DtMapCB(
  940. Widget w,
  941. XtPointer client_data,
  942. XtPointer call_data )
  943. {
  944. DtWsmRemoveWorkspaceFunctions(style.display, XtWindow(XtParent(w)));
  945. if (!save.restoreFlag)
  946. putDialog((Widget)client_data, w);
  947. XtRemoveCallback(style.backdropDialog, XmNmapCallback, _DtMapCB, NULL);
  948. }
  949. /************************************************************************
  950. * restoreBackdrop()
  951. *
  952. * restore any state information saved with saveBackdrop.
  953. * This is called from restoreSession with the application
  954. * shell and the special xrm database retrieved for restore.
  955. ************************************************************************/
  956. void
  957. restoreBackdrop(
  958. Widget shell,
  959. XrmDatabase db )
  960. {
  961. XrmName xrm_name[5];
  962. XrmRepresentation rep_type;
  963. XrmValue value;
  964. xrm_name [0] = XrmStringToQuark (BACKDROPSDLG);
  965. xrm_name [2] = 0;
  966. /* get x position */
  967. xrm_name [1] = XrmStringToQuark ("x");
  968. if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value)) {
  969. XtSetArg (save.posArgs[save.poscnt], XmNx, atoi((char *)value.addr));
  970. save.poscnt++;
  971. save.restoreFlag = True;
  972. }
  973. /* get y position */
  974. xrm_name [1] = XrmStringToQuark ("y");
  975. if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value)) {
  976. XtSetArg (save.posArgs[save.poscnt], XmNy, atoi((char *)value.addr));
  977. save.poscnt++;
  978. }
  979. /* get width */
  980. xrm_name [1] = XrmStringToQuark ("width");
  981. if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value)) {
  982. XtSetArg(save.posArgs[save.poscnt], XmNwidth, atoi((char *)value.addr));
  983. save.poscnt++;
  984. }
  985. /* get height */
  986. xrm_name [1] = XrmStringToQuark ("height");
  987. if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value)) {
  988. XtSetArg(save.posArgs[save.poscnt],XmNheight, atoi((char *)value.addr));
  989. save.poscnt++;
  990. }
  991. xrm_name [1] = XrmStringToQuark ("ismapped");
  992. XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
  993. /* Are we supposed to be mapped? */
  994. if (strcmp(value.addr, "True") == 0)
  995. BackdropDialog(shell);
  996. }
  997. /************************************************************************
  998. * saveBackdrop()
  999. *
  1000. * This routine will write out to the passed file descriptor any state
  1001. * information this dialog needs. It is called from saveSessionCB with the
  1002. * file already opened.
  1003. * All information is saved in xrm format. There is no restriction
  1004. * on what can be saved. It doesn't have to be defined or be part of any
  1005. * widget or Xt definition. Just name and save it here and recover it in
  1006. * restoreBackdrop. The suggested minimum is whether you are mapped, and your
  1007. * location.
  1008. ************************************************************************/
  1009. void
  1010. saveBackdrop(
  1011. int fd )
  1012. {
  1013. Position x,y;
  1014. Dimension width, height;
  1015. char *bufr = style.tmpBigStr; /* size=[1024], make bigger if needed */
  1016. XmVendorShellExtObject vendorExt;
  1017. XmWidgetExtData extData;
  1018. if (style.backdropDialog != NULL)
  1019. {
  1020. if (XtIsManaged(style.backdropDialog))
  1021. sprintf(bufr, "*backdropsDialog.ismapped: True\n");
  1022. else
  1023. sprintf(bufr, "*backdropsDialog.ismapped: False\n");
  1024. /* Get and write out the geometry info for our Window */
  1025. x = XtX (XtParent(style.backdropDialog));
  1026. y = XtY (XtParent(style.backdropDialog));
  1027. width = XtWidth (style.backdropDialog);
  1028. height = XtHeight (style.backdropDialog);
  1029. /* Modify x & y to take into account window mgr frames
  1030. * This is pretty bogus, but I don't know a better way to do it.
  1031. */
  1032. extData = _XmGetWidgetExtData(style.shell, XmSHELL_EXTENSION);
  1033. vendorExt = (XmVendorShellExtObject)extData->widget;
  1034. x -= vendorExt->vendor.xOffset;
  1035. y -= vendorExt->vendor.yOffset;
  1036. sprintf(bufr, "%s*backdropsDialog.x: %d\n", bufr, x);
  1037. sprintf(bufr, "%s*backdropsDialog.y: %d\n", bufr, y);
  1038. sprintf(bufr, "%s*backdropsDialog.width: %d\n", bufr, width);
  1039. sprintf(bufr, "%s*backdropsDialog.height: %d\n", bufr, height);
  1040. sprintf(bufr, "%s*backdropsDialog.selectedItemNum: %d\n", bufr,
  1041. backdrops.selected);
  1042. sprintf(bufr, "%s*backdropsDialog.selectedItem: %s\n", bufr,
  1043. backdrops.bitmapNames[backdrops.selected]);
  1044. if(-1 == write (fd, bufr, strlen(bufr))) {
  1045. perror(strerror(errno));
  1046. }
  1047. }
  1048. }