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