dthello.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205
  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 1993, 1994 Hewlett-Packard Company *
  25. * (c) Copyright 1993, 1994 International Business Machines Corp. *
  26. * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
  27. * (c) Copyright 1993, 1994 Novell, Inc. *
  28. */
  29. /******************************<+>*************************************
  30. **********************************************************************
  31. **
  32. ** File: dthello.c
  33. **
  34. ** Project: HP Visual User Environment
  35. **
  36. ** Description:
  37. ** -----------
  38. ** This file implements the startup transition for the DT
  39. ** environment
  40. **
  41. **
  42. **********************************************************************
  43. **
  44. ** (c) Copyright 1990, 1991, 1992 Hewlett-Packard Company
  45. ** All rights reserved
  46. **
  47. **********************************************************************
  48. ******************************<+>*************************************/
  49. /*
  50. * Notes on conditional compilation:
  51. *
  52. * AUTO_TOP If defined, the dthello window will automatically
  53. * raise itself over any window that obscures it.
  54. *
  55. * BLOCK_CENTER_FILES
  56. * If defined, dthello will center the text from
  57. * input files as a block as opposed to line-by-line.
  58. */
  59. /*
  60. * Included Files:
  61. */
  62. #include <stdio.h>
  63. #include <stdlib.h>
  64. #include <unistd.h>
  65. #include <X11/Xlib.h>
  66. #include <X11/Intrinsic.h>
  67. #include <X11/StringDefs.h>
  68. #include <X11/Xutil.h>
  69. #include <Xm/MwmUtil.h>
  70. #include <sys/signal.h>
  71. #include <Xm/Xm.h>
  72. #include <Dt/GetDispRes.h>
  73. #include <Dt/HourGlass.h>
  74. #include <limits.h>
  75. #include <locale.h>
  76. #ifndef NO_MESSAGE_CATALOG
  77. # include <Dt/MsgCatP.h>
  78. #endif
  79. #include <Dt/EnvControlP.h>
  80. #include "dthello.h"
  81. #ifndef NO_MESSAGE_CATALOG
  82. # define GETMESSAGE(set, number, string) GetMessage(set, number, string)
  83. #else
  84. # define GETMESSAGE(set, number, string) string
  85. #endif
  86. #if !defined(NL_CAT_LOCALE)
  87. #define NL_CAT_LOCALE 0
  88. #endif
  89. /*
  90. * Globals
  91. */
  92. Window welcome; /* Welcome window ID */
  93. Display *dpy; /* X server connection */
  94. struct globalStruct vhGD;
  95. int x_offset = 0; /* for left-justifying text */
  96. int box_line_width = 0; /* for drawing a box */
  97. XFontSet fontset; /* Font descriptor for ILS */
  98. unsigned long textHeight; /* Font size parameters */
  99. unsigned long fg, bg; /* Pixel values */
  100. Boolean colorSuccess = True; /* Success at allocating colors */
  101. XGCValues gcv; /* Struct for creating GC */
  102. unsigned int totalHeight; /* total Height used for text */
  103. unsigned int displayHeight; /* height of display in pixels */
  104. int maxWidth; /* max width of lines read in from file */
  105. unsigned int displayWidth; /* width of display in pixels */
  106. GC gc; /* GC to draw with */
  107. static XrmOptionDescRec optTable[] = {
  108. {"-font", "*vfont", XrmoptionSepArg, (XtPointer) NULL},
  109. {"-fnt", "*vfont", XrmoptionSepArg, (XtPointer) NULL},
  110. };
  111. static int noptTable = sizeof(optTable)/sizeof(optTable[0]);
  112. ArgSpec argSpecs[] =
  113. {
  114. {"-bground", 8}, /* background color */
  115. #define BG_ARG 0
  116. {"-fground", 8}, /* foreground color */
  117. #define FG_ARG 1
  118. {"-string", 7}, /* string to display */
  119. #define STRING_ARG 2
  120. {"-fnt", 4}, /* font to use */
  121. #define FONT_ARG 3
  122. {"-timeout", 8}, /* timeout amount in seconds*/
  123. #define TIME_ARG 4
  124. {"-file", 5}, /* file */
  125. #define FILE_ARG 5
  126. };
  127. char *ppchFileNames[MAX_FILES]; /* names of files to print */
  128. unsigned char *ppchText[MAX_LINES]; /* text lines to print out */
  129. int numFiles; /* number of files to print */
  130. int numLines; /* number of text lines to print out */
  131. #ifdef BLOCK_CENTER_FILES
  132. int centerLines; /* number of text lines to print centered */
  133. #endif /* BLOCK_CENTER_FILES */
  134. char *progName; /* who we are */
  135. char *fontArg; /* font argument */
  136. int sizeFontArg;
  137. char *stringArg; /* string argument */
  138. int sizeStringArg;
  139. char *bgArg; /* background argument */
  140. int sizeBgArg;
  141. char *fgArg; /* foreground argument */
  142. int sizeFgArg;
  143. char *xoffsetArg; /* text x_offset argument */
  144. int sizeXoffsetArg;
  145. char *timeArg; /* timeout argument, in seconds */
  146. int sizeTimeArg;
  147. int sizeFileArg;
  148. Boolean Done; /* while painting text */
  149. static VhResourceEntry restable[] = {
  150. { vNbackground, vCBackground, &bgArg, &sizeBgArg },
  151. { vNforeground, vCForeground, &fgArg, &sizeFgArg },
  152. { vNfont, vCFont, &fontArg, &sizeFontArg },
  153. { vNxoffset, vCXoffset, &xoffsetArg, &sizeXoffsetArg },
  154. { vNstring, vCString, &stringArg, &sizeStringArg },
  155. { vNfile, vCFile, &ppchFileNames[0], &sizeFileArg },
  156. { vNtimeout, vCTimeout, &timeArg, &sizeTimeArg },
  157. };
  158. void
  159. Usage(void)
  160. {
  161. fprintf(stderr, (char *) GETMESSAGE (4, 4,
  162. "usage: %s [-display <display>] [-bground <color>] [-fground <color>]\n"),
  163. progName);
  164. fprintf(stderr, "%s", (char *) GETMESSAGE (4, 5,
  165. "\t[-font <font>] [-string <message>] [-timeout <seconds>] [-file <name>]\n"));
  166. }
  167. /*************************************<->*************************************
  168. *
  169. * main (argc, argv)
  170. *
  171. *
  172. * Description:
  173. * -----------
  174. * This is the main routine that does almost all the work.
  175. *
  176. * Inputs:
  177. * ------
  178. * argc = Std C argument count
  179. * argv = Std C argument vector
  180. *
  181. * Outputs:
  182. * --------
  183. * Exit code
  184. *
  185. * Comments:
  186. * ---------
  187. * This works by creating an override-redirect window the size of
  188. * the screen and painting a message on it. At the same time, a
  189. * 1x1 window is created that will be picked up by the window
  190. * manager. When the window manager reparents the little window,
  191. * this program exits.
  192. *
  193. * Synopsis:
  194. * ---------
  195. * dthello [-display <display>] [-fground <color>] [-bground <color>]
  196. * [-font <fontname>] [-string <message>] [-file <filename>]
  197. * [-timeout <seconds>]
  198. *
  199. *************************************<->***********************************/
  200. int
  201. main (int argc, char **argv)
  202. {
  203. Window wmwin; /* Window ID for wm */
  204. XEvent event; /* Event received */
  205. unsigned long mask; /* mask for window attribs */
  206. XSetWindowAttributes xwa; /* Set Window Attribute struct */
  207. int argn; /* temp for parsing args */
  208. XColor colorDef; /* for parsing/allocating colors */
  209. Colormap colormap; /* color map of screen */
  210. Atom xaMwmHints; /* mwm hints atom */
  211. PropMotifWmHints mwmHints; /* mwm hints structure */
  212. Visual *pdv; /* X visual structure */
  213. FILE *fp; /* file pointer */
  214. int i; /* loop index */
  215. char *default_string; /* default message */
  216. XtAppContext appcontext;
  217. char *def_str;
  218. char **missing_clist;
  219. int missing_count;
  220. XFontSetExtents *extents;
  221. XtSetLanguageProc( NULL, NULL, NULL );
  222. /*
  223. * Initialization
  224. */
  225. /*
  226. * Set up NLSPATH, app-defaults, etc. for this DT client.
  227. */
  228. _DtEnvControl(DT_ENV_SET);
  229. /*
  230. * Process command line arguments
  231. */
  232. progName = argv[0];
  233. /* fontArg = DEFAULT_FONT; */
  234. bgArg = NULL;
  235. fgArg = NULL;
  236. timeArg = DEFAULT_TIME;
  237. numFiles = 0;
  238. sizeFileArg = 0;
  239. /*
  240. * Initialize Toolkit, open display
  241. */
  242. XtToolkitInitialize();
  243. appcontext = XtCreateApplicationContext();
  244. dpy = XtOpenDisplay (appcontext, NULL, argv[0], DTHELLO_CLASS_NAME,
  245. optTable, noptTable, (int *)(&argc), argv);
  246. if (dpy == NULL)
  247. {
  248. setlocale(LC_ALL, "");
  249. fprintf(stderr, (char *)
  250. GETMESSAGE(4, 1, "%s: can't open display\n"), progName);
  251. exit(1);
  252. }
  253. default_string = strdup (
  254. ((char *)GETMESSAGE(2, 3,
  255. "Starting the\nCommon Desktop Environment\n\n")));
  256. stringArg = default_string;
  257. /*
  258. * Find appropriate default font
  259. * and offset from the left side of the screen
  260. */
  261. switch (_DtGetDisplayResolution(dpy, XDefaultScreen(dpy)))
  262. {
  263. case LOW_RES_DISPLAY:
  264. fontArg = DEFAULT_FONT_SMALL;
  265. x_offset = DEFAULT_XOFFSET_SMALL;
  266. box_line_width = BOX_LINE_WIDTH_SMALL;
  267. break;
  268. case MED_RES_DISPLAY:
  269. fontArg = DEFAULT_FONT_MEDIUM;
  270. x_offset = DEFAULT_XOFFSET_MEDIUM;
  271. box_line_width = BOX_LINE_WIDTH_MEDIUM;
  272. break;
  273. case HIGH_RES_DISPLAY:
  274. fontArg = DEFAULT_FONT_LARGE;
  275. x_offset = DEFAULT_XOFFSET_LARGE;
  276. box_line_width = BOX_LINE_WIDTH_LARGE;
  277. break;
  278. default:
  279. fontArg = DEFAULT_FONT_SMALL;
  280. x_offset = DEFAULT_XOFFSET_SMALL;
  281. box_line_width = BOX_LINE_WIDTH_SMALL;
  282. break;
  283. }
  284. /*
  285. * Fetch resources
  286. */
  287. VhGetResources (dpy, progName, DTHELLO_CLASS,
  288. restable, XtNumber(restable));
  289. /* assign the x_offset to the value set in the resource list if given by the user */
  290. /* RK 11.06.93 */
  291. if( xoffsetArg != NULL)
  292. x_offset = atoi(xoffsetArg);
  293. if (x_offset < 0)
  294. {
  295. x_offset = -x_offset;
  296. }
  297. if (sizeFileArg != 0)
  298. {
  299. numFiles = 1;
  300. }
  301. /*
  302. * Parse remaining command line arguments
  303. */
  304. for (argn = 1; argn < argc; argn++)
  305. {
  306. if ((*argv[argn] == '-') &&
  307. (argn+1 < argc))
  308. {
  309. if (ArgMatch (argv[argn], BG_ARG))
  310. {
  311. bgArg = argv[++argn];
  312. continue;
  313. }
  314. else if (ArgMatch (argv[argn], FG_ARG))
  315. {
  316. fgArg = argv[++argn];
  317. continue;
  318. }
  319. else if (ArgMatch (argv[argn], STRING_ARG))
  320. {
  321. stringArg = argv[++argn];
  322. continue;
  323. }
  324. else if (ArgMatch (argv[argn], FONT_ARG))
  325. {
  326. fontArg = argv[++argn];
  327. continue;
  328. }
  329. else if (ArgMatch (argv[argn], TIME_ARG))
  330. {
  331. timeArg = argv[++argn];
  332. if (atoi(timeArg) <= 0)
  333. {
  334. fprintf (stderr, (char *)
  335. GETMESSAGE(4, 2, "%s: timeout must be positive\n"),
  336. argv[0]);
  337. timeArg = DEFAULT_TIME;
  338. }
  339. continue;
  340. }
  341. else if (ArgMatch (argv[argn], FILE_ARG))
  342. {
  343. argn++;
  344. if (numFiles < MAX_FILES)
  345. {
  346. ppchFileNames[numFiles] = (char *) argv[argn];
  347. numFiles++;
  348. }
  349. else
  350. {
  351. fprintf(stderr, (char *) GETMESSAGE(4, 3,
  352. "%1$s: Maxiumum of %2$d files allowed, skipping %3$s\n"),
  353. argv[0], MAX_FILES, argv[argn]);
  354. }
  355. continue;
  356. }
  357. else
  358. {
  359. Usage();
  360. exit(1);
  361. }
  362. }
  363. else
  364. {
  365. Usage();
  366. exit(1);
  367. }
  368. }
  369. displayHeight = XDisplayHeight (dpy, XDefaultScreen(dpy));
  370. displayWidth = XDisplayWidth (dpy, XDefaultScreen(dpy));
  371. /*
  372. * Set default fg/bg colors if not specified.
  373. * (adjust for low-color systems)
  374. */
  375. pdv = XDefaultVisual(dpy, XDefaultScreen(dpy));
  376. /*
  377. * Set default colors if not specified on command line.
  378. */
  379. if ((XDefaultDepth(dpy, XDefaultScreen(dpy)) <= 4) ||
  380. (pdv->class == StaticGray) ||
  381. (pdv->class == GrayScale))
  382. {
  383. /*
  384. * B&W, GrayScale, or low-color systems
  385. */
  386. if (!bgArg)
  387. {
  388. bgArg = DEFAULT_LOW_BG;
  389. }
  390. if (!fgArg)
  391. {
  392. fgArg = DEFAULT_LOW_FG;
  393. }
  394. }
  395. else
  396. {
  397. /*
  398. * Medium- to High-color systems
  399. */
  400. if (!bgArg)
  401. {
  402. bgArg = DEFAULT_BG;
  403. }
  404. if (!fgArg)
  405. {
  406. fgArg = DEFAULT_FG;
  407. }
  408. }
  409. /*
  410. * Load the font.
  411. */
  412. if ((fontset = XCreateFontSet(dpy, fontArg, &missing_clist, &missing_count,
  413. &def_str)) == NULL)
  414. {
  415. fprintf(stderr, (char *)
  416. GETMESSAGE (4, 6, "%1$s: display %2$s doesn't know font %3$s\n"),
  417. argv[0], DisplayString(dpy), fontArg);
  418. if ((fontset = XCreateFontSet(dpy, DEFAULT_FONT, &missing_clist,
  419. &missing_count, &def_str)) == NULL)
  420. {
  421. fprintf(stderr, (char *)
  422. GETMESSAGE (4, 6, "%1$s: display %2$s doesn't know font %3$s\n"),
  423. argv[0], DisplayString(dpy), DEFAULT_FONT);
  424. }
  425. if ((NULL == fontset) &&
  426. (fontset = XCreateFontSet(dpy, FIXED_FONT, &missing_clist,
  427. &missing_count, &def_str)) == NULL)
  428. {
  429. fprintf(stderr, (char *)
  430. GETMESSAGE (4, 6, "%1$s: display %2$s doesn't know font %3$s\n"),
  431. argv[0], DisplayString(dpy), FIXED_FONT);
  432. exit(1);
  433. }
  434. }
  435. extents = XExtentsOfFontSet(fontset);
  436. textHeight = extents->max_ink_extent.height;
  437. /*
  438. * Print the copyright file by default if no other file
  439. * specified
  440. */
  441. #ifdef DEFAULT_FILE
  442. if (numFiles == 0)
  443. {
  444. ppchFileNames[numFiles] = (char *) DEFAULT_FILE;
  445. numFiles = 1;
  446. }
  447. #endif
  448. /*
  449. * Break the text string up into separate lines
  450. * and place into message buffer.
  451. */
  452. SeparateTextLines ((unsigned char *)stringArg);
  453. #ifdef BLOCK_CENTER_FILES
  454. centerLines = numLines;
  455. #endif /* BLOCK_CENTER_FILES */
  456. for (i = 0; i < numFiles; i++)
  457. {
  458. maxWidth = 0;
  459. if (!(fp = fopen ((char *)ppchFileNames[i], "r")))
  460. {
  461. fprintf (stderr, (char *)
  462. GETMESSAGE (4, 7, "%1$s: unable to open file %2$s\n"),
  463. argv[0], ppchFileNames[i]);
  464. }
  465. else
  466. {
  467. /*
  468. * read in lines
  469. */
  470. ReadInTextLines (fp, fontset, (unsigned int *)&maxWidth);
  471. }
  472. }
  473. /*
  474. * Get the colors
  475. */
  476. colormap = XDefaultColormap (dpy, XDefaultScreen(dpy));
  477. /*
  478. * Get background color
  479. */
  480. if (!XParseColor (dpy, colormap, bgArg, &colorDef))
  481. {
  482. /* failed to get background color, try low color default */
  483. colorSuccess = False;
  484. fprintf(stderr, (char *) GETMESSAGE (4, 8,
  485. "%1$s: can't set background to %2$s, using %3$s.\n"),
  486. argv[0], bgArg, DEFAULT_LOW_BG);
  487. XParseColor (dpy, colormap, DEFAULT_LOW_BG, &colorDef);
  488. }
  489. XAllocColor (dpy, colormap, &colorDef);
  490. bg = colorDef.pixel;
  491. /*
  492. * Get foreground color
  493. */
  494. if (!XParseColor (dpy, colormap, fgArg, &colorDef))
  495. {
  496. /* failed to get foreground color, try low color default */
  497. colorSuccess = False;
  498. fprintf(stderr, (char *) GETMESSAGE (4, 9,
  499. "%1$s: can't set foreground to %2$s, using %3$s.\n"),
  500. argv[0], fgArg, DEFAULT_LOW_FG);
  501. XParseColor (dpy, colormap, DEFAULT_LOW_FG, &colorDef);
  502. }
  503. XAllocColor (dpy, colormap, &colorDef);
  504. fg = colorDef.pixel;
  505. /*
  506. * Create 1x1 window to catch reparenting action of window manager
  507. * Request no mwm decoration to reduce flash.
  508. * Request no mwm functions to avoid icon in icon box.
  509. */
  510. wmwin = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
  511. 0, 0, 1, 1, 0, bg, bg);
  512. xaMwmHints = XInternAtom (dpy, _XA_MOTIF_WM_HINTS, 0);
  513. mwmHints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
  514. mwmHints.decorations = 0;
  515. mwmHints.functions = 0;
  516. XChangeProperty (dpy, wmwin, xaMwmHints, xaMwmHints, 32,
  517. PropModeReplace, (unsigned char *) &mwmHints,
  518. sizeof(PropMotifWmHints)/sizeof(long));
  519. XSelectInput (dpy, wmwin, StructureNotifyMask);
  520. XMapWindow(dpy, wmwin);
  521. /*
  522. * Create override-redirect window for display of transition
  523. * message.
  524. */
  525. welcome = XCreateSimpleWindow (dpy, DefaultRootWindow (dpy), 0, 0,
  526. displayWidth, displayHeight, 0, bg, bg);
  527. mask = CWOverrideRedirect | CWEventMask | CWCursor;
  528. xwa.override_redirect = 1;
  529. #ifdef AUTO_TOP
  530. xwa.event_mask = ExposureMask | VisibilityChangeMask;
  531. #else /* AUTO_TOP */
  532. xwa.event_mask = ExposureMask;
  533. #endif /* AUTO_TOP */
  534. xwa.cursor = _DtGetHourGlassCursor(dpy);
  535. XChangeWindowAttributes (dpy, welcome, mask, &xwa);
  536. XMapWindow(dpy, welcome);
  537. /*
  538. * Event loop for painting text
  539. */
  540. Done = True;
  541. while (Done)
  542. {
  543. /*
  544. * Get the next event
  545. */
  546. /* XNextEvent(dpy, &event); */
  547. XtAppNextEvent(appcontext, &event);
  548. if (event.type == Expose &&
  549. event.xexpose.window == welcome &&
  550. event.xexpose.count == 0)
  551. {
  552. /*
  553. * Remove any other pending Expose events from the queue
  554. */
  555. while (XCheckTypedEvent(dpy, Expose, &event));
  556. /*
  557. * Create the GC for drawing the box and painting the text.
  558. */
  559. gcv.foreground = fg;
  560. gcv.background = bg;
  561. gc = XCreateGC(dpy, welcome, (GCForeground | GCBackground), &gcv);
  562. XClearWindow(dpy, welcome);
  563. DrawBox();
  564. PaintText();
  565. XFlush(dpy);
  566. Done = False;
  567. }
  568. } /* end while */
  569. /*
  570. * set up the timeout
  571. */
  572. signal (SIGALRM, (void (*)()) CatchAlarm);
  573. alarm (atoi(timeArg));
  574. /*
  575. * Event loop
  576. */
  577. while (True)
  578. {
  579. /*
  580. * Get the next event
  581. */
  582. /* XNextEvent(dpy, &event); */
  583. XtAppNextEvent(appcontext, &event);
  584. if (event.type == ReparentNotify &&
  585. event.xany.window == wmwin)
  586. {
  587. /*
  588. * this is our cue...exit, stage left
  589. */
  590. alarm(0);
  591. break;
  592. }
  593. else
  594. {
  595. /* normal color serving process */
  596. XtDispatchEvent(&event);
  597. }
  598. } /* end while */
  599. exit(0);
  600. }
  601. /*************************************<->*************************************
  602. *
  603. * ArgMatch (pch, arn)
  604. *
  605. *
  606. * Description:
  607. * -----------
  608. * This function determines if a string matches a predefined switch.
  609. *
  610. * Inputs:
  611. * ------
  612. * pch = candidate string
  613. * arn = number of switch we are trying to match.
  614. *
  615. * Outputs:
  616. * --------
  617. * Return = True if match succeeds.
  618. *
  619. * Comments:
  620. * ---------
  621. * Would need work to be localized.
  622. *
  623. *************************************<->***********************************/
  624. int
  625. ArgMatch (char *pch, int arn)
  626. {
  627. int rval = False;
  628. if (!strncmp(pch, argSpecs[arn].name, argSpecs[arn].len))
  629. {
  630. rval = True;
  631. }
  632. return (rval);
  633. }
  634. /*************************************<->*************************************
  635. *
  636. * SkipWhitespace (*pch)
  637. *
  638. *
  639. * Description:
  640. * -----------
  641. * This procedure scans a string and returns a pointer to the first
  642. * non-whitespace character.
  643. *
  644. * Inputs:
  645. * ------
  646. * pch = pointer to string to scan
  647. *
  648. * Outputs:
  649. * --------
  650. * Return = pointer to first non-white character
  651. *
  652. * Comments:
  653. * ---------
  654. * Skips blanks and horizontal tabs.
  655. *
  656. *************************************<->***********************************/
  657. unsigned char *
  658. SkipWhitespace (unsigned char *pch)
  659. {
  660. int chlen;
  661. if (pch)
  662. {
  663. while ((*pch != '\0') &&
  664. ((chlen = mblen ((char *)pch, MB_CUR_MAX)) == 1) &&
  665. ((*pch == '\t') || (*pch == ' ')))
  666. {
  667. pch += chlen;
  668. }
  669. }
  670. return (pch);
  671. }
  672. /*************************************<->*************************************
  673. *
  674. * KillNewlines (*pch)
  675. *
  676. *
  677. * Description:
  678. * -----------
  679. * This procedure scans a string and replaces the first newline
  680. * with a NULL.
  681. *
  682. * Inputs:
  683. * ------
  684. * pch = pointer to string to scan
  685. *
  686. * Outputs:
  687. * --------
  688. * pch = modified
  689. *
  690. * Comments:
  691. * ---------
  692. *
  693. *************************************<->***********************************/
  694. void
  695. KillNewlines (unsigned char *pch)
  696. {
  697. int chlen;
  698. if (pch)
  699. {
  700. while (*pch != '\0')
  701. {
  702. if (((chlen = mblen ((char *)pch, MB_CUR_MAX)) == 1) &&
  703. (*pch == '\n'))
  704. {
  705. *pch = '\0';
  706. break;
  707. }
  708. pch += chlen;
  709. }
  710. }
  711. }
  712. /*************************************<->*************************************
  713. *
  714. * ReadInTextLines (fp, font, pMaxWidth)
  715. *
  716. *
  717. * Description:
  718. * -----------
  719. * This procedure reads in lines from a file for the message to
  720. * display.
  721. *
  722. * Inputs:
  723. * ------
  724. * pchIn = pointer to message string
  725. * font = font structure to be used to print with
  726. * pMaxWidth = width of largest line
  727. *
  728. * Outputs:
  729. * --------
  730. * Return = none
  731. * modifies global numLines
  732. *
  733. * Comments:
  734. * ---------
  735. * Global data ppchText is modified by this routine to contain
  736. * copies of the text lines from pchIn. pchIn is not modified.
  737. *
  738. *************************************<->***********************************/
  739. void
  740. ReadInTextLines (FILE *fp, XFontSet fontset, unsigned int *pMaxWidth)
  741. {
  742. unsigned int width;
  743. int allowedLines;
  744. /* count the number of lines in the file */
  745. allowedLines = (displayHeight - (2 * box_line_width))/ textHeight;
  746. while (numLines < allowedLines)
  747. {
  748. ppchText[numLines] = (unsigned char *) malloc (1+MAX_COLUMNS);
  749. if (!ppchText[numLines] ||
  750. !fgets ((char *)ppchText[numLines], MAX_COLUMNS, fp))
  751. {
  752. break;
  753. }
  754. KillNewlines (ppchText[numLines]);
  755. #ifndef BLOCK_CENTER_FILES
  756. ppchText[numLines] = SkipWhitespace (ppchText[numLines]);
  757. #endif /* not BLOCK_CENTER_FILES */
  758. width = XmbTextEscapement(fontset, (char *)(ppchText[numLines]),
  759. strlen((char *)ppchText[numLines]));
  760. if (width > *pMaxWidth)
  761. {
  762. *pMaxWidth = width;
  763. }
  764. numLines++;
  765. }
  766. }
  767. /*************************************<->*************************************
  768. *
  769. * SeparateTextLines (pchIn)
  770. *
  771. *
  772. * Description:
  773. * -----------
  774. * This procedure takes a message string and separates it into
  775. * text lines based on the presence of new line characters.
  776. *
  777. * Inputs:
  778. * ------
  779. * pchIn = pointer to message string
  780. *
  781. * Outputs:
  782. * --------
  783. * Return = none
  784. *
  785. * Comments:
  786. * ---------
  787. * Global data ppchText is modified by this routine to contain
  788. * copies of the text lines from pchIn. pchIn is not modified.
  789. *
  790. *************************************<->***********************************/
  791. void
  792. SeparateTextLines (unsigned char *pchIn)
  793. {
  794. unsigned char *pch, *pch1, *pch2;
  795. unsigned char *pchInEnd;
  796. int i, chlen = 0;
  797. /* count the number of new line characters in the string */
  798. numLines = 1;
  799. for (pch = pchIn; *pch; )
  800. {
  801. if (((chlen = mblen ((char *)pch, MB_CUR_MAX)) == 1) &&
  802. (*pch == '\n'))
  803. {
  804. numLines++;
  805. }
  806. pch += chlen;
  807. }
  808. if ((chlen == 1) && (*(pch-1) == '\n'))
  809. {
  810. numLines--; /* don't count terminating newline */
  811. }
  812. pch2 = pch1 = pchIn;
  813. pchInEnd = pchIn + strlen((char *)pchIn);
  814. for (i = 0; (i < numLines) && (pch1 < pchInEnd); i++)
  815. {
  816. while ((*pch2 != '\0') &&
  817. !(((chlen = mblen ((char *)pch2, MB_CUR_MAX)) == 1) &&
  818. (*pch2 == '\n')))
  819. {
  820. pch2 += chlen;
  821. }
  822. if (*pch2 == '\n')
  823. {
  824. *pch2 = '\0';
  825. }
  826. ppchText[i] = (unsigned char *) malloc (1+strlen ((char *)pch1));
  827. if (ppchText[i])
  828. {
  829. strcpy ((char *)ppchText[i], (char *)pch1);
  830. }
  831. else
  832. {
  833. fprintf (stderr, (char *) GETMESSAGE (4, 10,
  834. "%s: Insufficient memory (SeparateTextLines)\n"),
  835. progName);
  836. exit (1);
  837. }
  838. /* advance pointers */
  839. pch1 = ++pch2;
  840. }
  841. }
  842. /*************************************<->*************************************
  843. *
  844. * CatchAlarm (sig)
  845. *
  846. *
  847. * Description:
  848. * -----------
  849. * This function catches the SIG_ALRM signal generated when the
  850. * timer expires.
  851. *
  852. * Inputs:
  853. * ------
  854. * sig = signal number
  855. *
  856. * Outputs:
  857. * --------
  858. * Return = none
  859. *
  860. * Comments:
  861. * ---------
  862. *
  863. *************************************<->***********************************/
  864. void
  865. CatchAlarm ( int sig)
  866. {
  867. /* timer expired, exit */
  868. exit(0);
  869. }
  870. #ifndef NO_MESSAGE_CATALOG
  871. /*****************************************************************************
  872. *
  873. * Function: GetMessage
  874. *
  875. * Parameters:
  876. *
  877. * int set - The message catalog set number.
  878. *
  879. * int n - The message number.
  880. *
  881. * char *s - The default message if the message is not
  882. * retrieved from a message catalog.
  883. *
  884. * Returns: the string for set 'set' and number 'n'.
  885. *
  886. *****************************************************************************/
  887. char *
  888. GetMessage(
  889. int set,
  890. int n,
  891. char *s )
  892. {
  893. static int first = 1;
  894. static nl_catd nlmsg_fd = (nl_catd) -1;
  895. if ( first )
  896. {
  897. first = 0;
  898. nlmsg_fd = CATOPEN("dthello", NL_CAT_LOCALE);
  899. }
  900. return CATGETS(nlmsg_fd, set, n, s);
  901. }
  902. #endif
  903. /*************************************<->*************************************
  904. *
  905. * void VhGetResources
  906. *
  907. *
  908. * Description:
  909. * -----------
  910. * Gets the resources for the client
  911. *
  912. *
  913. * Inputs:
  914. * ------
  915. *
  916. * Outputs:
  917. * -------
  918. *
  919. * Comments:
  920. * --------
  921. *
  922. *************************************<->***********************************/
  923. void
  924. VhGetResources(Display *dpy, char *name, char *class,
  925. VhResourceEntry *res, int num)
  926. {
  927. #define INIT_SIZE 256
  928. #define SRCH_SIZE 20
  929. int i;
  930. XrmValue xrmv;
  931. XrmQuark Qtype, Qstring, Qname, Qclass;
  932. XrmQuark Qnres[4], Qcres[4];
  933. XrmHashTable searchList[SRCH_SIZE];
  934. /*
  935. * We only deal with string-type resources
  936. */
  937. Qstring = XrmStringToQuark (XtRString);
  938. /*
  939. * Get resource search list for "dthello"
  940. */
  941. XrmStringToQuarkList (name, Qnres);
  942. XrmStringToQuarkList (class, Qcres);
  943. if (XrmQGetSearchList(XtDatabase(dpy), Qnres, Qcres, searchList,
  944. SRCH_SIZE))
  945. {
  946. /*
  947. * Look for all resources at this level
  948. */
  949. for (i = 0; i < num; i++)
  950. {
  951. Qname = XrmStringToQuark (res[i].resname);
  952. Qclass = XrmStringToQuark (res[i].resclass);
  953. if ((XrmQGetSearchResource (searchList, Qname, Qclass,
  954. &Qtype, &xrmv)) &&
  955. (Qtype == Qstring))
  956. {
  957. *(res[i].ppvalue) = (char *) xrmv.addr;
  958. *res[i].size = (int) xrmv.size;
  959. }
  960. }
  961. }
  962. }
  963. void
  964. PaintText( void )
  965. {
  966. int i, x, y;
  967. XFontSetExtents *extents;
  968. /*
  969. * Paint the string onto the screen
  970. */
  971. y = (displayHeight - totalHeight) / 2;
  972. if (y < 0)
  973. {
  974. y = 0;
  975. }
  976. /* adjust origin by font metric */
  977. extents = XExtentsOfFontSet(fontset);
  978. y += -(extents->max_logical_extent.y);
  979. x = box_line_width + x_offset;
  980. for (i = 0; i < numLines; i++)
  981. {
  982. /* draw the string */
  983. XmbDrawString (dpy, welcome, fontset, gc, x, y,
  984. (char *)(ppchText[i]), strlen((char *)ppchText[i]));
  985. /* move to next "line" */
  986. y += textHeight;
  987. }
  988. }
  989. void
  990. DrawBox( void )
  991. {
  992. int LTX, LTY, RTX, RTY, LBX, LBY, RBX, RBY;
  993. int L_middle; /* pixels to the midpoint of the line width */
  994. Boolean useDecoration = True;
  995. /* compute the height of the font */
  996. totalHeight = textHeight * numLines;
  997. /*
  998. * Set limits
  999. */
  1000. if ((( 2 * box_line_width ) + x_offset + maxWidth) > displayWidth)
  1001. {
  1002. useDecoration = False;
  1003. x_offset = 0;
  1004. }
  1005. if (!useDecoration)
  1006. return;
  1007. L_middle = box_line_width / 2;
  1008. /********************************************************
  1009. +----------------------------------------------+
  1010. | (LTX, LTY) (RTX, RTY) |
  1011. | |
  1012. | (Draw counterclockwise, beginning from |
  1013. | top left.) |
  1014. | |
  1015. | |
  1016. | |
  1017. | |
  1018. | |
  1019. | |
  1020. | (LBX, LBY) (RBX, RBY) |
  1021. +----------------------------------------------+
  1022. ********************************************************/
  1023. LTX = 0;
  1024. LTY = 0;
  1025. RTX = displayWidth;
  1026. RTY = 0;
  1027. LBX = 0;
  1028. LBY = displayHeight;
  1029. RBX = displayWidth ;
  1030. RBY = displayHeight;
  1031. XSetLineAttributes(dpy, gc, box_line_width, LineSolid, CapButt, JoinMiter);
  1032. XDrawLine(dpy, welcome, gc,
  1033. LTX, LTY + L_middle,
  1034. RTX, RTY + L_middle);
  1035. XDrawLine(dpy, welcome, gc,
  1036. RTX - L_middle, RTY,
  1037. RBX - L_middle, RBY);
  1038. XDrawLine(dpy, welcome, gc,
  1039. RBX, RBY - L_middle,
  1040. LBX, LBY - L_middle);
  1041. XDrawLine(dpy, welcome, gc,
  1042. LBX + L_middle, LBY,
  1043. LTX + L_middle, LTY);
  1044. }
  1045. int
  1046. Xestrcmp(const char * const s1, const char * const s2)
  1047. {
  1048. if (s1 == s2) return 0;
  1049. {
  1050. const char * p1 = (s1) ? s1 : "";
  1051. const char * p2 = (s2) ? s2 : "";
  1052. return strcmp((char *)p1, (char *)p2);
  1053. }
  1054. }
  1055. /************** eof ******************/