Annotation of Amaya/amaya/AHTBridge.c, revision 1.96
1.9 cvs 1: /*
2: *
1.93 vatton 3: * (c) COPYRIGHT INRIA and W3C, 1996-2004
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.85 gully 21: #include <glib.h>
1.68 cvs 22: #endif /* _GTK */
23:
1.94 gully 24: #ifdef _WX
25: #include "wxAmayaTimer.h"
26: #include "wxAmayaSocketEvent.h"
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.96 ! vatton 42: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.85 gully 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.85 gully 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 */
81: #if defined(_NOGUI)
1.85 gully 82: typedef struct sStatus {
83: int read;
84: int write;
85: int except;
86: } SocketStatus;
1.88 cvs 87: #endif /* #ifdef _NOGUI */
1.96 ! vatton 88: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.89 cvs 89: #define SOCK_TABLE_SIZE 67
90: #define HASH(s) ((s) % SOCK_TABLE_SIZE)
91: static SocketStatus persSockets[SOCK_TABLE_SIZE];
1.96 ! vatton 92: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
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.96 ! vatton 112: return (0);
1.4 cvs 113: }
1.85 gully 114:
1.94 gully 115: #if defined(_GTK)
1.79 cvs 116: static void AHTCallback_bridgeGTK (gpointer data, gint source, GdkInputCondition condition)
117: {
118: int status; /* the status result of the libwwww call */
119: HTEventType type = HTEvent_ALL;
120: int v;
121: int socket;
122: ms_t now = HTGetTimeInMillis();
123:
124: socket = (SOCKET) data;
125: v = HASH (socket);
126:
127: /* convert the FD into an HTEventType which will allow us to find the
128: request associated with the socket */
129:
130: /* I could send some other data here, like the event itself, right */
131: switch (condition)
132: {
133: case GDK_INPUT_READ:
134: type = HTEvent_READ;
135: break;
136: case GDK_INPUT_WRITE:
137: type = HTEvent_WRITE;
138: break;
139: case GDK_INPUT_EXCEPTION:
140: type = HTEvent_OOB;
141: break;
142: default:
143: type = HTEvent_ALL;
144: break;
145: } /* switch */
146:
147: /* Invokes the callback associated to the requests */
148:
149: /** CanDoStop_set (FALSE); **/
150: if ((status = HTEventList_dispatch (socket, type, now)) != HT_OK)
151: {
152: #ifdef DEBUG_LIBWWW
153: HTTrace ("Callback.... returned a value != HT_OK");
154: #endif
155: }
156: /*** CanDoStop_set (TRUE); **/
157: }
1.94 gully 158: #endif /* _GTK */
159:
160:
161: #if defined(_WX)
162: static void AHTCallback_bridgeWX ( int register_id, int socket, wxAmayaSocketCondition condition)
163: {
164: int status; /* the status result of the libwwww call */
165: HTEventType type = HTEvent_ALL;
166: int v;
167: ms_t now = HTGetTimeInMillis();
168:
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 WXAMAYASOCKET_READ:
178: type = HTEvent_READ;
179: break;
180: case WXAMAYASOCKET_WRITE:
181: type = HTEvent_WRITE;
182: break;
183: case WXAMAYASOCKET_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: }
202: #endif /* _WX */
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.91 gully 213: AHTReqContext *me = (AHTReqContext *)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.92 cvs 271: #ifdef _WINGUI
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.92 cvs 328: #endif /* _WINGUI */
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.96 ! vatton 349: #if defined(_GTK) || defined(_WX)
1.94 gully 350: /* need something special for HTEvent_CLOSE */
1.58 cvs 351: if (type & ReadBits)
352: RequestRegisterReadXtevent (sock);
353:
354: if (type & WriteBits)
355: RequestRegisterWriteXtevent (sock);
356:
357: if (type & ExceptBits)
358: RequestRegisterExceptXtevent (sock);
1.96 ! vatton 359: #endif /* defined(_GTK) || defined(_WX) */
1.94 gully 360: #ifdef _WINDOWS
1.50 cvs 361: /* under windows, libwww requires an explicit FD_CLOSE registration
1.58 cvs 362: to detect HTTP responses not having a Content-Length header */
1.95 cvs 363: status = HTEventList_register (sock, (HTEventType)(type | HTEvent_CLOSE) , event);
1.94 gully 364: #endif /* _WINDOWS */
365: #if defined(_UNIX)
1.58 cvs 366: status = HTEventList_register (sock, type, event);
1.94 gully 367: #endif /* #if defined(_UNIX) */
1.96 ! vatton 368:
1.58 cvs 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.96 ! vatton 386: #if defined(_GTK) || defined(_WX)
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.96 ! vatton 396: #endif /* #if defined(_GTK) || defined(_WX) */
1.35 cvs 397:
1.58 cvs 398: /* @@@ if this is the default for windows, no need to have AHTEvent_..
399: in windows!! */
400: /* call libwww's default routine */
401: status = HTEventList_unregister (sock, type);
1.7 cvs 402: return (status);
1.4 cvs 403: }
1.35 cvs 404:
1.58 cvs 405: /* Private functions */
406:
1.11 cvs 407: /*----------------------------------------------------------------------
408: RequestKillAllXtevents
409: front-end for kill all Xt events associated with the request pointed
410: to by "me".
411: ----------------------------------------------------------------------*/
1.79 cvs 412: void RequestKillAllXtevents (AHTReqContext * me)
1.4 cvs 413: {
1.96 ! vatton 414: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 415: int sock = INVSOC;
416:
417: return;
418: /* @@@ what to do with this one? @@@ */
419: if (me->read_sock != INVSOC)
420: sock = me->read_sock;
421: else
422: if (me->write_sock != INVSOC)
423: sock = me->write_sock;
424: else
425: if (me->except_sock != INVSOC)
426: sock = me->except_sock;
427:
428: #ifdef DEBUG_LIBWWW
1.7 cvs 429: if (THD_TRACE)
1.58 cvs 430: fprintf (stderr, "RequestKillAllXtEvents: Clearing XtInputs\n");
431: #endif /* DEBUG_LIBWWW */
1.4 cvs 432:
1.58 cvs 433: RequestKillReadXtevent (sock);
434: RequestKillWriteXtevent (sock);
435: RequestKillExceptXtevent (sock);
1.96 ! vatton 436: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.4 cvs 437: }
438:
1.11 cvs 439: /*----------------------------------------------------------------------
1.18 cvs 440: RequestRegisterReadXtevent
441: Registers with Xt the read events associated with socket sock
442: ----------------------------------------------------------------------*/
1.79 cvs 443: static void RequestRegisterReadXtevent (SOCKET sock)
1.18 cvs 444: {
1.96 ! vatton 445: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 446: int v;
447:
448: v = HASH (sock);
449: if (!persSockets[v].read)
1.18 cvs 450: {
1.94 gully 451: #if defined(_GTK)
1.96 ! vatton 452: persSockets[v].read = gdk_input_add ((gint) sock,
! 453: GDK_INPUT_READ,
! 454: AHTCallback_bridgeGTK,
! 455: (gpointer) sock);
1.94 gully 456: #endif /* _GTK */
457: #if defined(_WX)
1.96 ! vatton 458: persSockets[v].read = wxAmayaSocketEvent::RegisterSocket( sock,
1.94 gully 459: WXAMAYASOCKET_READ,
460: AHTCallback_bridgeWX );
461: #endif /* _WX */
1.79 cvs 462:
1.58 cvs 463: #ifdef DEBUG_LIBWWW
1.18 cvs 464: if (THD_TRACE)
1.58 cvs 465: fprintf (stderr, "RegisterReadXtEvent: adding XtInput %lu Socket %d\n",
466: persSockets[v].read, sock);
467: #endif /* DEBUG_LIBWWW */
1.18 cvs 468: }
1.96 ! vatton 469: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.18 cvs 470: }
471:
472: /*----------------------------------------------------------------------
1.11 cvs 473: RequestKillReadXtevent
474: kills any read Xt event associated with the request pointed to by "me".
475: ----------------------------------------------------------------------*/
1.79 cvs 476: static void RequestKillReadXtevent (SOCKET sock)
1.4 cvs 477: {
1.96 ! vatton 478: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 479: int v;
480:
481: v = HASH (sock);
482: if (persSockets[v].read)
483: {
484: #ifdef DEBUG_LIBWWW
485: if (THD_TRACE)
486: fprintf (stderr, "UnregisterReadXtEvent: Clearing XtInput %lu\n",
487: persSockets[v].read);
488: #endif /* DEBUG_LIBWWW */
1.85 gully 489:
1.94 gully 490: #if defined(_GTK)
1.79 cvs 491: gdk_input_remove (persSockets[v].read);
492: persSockets[v].read = (gint) 0;
493: #endif /* !_GTK */
1.94 gully 494: #if defined(_WX)
495: wxAmayaSocketEvent::UnregisterSocket( persSockets[v].read );
496: persSockets[v].read = 0;
497: #endif /* _WX */
498:
1.58 cvs 499: }
1.96 ! vatton 500: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.18 cvs 501: }
502:
503: /*----------------------------------------------------------------------
504: RequestRegisterWriteXtevent
505: Registers with Xt the write events associated with socket sock
506: ----------------------------------------------------------------------*/
1.79 cvs 507: static void RequestRegisterWriteXtevent (SOCKET sock)
1.18 cvs 508: {
1.96 ! vatton 509: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 510: int v;
1.96 ! vatton 511:
1.58 cvs 512: v = HASH (sock);
513: if (!persSockets[v].write)
514: {
1.94 gully 515: #if defined(_GTK)
1.96 ! vatton 516: persSockets[v].write = gdk_input_add ((gint) sock,
! 517: GDK_INPUT_WRITE,
! 518: AHTCallback_bridgeGTK,
! 519: (gpointer) sock);
1.94 gully 520: #endif /* _GTK */
521: #if defined(_WX)
1.96 ! vatton 522: persSockets[v].write = wxAmayaSocketEvent::RegisterSocket( sock,
1.94 gully 523: WXAMAYASOCKET_WRITE,
524: AHTCallback_bridgeWX );
525: #endif /* _WX */
1.79 cvs 526:
1.58 cvs 527: #ifdef DEBUG_LIBWWW
1.18 cvs 528: if (THD_TRACE)
1.58 cvs 529: fprintf (stderr, "RegisterWriteXtEvent: Adding XtInput %lu Socket %d\n",
530: persSockets[v].write, sock);
531: #endif /* DEBUG_LIBWWW */
532:
533: }
1.96 ! vatton 534: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.4 cvs 535: }
536:
1.11 cvs 537: /*----------------------------------------------------------------------
538: RequestKillWriteXtevent
539: kills any write Xt event associated with the request pointed to
540: by "me".
541: ----------------------------------------------------------------------*/
1.79 cvs 542: static void RequestKillWriteXtevent (SOCKET sock)
1.4 cvs 543: {
1.96 ! vatton 544: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 545: int v;
546:
547: v = HASH (sock);
548: if (persSockets[v].write)
549: {
550: #ifdef DEBUG_LIBWWW
551: if (THD_TRACE)
552: fprintf (stderr, "UnRegisterWriteXtEvent: Clearing Write XtInputs "
553: "%lu\n",
554: persSockets[v].write);
555: #endif /* DEBUG_LIBWWW */
1.85 gully 556:
1.94 gully 557: #if defined(_GTK)
1.79 cvs 558: gdk_input_remove (persSockets[v].write);
559: persSockets[v].write = (gint) 0;
1.85 gully 560: #endif /* _GTK */
1.94 gully 561: #if defined(_WX)
562: wxAmayaSocketEvent::UnregisterSocket( persSockets[v].write );
563: persSockets[v].write = 0;
564: #endif /* _WX */
565:
1.58 cvs 566: }
1.96 ! vatton 567: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.18 cvs 568: }
569:
570: /*----------------------------------------------------------------------
571: RequestRegisterExceptXtevent
572: Registers with Xt the except events associated with socket sock
573: ----------------------------------------------------------------------*/
1.79 cvs 574: static void RequestRegisterExceptXtevent (SOCKET sock)
1.18 cvs 575: {
1.96 ! vatton 576: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 577: int v;
578:
579: v = HASH (sock);
580: if (!persSockets[v].except)
1.18 cvs 581: {
1.94 gully 582: #if defined(_GTK)
1.96 ! vatton 583: persSockets[v].except = gdk_input_add ((gint) sock,
! 584: GDK_INPUT_EXCEPTION,
! 585: AHTCallback_bridgeGTK,
! 586: (gpointer) sock);
1.85 gully 587: #endif /* _GTK */
1.94 gully 588: #if defined(_WX)
589: persSockets[v].except =
590: wxAmayaSocketEvent::RegisterSocket( sock,
591: WXAMAYASOCKET_EXCEPTION,
592: AHTCallback_bridgeWX );
593: #endif /* _WX */
594:
595: #ifdef DEBUG_LIBWWW
1.58 cvs 596: if (THD_TRACE)
597: fprintf (stderr, "RegisterExceptXtEvent: adding XtInput %lu Socket %d\n",
598: persSockets[v].except, sock);
599: #endif /* DEBUG_LIBWWW */
1.18 cvs 600: }
1.96 ! vatton 601: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.4 cvs 602: }
603:
1.11 cvs 604: /*----------------------------------------------------------------------
605: RequestKillExceptXtevent
606: kills any exception Xt event associated with the request pointed to
607: by "me".
608: ----------------------------------------------------------------------*/
1.79 cvs 609: static void RequestKillExceptXtevent (SOCKET sock)
1.4 cvs 610: {
1.96 ! vatton 611: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 612: int v;
613:
614: v = HASH (sock);
615: if (persSockets[v].except)
616: {
617: #ifdef DEBUG_LIBWWW
618: if (THD_TRACE)
619: fprintf (stderr, "UnregisterExceptXtEvent: Clearing Except XtInputs "
620: "%lu\n", persSockets[v].except);
621: #endif /* DEBUG_LIBWWW */
1.85 gully 622:
1.94 gully 623: #if defined(_GTK)
1.79 cvs 624: gdk_input_remove (persSockets[v].except);
625: persSockets[v].except = (gint) 0;
1.85 gully 626: #endif /* _GTK */
1.94 gully 627: #if defined(_WX)
628: wxAmayaSocketEvent::UnregisterSocket( persSockets[v].except );
629: persSockets[v].except = 0;
630: #endif /* _WX */
1.58 cvs 631: }
1.96 ! vatton 632: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.58 cvs 633: }
634:
635: /*----------------------------------------------------------------------
636: Xt Timer functions
637: ----------------------------------------------------------------------*/
638:
639: struct _HTTimer {
1.96 ! vatton 640: ms_t millis; /* Relative value in millis */
! 641: ms_t expires; /* Absolute value in millis */
! 642: BOOL relative;
! 643: BOOL repetitive;
! 644: void * param; /* Client supplied context */
! 645: HTTimerCallback * cbf;
1.58 cvs 646: };
647:
648: struct _AmayaTimer {
649: HTTimer *libwww_timer;
1.85 gully 650: #ifdef _GTK
1.79 cvs 651: guint xt_timer;
1.85 gully 652: #endif /* _GTK */
1.94 gully 653: #ifdef _WX
654: wxAmayaTimer * xt_timer;
655: #endif /* _WX */
1.85 gully 656: #ifdef _NOGUI
657: unsigned int xt_timer;
658: #endif /* #ifdef _NOGUI */
1.58 cvs 659: };
660: typedef struct _AmayaTimer AmayaTimer;
661:
662: static HTList *Timers = NULL;
663:
664: /*----------------------------------------------------------------------
1.79 cvs 665: TimerCallback
666: called by the system event loop. Timers shouldn't be restarted
667: on exiting.
1.58 cvs 668: ----------------------------------------------------------------------*/
669: void *TimerCallback (XtPointer cdata, XtIntervalId *id)
670: {
671: return (0);
672: }
1.86 gully 673:
1.85 gully 674: #ifdef _GTK
1.79 cvs 675: /*----------------------------------------------------------------------
676: TimerCallbackGTK
1.81 kahan 677: The callback returns FALSE to destroy the timer that called it.
1.79 cvs 678: ----------------------------------------------------------------------*/
679: gboolean TimerCallbackGTK (gpointer id)
680: {
681: HTList *cur, *last;
682: AmayaTimer *me;
683: HTTimer *libwww_timer;
684: AmayaTimer *data;
685:
686: data = (AmayaTimer *) id;
687:
688: if (!AmayaIsAlive ()
689: || Timers == NULL)
1.81 kahan 690: return (FALSE);
1.79 cvs 691:
692: /* find the timer from the uid */
693: last = cur = Timers;
694: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
695: {
696: if (me == data)
697: break;
698: last = cur;
699: }
700:
701: if (me)
702: {
703: libwww_timer = me->libwww_timer;
704: /* remove the element from the list @@@ can be optimized later */
705: HTList_quickRemoveElement(cur, last);
706: TtaFreeMemory (me);
707: HTTimer_dispatch (libwww_timer);
708: }
709: return (FALSE);
710: }
1.85 gully 711: #endif /* _GTK */
1.79 cvs 712:
1.58 cvs 713: /*----------------------------------------------------------------------
1.94 gully 714: TimerCallbackWX
715: called when a timer is throw
716: ----------------------------------------------------------------------*/
717: void TimerCallbackWX( void * p_context )
718: {
719: #ifdef _WX
720: HTList *cur, *last;
721: AmayaTimer *me;
722: HTTimer *libwww_timer;
723: AmayaTimer *data;
724:
725: data = (AmayaTimer *)p_context;
726:
727: if (!AmayaIsAlive ()
728: || Timers == NULL)
729: return;
730:
731: /* find the timer from the uid */
732: last = cur = Timers;
733: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
734: {
735: if (me == data)
736: break;
737: last = cur;
738: }
739:
740: if (me)
741: {
742: libwww_timer = me->libwww_timer;
743: /* remove the element from the list @@@ can be optimized later */
744: HTList_quickRemoveElement(cur, last);
745:
746: /* delete explicitely the AmayaTimer */
747: delete wxDynamicCast(me->xt_timer, wxAmayaTimer);
748:
749: TtaFreeMemory (me);
750: HTTimer_dispatch (libwww_timer);
751: }
752: #endif /* _WX */
753: }
754:
755: /*----------------------------------------------------------------------
1.59 cvs 756: KillAllTimers
1.58 cvs 757: ----------------------------------------------------------------------*/
1.59 cvs 758: void KillAllTimers (void)
1.58 cvs 759: {
1.96 ! vatton 760: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 761: /* @@@ maybe add something else to kill the Xt things */
762: if (Timers)
763: HTList_delete (Timers);
1.65 cvs 764: Timers = NULL;
1.96 ! vatton 765: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.58 cvs 766: }
767:
768: /*----------------------------------------------------------------------
1.59 cvs 769: AMAYA_SetTimer
770: ----------------------------------------------------------------------*/
771: void AMAYA_SetTimer (HTTimer *libwww_timer)
1.58 cvs 772: {
1.96 ! vatton 773: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 774: HTList *cur, *last;
775: AmayaTimer *me;
776:
1.90 gully 777: if (!AmayaIsAlive ()
1.58 cvs 778: || libwww_timer == NULL
779: || libwww_timer->expires == 0)
780: return;
781:
782: if (Timers == NULL)
783: Timers = HTList_new ();
784:
785: /* see if this timer existed already */
786: last = cur = Timers;
787: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
788: {
789: if (me->libwww_timer == libwww_timer)
790: break;
791: last = cur;
792: }
793:
794: if (me)
795: {
796: /* remove the old timer */
797: if (me->xt_timer)
798: {
1.85 gully 799: #ifdef _GTK
1.79 cvs 800: gtk_timeout_remove (me->xt_timer);
801: me->xt_timer = (guint) 0;
802: #endif /* !_GTK */
1.94 gully 803: #ifdef _WX
804: delete wxDynamicCast(me->xt_timer, wxTimer);
805: me->xt_timer = NULL;
806: #endif /* _WX */
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,
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.96 ! vatton 830: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
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.96 ! vatton 838: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
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.58 cvs 850: break;
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
861: delete wxDynamicCast(me->xt_timer, wxTimer);
862: #endif /* _WX */
863:
1.58 cvs 864: /* and the element from the list */
1.65 cvs 865: HTList_removeObject (Timers, me);
1.58 cvs 866: TtaFreeMemory (me);
867: }
1.96 ! vatton 868: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.31 cvs 869: }
1.86 gully 870:
Webmaster