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