Annotation of Amaya/amaya/AHTBridge.c, revision 1.90
1.9 cvs 1: /*
2: *
1.84 vatton 3: * (c) COPYRIGHT INRIA and W3C, 1996-2003
1.9 cvs 4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
1.75 cvs 7:
1.14 cvs 8: /*
9: * AHTBridge.c : This module implements the callback setup and
10: * handlers between the Xt, libwww, and Amaya procedures. It's responsible
11: * for assigning, modifying, and supressing Xt events to the active
12: * requests.
13: *
14: * Author: J Kahan
1.67 cvs 15: * J. K./R. Guetari. Windows NT/95 routines
1.79 cvs 16: * J. K./S. Gully GTK routines
1.14 cvs 17: *
18: */
1.68 cvs 19: #ifdef _GTK
1.85 gully 20: #include <glib.h>
1.68 cvs 21: #endif /* _GTK */
22:
1.16 cvs 23: #define THOT_EXPORT extern
1.4 cvs 24: #include "amaya.h"
1.10 cvs 25: #include "AHTBridge_f.h"
26: #include "AHTFWrite_f.h"
27: #include "query_f.h"
28: #include "answer_f.h"
1.64 cvs 29: #include "HTEvtLst.h"
1.4 cvs 30:
1.58 cvs 31: #if 0
32: #define DEBUG_LIBWWW
33: #define THD_TRACE 1
34: #endif
35:
1.85 gully 36: #ifdef _MOTIF
37: /* Amaya's X appcontext */
38: extern ThotAppContext app_cont;
39: #endif /* #ifdef _MOTIF */
40:
41: #if defined(_MOTIF) || defined(_GTK)
42: /* Private functions */
43: static void RequestRegisterReadXtevent (SOCKET);
44: static void RequestKillReadXtevent (SOCKET);
45: static void RequestRegisterWriteXtevent ( SOCKET);
46: static void RequestKillWriteXtevent (SOCKET);
47: static void RequestRegisterExceptXtevent ( SOCKET);
48: static void RequestKillExceptXtevent (SOCKET);
49: #endif /* #if defined(_MOTIF) || defined(_GTK) */
1.24 cvs 50:
1.32 cvs 51: /* Private variables */
1.4 cvs 52:
53: /*
1.58 cvs 54: * this set of HTEventType map our WinSock "socket event HTEventType" into
1.4 cvs 55: * our read and write sets. Note that under the canonical Unix model,
56: * a non-blocking socket passed to an accept() call will appear as readable,
57: * whilst a non-blocking call to connect() will appear as writeable. In add.
58: * if the connection has been closed, the socket will appear readable under
59: * BSD Unix semantics
60: */
1.32 cvs 61:
1.58 cvs 62: static const HTEventType ReadBits = HTEvent_READ | HTEvent_ACCEPT | HTEvent_CLOSE;
63: static const HTEventType WriteBits = HTEvent_WRITE | HTEvent_CONNECT;
64: static const HTEventType ExceptBits = HTEvent_OOB;
65:
1.85 gully 66: #ifdef _MOTIF
67: typedef struct sStatus {
68: XtInputId read; /* the different Xt Id's */
69: XtInputId write;
70: XtInputId except;
71: } SocketStatus;
72: #endif /*! #ifdef _MOTIF */
1.79 cvs 73:
74: #ifdef _GTK
1.85 gully 75: typedef struct sStatus {
76: gint read; /* the different GTK Id's */
77: gint write;
78: gint except;
79: } SocketStatus;
1.79 cvs 80: #endif /* _GTK */
1.4 cvs 81:
1.85 gully 82: #ifdef _NOGUI
83: typedef struct sStatus {
84: int read;
85: int write;
86: int except;
87: } SocketStatus;
1.88 cvs 88: #endif /* #ifdef _NOGUI */
1.85 gully 89:
1.89 cvs 90: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
91: #define SOCK_TABLE_SIZE 67
92: #define HASH(s) ((s) % SOCK_TABLE_SIZE)
93: static SocketStatus persSockets[SOCK_TABLE_SIZE];
94: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.4 cvs 95:
1.10 cvs 96: /*--------------------------------------------------------------------
97: AHTCallback_bridge
1.11 cvs 98: this function acts as a bridge between Xt and libwww. From the Xt
99: point of view, this function is the callback handler whenever there's
100: any activity on the sockets associated with the active requests. From
101: the libwww point of view, this is the function that takes the initiative
102: to invoke the callback function associated with an active request,
103: whenever there's an activity in the socket associated to it.
104: In this latter aspect, this function is similar to the library's
105: own __DoCallback() function.
106: Upon activation, the function looks up the request associated with the
107: active socket and then looks up the cbf associated with that request.
108: Upon completion of the execution of the request's cbf, it verifies
109: the state of the request and, if it's an asynchronous request, deletes
110: the memory allocated to it.
1.10 cvs 111: -------------------------------------------------------------------*/
1.80 kahan 112: void *AHTCallback_bridge (caddr_t cd, int *s, XtInputId * id)
1.4 cvs 113: {
1.86 gully 114: #ifdef _MOTIF
1.11 cvs 115: int status; /* the status result of the libwwww call */
1.58 cvs 116: HTEventType type = HTEvent_ALL;
1.38 cvs 117: int v;
1.40 cvs 118: int socket = *s;
1.58 cvs 119: ms_t now = HTGetTimeInMillis();
120:
121: v = HASH (socket);
1.4 cvs 122:
1.58 cvs 123: /* convert the FD into an HTEventType which will allow us to find the
124: request associated with the socket */
1.47 cvs 125:
1.58 cvs 126: /* I could send some other data here, like the event itself, right */
127: switch ((XtInputId) cd)
1.47 cvs 128: {
1.58 cvs 129: case XtInputReadMask:
130: type = HTEvent_READ;
131: break;
132: case XtInputWriteMask:
133: type = HTEvent_WRITE;
134: break;
135: case XtInputExceptMask:
136: type = HTEvent_OOB;
137: break;
138: default:
139: type = HTEvent_ALL;
140: break;
141: } /* switch */
1.47 cvs 142:
1.32 cvs 143: /* Invokes the callback associated to the requests */
144:
1.66 cvs 145: /** CanDoStop_set (FALSE); **/
1.58 cvs 146: if ((status = HTEventList_dispatch (socket, type, now)) != HT_OK)
147: {
1.36 cvs 148: #ifdef DEBUG_LIBWWW
1.58 cvs 149: HTTrace ("Callback.... returned a value != HT_OK");
1.36 cvs 150: #endif
1.58 cvs 151: }
1.41 cvs 152:
1.66 cvs 153: /*** CanDoStop_set (TRUE); **/
1.86 gully 154: #endif /* _MOTIF */
155:
1.7 cvs 156: return (0);
1.4 cvs 157: }
1.85 gully 158:
159: #ifdef _GTK
1.79 cvs 160: static void AHTCallback_bridgeGTK (gpointer data, gint source, GdkInputCondition condition)
161: {
162: int status; /* the status result of the libwwww call */
163: HTEventType type = HTEvent_ALL;
164: int v;
165: int socket;
166: ms_t now = HTGetTimeInMillis();
167:
168: socket = (SOCKET) data;
169: v = HASH (socket);
170:
171: /* convert the FD into an HTEventType which will allow us to find the
172: request associated with the socket */
173:
174: /* I could send some other data here, like the event itself, right */
175: switch (condition)
176: {
177: case GDK_INPUT_READ:
178: type = HTEvent_READ;
179: break;
180: case GDK_INPUT_WRITE:
181: type = HTEvent_WRITE;
182: break;
183: case GDK_INPUT_EXCEPTION:
184: type = HTEvent_OOB;
185: break;
186: default:
187: type = HTEvent_ALL;
188: break;
189: } /* switch */
190:
191: /* Invokes the callback associated to the requests */
192:
193: /** CanDoStop_set (FALSE); **/
194: if ((status = HTEventList_dispatch (socket, type, now)) != HT_OK)
195: {
196: #ifdef DEBUG_LIBWWW
197: HTTrace ("Callback.... returned a value != HT_OK");
198: #endif
199: }
200: /*** CanDoStop_set (TRUE); **/
201: }
1.85 gully 202: #endif /* _GTK */
1.41 cvs 203:
204: /*--------------------------------------------------------------------
205: ProcessTerminateRequest
206: This function is called whenever a request has ended. If the requested
207: ended normally, the function will call any callback associated to the
208: request. Otherwise, it will just mark the request as over.
209: -------------------------------------------------------------------*/
1.82 vatton 210: void ProcessTerminateRequest (HTRequest *request, HTResponse *response,
211: void *param, int status)
1.41 cvs 212: {
1.58 cvs 213: AHTReqContext *me = HTRequest_context (request);
1.56 cvs 214:
1.58 cvs 215: /* choose a correct treatment in function of the request's
1.41 cvs 216: being associated with an error, with an interruption, or with a
217: succesful completion */
1.64 cvs 218:
219: #ifdef DEBUG_LIBWWW
220: if (THD_TRACE)
1.82 vatton 221: fprintf (stderr,"ProcessTerminateRequest: processing req %p, url %s,\
222: status %d\n", me, me->urlName, me->reqStatus);
1.64 cvs 223: #endif /* DEBUG_LIBWWW */
1.83 kahan 224: if (me->reqStatus == HT_END)
1.41 cvs 225: {
1.58 cvs 226: if (AmayaIsAlive () && me->terminate_cbf)
1.82 vatton 227: (*me->terminate_cbf) (me->docid, 0, me->urlName, me->outputfile,
228: &(me->http_headers), me->context_tcbf);
1.58 cvs 229:
1.41 cvs 230: }
1.42 cvs 231: else if (me->reqStatus == HT_ABORT)
1.41 cvs 232: /* either the application ended or the user pressed the stop
233: button. We erase the incoming file, if it exists */
234: {
1.52 cvs 235: if (AmayaIsAlive () && me->terminate_cbf)
1.82 vatton 236: (*me->terminate_cbf) (me->docid, -1, me->urlName, me->outputfile,
237: &(me->http_headers), me->context_tcbf);
1.78 cvs 238: if (me->outputfile && me->outputfile[0] != EOS)
1.41 cvs 239: {
1.70 cvs 240: TtaFileUnlink (me->outputfile);
1.78 cvs 241: me->outputfile[0] = EOS;
1.70 cvs 242: }
1.41 cvs 243: }
1.83 kahan 244: else if (me->reqStatus == HT_ERR)
1.41 cvs 245: {
246: /* there was an error */
1.90 ! gully 247: if (AmayaIsAlive () && me->terminate_cbf)
1.82 vatton 248: (*me->terminate_cbf) (me->docid, -2, me->urlName, me->outputfile,
249: &(me->http_headers), me->context_tcbf);
1.41 cvs 250:
1.78 cvs 251: if (me->outputfile && me->outputfile[0] != EOS)
1.41 cvs 252: {
1.70 cvs 253: TtaFileUnlink (me->outputfile);
1.78 cvs 254: me->outputfile[0] = EOS;
1.41 cvs 255: }
256: }
1.58 cvs 257:
1.41 cvs 258: /* we erase the context if we're dealing with an asynchronous request */
1.61 cvs 259: if ((me->mode & AMAYA_ASYNC)
260: || (me->mode & AMAYA_IASYNC))
1.58 cvs 261: {
1.63 cvs 262: Document doc = me->docid;
1.58 cvs 263: me->reqStatus = HT_END;
264: /*** @@@ do we need this? yes!! **/
265: AHTLoadTerminate_handler (request, response, param, status);
266: AHTReqContext_delete (me);
1.63 cvs 267: AHTPrintPendingRequestStatus (doc, YES);
1.58 cvs 268: }
269: }
1.4 cvs 270:
1.32 cvs 271: #ifdef _WINDOWS
1.29 cvs 272: /*----------------------------------------------------------------
1.32 cvs 273: WIN_Activate_Request
1.29 cvs 274: when there are more open requests than available sockets, the
275: requests are put in a "pending state." When a socket becomes
276: available, libwww associates it with a pending request and then
277: calls this callback function. This function is responsible for
278: opening the temporary file where the GET and POST results
279: will be stored. The function is also responsible for
280: registering the socket with the Xt event loop.
281: Consult the libwww manual for more details on the signature
282: of this function.
283: ----------------------------------------------------------------*/
1.79 cvs 284: int WIN_Activate_Request (HTRequest * request, HTAlertOpcode op, int msgnum, const char *dfault, void *input, HTAlertPar * reply)
1.29 cvs 285: {
286: AHTReqContext *me = HTRequest_context (request);
287:
1.58 cvs 288: if (me->reqStatus == HT_NEW)
289: {
290: if (!(me->output)
291: && (me->output != stdout)
292: && me->outputfile
1.78 cvs 293: && (me->output = fopen (me->outputfile, "wb")) == NULL) {
1.58 cvs 294: /* the request is associated with a file */
1.78 cvs 295: me->outputfile[0] = EOS; /* file could not be opened */
1.70 cvs 296: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE), me->outputfile);
1.58 cvs 297: me->reqStatus = HT_ERR;
298:
299: if (me->error_html)
300: DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR; /* so we can show the error message */
301: }
302: else
303: {
304: #ifdef DEBUG_LIBWWW
305: if (THD_TRACE)
306: fprintf (stderr, "WIN_Activate_Request: Activating pending %s. "
307: "Open fd %d\n", me->urlName, (int) me->output);
308: #endif /* DEBUG_LIBWWW */
309: HTRequest_setOutputStream (me->request, AHTFWriter_new (me->request, me->output, YES));
310: /*change the status of the request */
311: me->reqStatus = HT_WAITING;
312: }
313: }
314: else if (me->reqStatus == HT_WAITING)
315: {
316: /*change the status of the request */
317: rewind (me->output);
318: if (HTRequest_outputStream (me->request) == NULL)
319: HTRequest_setOutputStream (me->request, AHTFWriter_new (me->request, me->output, YES));
320: }
1.32 cvs 321: else {
1.36 cvs 322: me->reqStatus = HT_ERR;
1.32 cvs 323: }
324:
1.36 cvs 325: return ((me->reqStatus != HT_ERR) ? HT_OK : HT_ERROR);
1.32 cvs 326: }
327:
1.85 gully 328: #endif /* _WINDOWS */
1.60 cvs 329:
1.11 cvs 330: /*----------------------------------------------------------------------
331: AHTEvent_register
332: callback called by libwww whenever a socket is open and associated
333: to a request. It sets the pertinent Xt events so that the Xt Event
334: loops gets an interruption whenever there's action of the socket.
335: In addition, it registers the request with libwww.
336: ----------------------------------------------------------------------*/
1.58 cvs 337: int AHTEvent_register (SOCKET sock, HTEventType type, HTEvent *event)
1.4 cvs 338: {
1.85 gully 339: int status = 0;
1.7 cvs 340:
1.40 cvs 341: if (sock == INVSOC)
342: {
1.36 cvs 343: #ifdef DEBUG_LIBWWW
1.58 cvs 344: fprintf(stderr, "AHTEvent_register: sock = INVSOC\n");
1.37 cvs 345: #endif /* DEBUG_LIBWWW */
1.58 cvs 346: return (0);
347: }
1.43 cvs 348:
1.85 gully 349: #if defined(_MOTIF) || defined(_GTK)
1.58 cvs 350: /* need something special for HTEvent_CLOSE */
351: if (type & ReadBits)
352: RequestRegisterReadXtevent (sock);
353:
354: if (type & WriteBits)
355: RequestRegisterWriteXtevent (sock);
356:
357: if (type & ExceptBits)
358: RequestRegisterExceptXtevent (sock);
1.85 gully 359: #endif /* #if defined(_MOTIF) || defined(_GTK) */
1.58 cvs 360:
1.51 cvs 361: #ifdef _WINDOWS
1.50 cvs 362: /* under windows, libwww requires an explicit FD_CLOSE registration
1.58 cvs 363: to detect HTTP responses not having a Content-Length header */
364: status = HTEventList_register (sock, type | HTEvent_CLOSE , event);
1.85 gully 365: #endif /* _WINDOWS */
366:
367: #if defined(_MOTIF) || defined(_GTK)
1.58 cvs 368: status = HTEventList_register (sock, type, event);
1.85 gully 369: #endif /* #if defined(_MOTIF) || defined(_GTK) */
1.58 cvs 370:
371: return (status);
372: }
1.50 cvs 373:
1.34 cvs 374: /*----------------------------------------------------------------------
375: AHTEvent_unregister
376: callback called by libwww each time a request is unregistered. This
377: function takes care of unregistering the pertinent Xt events
378: associated with the request's socket. In addition, it unregisters
379: the request from libwww.
380: ----------------------------------------------------------------------*/
1.58 cvs 381: int AHTEvent_unregister (SOCKET sock, HTEventType type)
1.34 cvs 382: {
1.58 cvs 383: int status;
1.76 kahan 384:
385: if (sock == INVSOC)
386: return HT_OK;
1.38 cvs 387:
1.85 gully 388: #if defined(_MOTIF) || defined(_GTK)
1.58 cvs 389: /* remove the Xt event hooks */
390: if (type & ReadBits)
391: RequestKillReadXtevent (sock);
392:
393: if (type & WriteBits)
394: RequestKillWriteXtevent (sock);
395:
396: if (type & ExceptBits)
397: RequestKillExceptXtevent (sock);
1.85 gully 398: #endif /* #if defined(_MOTIF) || defined(_GTK) */
1.35 cvs 399:
1.58 cvs 400: /* @@@ if this is the default for windows, no need to have AHTEvent_..
401: in windows!! */
1.35 cvs 402:
1.58 cvs 403: /* call libwww's default routine */
404: status = HTEventList_unregister (sock, type);
405:
1.7 cvs 406: return (status);
1.4 cvs 407: }
1.35 cvs 408:
1.58 cvs 409: /* Private functions */
410:
1.11 cvs 411: /*----------------------------------------------------------------------
412: RequestKillAllXtevents
413: front-end for kill all Xt events associated with the request pointed
414: to by "me".
415: ----------------------------------------------------------------------*/
1.79 cvs 416: void RequestKillAllXtevents (AHTReqContext * me)
1.4 cvs 417: {
1.86 gully 418: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 419: int sock = INVSOC;
420:
421: return;
422:
423: /* @@@ what to do with this one? @@@ */
424: if (me->read_sock != INVSOC)
425: sock = me->read_sock;
426: else
427: if (me->write_sock != INVSOC)
428: sock = me->write_sock;
429: else
430: if (me->except_sock != INVSOC)
431: sock = me->except_sock;
432:
433: #ifdef DEBUG_LIBWWW
1.7 cvs 434: if (THD_TRACE)
1.58 cvs 435: fprintf (stderr, "RequestKillAllXtEvents: Clearing XtInputs\n");
436: #endif /* DEBUG_LIBWWW */
1.4 cvs 437:
1.58 cvs 438:
439: RequestKillReadXtevent (sock);
440: RequestKillWriteXtevent (sock);
441: RequestKillExceptXtevent (sock);
1.86 gully 442: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.4 cvs 443: }
444:
1.11 cvs 445: /*----------------------------------------------------------------------
1.18 cvs 446: RequestRegisterReadXtevent
447: Registers with Xt the read events associated with socket sock
448: ----------------------------------------------------------------------*/
1.79 cvs 449: static void RequestRegisterReadXtevent (SOCKET sock)
1.18 cvs 450: {
1.86 gully 451: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 452: int v;
453:
454: v = HASH (sock);
455:
456: if (!persSockets[v].read)
1.18 cvs 457: {
1.85 gully 458:
459: #ifdef _MOTIF
1.58 cvs 460: persSockets[v].read =
461: XtAppAddInput (app_cont,
462: sock,
463: (XtPointer) XtInputReadMask,
464: (XtInputCallbackProc) AHTCallback_bridge,
465: (XtPointer) XtInputReadMask);
1.85 gully 466: #endif /* _MOTIF */
467:
468: #ifdef _GTK
1.79 cvs 469: persSockets[v].read =
470: gdk_input_add ((gint) sock,
471: GDK_INPUT_READ,
472: AHTCallback_bridgeGTK,
473: (gpointer) sock);
474: #endif /* !_GTK */
475:
1.58 cvs 476: #ifdef DEBUG_LIBWWW
1.18 cvs 477: if (THD_TRACE)
1.58 cvs 478: fprintf (stderr, "RegisterReadXtEvent: adding XtInput %lu Socket %d\n",
479: persSockets[v].read, sock);
480: #endif /* DEBUG_LIBWWW */
1.18 cvs 481: }
1.86 gully 482: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.18 cvs 483: }
484:
485: /*----------------------------------------------------------------------
1.11 cvs 486: RequestKillReadXtevent
487: kills any read Xt event associated with the request pointed to by "me".
488: ----------------------------------------------------------------------*/
1.79 cvs 489: static void RequestKillReadXtevent (SOCKET sock)
1.4 cvs 490: {
1.86 gully 491: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 492: int v;
493:
494: v = HASH (sock);
495:
496: if (persSockets[v].read)
497: {
498: #ifdef DEBUG_LIBWWW
499: if (THD_TRACE)
500: fprintf (stderr, "UnregisterReadXtEvent: Clearing XtInput %lu\n",
501: persSockets[v].read);
502: #endif /* DEBUG_LIBWWW */
1.85 gully 503:
504: #ifdef _MOTIF
1.58 cvs 505: XtRemoveInput (persSockets[v].read);
506: persSockets[v].read = (XtInputId) NULL;
1.85 gully 507: #endif /* _MOTIF */
508:
509: #ifdef _GTK
1.79 cvs 510: gdk_input_remove (persSockets[v].read);
511: persSockets[v].read = (gint) 0;
512: #endif /* !_GTK */
1.85 gully 513:
1.58 cvs 514: }
1.86 gully 515: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.18 cvs 516: }
517:
518: /*----------------------------------------------------------------------
519: RequestRegisterWriteXtevent
520: Registers with Xt the write events associated with socket sock
521: ----------------------------------------------------------------------*/
1.79 cvs 522: static void RequestRegisterWriteXtevent (SOCKET sock)
1.18 cvs 523: {
1.86 gully 524: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 525: int v;
526: v = HASH (sock);
1.18 cvs 527:
1.58 cvs 528: if (!persSockets[v].write)
529: {
1.85 gully 530: #ifdef _MOTIF
1.58 cvs 531: persSockets[v].write =
532: XtAppAddInput (app_cont,
533: sock,
1.18 cvs 534: (XtPointer) XtInputWriteMask,
535: (XtInputCallbackProc) AHTCallback_bridge,
536: (XtPointer) XtInputWriteMask);
1.85 gully 537: #endif /* _MOTIF */
538:
539: #ifdef _GTK
1.79 cvs 540: persSockets[v].write =
541: gdk_input_add ((gint) sock,
542: GDK_INPUT_WRITE,
543: AHTCallback_bridgeGTK,
544: (gpointer) sock);
1.85 gully 545: #endif /* _GTK */
1.79 cvs 546:
1.58 cvs 547: #ifdef DEBUG_LIBWWW
1.18 cvs 548: if (THD_TRACE)
1.58 cvs 549: fprintf (stderr, "RegisterWriteXtEvent: Adding XtInput %lu Socket %d\n",
550: persSockets[v].write, sock);
551: #endif /* DEBUG_LIBWWW */
552:
553: }
1.86 gully 554: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.4 cvs 555: }
556:
1.11 cvs 557: /*----------------------------------------------------------------------
558: RequestKillWriteXtevent
559: kills any write Xt event associated with the request pointed to
560: by "me".
561: ----------------------------------------------------------------------*/
1.79 cvs 562: static void RequestKillWriteXtevent (SOCKET sock)
1.4 cvs 563: {
1.86 gully 564: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 565: int v;
566:
567: v = HASH (sock);
568:
569: if (persSockets[v].write)
570: {
571: #ifdef DEBUG_LIBWWW
572: if (THD_TRACE)
573: fprintf (stderr, "UnRegisterWriteXtEvent: Clearing Write XtInputs "
574: "%lu\n",
575: persSockets[v].write);
576: #endif /* DEBUG_LIBWWW */
1.85 gully 577:
578: #ifdef _MOTIF
1.58 cvs 579: XtRemoveInput (persSockets[v].write);
580: persSockets[v].write = (XtInputId) NULL;
1.85 gully 581: #endif /* _MOTIF */
582:
583: #ifdef _GTK
1.79 cvs 584: gdk_input_remove (persSockets[v].write);
585: persSockets[v].write = (gint) 0;
1.85 gully 586: #endif /* _GTK */
587:
1.58 cvs 588: }
1.86 gully 589: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.18 cvs 590: }
591:
592: /*----------------------------------------------------------------------
593: RequestRegisterExceptXtevent
594: Registers with Xt the except events associated with socket sock
595: ----------------------------------------------------------------------*/
1.79 cvs 596: static void RequestRegisterExceptXtevent (SOCKET sock)
1.18 cvs 597: {
1.86 gully 598: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 599: int v;
600:
601: v = HASH (sock);
602:
603: if (!persSockets[v].except)
1.18 cvs 604: {
1.85 gully 605: #ifdef _MOTIF
1.58 cvs 606: persSockets[v].except =
607: XtAppAddInput (app_cont,
608: sock,
609: (XtPointer) XtInputExceptMask,
610: (XtInputCallbackProc) AHTCallback_bridge,
611: (XtPointer) XtInputExceptMask);
1.85 gully 612: #endif /* _MOTIF */
613:
614: #ifdef _GTK
1.79 cvs 615: persSockets[v].except =
616: gdk_input_add ((gint) sock,
617: GDK_INPUT_EXCEPTION,
618: AHTCallback_bridgeGTK,
619: (gpointer) sock);
1.85 gully 620: #endif /* _GTK */
621:
1.58 cvs 622: #ifdef DEBUG_LIBWWW
623: if (THD_TRACE)
624: fprintf (stderr, "RegisterExceptXtEvent: adding XtInput %lu Socket %d\n",
625: persSockets[v].except, sock);
626: #endif /* DEBUG_LIBWWW */
1.18 cvs 627: }
1.86 gully 628: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.4 cvs 629: }
630:
1.11 cvs 631: /*----------------------------------------------------------------------
632: RequestKillExceptXtevent
633: kills any exception Xt event associated with the request pointed to
634: by "me".
635: ----------------------------------------------------------------------*/
1.79 cvs 636: static void RequestKillExceptXtevent (SOCKET sock)
1.4 cvs 637: {
1.86 gully 638: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 639: int v;
640:
641: v = HASH (sock);
642: if (persSockets[v].except)
643: {
644: #ifdef DEBUG_LIBWWW
645: if (THD_TRACE)
646: fprintf (stderr, "UnregisterExceptXtEvent: Clearing Except XtInputs "
647: "%lu\n", persSockets[v].except);
648: #endif /* DEBUG_LIBWWW */
1.85 gully 649:
650: #ifdef _MOTIF
1.58 cvs 651: XtRemoveInput (persSockets[v].except);
652: persSockets[v].except = (XtInputId) NULL;
1.85 gully 653: #endif /* _MOTIF */
654:
655: #ifdef _GTK
1.79 cvs 656: gdk_input_remove (persSockets[v].except);
657: persSockets[v].except = (gint) 0;
1.85 gully 658: #endif /* _GTK */
659:
1.58 cvs 660: }
1.86 gully 661: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.58 cvs 662: }
663:
664: /*----------------------------------------------------------------------
665: Xt Timer functions
666: ----------------------------------------------------------------------*/
667:
668: struct _HTTimer {
669: ms_t millis; /* Relative value in millis */
670: ms_t expires; /* Absolute value in millis */
671: BOOL relative;
672: BOOL repetitive;
673: void * param; /* Client supplied context */
674: HTTimerCallback * cbf;
675: };
676:
677: struct _AmayaTimer {
678: HTTimer *libwww_timer;
1.85 gully 679:
680: #ifdef _MOTIF
1.58 cvs 681: XtIntervalId xt_timer;
1.85 gully 682: #endif /* _MOTIF */
683:
684: #ifdef _GTK
1.79 cvs 685: guint xt_timer;
1.85 gully 686: #endif /* _GTK */
687:
688: #ifdef _NOGUI
689: unsigned int xt_timer;
690: #endif /* #ifdef _NOGUI */
691:
1.58 cvs 692: };
693:
694: typedef struct _AmayaTimer AmayaTimer;
695:
696: static HTList *Timers = NULL;
697:
698: /*----------------------------------------------------------------------
1.79 cvs 699: TimerCallback
700: called by the system event loop. Timers shouldn't be restarted
701: on exiting.
1.58 cvs 702: ----------------------------------------------------------------------*/
703: void *TimerCallback (XtPointer cdata, XtIntervalId *id)
704: {
1.86 gully 705: #ifdef _MOTIF
1.58 cvs 706: HTList *cur, *last;
707: AmayaTimer *me;
708: HTTimer *libwww_timer;
709:
710: if (!AmayaIsAlive ()
711: || Timers == NULL)
712: return (0);
713:
714: /* find the timer from the uid */
715: last = cur = Timers;
716: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
717: {
718: if (me->xt_timer == *id)
719: break;
720: last = cur;
721: }
722:
723: if (me)
724: {
725: libwww_timer = me->libwww_timer;
726: /* remove the element from the list @@@ can be optimized later */
727: HTList_quickRemoveElement(cur, last);
728: TtaFreeMemory (me);
729: HTTimer_dispatch (libwww_timer);
730: }
1.86 gully 731: #endif /* _MOTIF */
732:
1.58 cvs 733: return (0);
1.86 gully 734:
1.58 cvs 735: }
1.86 gully 736:
1.58 cvs 737:
1.85 gully 738: #ifdef _GTK
1.79 cvs 739: /*----------------------------------------------------------------------
740: TimerCallbackGTK
1.81 kahan 741: The callback returns FALSE to destroy the timer that called it.
1.79 cvs 742: ----------------------------------------------------------------------*/
743: gboolean TimerCallbackGTK (gpointer id)
744: {
745: HTList *cur, *last;
746: AmayaTimer *me;
747: HTTimer *libwww_timer;
748: AmayaTimer *data;
749:
750: data = (AmayaTimer *) id;
751:
752: if (!AmayaIsAlive ()
753: || Timers == NULL)
1.81 kahan 754: return (FALSE);
1.79 cvs 755:
756: /* find the timer from the uid */
757: last = cur = Timers;
758: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
759: {
760: if (me == data)
761: break;
762: last = cur;
763: }
764:
765: if (me)
766: {
767: libwww_timer = me->libwww_timer;
768: /* remove the element from the list @@@ can be optimized later */
769: HTList_quickRemoveElement(cur, last);
770: TtaFreeMemory (me);
771: HTTimer_dispatch (libwww_timer);
772: }
773:
774: return (FALSE);
775: }
1.85 gully 776: #endif /* _GTK */
1.79 cvs 777:
1.58 cvs 778: /*----------------------------------------------------------------------
1.59 cvs 779: KillAllTimers
1.58 cvs 780: ----------------------------------------------------------------------*/
1.59 cvs 781: void KillAllTimers (void)
1.58 cvs 782: {
1.86 gully 783: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 784: /* @@@ maybe add something else to kill the Xt things */
785: if (Timers)
786: HTList_delete (Timers);
1.65 cvs 787: Timers = NULL;
1.86 gully 788: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.58 cvs 789: }
790:
791: /*----------------------------------------------------------------------
1.59 cvs 792: AMAYA_SetTimer
793: ----------------------------------------------------------------------*/
794: void AMAYA_SetTimer (HTTimer *libwww_timer)
1.58 cvs 795: {
1.86 gully 796: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 797: HTList *cur, *last;
798: AmayaTimer *me;
799:
1.90 ! gully 800: if (!AmayaIsAlive ()
1.58 cvs 801: || libwww_timer == NULL
802: || libwww_timer->expires == 0)
803: return;
804:
805: if (Timers == NULL)
806: Timers = HTList_new ();
807:
808: /* see if this timer existed already */
809: last = cur = Timers;
810: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
811: {
812: if (me->libwww_timer == libwww_timer)
813: break;
814: last = cur;
815: }
816:
817: if (me)
818: {
819: /* remove the old timer */
820: if (me->xt_timer)
821: {
1.85 gully 822:
823: #ifdef _MOTIF
1.58 cvs 824: XtRemoveTimeOut (me->xt_timer);
1.59 cvs 825: me->xt_timer = (XtIntervalId) NULL;
1.85 gully 826: #endif /* _MOTIF */
827:
828: #ifdef _GTK
1.79 cvs 829: gtk_timeout_remove (me->xt_timer);
830: me->xt_timer = (guint) 0;
831: #endif /* !_GTK */
1.85 gully 832:
833: }
1.58 cvs 834: }
835: else
836: {
837: /* create a new element */
838: me = TtaGetMemory (sizeof (AmayaTimer));
839: /* and add it to the list */
840: HTList_addObject(last, (void *) me);
841: me->libwww_timer = libwww_timer;
842: }
843:
844: /* add a new time out */
1.85 gully 845: #ifdef _MOTIF
1.58 cvs 846: me->xt_timer = XtAppAddTimeOut (app_cont,
847: me->libwww_timer->millis,
848: (XtTimerCallbackProc) TimerCallback,
849: (XtPointer *) (void *) me);
1.85 gully 850: #endif /* _MOTIF */
851:
852: #ifdef _GTK
1.79 cvs 853: me->xt_timer = gtk_timeout_add ((guint32) me->libwww_timer->millis,
854: (GtkFunction) TimerCallbackGTK,
855: (gpointer) me);
1.85 gully 856: #endif /* _GTK */
857:
1.86 gully 858: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.58 cvs 859: }
860:
861: /*----------------------------------------------------------------------
1.59 cvs 862: AMAYA_DeleteTimer
1.58 cvs 863: ----------------------------------------------------------------------*/
1.59 cvs 864: void AMAYA_DeleteTimer (HTTimer *libwww_timer)
1.58 cvs 865: {
1.86 gully 866: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI)
1.58 cvs 867: HTList *cur, *last;
868: AmayaTimer *me;
869:
1.59 cvs 870: if (Timers == NULL || libwww_timer == NULL)
1.58 cvs 871: return;
872:
873: /* find the id */
874: last = cur = Timers;
875: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
876: {
1.59 cvs 877: if (me->libwww_timer == libwww_timer)
1.58 cvs 878: break;
879: last = cur;
880: }
881:
882: if (me)
883: {
884: /* remove the Xt timer */
1.85 gully 885: #ifdef _MOTIF
1.58 cvs 886: XtRemoveTimeOut (me->xt_timer);
1.85 gully 887: #endif /* _MOTIF */
888:
889: #ifdef _GTK
1.79 cvs 890: gtk_timeout_remove (me->xt_timer);
1.85 gully 891: #endif /* _GTK */
892:
1.58 cvs 893: /* and the element from the list */
1.65 cvs 894: HTList_removeObject (Timers, me);
1.58 cvs 895: TtaFreeMemory (me);
896: }
1.86 gully 897: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */
1.31 cvs 898: }
1.86 gully 899:
Webmaster