home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / wscrawl / part02 < prev    next >
Internet Message Format  |  1990-07-15  |  45KB

  1. Path: uunet!munnari.oz.au!metro!sunaus.oz!newstop!sun!hpcvlx.cv.hp.com
  2. From: brianw@hpcvlx.cv.hp.com (Brian Wilson)
  3. Newsgroups: comp.sources.x
  4. Subject: v08i054: wscrawl, Part02/05
  5. Message-ID: <138939@sun.Eng.Sun.COM>
  6. Date: 15 Jul 90 18:57:15 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1137
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: Brian Wilson <brianw@hpcvlx.cv.hp.com>
  12. Posting-number: Volume 8, Issue 54
  13. Archive-name: wscrawl/part02
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # If this archive is complete, you will see the following message at the end:
  22. #        "End of archive 2 (of 5)."
  23. # Contents:  wscrawl/README wscrawl/xac
  24. # Wrapped by argv@turnpike on Sun Jul 15 11:47:10 1990
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'wscrawl/README' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'wscrawl/README'\"
  28. else
  29. echo shar: Extracting \"'wscrawl/README'\" \(3336 characters\)
  30. sed "s/^X//" >'wscrawl/README' <<'END_OF_FILE'
  31. X
  32. X                               WSCRAWL 
  33. X         (multi-display, multi-user, communications program)
  34. X              by Brian Wilson, brianw@cv.hp.com
  35. X
  36. X
  37. XWhat "wscrawl" is:
  38. X------------------
  39. X
  40. X    The program "wscrawl" is a demo of the networking capabilities of
  41. XX-Windows.  The word "wscrawl" stands for "window-scrawl".  The user may 
  42. Xthink of wscrawl as a paint program shared by any number of people at 
  43. Xthe same time.  When wscrawl is run, it opens up a separate window on each 
  44. Xparticipant's display.  From that point onward, each participant sees 
  45. Xthe actions and ideas of every other participant as they occur. Each individual
  46. Xmay simply watch, or participate at any moment.  Any individual may exit
  47. Xout of the session at any time without affecting the other participants.  
  48. X
  49. X
  50. X
  51. XTo quickly get the concept of wscrawl:
  52. X--------------------------------------
  53. X
  54. X     1) set your DISPLAY environment variable appropriately.  
  55. X        (example for me at my workstation: "export DISPLAY=hpcvxbw:0")
  56. X
  57. X     2) have a friend (with X11 running) xhost your workstation
  58. X    (example for my friend: "xhost +"  <-- xhost everyone in the world)
  59. X
  60. X     3) start a wscrawl session between the two of you
  61. X    (example for me: "wscrawl -d hpcvxca:0" <-- my friend is hpcvxca:0)
  62. X
  63. X     4) push the left mouse button down and move the mouse.  For some menu
  64. X    options, click on the menus at the top of the wscrawl window.
  65. X
  66. X     5) Concepts to try:
  67. X
  68. X      a) Play tic-tac-toe between two workstations.  Change colors of pen 
  69. X         and draw the board in the center of the wscrawl window.  Each 
  70. X         player should use a different color.
  71. X          
  72. X          b) type a message to your friend.  This is done by selecting the
  73. X         "Type" item from the "Control" menu, then clicking the left
  74. X         button somewhere.  Type on the keyboard.  Try changine fonts.
  75. X
  76. X          c) Wscrawl to someone out of sight earshot.  Wscrawl to them,
  77. X         and then call them on the telephone.  By talking and scrawling
  78. X         diagrams, you can simulate being there with an pad and pencil.
  79. X
  80. X          d) resize your wscrawl window.  Notice that ALL wscrawl windows
  81. X         on ALL displays will resize accordingly.  This guarantees you
  82. X         are all seeing the same picture at all times.  Resize your window
  83. X         to the size of the display you are working at.
  84. X
  85. X          e) any person out of the total group may select "Close Window" from
  86. X         the "Control" menu at any time.  This change is duely noted in
  87. X         the "STATUS" window at the bottom of each wscrawl window.  The
  88. X         other people may continue to scrawl with no problems.
  89. X
  90. X      f) scrawl a picture, then pull down the "Control" menu and select
  91. X         "Add a Display".  Type the name of your friend into the dialog
  92. X         box and hit return.  After a few seconds, your friend will see
  93. X         this new picture.
  94. X
  95. X          g) Fire up several wscrawl windows on your one display.  For me,
  96. X         I would type "wscrawl -d hpcvxbw:0 -d hpcvxbw:0 -d hpcvxbw:0".  
  97. X         See how it behaves.
  98. X
  99. X          h) Try some "File I/O".  Wscrawl saves and reads both standard
  100. X         X bitmap files and xwd standard files.  Import or export some
  101. X         of your favorite bitmaps, or dump a window using "xwd" and 
  102. X         load it into wscrawl.
  103. X
  104. X
  105. XQuestions, comments, hacked source code: 
  106. X----------------------------------------
  107. XBrian Wilson
  108. Xbrianw@cv.hp.com
  109. X
  110. END_OF_FILE
  111. if test 3336 -ne `wc -c <'wscrawl/README'`; then
  112.     echo shar: \"'wscrawl/README'\" unpacked with wrong size!
  113. fi
  114. # end of 'wscrawl/README'
  115. fi
  116. if test -f 'wscrawl/xac' -a "${1}" != "-c" ; then 
  117.   echo shar: Will not clobber existing file \"'wscrawl/xac'\"
  118. else
  119. echo shar: Extracting \"'wscrawl/xac'\" \(37771 characters\)
  120. sed "s/^X//" >'wscrawl/xac' <<'END_OF_FILE'
  121. X           "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1");
  122. X    else if (strcmp(font_file_name, "courR14") == 0)
  123. X    strcpy(xlfd_string, 
  124. X           "-adobe-courier-medium-r-normal--14-140-75-75-m-90-iso8859-1");
  125. X    else if (strcmp(font_file_name, "timBI18") == 0)
  126. X    strcpy(xlfd_string, 
  127. X           "-adobe-times-bold-i-normal--18-180-75-75-p-98-iso8859-1");
  128. X    else if (strcmp(font_file_name, "courR24") == 0)
  129. X    strcpy(xlfd_string, 
  130. X           "-adobe-courier-medium-r-normal--24-240-75-75-m-150-iso8859-1");
  131. X    else if (strcmp(font_file_name, "timR24") == 0)
  132. X    strcpy(xlfd_string, 
  133. X           "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1");
  134. X    else if (strcmp(font_file_name, "timBI24") == 0)
  135. X    strcpy(xlfd_string, 
  136. X           "-adobe-times-bold-i-normal--24-240-75-75-p-128-iso8859-1");
  137. X    else if (strcmp(font_file_name, "ncenR24") == 0)
  138. X    strcpy(xlfd_string, 
  139. X "-adobe-new century schoolbook-medium-r-normal--24-240-75-75-p-137-iso8859-1");
  140. X    else if (strcmp(font_file_name, "vbee-36") == 0)
  141. X    strcpy(xlfd_string, "vbee-36");
  142. X    else if (strcmp(font_file_name, "vr-40") == 0)
  143. X    strcpy(xlfd_string, "vr-40");
  144. X    else if (strcmp(font_file_name, "vgl-40") == 0)
  145. X    strcpy(xlfd_string, "vgl-40");
  146. X    else if (strcmp(font_file_name, "vgl-40") == 0)
  147. X    strcpy(xlfd_string, "vsgn-57");
  148. X    else
  149. X    return(FALSE);  /*not one of these fonts*/
  150. X
  151. X    if ((the_font_struct = XLoadQueryFont(disp_info[i].disp,
  152. X          xlfd_string)) != NULL)
  153. X    {
  154. X        gcvalues.font = the_font_struct->fid;
  155. X        disp_info[disp_num].the_font_struct = the_font_struct;
  156. X        gcvalues.font = the_font_struct->fid;
  157. X        XChangeGC(disp_info[i].disp, disp_info[disp_num].win_gc[i], GCFont, 
  158. X                &gcvalues);
  159. X        return(TRUE);
  160. X     }
  161. X     else 
  162. X        return(FALSE);
  163. X}
  164. X
  165. X
  166. X/*
  167. X * menu_selection - this function does the appropriate actions as specified
  168. X *              by the menu referenced by the menu_num and item_num passed as
  169. X *              parameters.
  170. X */
  171. Xmenu_selection(disp_num, menu_num, num_people_drawing, item_num)
  172. Xint disp_num, menu_num, *num_people_drawing, item_num;
  173. X{
  174. X     int i, temp_num;
  175. X     XColor scrn_def_ret, exact_def_ret;
  176. X     XFontStruct *the_font_struct;
  177. X     XWindowAttributes attr_ret;
  178. X
  179. X     switch (menu_num)
  180. X     {
  181. X     case 0:                       /*Control menu*/
  182. X         switch (item_num)
  183. X         {
  184. X         case 1:          /*scrawl*/
  185. X                 if (disp_info[disp_num].cursor_on == TRUE)
  186. X                 {
  187. X             disp_info[disp_num].cursor_on = FALSE;
  188. X                      XDrawLine(disp_info[disp_num].disp, 
  189. X                 disp_info[disp_num].win_id,
  190. X                 disp_info[disp_num].cursor_gc, 
  191. X                 disp_info[disp_num].cur_pos.x, 
  192. X                 disp_info[disp_num].cur_pos.y, 
  193. X                 disp_info[disp_num].cur_pos.x + 
  194. X                 disp_info[disp_num].prompt_width, 
  195. X                 disp_info[disp_num].cur_pos.y);
  196. X                     }
  197. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  198. X                         (*num_people_drawing)--;  /*stopped input for now*/
  199. X              disp_info[disp_num].scrawl_mode = SCRAWLING;
  200. X             disp_info[disp_num].menu[menu_num].checked_item = 1;
  201. X             disp_info[disp_num].pen_width = 
  202. X                     disp_info[disp_num].pen_widths.scrawl;
  203. X             for (i=1; i<disp_info[disp_num].menu[2].num_items; i++)
  204. X             {   /*determine which pen width we have*/
  205. X                     sscanf(menu_text[2][i], "%d", &temp_num);
  206. X                         if (temp_num >= disp_info[disp_num].pen_width)
  207. X             {
  208. X                     disp_info[disp_num].menu[2].checked_item=i;
  209. X                 break;
  210. X                         }
  211. X             }
  212. X                 for (i=0; i<num_of_disps; i++)
  213. X                 {
  214. X             if (disp_info[i].in_session_bool)
  215. X             {
  216. X                             gcvalues.line_width =disp_info[disp_num].pen_width;
  217. X                         XChangeGC(disp_info[i].disp, 
  218. X                       disp_info[disp_num].win_gc[i], 
  219. X                       GCLineWidth, &gcvalues);
  220. X             }
  221. X                 }
  222. X             XDefineCursor(disp_info[disp_num].disp,
  223. X                disp_info[disp_num].win_id,
  224. X            XCreateFontCursor(disp_info[disp_num].disp, XC_dot));
  225. X             break;
  226. X         case 2:          /*airbrush*/
  227. X                 if (disp_info[disp_num].cursor_on == TRUE)
  228. X                 {
  229. X             disp_info[disp_num].cursor_on = FALSE;
  230. X                      XDrawLine(disp_info[disp_num].disp, 
  231. X                 disp_info[disp_num].win_id,
  232. X                 disp_info[disp_num].cursor_gc, 
  233. X                 disp_info[disp_num].cur_pos.x, 
  234. X                 disp_info[disp_num].cur_pos.y, 
  235. X                 disp_info[disp_num].cur_pos.x + 
  236. X                 disp_info[disp_num].prompt_width, 
  237. X                 disp_info[disp_num].cur_pos.y);
  238. X                     }
  239. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  240. X                         (*num_people_drawing)--;  /*stopped input for now*/
  241. X             disp_info[disp_num].scrawl_mode = AIRBRUSHING;
  242. X             disp_info[disp_num].menu[menu_num].checked_item = 2;
  243. X             disp_info[disp_num].pen_width = 
  244. X                       disp_info[disp_num].pen_widths.airbrush;
  245. X             for (i=1; i<disp_info[disp_num].menu[2].num_items; i++)
  246. X             {   /*determine which pen width we have*/
  247. X                     sscanf(menu_text[2][i], "%d", &temp_num);
  248. X                         if (temp_num >= disp_info[disp_num].pen_width)
  249. X             {
  250. X                     disp_info[disp_num].menu[2].checked_item=i;
  251. X                 break;
  252. X                         }
  253. X             }
  254. X             XDefineCursor(disp_info[disp_num].disp,
  255. X                disp_info[disp_num].win_id,
  256. X            XCreateFontCursor(disp_info[disp_num].disp, 
  257. X            XC_spraycan));
  258. X             break;
  259. X         case 3:          /*type*/
  260. X             if (disp_info[disp_num].scrawl_mode != TYPING)
  261. X                         (*num_people_drawing)++;  /*started input for now*/
  262. X             disp_info[disp_num].scrawl_mode = TYPING;
  263. X             disp_info[disp_num].menu[menu_num].checked_item = 3;
  264. X             XDefineCursor(disp_info[disp_num].disp,
  265. X                disp_info[disp_num].win_id,
  266. X            XCreateFontCursor(disp_info[disp_num].disp, XC_xterm));
  267. X             break;
  268. X         case 4:           /*eraser*/
  269. X                 if (disp_info[disp_num].cursor_on == TRUE)
  270. X                 {
  271. X             disp_info[disp_num].cursor_on = FALSE;
  272. X                      XDrawLine(disp_info[disp_num].disp, 
  273. X                 disp_info[disp_num].win_id,
  274. X                 disp_info[disp_num].cursor_gc, 
  275. X                 disp_info[disp_num].cur_pos.x, 
  276. X                 disp_info[disp_num].cur_pos.y, 
  277. X                 disp_info[disp_num].cur_pos.x + 
  278. X                 disp_info[disp_num].prompt_width, 
  279. X                 disp_info[disp_num].cur_pos.y);
  280. X                     }
  281. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  282. X                         (*num_people_drawing)--;  /*stopped input for now*/
  283. X             disp_info[disp_num].scrawl_mode = ERASING;
  284. X             disp_info[disp_num].menu[menu_num].checked_item = 4;
  285. X             disp_info[disp_num].pen_width = 
  286. X                       disp_info[disp_num].pen_widths.eraser;
  287. X             for (i=1; i<disp_info[disp_num].menu[2].num_items; i++)
  288. X             {   /*determine which pen width we have*/
  289. X                     sscanf(menu_text[2][i], "%d", &temp_num);
  290. X                         if (temp_num >= disp_info[disp_num].pen_width)
  291. X             {
  292. X                     disp_info[disp_num].menu[2].checked_item=i;
  293. X                 break;
  294. X                         }
  295. X             }
  296. X             XDefineCursor(disp_info[disp_num].disp,
  297. X                disp_info[disp_num].win_id,
  298. X            XCreateFontCursor(disp_info[disp_num].disp, 
  299. X            XC_draped_box));
  300. X             break;
  301. X         case 5:           /*shapes*/
  302. X                 if (disp_info[disp_num].cursor_on == TRUE)
  303. X                 {
  304. X             disp_info[disp_num].cursor_on = FALSE;
  305. X                      XDrawLine(disp_info[disp_num].disp, 
  306. X                 disp_info[disp_num].win_id,
  307. X                 disp_info[disp_num].cursor_gc, 
  308. X                 disp_info[disp_num].cur_pos.x, 
  309. X                 disp_info[disp_num].cur_pos.y, 
  310. X                 disp_info[disp_num].cur_pos.x + 
  311. X                 disp_info[disp_num].prompt_width, 
  312. X                 disp_info[disp_num].cur_pos.y);
  313. X                     }
  314. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  315. X                         (*num_people_drawing)--;  /*stopped input for now*/
  316. X             disp_info[disp_num].scrawl_mode = SELECTING_AN_AREA;
  317. X             disp_info[disp_num].menu[menu_num].checked_item = 5;
  318. X             disp_info[disp_num].pen_width = 
  319. X                     disp_info[disp_num].pen_widths.shape;
  320. X             for (i=1; i<disp_info[disp_num].menu[2].num_items; i++)
  321. X             {   /*determine which pen width we have*/
  322. X                     sscanf(menu_text[2][i], "%d", &temp_num);
  323. X                         if (temp_num >= disp_info[disp_num].pen_width)
  324. X             {
  325. X                     disp_info[disp_num].menu[2].checked_item = i;
  326. X                 break;
  327. X                         }
  328. X             }
  329. X             disp_info[disp_num].dialog_what = DRAW_SHAPE;
  330. X                 for (i=0; i<num_of_disps; i++)
  331. X                 {
  332. X             if (disp_info[i].in_session_bool)
  333. X             {
  334. X                             gcvalues.line_width =disp_info[disp_num].pen_width;
  335. X                         XChangeGC(disp_info[i].disp, 
  336. X                       disp_info[disp_num].win_gc[i], 
  337. X                       GCLineWidth, &gcvalues);
  338. X             }
  339. X                 }
  340. X             XDefineCursor(disp_info[disp_num].disp,
  341. X                disp_info[disp_num].win_id,
  342. X            XCreateFontCursor(disp_info[disp_num].disp, 
  343. X            XC_crosshair));
  344. X             break;
  345. X         case 6:           /*Rubber Pointer*/
  346. X                 if (disp_info[disp_num].cursor_on == TRUE)
  347. X                 {
  348. X             disp_info[disp_num].cursor_on = FALSE;
  349. X                      XDrawLine(disp_info[disp_num].disp, 
  350. X                 disp_info[disp_num].win_id,
  351. X                 disp_info[disp_num].cursor_gc, 
  352. X                 disp_info[disp_num].cur_pos.x, 
  353. X                 disp_info[disp_num].cur_pos.y, 
  354. X                 disp_info[disp_num].cur_pos.x + 
  355. X                 disp_info[disp_num].prompt_width, 
  356. X                 disp_info[disp_num].cur_pos.y);
  357. X                     }
  358. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  359. X                         (*num_people_drawing)--;  /*stopped input for now*/
  360. X              disp_info[disp_num].scrawl_mode = RUBBER_POINTING;
  361. X             disp_info[disp_num].menu[menu_num].checked_item = 6;
  362. X             XDefineCursor(disp_info[disp_num].disp,
  363. X                disp_info[disp_num].win_id,
  364. X            XCreateFontCursor(disp_info[disp_num].disp, XC_target));
  365. X             break;
  366. X         case 7:           /*clear all windows*/
  367. X                 for (i=0; i<num_of_disps; i++)
  368. X                 {
  369. X             if (disp_info[i].in_session_bool)
  370. X             {
  371. X                 XGetWindowAttributes(disp_info[i].disp, 
  372. X                              disp_info[i].win_id, &attr_ret);
  373. X                 XClearArea(disp_info[i].disp, 
  374. X                    disp_info[i].win_id, 0, 0, attr_ret.width,
  375. X                    attr_ret.height, False);
  376. X                             XFlush(disp_info[i].disp);
  377. X
  378. X                         if (disp_info[i].cursor_on == TRUE)
  379. X                         {/*we must turn it BACK ON, because XClear offed*/
  380. X                              XDrawLine(disp_info[i].disp, 
  381. X                         disp_info[i].win_id,
  382. X                         disp_info[i].cursor_gc, 
  383. X                         disp_info[i].cur_pos.x, 
  384. X                         disp_info[i].cur_pos.y, 
  385. X                         disp_info[i].cur_pos.x + 
  386. X                         disp_info[i].prompt_width, 
  387. X                         disp_info[i].cur_pos.y);
  388. X                             }
  389. X             }
  390. X                 }
  391. X             NOTHING_DRAWN_YET = TRUE;
  392. X             break;
  393. X         case 8:          /*dotted line (not a valid choice)*/
  394. X             break;
  395. X         case 9:          /*Add Display*/
  396. X             disp_info[disp_num].previous_scrawl_mode = 
  397. X                             disp_info[disp_num].scrawl_mode;
  398. X                 if (disp_info[disp_num].cursor_on == TRUE)
  399. X                 {
  400. X             disp_info[disp_num].cursor_on = FALSE;
  401. X                      XDrawLine(disp_info[disp_num].disp, 
  402. X                     disp_info[disp_num].win_id,
  403. X                     disp_info[disp_num].cursor_gc, 
  404. X                     disp_info[disp_num].cur_pos.x, 
  405. X                     disp_info[disp_num].cur_pos.y, 
  406. X                     disp_info[disp_num].cur_pos.x + 
  407. X                     disp_info[disp_num].prompt_width, 
  408. X                     disp_info[disp_num].cur_pos.y);
  409. X                     }
  410. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  411. X                         (*num_people_drawing)--;  /*stopped input for now*/
  412. X             XDefineCursor(disp_info[disp_num].disp,
  413. X                           disp_info[disp_num].win_id,
  414. X                       XCreateFontCursor(disp_info[disp_num].disp, 
  415. X                      XC_cross));
  416. X             disp_info[disp_num].dialog_reply_index = 0;
  417. X             disp_info[disp_num].dialog_text_prompt = 
  418. X                               "Enter Display To Add:";
  419. X             put_up_dialog(disp_num);
  420. X             disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG;
  421. X             disp_info[disp_num].dialog_what = ADD_A_DISPLAY;
  422. X             break;
  423. X         case 10:          /*close window. Succeed from the session*/
  424. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  425. X                         (*num_people_drawing)--;  /*stopped input for now*/
  426. X                     XDestroyWindow(disp_info[disp_num].disp, 
  427. X                    disp_info[disp_num].win_id);
  428. X                     disp_info[disp_num].in_session_bool = FALSE; /*no window*/
  429. X                     XCloseDisplay(disp_info[disp_num].disp);
  430. X                     for (i=temp_num=0; i< num_of_disps; i++)
  431. X                     {
  432. X                        if (disp_info[i].in_session_bool)
  433. X                    {
  434. X                        temp_num = TRUE;
  435. X                        break;
  436. X                    }
  437. X                 }
  438. X                 if (temp_num)
  439. X             {
  440. X                         for (i=0; i<num_of_disps; i++)
  441. X                     {
  442. X                         if (disp_info[i].in_session_bool)
  443. X                             place_and_draw_status_win(i);
  444. X                     }
  445. X             }
  446. X             else
  447. X                    exit(0);/*if no one is still in session, stop running*/
  448. X             break;
  449. X         }
  450. X         break;
  451. X     case 1:                       /*PenColor menu*/
  452. X         strncpy(disp_info[disp_num].pen_color_str, menu_text[1][item_num],
  453. X             40);
  454. X         disp_info[disp_num].menu[menu_num].checked_item = item_num;
  455. X         for (i=0; i<num_of_disps; i++)
  456. X         {
  457. X                 if (disp_info[i].in_session_bool)
  458. X             {
  459. X                     if (!XAllocNamedColor(disp_info[i].disp, DefaultColormap(
  460. X                 disp_info[i].disp, DefaultScreen(disp_info[i].disp)), 
  461. X                 menu_text[1][item_num], &scrn_def_ret, &exact_def_ret))
  462. X                 {
  463. X                 continue;        /*sorry, no good. No colors left.*/
  464. X                 }
  465. X                     gcvalues.foreground = scrn_def_ret.pixel;
  466. X             XChangeGC(disp_info[i].disp, 
  467. X                   disp_info[disp_num].win_gc[i], GCForeground, 
  468. X                   &gcvalues);
  469. X         }
  470. X         }
  471. X         break;
  472. X     case 2:                       /*PenWidth menu*/
  473. X         sscanf(menu_text[2][item_num], "%d", &temp_num);
  474. X         disp_info[disp_num].pen_width = temp_num;
  475. X         disp_info[disp_num].menu[menu_num].checked_item = item_num;
  476. X         switch(disp_info[disp_num].scrawl_mode)
  477. X         {
  478. X         case SCRAWLING: 
  479. X                 disp_info[disp_num].pen_widths.scrawl = temp_num;
  480. X             break;
  481. X         case AIRBRUSHING: 
  482. X                 disp_info[disp_num].pen_widths.airbrush = temp_num;
  483. X             break;
  484. X         case ERASING: 
  485. X                 disp_info[disp_num].pen_widths.eraser = temp_num;
  486. X             break;
  487. X         case SELECTING_AN_AREA: 
  488. X                 disp_info[disp_num].pen_widths.shape = temp_num;
  489. X             break;
  490. X         default: 
  491. X             break;
  492. X         }
  493. X             
  494. X         for (i=0; i<num_of_disps; i++)
  495. X         {
  496. X                 if (disp_info[i].in_session_bool)
  497. X             {
  498. X                     gcvalues.line_width = temp_num;
  499. X                 XChangeGC(disp_info[i].disp, 
  500. X               disp_info[disp_num].win_gc[i], 
  501. X               GCLineWidth, &gcvalues);
  502. X         }
  503. X         }
  504. X         break;
  505. X     case 3:                       /*PenCapStyle menu*/
  506. X             switch(item_num)
  507. X         {
  508. X         case 1: temp_num = CapRound; break;
  509. X         case 2: temp_num = CapButt; break;
  510. X         case 3: temp_num = CapNotLast; break;
  511. X         case 4: temp_num = CapProjecting; break;
  512. X         }
  513. X         disp_info[disp_num].capstyle = temp_num;
  514. X         disp_info[disp_num].menu[menu_num].checked_item = item_num;
  515. X         for (i=0; i<num_of_disps; i++)
  516. X         {
  517. X                 if (disp_info[i].in_session_bool)
  518. X             {
  519. X                     gcvalues.cap_style = temp_num;
  520. X                 XChangeGC(disp_info[i].disp, 
  521. X               disp_info[disp_num].win_gc[i], 
  522. X               GCCapStyle, &gcvalues);
  523. X         }
  524. X         }
  525. X         break;
  526. X     case 4:                       /*Font menu*/
  527. X         strncpy(disp_info[disp_num].font_str, menu_text[4][item_num],
  528. X             250);
  529. X
  530. X         for (i=0; i<num_of_disps; i++)
  531. X         {
  532. X                 if (disp_info[i].in_session_bool)
  533. X             {
  534. X                 if ((the_font_struct=XLoadQueryFont(disp_info[i].disp,
  535. X                      menu_text[4][item_num])) != NULL)
  536. X                 {
  537. X                     gcvalues.font = the_font_struct->fid;
  538. X                     disp_info[disp_num].the_font_struct = 
  539. X                                  the_font_struct;
  540. X                             gcvalues.font = the_font_struct->fid;
  541. X                     XChangeGC(disp_info[i].disp, 
  542. X                           disp_info[disp_num].win_gc[i], GCFont, 
  543. X                           &gcvalues);
  544. X                 }
  545. X             else if (load_moron_fonts(disp_num, i, 
  546. X                  menu_text[4][item_num]) == FALSE)
  547. X             {
  548. X                 printf("Couldn't allocate font.\n");
  549. X             }
  550. X         }
  551. X         }
  552. X
  553. X         if (disp_info[disp_num].cursor_on == TRUE)     /*turn it off   */
  554. X         {                            /*and don't tell*/
  555. X                 XDrawLine(disp_info[disp_num].disp, 
  556. X             disp_info[disp_num].win_id,
  557. X                 disp_info[disp_num].cursor_gc, 
  558. X                 disp_info[disp_num].cur_pos.x, 
  559. X                 disp_info[disp_num].cur_pos.y, 
  560. X                 disp_info[disp_num].cur_pos.x + 
  561. X                 disp_info[disp_num].prompt_width, 
  562. X                 disp_info[disp_num].cur_pos.y);
  563. X             }
  564. X
  565. X             disp_info[disp_num].prompt_width = 
  566. X                   disp_info[disp_num].the_font_struct->max_bounds.width;
  567. X         disp_info[disp_num].char_height = 
  568. X               (disp_info[disp_num].the_font_struct)->max_bounds.ascent +
  569. X               (disp_info[disp_num].the_font_struct)->max_bounds.descent;
  570. X         disp_info[disp_num].type_history = NULL;
  571. X         disp_info[disp_num].menu[menu_num].checked_item = item_num;
  572. X         
  573. X         if (disp_info[disp_num].cursor_on == TRUE)   /*it is really off*/
  574. X         {                                            /*'cause look above*/
  575. X             disp_info[disp_num].cursor_on = TRUE;
  576. X                 XDrawLine(disp_info[disp_num].disp, 
  577. X             disp_info[disp_num].win_id,
  578. X                 disp_info[disp_num].cursor_gc, 
  579. X                 disp_info[disp_num].cur_pos.x, 
  580. X                 disp_info[disp_num].cur_pos.y, 
  581. X                 disp_info[disp_num].cur_pos.x + 
  582. X                 disp_info[disp_num].prompt_width, 
  583. X                 disp_info[disp_num].cur_pos.y);
  584. X             }
  585. X         break;
  586. X     case 5:                       /*Shape menu*/
  587. X         menu_selection(disp_num, 0, num_people_drawing, 5);/*choose shape*/
  588. X         disp_info[disp_num].menu[menu_num].checked_item = item_num;
  589. X             switch(item_num)
  590. X         {
  591. X         case 1: 
  592. X             disp_info[disp_num].current_shape = STRAIGHT_LINE;
  593. X             break;
  594. X         case 2: 
  595. X             disp_info[disp_num].current_shape = OUTLINE_RECT;
  596. X             break;
  597. X         case 3: 
  598. X             disp_info[disp_num].current_shape = FILLED_RECT;
  599. X             break;
  600. X         case 4: 
  601. X             disp_info[disp_num].current_shape = OUTLINE_OVAL;
  602. X             break;
  603. X         case 5: 
  604. X             disp_info[disp_num].current_shape = FILLED_OVAL;
  605. X             break;
  606. X         default: break;
  607. X         }
  608. X         break;
  609. X     case 6:                       /*File I/O menu*/
  610. X             switch(item_num)
  611. X         {
  612. X         case 1:          /*Save Bitmap*/
  613. X                 if (disp_info[disp_num].cursor_on == TRUE)
  614. X                 {
  615. X             disp_info[disp_num].cursor_on = FALSE;
  616. X                      XDrawLine(disp_info[disp_num].disp, 
  617. X                     disp_info[disp_num].win_id,
  618. X                     disp_info[disp_num].cursor_gc, 
  619. X                     disp_info[disp_num].cur_pos.x, 
  620. X                     disp_info[disp_num].cur_pos.y, 
  621. X                     disp_info[disp_num].cur_pos.x + 
  622. X                     disp_info[disp_num].prompt_width, 
  623. X                     disp_info[disp_num].cur_pos.y);
  624. X                     }
  625. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  626. X                         (*num_people_drawing)--;  /*stopped input for now*/
  627. X             disp_info[disp_num].previous_scrawl_mode = 
  628. X                                    disp_info[disp_num].scrawl_mode;
  629. X             disp_info[disp_num].scrawl_mode = SELECTING_AN_AREA;
  630. X             disp_info[disp_num].dialog_what = SAVE_BITMAP;
  631. X             XDefineCursor(disp_info[disp_num].disp,
  632. X                           disp_info[disp_num].win_id,
  633. X                       XCreateFontCursor(disp_info[disp_num].disp, 
  634. X                      XC_crosshair));
  635. X             break;
  636. X         case 2:         /*Read In Bitmap*/
  637. X                 if (disp_info[disp_num].cursor_on == TRUE)
  638. X                 {
  639. X             disp_info[disp_num].cursor_on = FALSE;
  640. X                      XDrawLine(disp_info[disp_num].disp, 
  641. X                     disp_info[disp_num].win_id,
  642. X                     disp_info[disp_num].cursor_gc, 
  643. X                     disp_info[disp_num].cur_pos.x, 
  644. X                     disp_info[disp_num].cur_pos.y, 
  645. X                     disp_info[disp_num].cur_pos.x + 
  646. X                     disp_info[disp_num].prompt_width, 
  647. X                     disp_info[disp_num].cur_pos.y);
  648. X                     }
  649. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  650. X                         (*num_people_drawing)--;  /*stopped input for now*/
  651. X             XDefineCursor(disp_info[disp_num].disp,
  652. X                           disp_info[disp_num].win_id,
  653. X                       XCreateFontCursor(disp_info[disp_num].disp, 
  654. X                      XC_cross));
  655. X             disp_info[disp_num].dialog_reply_index = 0;
  656. X             disp_info[disp_num].dialog_text_prompt = 
  657. X                               "File To Read Bitmap From:";
  658. X             put_up_dialog(disp_num);
  659. X             disp_info[disp_num].previous_scrawl_mode = 
  660. X                                    disp_info[disp_num].scrawl_mode;
  661. X             disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG;
  662. X             disp_info[disp_num].dialog_what = READ_IN_BITMAP;
  663. X             break;
  664. X         case 3:             /*Read Text File*/
  665. X                 if (disp_info[disp_num].cursor_on == TRUE)
  666. X                 {
  667. X             disp_info[disp_num].cursor_on = FALSE;
  668. X                      XDrawLine(disp_info[disp_num].disp, 
  669. X                     disp_info[disp_num].win_id,
  670. X                     disp_info[disp_num].cursor_gc, 
  671. X                     disp_info[disp_num].cur_pos.x, 
  672. X                     disp_info[disp_num].cur_pos.y, 
  673. X                     disp_info[disp_num].cur_pos.x + 
  674. X                     disp_info[disp_num].prompt_width, 
  675. X                     disp_info[disp_num].cur_pos.y);
  676. X                     }
  677. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  678. X                         (*num_people_drawing)--;  /*stopped input for now*/
  679. X             XDefineCursor(disp_info[disp_num].disp,
  680. X                           disp_info[disp_num].win_id,
  681. X                       XCreateFontCursor(disp_info[disp_num].disp, 
  682. X                      XC_cross));
  683. X             disp_info[disp_num].dialog_reply_index = 0;
  684. X             disp_info[disp_num].dialog_text_prompt = 
  685. X                               "File To Read Text From:";
  686. X             put_up_dialog(disp_num);
  687. X             disp_info[disp_num].previous_scrawl_mode = 
  688. X                                    disp_info[disp_num].scrawl_mode;
  689. X             disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG;
  690. X             disp_info[disp_num].dialog_what = READ_TEXTFILE;
  691. X             break;
  692. X         case 4:          /*Save Image*/
  693. X                 if (disp_info[disp_num].cursor_on == TRUE)
  694. X                 {
  695. X             disp_info[disp_num].cursor_on = FALSE;
  696. X                      XDrawLine(disp_info[disp_num].disp, 
  697. X                     disp_info[disp_num].win_id,
  698. X                     disp_info[disp_num].cursor_gc, 
  699. X                     disp_info[disp_num].cur_pos.x, 
  700. X                     disp_info[disp_num].cur_pos.y, 
  701. X                     disp_info[disp_num].cur_pos.x + 
  702. X                     disp_info[disp_num].prompt_width, 
  703. X                     disp_info[disp_num].cur_pos.y);
  704. X                     }
  705. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  706. X                         (*num_people_drawing)--;  /*stopped input for now*/
  707. X             disp_info[disp_num].previous_scrawl_mode = 
  708. X                                    disp_info[disp_num].scrawl_mode;
  709. X             disp_info[disp_num].scrawl_mode = SELECTING_AN_AREA;
  710. X             disp_info[disp_num].dialog_what = SAVE_IMAGE;
  711. X             XDefineCursor(disp_info[disp_num].disp,
  712. X                           disp_info[disp_num].win_id,
  713. X                       XCreateFontCursor(disp_info[disp_num].disp, 
  714. X                      XC_crosshair));
  715. X             break;
  716. X         case 5:         /*Read In Image*/
  717. X                 if (disp_info[disp_num].cursor_on == TRUE)
  718. X                 {
  719. X             disp_info[disp_num].cursor_on = FALSE;
  720. X                      XDrawLine(disp_info[disp_num].disp, 
  721. X                     disp_info[disp_num].win_id,
  722. X                     disp_info[disp_num].cursor_gc, 
  723. X                     disp_info[disp_num].cur_pos.x, 
  724. X                     disp_info[disp_num].cur_pos.y, 
  725. X                     disp_info[disp_num].cur_pos.x + 
  726. X                     disp_info[disp_num].prompt_width, 
  727. X                     disp_info[disp_num].cur_pos.y);
  728. X                     }
  729. X             if (disp_info[disp_num].scrawl_mode == TYPING)
  730. X                         (*num_people_drawing)--;  /*stopped input for now*/
  731. X             XDefineCursor(disp_info[disp_num].disp,
  732. X                           disp_info[disp_num].win_id,
  733. X                       XCreateFontCursor(disp_info[disp_num].disp, 
  734. X                      XC_cross));
  735. X             disp_info[disp_num].dialog_reply_index = 0;
  736. X             disp_info[disp_num].dialog_text_prompt = 
  737. X                               "File To Read Image From:";
  738. X             put_up_dialog(disp_num);
  739. X             disp_info[disp_num].previous_scrawl_mode = 
  740. X                                    disp_info[disp_num].scrawl_mode;
  741. X             disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG;
  742. X             disp_info[disp_num].dialog_what = READ_IN_IMAGE;
  743. X             break;
  744. X         }
  745. X         break;
  746. X     default:
  747. X         printf("ERROR: Unknown menu number in menu_selection().\n");
  748. X         exit(0);
  749. X         break;
  750. X     }
  751. X}
  752. X
  753. X
  754. X/*
  755. X * draw_menu_text - this function draws the menu contents such as text 
  756. X *              and checkmarks as specified by the display and the menu_num. 
  757. X *              This is usually called in response to an expose event, etc.
  758. X */
  759. Xdraw_menu_text(disp_num, menu_num)
  760. Xint disp_num, menu_num;
  761. X{
  762. X    int i;
  763. X
  764. X    /*
  765. X     * draw the bar under the menu heading
  766. X     */
  767. X    XDrawLine(disp_info[disp_num].disp,
  768. X          disp_info[disp_num].menu[menu_num].win_id,
  769. X          disp_info[disp_num].fg_menu_gc, 0, MENU_ITEM_HEIGHT+1, 
  770. X          MENU_ITEM_WIDTH, MENU_ITEM_HEIGHT+1);
  771. X
  772. X    /*
  773. X     * draw all the text
  774. X     */
  775. X    for (i=0; i<disp_info[disp_num].menu[menu_num].num_items; i++)
  776. X    {
  777. X        XDrawString(disp_info[disp_num].disp,
  778. X           disp_info[disp_num].menu[menu_num].win_id, 
  779. X           disp_info[disp_num].fg_menu_gc, 15, i*MENU_ITEM_HEIGHT + 18, 
  780. X           menu_text[menu_num][i], strlen(menu_text[menu_num][i]));
  781. X    }
  782. X
  783. X    /*
  784. X     * draw the check mark of the current menu as long as the menu has a check
  785. X     */
  786. X    if (menu_num != 6)
  787. X    {
  788. X        XDrawLine(disp_info[disp_num].disp,
  789. X          disp_info[disp_num].menu[menu_num].win_id,
  790. X          disp_info[disp_num].fg_menu_gc, 4, 
  791. X          disp_info[disp_num].menu[menu_num].checked_item * 
  792. X          MENU_ITEM_HEIGHT + 15, 
  793. X          7, disp_info[disp_num].menu[menu_num].checked_item * 
  794. X          MENU_ITEM_HEIGHT + 18);
  795. X        XDrawLine(disp_info[disp_num].disp,
  796. X          disp_info[disp_num].menu[menu_num].win_id,
  797. X          disp_info[disp_num].fg_menu_gc, 7, 
  798. X          disp_info[disp_num].menu[menu_num].checked_item * 
  799. X          MENU_ITEM_HEIGHT + 18, 
  800. X          12, disp_info[disp_num].menu[menu_num].checked_item * 
  801. X          MENU_ITEM_HEIGHT + 9);
  802. X    }
  803. X    XFlush(disp_info[disp_num].disp);
  804. X}
  805. X
  806. X
  807. X/*
  808. X * draw_menu - this function draws the menus on the display whose index is
  809. X *              passed as the argument.  This function is invoked usually
  810. X *              when someone has just boinked the menu, causing it to unroll
  811. X *              out with all the choices.  It can also be invoked when someone
  812. X *              has let up the mouse button, probably making a choice. 
  813. X *              The "current_menu" field of the disp_info struct should be
  814. X *              set to the menu which changed.
  815. X */
  816. Xdraw_menu(disp_num)
  817. Xint disp_num;
  818. X{
  819. X    int menu_num;
  820. X    XWindowChanges new_dim;
  821. X
  822. X    menu_num = disp_info[disp_num].current_menu;
  823. X
  824. X    if (disp_info[disp_num].pointer_state != IN_MENU)    /*retract menu*/
  825. X    {
  826. X        new_dim.height = MENU_ITEM_HEIGHT;
  827. X    }
  828. X    else                                                 /*extend a menu*/
  829. X    {
  830. X        new_dim.height = disp_info[disp_num].menu[menu_num].num_items * 
  831. X             MENU_ITEM_HEIGHT;
  832. X    }
  833. X    XConfigureWindow(disp_info[disp_num].disp, 
  834. X           disp_info[disp_num].menu[menu_num].win_id, CWHeight, &new_dim);
  835. X
  836. X    /*
  837. X     * The following is commented out because an expose event will occur,
  838. X     * causing the menu text to be displayed WITHOUT this line.  Why keep
  839. X     * it here you ask me?  Well, I can't answer that; it would reveal the
  840. X     * location of insidious bugs in certain HP systems.  :-)
  841. X     */
  842. X    /*
  843. X    draw_menu_text(disp_num, menu_num);
  844. X     */
  845. X}
  846. X
  847. X
  848. X/*
  849. X * slide_rubberband_box - this function waves the fixed size rubberband
  850. X *                  box all over the window, waiting for the user to
  851. X *                  click the button, thus placing the bitmap or image on all
  852. X *                  of the displays.
  853. X */
  854. Xslide_rubberband_box(disp_num, num_people_drawing)
  855. Xint disp_num, *num_people_drawing;
  856. X{
  857. X    Window rr, cr;          /* <-- These here are good variables, buckwheat.*/
  858. X    unsigned int mskr;
  859. X    int rxr, ryr, win_x, win_y;
  860. X    int top, left, width, height, old_top, old_left;
  861. X
  862. X    width = disp_info[disp_num].rubber_band_width;
  863. X    height = disp_info[disp_num].rubber_band_height;
  864. X
  865. X    if (disp_info[disp_num].first_point_bool)
  866. X    {  
  867. X        XQueryPointer(disp_info[disp_num].disp, 
  868. X              disp_info[disp_num].win_id, &rr, &cr, &rxr, 
  869. X              &ryr, &win_x, &win_y,&mskr);
  870. X        disp_info[disp_num].cur_pos.x = win_x;
  871. X        disp_info[disp_num].cur_pos.y = win_y;
  872. X        disp_info[disp_num].first_point_bool = FALSE;
  873. X        (*num_people_drawing)++;     /*slide this around till you click*/
  874. X
  875. X    top = disp_info[disp_num].cur_pos.y - 
  876. X                    disp_info[disp_num].rubber_band_height/2;
  877. X    left = disp_info[disp_num].cur_pos.x - 
  878. X                    disp_info[disp_num].rubber_band_width/2;
  879. X
  880. X    XDrawRectangle(disp_info[disp_num].disp, disp_info[disp_num].win_id,
  881. X           disp_info[disp_num].rubber_band_gc,
  882. X           left, top, width, height);
  883. X        XFlush(disp_info[disp_num].disp);
  884. X    }
  885. X
  886. X    XQueryPointer(disp_info[disp_num].disp, 
  887. X              disp_info[disp_num].win_id, &rr, &cr, &rxr, 
  888. X              &ryr, &win_x, &win_y,&mskr);
  889. X    if ((disp_info[disp_num].cur_pos.x != win_x) ||
  890. X        (disp_info[disp_num].cur_pos.y != win_y))
  891. X    {
  892. X    /*
  893. X     * erase the old rubber band box
  894. X     */
  895. X    old_top = disp_info[disp_num].cur_pos.y - 
  896. X                    disp_info[disp_num].rubber_band_height/2;
  897. X    old_left = disp_info[disp_num].cur_pos.x - 
  898. X                    disp_info[disp_num].rubber_band_width/2;
  899. X    XDrawRectangle(disp_info[disp_num].disp, disp_info[disp_num].win_id,
  900. X           disp_info[disp_num].rubber_band_gc,
  901. X           old_left, old_top, width, height);
  902. X    /*
  903. X     * draw the new rubber band box
  904. X     */
  905. X        disp_info[disp_num].cur_pos.x = win_x;
  906. X        disp_info[disp_num].cur_pos.y = win_y;
  907. X    top = disp_info[disp_num].cur_pos.y - height/2;
  908. X    left = disp_info[disp_num].cur_pos.x - width/2;
  909. X    XDrawRectangle(disp_info[disp_num].disp, disp_info[disp_num].win_id,
  910. X           disp_info[disp_num].rubber_band_gc, left, top, width, height);
  911. X    }
  912. X}
  913. X
  914. X
  915. X/*
  916. X * type_on_dialog - this routine is called once a cycle if the user is 
  917. X *                  currently supposed to be typing in the dialog box.
  918. X *                  This function handles the text, etc.
  919. X *                  Global index: disp_info[disp_num].dialog_reply_index
  920. X */
  921. Xtype_on_dialog(disp_num)
  922. Xint disp_num;
  923. X{
  924. X    XEvent the_event;
  925. X    KeySym ksr;
  926. X    char the_char[256];
  927. X    int index;
  928. X
  929. X    if (XPending(disp_info[disp_num].disp))   /*check if there is a KeyPress*/
  930. X    {
  931. X    XNextEvent(disp_info[disp_num].disp, &the_event);
  932. X        if (the_event.type != KeyPress)
  933. X    {
  934. X            XPutBackEvent(disp_info[disp_num].disp, &the_event);
  935. X        return(0);
  936. X    }
  937. X    else    /*it IS a KeyPressedEvent*/
  938. X    {
  939. X        index = disp_info[disp_num].dialog_reply_index;
  940. X            the_char[0] = 0;
  941. X            XLookupString((XKeyEvent *) (&the_event),the_char,10, &ksr, NULL);
  942. X            if (the_char[0] == 0)
  943. X                return(0);                /*it was a shift or some such*/
  944. X            else if (the_char[0] == 8)  /*8 == Backspace*/
  945. X            {
  946. X        if (index != 0)
  947. X        {
  948. X            index--;
  949. X                    (disp_info[disp_num].dialog_reply_index)--;
  950. X             XClearArea(disp_info[disp_num].disp,
  951. X                        disp_info[disp_num].dialog_win_id, 
  952. X                14 + index*FIXED_CHAR_WIDTH, DIALOG_WIN_HEIGHT-27,
  953. X                FIXED_CHAR_WIDTH, 19, False);
  954. X        }
  955. X        }
  956. X            else if (the_char[0] == 13)   /*13 == Carriage Return*/
  957. X            {
  958. X            /*unmap dialog and take action*/
  959. X                XUnmapWindow(disp_info[disp_num].disp, 
  960. X               disp_info[disp_num].dialog_win_id);
  961. X        XSync(disp_info[disp_num].disp, False);
  962. X        disp_info[disp_num].dialog_text_return[index] = '\0';
  963. X        parse_and_fix_dialog_text(disp_num);
  964. X        do_dialog_action(disp_num);
  965. X        }
  966. X            else
  967. X        {
  968. X        XDrawString(disp_info[disp_num].disp, 
  969. X            disp_info[disp_num].dialog_win_id,
  970. X            disp_info[disp_num].fg_menu_gc, 
  971. X            14 + index*FIXED_CHAR_WIDTH, DIALOG_WIN_HEIGHT - 12,
  972. X            the_char, 1);
  973. X        disp_info[disp_num].dialog_text_return[index] = the_char[0];
  974. X        (disp_info[disp_num].dialog_reply_index)++;
  975. X        }
  976. X        }
  977. X    }
  978. X}
  979. X
  980. X
  981. X/*
  982. X * parse_and_fix_dialog_text - this function parses the dialog text
  983. X *                  and replaces anything like a tilda or etc with the
  984. X *                  appropriate environment variable or string.
  985. X */
  986. Xparse_and_fix_dialog_text(disp_num)
  987. Xint disp_num;
  988. X{
  989. X    char temp_str[512], temp_str2[512], current_line[512], login_name[512];
  990. X    char temp_str3[512];
  991. X    char *tmp_ptr;
  992. X    int index, i, c, length_name;
  993. X    FILE *fp;
  994. X
  995. X    strncpy(temp_str, disp_info[disp_num].dialog_text_return, 510);
  996. X
  997. X    for (index=0; temp_str[index] != '\0'; index++)
  998. X    if (temp_str[index] != ' ')
  999. X        break;
  1000. X
  1001. X    if ((temp_str[index] == '~') && (temp_str[index+1] == '/'))
  1002. X    {
  1003. X    strncpy(temp_str2, getenv("HOME"), 250);
  1004. X    strncat(temp_str2, (char *)&(temp_str[index+1]), 250);
  1005. X    strncpy(disp_info[disp_num].dialog_text_return, temp_str2, 510);
  1006. X    disp_info[disp_num].dialog_reply_index = strlen(temp_str2);
  1007. X    return(1);
  1008. X    }
  1009. X    else if (temp_str[index] == '~')
  1010. X    {
  1011. X    for (i=index+1; (temp_str[i] != '/') && (temp_str[i] != '\0'); i++)
  1012. X            login_name[i-index-1] = temp_str[i];
  1013. X    login_name[i-index-1] = '\0';
  1014. X        length_name = strlen(login_name);
  1015. X
  1016. X        if ((fp = fopen("/etc/passwd", "r")) == NULL)
  1017. X        {
  1018. X            printf("ERROR: Could not open /etc/passwd.\n");
  1019. X        return(0);
  1020. X    }
  1021. X    while ((c = getc(fp)) != EOF)
  1022. X    {
  1023. X        ungetc(c, fp);
  1024. X        fgets(current_line, 510, fp);       /*get the line*/
  1025. X        strncpy(temp_str2, current_line, length_name);
  1026. X        temp_str2[length_name] = '\0';
  1027. X            if (strcmp(temp_str2, login_name) == 0)    /*this is the line*/
  1028. X        {
  1029. X                tmp_ptr = &strpbrk(&strpbrk(&strpbrk(&strpbrk(&strpbrk(
  1030. X                           current_line, ":")[1], 
  1031. X                   ":")[1], ":")[1], ":")[1], ":")[1];
  1032. X
  1033. X        for (i=0; tmp_ptr[i] != ':'; i++)
  1034. X             temp_str2[i] = tmp_ptr[i];
  1035. X        temp_str2[i] = '\0';
  1036. X
  1037. X            sprintf(temp_str3, "%s%s", temp_str2, 
  1038. X            (char *)&(temp_str[index+1+length_name]));
  1039. X                fclose(fp);
  1040. X
  1041. X            strncpy(disp_info[disp_num].dialog_text_return, temp_str3, 510);
  1042. X            disp_info[disp_num].dialog_reply_index = strlen(temp_str3);
  1043. X                return(1);
  1044. X        }
  1045. X    }
  1046. X        fclose(fp);
  1047. X    printf("ERROR: user specified was not found in /etc/passwd.\n");
  1048. X    return(0);
  1049. X    }
  1050. X}
  1051. X
  1052. X
  1053. X/*
  1054. X * type_on_screens - this function types on the screens of all the people
  1055. X *                   by reading if any keys have been depressed, and if so,
  1056. X *                   it puts that character up on all the displays currently
  1057. X *                   open.  <-- Darn smart, eh?  You probably couldn't have
  1058. X *                   figured out that on your own.  ;-)
  1059. X */
  1060. Xtype_on_screens(input_disp)
  1061. Xint input_disp;
  1062. X{
  1063. X    XEvent the_event;
  1064. X    Window rr, cr;                 /* <-- These here are variables, son.*/
  1065. X    KeySym ksr;
  1066. X    unsigned int mskr;
  1067. X    int i, rxr, ryr, win_x, win_y;
  1068. X    char the_char[256];
  1069. X
  1070. X    if (disp_info[input_disp].first_point_bool)
  1071. X    {
  1072. X        XQueryPointer(disp_info[input_disp].disp, 
  1073. X              disp_info[input_disp].win_id, &rr, &cr, &rxr, 
  1074. X              &ryr, &win_x, &win_y,&mskr);
  1075. X    disp_info[input_disp].orig_x = win_x;
  1076. X        disp_info[input_disp].cur_pos.x = win_x;
  1077. X        disp_info[input_disp].cur_pos.y = win_y;
  1078. X        disp_info[input_disp].first_point_bool = FALSE;
  1079. X        disp_info[input_disp].prompt_width = 
  1080. X             disp_info[input_disp].the_font_struct->max_bounds.width;
  1081. X    disp_info[input_disp].char_height = 
  1082. X       (disp_info[input_disp].the_font_struct)->max_bounds.ascent +
  1083. X       (disp_info[input_disp].the_font_struct)->max_bounds.descent;
  1084. X    disp_info[input_disp].type_history = NULL;
  1085. X
  1086. X    /*draw the cursor*/
  1087. X    disp_info[input_disp].cursor_on = TRUE;
  1088. X    XDrawLine(disp_info[input_disp].disp, disp_info[input_disp].win_id,
  1089. X          disp_info[input_disp].cursor_gc, 
  1090. X          disp_info[input_disp].cur_pos.x, 
  1091. X          disp_info[input_disp].cur_pos.y, 
  1092. X          disp_info[input_disp].cur_pos.x + 
  1093. X          disp_info[input_disp].prompt_width, 
  1094. X          disp_info[input_disp].cur_pos.y);
  1095. X    }
  1096. X
  1097. X    if (XPending(disp_info[input_disp].disp))  /*check if there is a KeyPress*/
  1098. X    {
  1099. X    XNextEvent(disp_info[input_disp].disp, &the_event);
  1100. X        if (the_event.type != KeyPress)
  1101. X    {
  1102. X            XPutBackEvent(disp_info[input_disp].disp, &the_event);
  1103. X        return(0);
  1104. X    }
  1105. X    else    /*it IS a KeyPressedEvent*/
  1106. X    {
  1107. X            the_char[0] = 0;
  1108. X            XLookupString((XKeyEvent *) (&the_event),the_char,10, &ksr, NULL);
  1109. X            if (the_char[0] == 0)
  1110. X                return(0);                /*it was a shift or some such*/
  1111. X            if (the_char[0] == 13)        /*13 == Carriage Return*/
  1112. X            {
  1113. X            /*erase the cursor*/
  1114. X            disp_info[input_disp].cursor_on = FALSE;
  1115. X            XDrawLine(disp_info[input_disp].disp, 
  1116. X          disp_info[input_disp].win_id,
  1117. X          disp_info[input_disp].cursor_gc, 
  1118. X          disp_info[input_disp].cur_pos.x, 
  1119. X          disp_info[input_disp].cur_pos.y, 
  1120. X          disp_info[input_disp].cur_pos.x + 
  1121. END_OF_FILE
  1122. if test 37771 -ne `wc -c <'wscrawl/xac'`; then
  1123.     echo shar: \"'wscrawl/xac'\" unpacked with wrong size!
  1124. fi
  1125. # end of 'wscrawl/xac'
  1126. fi
  1127. echo shar: End of archive 2 \(of 5\).
  1128. cp /dev/null ark2isdone
  1129. MISSING=""
  1130. for I in 1 2 3 4 5 ; do
  1131.     if test ! -f ark${I}isdone ; then
  1132.     MISSING="${MISSING} ${I}"
  1133.     fi
  1134. done
  1135. if test "${MISSING}" = "" ; then
  1136.     echo You have unpacked all 5 archives.
  1137.     rm -f ark[1-9]isdone
  1138. else
  1139.     echo You still need to unpack the following archives:
  1140.     echo "        " ${MISSING}
  1141. fi
  1142. ##  End of shell archive.
  1143. exit 0
  1144. dan
  1145. ----------------------------------------------------
  1146. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1147. Opinions expressed reflect those of the author only.
  1148.