HyperText.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: HyperText.c /main/9 1999/10/14 14:45:38 mgreess $ */
  24. /************************************<+>*************************************
  25. ****************************************************************************
  26. **
  27. ** File: HyperText.c
  28. **
  29. ** Project: Text Graphic Display Library
  30. **
  31. ** Description: This body of code does all the work for hypertext links
  32. **
  33. **
  34. ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
  35. **
  36. ** (c) Copyright 1993, 1994 Hewlett-Packard Company
  37. ** (c) Copyright 1993, 1994 International Business Machines Corp.
  38. ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  39. ** (c) Copyright 1993, 1994 Novell, Inc.
  40. **
  41. **
  42. **
  43. ****************************************************************************
  44. ************************************<+>*************************************/
  45. /*
  46. * system includes
  47. */
  48. #include <errno.h>
  49. #include <signal.h>
  50. #include <stdlib.h>
  51. #ifdef _AIX
  52. #include <sys/select.h>
  53. #endif
  54. #include <sys/time.h>
  55. #include <sys/types.h>
  56. #include <unistd.h>
  57. #include <sys/wait.h>
  58. #include <Xm/DialogS.h>
  59. /*
  60. * Canvas Engine
  61. */
  62. #include "CanvasP.h"
  63. /*
  64. * private includes
  65. */
  66. #include "HelpErrorP.h"
  67. #include "DisplayAreaP.h"
  68. #include "DisplayAreaI.h"
  69. #include "FontI.h"
  70. #include "HourGlassI.h"
  71. #include "HyperTextI.h"
  72. #include "HelposI.h"
  73. #ifdef NLS16
  74. #endif
  75. /******** Private Function Declarations ********/
  76. static void ProcessEvents (
  77. DtHelpDispAreaStruct *pDAS,
  78. pid_t child_pid,
  79. Boolean child_flag);
  80. /******** End Private Function Declarations ********/
  81. /*********************************************************************
  82. * Private Variables
  83. *********************************************************************/
  84. typedef struct {
  85. char *link_spec;
  86. int type;
  87. char *descrip;
  88. } HyperList;
  89. /*********************************************************************
  90. * Private Functions
  91. *********************************************************************/
  92. /*********************************************************************
  93. * ProcessEvents
  94. *
  95. * ProcessEvents will do a select on the socket until the child
  96. * dies.
  97. *
  98. *********************************************************************/
  99. static void
  100. ProcessEvents (
  101. DtHelpDispAreaStruct *pDAS,
  102. pid_t child_pid,
  103. Boolean child_flag)
  104. {
  105. int result;
  106. int rMask;
  107. int myFd;
  108. pid_t pid;
  109. struct timeval *topPtr;
  110. struct timeval toStruct;
  111. Display *dpy = XtDisplay (pDAS->dispWid);
  112. XEvent event;
  113. /*
  114. * set a small time out.
  115. */
  116. toStruct.tv_usec = 500000; /* 500 miliseconds */
  117. toStruct.tv_sec = 0;
  118. topPtr = &toStruct;
  119. /*
  120. * get the socket's file descriptor
  121. */
  122. myFd = ConnectionNumber (dpy);
  123. do
  124. {
  125. rMask = (1 << (myFd % 32)); /* on t.o. select will clear */
  126. if (!XPending(dpy))
  127. {
  128. #if 0
  129. result = select(myFd+1, &rMask, 0, 0, topPtr);
  130. #else
  131. result = select(myFd+1, ((fd_set *)&rMask), 0, 0, topPtr);
  132. #endif
  133. /*
  134. * check to see if the select happened because of
  135. * a system interrupt.
  136. */
  137. /*
  138. * otherwise an exposure event happened.
  139. * fall through and XPending will be true,
  140. * forcing us to go to the XmUpdateDisplay call.
  141. */
  142. }
  143. else
  144. {
  145. /*
  146. * SYSTEM - Use XtDisplatchEvent????
  147. */
  148. XNextEvent (dpy, &event);
  149. if (event.type == Expose)
  150. XmUpdateDisplay (pDAS->dispWid);
  151. }
  152. /*
  153. * check to see if the child is still going
  154. */
  155. pid = waitpid (child_pid, (int *) 0, WNOHANG);
  156. if (pid == child_pid || pid == -1)
  157. child_flag = True;
  158. } while (!child_flag);
  159. }
  160. /*********************************************************************
  161. * Internal Public Functions
  162. *********************************************************************/
  163. /*********************************************************************
  164. * _DtHelpExecProcedure
  165. *
  166. * _DtHelpExecProcedure will fork/exec the command passed in. It will
  167. * then allow only exposure events to be processed until the
  168. * child dies.
  169. *
  170. *********************************************************************/
  171. void
  172. _DtHelpExecProcedure (
  173. XtPointer client_data,
  174. char *cmd )
  175. {
  176. pid_t pid;
  177. XWindowAttributes attr;
  178. char *pShell = "sh";
  179. Widget shellWidget;
  180. Boolean childFlag = False;
  181. pid_t childPid;
  182. DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
  183. /*
  184. * Turn on the wait cursor.
  185. */
  186. shellWidget = pDAS->dispWid;
  187. while (!XtIsSubclass(shellWidget, xmDialogShellWidgetClass))
  188. shellWidget = XtParent(shellWidget);
  189. _DtHelpTurnOnHourGlass(shellWidget);
  190. /*
  191. * Get the window event mask via the window attributes. Remember it.
  192. * Set the Input to only Exposure events.
  193. */
  194. XGetWindowAttributes (XtDisplay(pDAS->dispWid), XtWindow (pDAS->dispWid),
  195. &attr);
  196. XSelectInput (XtDisplay(pDAS->dispWid), XtWindow (pDAS->dispWid),
  197. ExposureMask);
  198. XSync (XtDisplay(pDAS->dispWid), 0);
  199. /*
  200. * initialize the global flag and variable.
  201. */
  202. childPid = -1;
  203. childFlag = False;
  204. /*
  205. * fork a child process.
  206. */
  207. childPid = fork ();
  208. /*
  209. * If the child, exec the cmd with a shell parent
  210. * so if the cmd ends in an ampersand, the command
  211. * will be put in the background and the shell will
  212. * die and return, creating a SIGCLD for us to catch.
  213. */
  214. if (childPid == 0)
  215. {
  216. execlp (pShell, pShell, "-c", cmd, ((char *) 0));
  217. _exit (1);
  218. }
  219. /*
  220. * Check to make sure the vfork was successful.
  221. */
  222. if (childPid != -1)
  223. {
  224. /*
  225. * check to see if the child is still going
  226. */
  227. pid = waitpid (childPid, (int *) 0, WNOHANG);
  228. if (!(pid == childPid || pid == -1))
  229. /*
  230. * process the exposure events in a special routine.
  231. */
  232. ProcessEvents (pDAS, childPid, childFlag);
  233. }
  234. /*
  235. * reset the input mask
  236. */
  237. XSelectInput (XtDisplay(pDAS->dispWid), XtWindow (pDAS->dispWid),
  238. (attr.your_event_mask));
  239. /*
  240. * turn off the wait cursor
  241. */
  242. _DtHelpTurnOffHourGlass(shellWidget);
  243. } /* End _DtHelpExecProcedure */
  244. /*********************************************************************
  245. * Function: _DtHelpProcessHyperSelection
  246. *
  247. * Determine if the user selected a segment that is a hypertext
  248. * link. If so, call the appropriate function to process it.
  249. *
  250. *********************************************************************/
  251. void
  252. _DtHelpProcessHyperSelection (
  253. XtPointer client_data,
  254. int downX,
  255. int downY,
  256. XEvent *event )
  257. {
  258. int upX;
  259. int upY;
  260. _DtCvLinkInfo ceHyper;
  261. DtHelpHyperTextStruct callData;
  262. DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
  263. if (pDAS->hyperCall == NULL)
  264. return;
  265. downY = downY + pDAS->firstVisible - pDAS->decorThickness;
  266. downX = downX + pDAS->virtualX - pDAS->decorThickness;
  267. upX = event->xbutton.x + pDAS->virtualX - pDAS->decorThickness;
  268. upY = event->xbutton.y + pDAS->firstVisible - pDAS->decorThickness;
  269. /*
  270. * turn off the old traversal
  271. */
  272. if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
  273. {
  274. pDAS->toc_flag |= _DT_HELP_DRAW_TOC_IND;
  275. _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_OFF, False,
  276. (XtIsRealized(pDAS->dispWid) ? True : False),
  277. NULL, NULL, NULL, NULL, NULL);
  278. }
  279. if (_DtCvSTATUS_OK ==
  280. _DtCanvasGetPosLink(pDAS->canvas,downX,downY,upX,upY,&ceHyper))
  281. {
  282. /*
  283. * turn the traversal on for the selected hyptext link.
  284. */
  285. if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
  286. {
  287. pDAS->toc_flag |= _DT_HELP_DRAW_TOC_IND;
  288. _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_ID, False,
  289. (XtIsRealized(pDAS->dispWid) ? True : False),
  290. ceHyper.specification,
  291. NULL, NULL, NULL, NULL);
  292. }
  293. callData.reason = XmCR_ACTIVATE;
  294. callData.event = event;
  295. callData.window = XtWindow (pDAS->dispWid);
  296. callData.specification = ceHyper.specification;
  297. callData.hyper_type = ceHyper.hyper_type;
  298. callData.window_hint = ceHyper.win_hint;
  299. (*(pDAS->hyperCall)) (pDAS, pDAS->clientData, &callData);
  300. }
  301. else if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
  302. /*
  303. * turn the traversal back on
  304. */
  305. _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_ON, False,
  306. (XtIsRealized(pDAS->dispWid) ? True : False),
  307. NULL, NULL, NULL, NULL, NULL);
  308. } /* End _DtHelpProcessHyperSelection */