123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $TOG: HyperText.c /main/9 1999/10/14 14:45:38 mgreess $ */
- /************************************<+>*************************************
- ****************************************************************************
- **
- ** File: HyperText.c
- **
- ** Project: Text Graphic Display Library
- **
- ** Description: This body of code does all the work for hypertext links
- **
- **
- ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
- **
- ** (c) Copyright 1993, 1994 Hewlett-Packard Company
- ** (c) Copyright 1993, 1994 International Business Machines Corp.
- ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
- ** (c) Copyright 1993, 1994 Novell, Inc.
- **
- **
- **
- ****************************************************************************
- ************************************<+>*************************************/
- /*
- * system includes
- */
- #include <errno.h>
- #include <signal.h>
- #include <stdlib.h>
- #ifdef _AIX
- #include <sys/select.h>
- #endif
- #include <sys/time.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <sys/wait.h>
- #include <Xm/DialogS.h>
- /*
- * Canvas Engine
- */
- #include "CanvasP.h"
- /*
- * private includes
- */
- #include "HelpErrorP.h"
- #include "DisplayAreaP.h"
- #include "DisplayAreaI.h"
- #include "FontI.h"
- #include "HourGlassI.h"
- #include "HyperTextI.h"
- #include "HelposI.h"
- #ifdef NLS16
- #endif
- /******** Private Function Declarations ********/
- static void ProcessEvents (
- DtHelpDispAreaStruct *pDAS,
- pid_t child_pid,
- Boolean child_flag);
- /******** End Private Function Declarations ********/
- /*********************************************************************
- * Private Variables
- *********************************************************************/
- typedef struct {
- char *link_spec;
- int type;
- char *descrip;
- } HyperList;
- /*********************************************************************
- * Private Functions
- *********************************************************************/
- /*********************************************************************
- * ProcessEvents
- *
- * ProcessEvents will do a select on the socket until the child
- * dies.
- *
- *********************************************************************/
- static void
- ProcessEvents (
- DtHelpDispAreaStruct *pDAS,
- pid_t child_pid,
- Boolean child_flag)
- {
- int result;
- int rMask;
- int myFd;
- pid_t pid;
- struct timeval *topPtr;
- struct timeval toStruct;
- Display *dpy = XtDisplay (pDAS->dispWid);
- XEvent event;
- /*
- * set a small time out.
- */
- toStruct.tv_usec = 500000; /* 500 miliseconds */
- toStruct.tv_sec = 0;
- topPtr = &toStruct;
- /*
- * get the socket's file descriptor
- */
- myFd = ConnectionNumber (dpy);
- do
- {
- rMask = (1 << (myFd % 32)); /* on t.o. select will clear */
- if (!XPending(dpy))
- {
- #if 0
- result = select(myFd+1, &rMask, 0, 0, topPtr);
- #else
- result = select(myFd+1, ((fd_set *)&rMask), 0, 0, topPtr);
- #endif
- /*
- * check to see if the select happened because of
- * a system interrupt.
- */
- /*
- * otherwise an exposure event happened.
- * fall through and XPending will be true,
- * forcing us to go to the XmUpdateDisplay call.
- */
- }
- else
- {
- /*
- * SYSTEM - Use XtDisplatchEvent????
- */
- XNextEvent (dpy, &event);
- if (event.type == Expose)
- XmUpdateDisplay (pDAS->dispWid);
- }
- /*
- * check to see if the child is still going
- */
- pid = waitpid (child_pid, (int *) 0, WNOHANG);
- if (pid == child_pid || pid == -1)
- child_flag = True;
- } while (!child_flag);
- }
- /*********************************************************************
- * Internal Public Functions
- *********************************************************************/
- /*********************************************************************
- * _DtHelpExecProcedure
- *
- * _DtHelpExecProcedure will fork/exec the command passed in. It will
- * then allow only exposure events to be processed until the
- * child dies.
- *
- *********************************************************************/
- void
- _DtHelpExecProcedure (
- XtPointer client_data,
- char *cmd )
- {
- pid_t pid;
- XWindowAttributes attr;
- char *pShell = "sh";
- Widget shellWidget;
- Boolean childFlag = False;
- pid_t childPid;
- DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
- /*
- * Turn on the wait cursor.
- */
- shellWidget = pDAS->dispWid;
- while (!XtIsSubclass(shellWidget, xmDialogShellWidgetClass))
- shellWidget = XtParent(shellWidget);
-
- _DtHelpTurnOnHourGlass(shellWidget);
- /*
- * Get the window event mask via the window attributes. Remember it.
- * Set the Input to only Exposure events.
- */
- XGetWindowAttributes (XtDisplay(pDAS->dispWid), XtWindow (pDAS->dispWid),
- &attr);
- XSelectInput (XtDisplay(pDAS->dispWid), XtWindow (pDAS->dispWid),
- ExposureMask);
- XSync (XtDisplay(pDAS->dispWid), 0);
- /*
- * initialize the global flag and variable.
- */
- childPid = -1;
- childFlag = False;
- /*
- * fork a child process.
- */
- childPid = fork ();
- /*
- * If the child, exec the cmd with a shell parent
- * so if the cmd ends in an ampersand, the command
- * will be put in the background and the shell will
- * die and return, creating a SIGCLD for us to catch.
- */
- if (childPid == 0)
- {
- execlp (pShell, pShell, "-c", cmd, ((char *) 0));
- _exit (1);
- }
- /*
- * Check to make sure the vfork was successful.
- */
- if (childPid != -1)
- {
- /*
- * check to see if the child is still going
- */
- pid = waitpid (childPid, (int *) 0, WNOHANG);
- if (!(pid == childPid || pid == -1))
- /*
- * process the exposure events in a special routine.
- */
- ProcessEvents (pDAS, childPid, childFlag);
- }
- /*
- * reset the input mask
- */
- XSelectInput (XtDisplay(pDAS->dispWid), XtWindow (pDAS->dispWid),
- (attr.your_event_mask));
- /*
- * turn off the wait cursor
- */
- _DtHelpTurnOffHourGlass(shellWidget);
- } /* End _DtHelpExecProcedure */
- /*********************************************************************
- * Function: _DtHelpProcessHyperSelection
- *
- * Determine if the user selected a segment that is a hypertext
- * link. If so, call the appropriate function to process it.
- *
- *********************************************************************/
- void
- _DtHelpProcessHyperSelection (
- XtPointer client_data,
- int downX,
- int downY,
- XEvent *event )
- {
- int upX;
- int upY;
- _DtCvLinkInfo ceHyper;
- DtHelpHyperTextStruct callData;
- DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
- if (pDAS->hyperCall == NULL)
- return;
- downY = downY + pDAS->firstVisible - pDAS->decorThickness;
- downX = downX + pDAS->virtualX - pDAS->decorThickness;
- upX = event->xbutton.x + pDAS->virtualX - pDAS->decorThickness;
- upY = event->xbutton.y + pDAS->firstVisible - pDAS->decorThickness;
- /*
- * turn off the old traversal
- */
- if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
- {
- pDAS->toc_flag |= _DT_HELP_DRAW_TOC_IND;
- _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_OFF, False,
- (XtIsRealized(pDAS->dispWid) ? True : False),
- NULL, NULL, NULL, NULL, NULL);
- }
- if (_DtCvSTATUS_OK ==
- _DtCanvasGetPosLink(pDAS->canvas,downX,downY,upX,upY,&ceHyper))
- {
- /*
- * turn the traversal on for the selected hyptext link.
- */
- if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
- {
- pDAS->toc_flag |= _DT_HELP_DRAW_TOC_IND;
- _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_ID, False,
- (XtIsRealized(pDAS->dispWid) ? True : False),
- ceHyper.specification,
- NULL, NULL, NULL, NULL);
- }
- callData.reason = XmCR_ACTIVATE;
- callData.event = event;
- callData.window = XtWindow (pDAS->dispWid);
- callData.specification = ceHyper.specification;
- callData.hyper_type = ceHyper.hyper_type;
- callData.window_hint = ceHyper.win_hint;
- (*(pDAS->hyperCall)) (pDAS, pDAS->clientData, &callData);
- }
- else if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
- /*
- * turn the traversal back on
- */
- _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_ON, False,
- (XtIsRealized(pDAS->dispWid) ? True : False),
- NULL, NULL, NULL, NULL, NULL);
- } /* End _DtHelpProcessHyperSelection */
|