2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: HyperText.c /main/9 1999/10/14 14:45:38 mgreess $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 ** Project: Text Graphic Display Library
31 ** Description: This body of code does all the work for hypertext links
34 ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
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.
43 ****************************************************************************
44 ************************************<+>*************************************/
54 #else /* SUN and IBM */
56 #include <sys/select.h>
59 #include <sys/types.h>
63 #include <Xm/DialogS.h>
74 #include "HelpErrorP.h"
75 #include "DisplayAreaP.h"
76 #include "DisplayAreaI.h"
78 #include "HourGlassI.h"
79 #include "HyperTextI.h"
85 /******** Private Function Declarations ********/
86 static void ProcessEvents (
87 DtHelpDispAreaStruct *pDAS,
90 /******** End Private Function Declarations ********/
92 /*********************************************************************
94 *********************************************************************/
102 /*********************************************************************
104 *********************************************************************/
105 /*********************************************************************
108 * ProcessEvents will do a select on the socket until the child
111 *********************************************************************/
114 DtHelpDispAreaStruct *pDAS,
123 struct timeval *topPtr;
124 struct timeval toStruct;
126 Display *dpy = XtDisplay (pDAS->dispWid);
131 * set a small time out.
133 toStruct.tv_usec = 500000; /* 500 miliseconds */
138 * get the socket's file descriptor
140 myFd = ConnectionNumber (dpy);
144 rMask = (1 << (myFd % 32)); /* on t.o. select will clear */
149 result = select(myFd+1, &rMask, 0, 0, topPtr);
151 result = select(myFd+1, ((fd_set *)&rMask), 0, 0, topPtr);
155 * check to see if the select happened because of
156 * a system interrupt.
159 * otherwise an exposure event happened.
160 * fall through and XPending will be true,
161 * forcing us to go to the XmUpdateDisplay call.
167 * SYSTEM - Use XtDisplatchEvent????
169 XNextEvent (dpy, &event);
170 if (event.type == Expose)
171 XmUpdateDisplay (pDAS->dispWid);
175 * check to see if the child is still going
177 pid = waitpid (child_pid, (int *) 0, WNOHANG);
178 if (pid == child_pid || pid == -1)
181 } while (!child_flag);
184 /*********************************************************************
185 * Internal Public Functions
186 *********************************************************************/
187 /*********************************************************************
188 * _DtHelpExecProcedure
190 * _DtHelpExecProcedure will fork/exec the command passed in. It will
191 * then allow only exposure events to be processed until the
194 *********************************************************************/
196 _DtHelpExecProcedure (
197 XtPointer client_data,
201 XWindowAttributes attr;
204 Boolean childFlag = False;
206 DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
209 * Turn on the wait cursor.
211 shellWidget = pDAS->dispWid;
212 while (!XtIsSubclass(shellWidget, xmDialogShellWidgetClass))
213 shellWidget = XtParent(shellWidget);
215 _DtHelpTurnOnHourGlass(shellWidget);
217 * Get the window event mask via the window attributes. Remember it.
218 * Set the Input to only Exposure events.
220 XGetWindowAttributes (XtDisplay(pDAS->dispWid), XtWindow (pDAS->dispWid),
222 XSelectInput (XtDisplay(pDAS->dispWid), XtWindow (pDAS->dispWid),
225 XSync (XtDisplay(pDAS->dispWid), 0);
228 * initialize the global flag and variable.
234 * fork a child process.
243 * If the child, exec the cmd with a shell parent
244 * so if the cmd ends in an ampersand, the command
245 * will be put in the background and the shell will
246 * die and return, creating a SIGCLD for us to catch.
250 execlp (pShell, pShell, "-c", cmd, ((char *) 0));
255 * Check to make sure the vfork was successful.
260 * check to see if the child is still going
262 pid = waitpid (childPid, (int *) 0, WNOHANG);
263 if (!(pid == childPid || pid == -1))
265 * process the exposure events in a special routine.
267 ProcessEvents (pDAS, childPid, childFlag);
271 * reset the input mask
273 XSelectInput (XtDisplay(pDAS->dispWid), XtWindow (pDAS->dispWid),
274 (attr.your_event_mask));
276 * turn off the wait cursor
278 _DtHelpTurnOffHourGlass(shellWidget);
280 } /* End _DtHelpExecProcedure */
282 /*********************************************************************
283 * Function: _DtHelpProcessHyperSelection
285 * Determine if the user selected a segment that is a hypertext
286 * link. If so, call the appropriate function to process it.
288 *********************************************************************/
290 _DtHelpProcessHyperSelection (
291 XtPointer client_data,
300 _DtCvLinkInfo ceHyper;
301 DtHelpHyperTextStruct callData;
302 DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
304 if (pDAS->hyperCall == NULL)
307 downY = downY + pDAS->firstVisible - pDAS->decorThickness;
308 downX = downX + pDAS->virtualX - pDAS->decorThickness;
309 upX = event->xbutton.x + pDAS->virtualX - pDAS->decorThickness;
310 upY = event->xbutton.y + pDAS->firstVisible - pDAS->decorThickness;
313 * turn off the old traversal
315 if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
317 pDAS->toc_flag |= _DT_HELP_DRAW_TOC_IND;
318 _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_OFF, False,
319 (XtIsRealized(pDAS->dispWid) ? True : False),
320 NULL, NULL, NULL, NULL, NULL);
323 if (_DtCvSTATUS_OK ==
324 _DtCanvasGetPosLink(pDAS->canvas,downX,downY,upX,upY,&ceHyper))
327 * turn the traversal on for the selected hyptext link.
329 if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
331 pDAS->toc_flag |= _DT_HELP_DRAW_TOC_IND;
332 _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_ID, False,
333 (XtIsRealized(pDAS->dispWid) ? True : False),
334 ceHyper.specification,
335 NULL, NULL, NULL, NULL);
338 callData.reason = XmCR_ACTIVATE;
339 callData.event = event;
340 callData.window = XtWindow (pDAS->dispWid);
341 callData.specification = ceHyper.specification;
342 callData.hyper_type = ceHyper.hyper_type;
343 callData.window_hint = ceHyper.win_hint;
345 (*(pDAS->hyperCall)) (pDAS, pDAS->clientData, &callData);
347 else if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
349 * turn the traversal back on
351 _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_ON, False,
352 (XtIsRealized(pDAS->dispWid) ? True : False),
353 NULL, NULL, NULL, NULL, NULL);
355 } /* End _DtHelpProcessHyperSelection */