Annotation of Amaya/amaya/AHTBridge.c, revision 1.100
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.100 ! gully 271: #ifdef _WINDOWS
1.29 cvs 272: /*----------------------------------------------------------------
1.32 cvs 273: WIN_Activate_Request
1.29 cvs 274: when there are more open requests than available sockets, the
275: requests are put in a "pending state." When a socket becomes
276: available, libwww associates it with a pending request and then
277: calls this callback function. This function is responsible for
278: opening the temporary file where the GET and POST results
279: will be stored. The function is also responsible for
280: registering the socket with the Xt event loop.
281: Consult the libwww manual for more details on the signature
282: of this function.
283: ----------------------------------------------------------------*/
1.97 vatton 284: int WIN_Activate_Request (HTRequest * request, HTAlertOpcode op,
285: int msgnum, const char *dfault, void *input,
286: HTAlertPar * reply)
1.29 cvs 287: {
1.100 ! gully 288: AHTReqContext *me = (AHTReqContext *)HTRequest_context (request);
1.29 cvs 289:
1.58 cvs 290: if (me->reqStatus == HT_NEW)
291: {
292: if (!(me->output)
293: && (me->output != stdout)
294: && me->outputfile
1.99 cvs 295: && ((me->output = TtaWriteOpen (me->outputfile)) == NULL))
1.97 vatton 296: {
1.58 cvs 297: /* the request is associated with a file */
1.78 cvs 298: me->outputfile[0] = EOS; /* file could not be opened */
1.97 vatton 299: TtaSetStatus (me->docid, 1,
300: TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE), me->outputfile);
1.58 cvs 301: me->reqStatus = HT_ERR;
302:
303: if (me->error_html)
1.97 vatton 304: /* so we can show the error message */
305: DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR;
1.58 cvs 306: }
307: else
308: {
309: #ifdef DEBUG_LIBWWW
310: if (THD_TRACE)
311: fprintf (stderr, "WIN_Activate_Request: Activating pending %s. "
312: "Open fd %d\n", me->urlName, (int) me->output);
313: #endif /* DEBUG_LIBWWW */
1.97 vatton 314: HTRequest_setOutputStream (me->request,
315: AHTFWriter_new (me->request, me->output, YES));
1.58 cvs 316: /*change the status of the request */
317: me->reqStatus = HT_WAITING;
318: }
319: }
320: else if (me->reqStatus == HT_WAITING)
321: {
322: /*change the status of the request */
323: rewind (me->output);
324: if (HTRequest_outputStream (me->request) == NULL)
325: HTRequest_setOutputStream (me->request, AHTFWriter_new (me->request, me->output, YES));
326: }
1.32 cvs 327: else {
1.36 cvs 328: me->reqStatus = HT_ERR;
1.32 cvs 329: }
330:
1.36 cvs 331: return ((me->reqStatus != HT_ERR) ? HT_OK : HT_ERROR);
1.32 cvs 332: }
333:
1.100 ! gully 334: #endif /* _WINDOWS */
1.60 cvs 335:
1.11 cvs 336: /*----------------------------------------------------------------------
337: AHTEvent_register
338: callback called by libwww whenever a socket is open and associated
339: to a request. It sets the pertinent Xt events so that the Xt Event
340: loops gets an interruption whenever there's action of the socket.
341: In addition, it registers the request with libwww.
342: ----------------------------------------------------------------------*/
1.58 cvs 343: int AHTEvent_register (SOCKET sock, HTEventType type, HTEvent *event)
1.4 cvs 344: {
1.85 gully 345: int status = 0;
1.7 cvs 346:
1.40 cvs 347: if (sock == INVSOC)
348: {
1.36 cvs 349: #ifdef DEBUG_LIBWWW
1.58 cvs 350: fprintf(stderr, "AHTEvent_register: sock = INVSOC\n");
1.37 cvs 351: #endif /* DEBUG_LIBWWW */
1.58 cvs 352: return (0);
353: }
1.100 ! gully 354: else
! 355: {
1.96 vatton 356: #if defined(_GTK) || defined(_WX)
1.94 gully 357: /* need something special for HTEvent_CLOSE */
1.58 cvs 358: if (type & ReadBits)
359: RequestRegisterReadXtevent (sock);
360:
361: if (type & WriteBits)
362: RequestRegisterWriteXtevent (sock);
363:
364: if (type & ExceptBits)
365: RequestRegisterExceptXtevent (sock);
1.96 vatton 366: #endif /* defined(_GTK) || defined(_WX) */
1.94 gully 367: #ifdef _WINDOWS
1.50 cvs 368: /* under windows, libwww requires an explicit FD_CLOSE registration
1.58 cvs 369: to detect HTTP responses not having a Content-Length header */
1.95 cvs 370: status = HTEventList_register (sock, (HTEventType)(type | HTEvent_CLOSE) , event);
1.94 gully 371: #endif /* _WINDOWS */
372: #if defined(_UNIX)
1.58 cvs 373: status = HTEventList_register (sock, type, event);
1.94 gully 374: #endif /* #if defined(_UNIX) */
1.96 vatton 375:
1.58 cvs 376: return (status);
1.100 ! gully 377: }
1.58 cvs 378: }
1.50 cvs 379:
1.34 cvs 380: /*----------------------------------------------------------------------
381: AHTEvent_unregister
382: callback called by libwww each time a request is unregistered. This
383: function takes care of unregistering the pertinent Xt events
384: associated with the request's socket. In addition, it unregisters
385: the request from libwww.
386: ----------------------------------------------------------------------*/
1.58 cvs 387: int AHTEvent_unregister (SOCKET sock, HTEventType type)
1.34 cvs 388: {
1.58 cvs 389: int status;
1.76 kahan 390:
391: if (sock == INVSOC)
392: return HT_OK;
1.38 cvs 393:
1.96 vatton 394: #if defined(_GTK) || defined(_WX)
1.58 cvs 395: /* remove the Xt event hooks */
396: if (type & ReadBits)
397: RequestKillReadXtevent (sock);
398:
399: if (type & WriteBits)
400: RequestKillWriteXtevent (sock);
401:
402: if (type & ExceptBits)
403: RequestKillExceptXtevent (sock);
1.96 vatton 404: #endif /* #if defined(_GTK) || defined(_WX) */
1.35 cvs 405:
1.58 cvs 406: /* @@@ if this is the default for windows, no need to have AHTEvent_..
407: in windows!! */
408: /* call libwww's default routine */
409: status = HTEventList_unregister (sock, type);
1.7 cvs 410: return (status);
1.4 cvs 411: }
1.35 cvs 412:
1.58 cvs 413: /* Private functions */
414:
1.11 cvs 415: /*----------------------------------------------------------------------
416: RequestKillAllXtevents
417: front-end for kill all Xt events associated with the request pointed
418: to by "me".
419: ----------------------------------------------------------------------*/
1.79 cvs 420: void RequestKillAllXtevents (AHTReqContext * me)
1.4 cvs 421: {
1.96 vatton 422: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 423: int sock = INVSOC;
424:
425: return;
426: /* @@@ what to do with this one? @@@ */
427: if (me->read_sock != INVSOC)
428: sock = me->read_sock;
429: else
430: if (me->write_sock != INVSOC)
431: sock = me->write_sock;
432: else
433: if (me->except_sock != INVSOC)
434: sock = me->except_sock;
435:
436: #ifdef DEBUG_LIBWWW
1.7 cvs 437: if (THD_TRACE)
1.58 cvs 438: fprintf (stderr, "RequestKillAllXtEvents: Clearing XtInputs\n");
439: #endif /* DEBUG_LIBWWW */
1.4 cvs 440:
1.58 cvs 441: RequestKillReadXtevent (sock);
442: RequestKillWriteXtevent (sock);
443: RequestKillExceptXtevent (sock);
1.96 vatton 444: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.4 cvs 445: }
446:
1.11 cvs 447: /*----------------------------------------------------------------------
1.18 cvs 448: RequestRegisterReadXtevent
449: Registers with Xt the read events associated with socket sock
450: ----------------------------------------------------------------------*/
1.79 cvs 451: static void RequestRegisterReadXtevent (SOCKET sock)
1.18 cvs 452: {
1.96 vatton 453: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 454: int v;
455:
456: v = HASH (sock);
457: if (!persSockets[v].read)
1.18 cvs 458: {
1.94 gully 459: #if defined(_GTK)
1.96 vatton 460: persSockets[v].read = gdk_input_add ((gint) sock,
461: GDK_INPUT_READ,
462: AHTCallback_bridgeGTK,
463: (gpointer) sock);
1.94 gully 464: #endif /* _GTK */
465: #if defined(_WX)
1.96 vatton 466: persSockets[v].read = wxAmayaSocketEvent::RegisterSocket( sock,
1.94 gully 467: WXAMAYASOCKET_READ,
468: AHTCallback_bridgeWX );
469: #endif /* _WX */
1.79 cvs 470:
1.58 cvs 471: #ifdef DEBUG_LIBWWW
1.18 cvs 472: if (THD_TRACE)
1.58 cvs 473: fprintf (stderr, "RegisterReadXtEvent: adding XtInput %lu Socket %d\n",
474: persSockets[v].read, sock);
475: #endif /* DEBUG_LIBWWW */
1.18 cvs 476: }
1.96 vatton 477: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.18 cvs 478: }
479:
480: /*----------------------------------------------------------------------
1.11 cvs 481: RequestKillReadXtevent
482: kills any read Xt event associated with the request pointed to by "me".
483: ----------------------------------------------------------------------*/
1.79 cvs 484: static void RequestKillReadXtevent (SOCKET sock)
1.4 cvs 485: {
1.96 vatton 486: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 487: int v;
488:
489: v = HASH (sock);
490: if (persSockets[v].read)
491: {
492: #ifdef DEBUG_LIBWWW
493: if (THD_TRACE)
494: fprintf (stderr, "UnregisterReadXtEvent: Clearing XtInput %lu\n",
495: persSockets[v].read);
496: #endif /* DEBUG_LIBWWW */
1.85 gully 497:
1.94 gully 498: #if defined(_GTK)
1.79 cvs 499: gdk_input_remove (persSockets[v].read);
500: persSockets[v].read = (gint) 0;
501: #endif /* !_GTK */
1.94 gully 502: #if defined(_WX)
503: wxAmayaSocketEvent::UnregisterSocket( persSockets[v].read );
504: persSockets[v].read = 0;
505: #endif /* _WX */
506:
1.58 cvs 507: }
1.96 vatton 508: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.18 cvs 509: }
510:
511: /*----------------------------------------------------------------------
512: RequestRegisterWriteXtevent
513: Registers with Xt the write events associated with socket sock
514: ----------------------------------------------------------------------*/
1.79 cvs 515: static void RequestRegisterWriteXtevent (SOCKET sock)
1.18 cvs 516: {
1.96 vatton 517: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 518: int v;
1.96 vatton 519:
1.58 cvs 520: v = HASH (sock);
521: if (!persSockets[v].write)
522: {
1.94 gully 523: #if defined(_GTK)
1.96 vatton 524: persSockets[v].write = gdk_input_add ((gint) sock,
525: GDK_INPUT_WRITE,
526: AHTCallback_bridgeGTK,
527: (gpointer) sock);
1.94 gully 528: #endif /* _GTK */
529: #if defined(_WX)
1.96 vatton 530: persSockets[v].write = wxAmayaSocketEvent::RegisterSocket( sock,
1.94 gully 531: WXAMAYASOCKET_WRITE,
532: AHTCallback_bridgeWX );
533: #endif /* _WX */
1.79 cvs 534:
1.58 cvs 535: #ifdef DEBUG_LIBWWW
1.18 cvs 536: if (THD_TRACE)
1.58 cvs 537: fprintf (stderr, "RegisterWriteXtEvent: Adding XtInput %lu Socket %d\n",
538: persSockets[v].write, sock);
539: #endif /* DEBUG_LIBWWW */
540:
541: }
1.96 vatton 542: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.4 cvs 543: }
544:
1.11 cvs 545: /*----------------------------------------------------------------------
546: RequestKillWriteXtevent
547: kills any write Xt event associated with the request pointed to
548: by "me".
549: ----------------------------------------------------------------------*/
1.79 cvs 550: static void RequestKillWriteXtevent (SOCKET sock)
1.4 cvs 551: {
1.96 vatton 552: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 553: int v;
554:
555: v = HASH (sock);
556: if (persSockets[v].write)
557: {
558: #ifdef DEBUG_LIBWWW
559: if (THD_TRACE)
560: fprintf (stderr, "UnRegisterWriteXtEvent: Clearing Write XtInputs "
561: "%lu\n",
562: persSockets[v].write);
563: #endif /* DEBUG_LIBWWW */
1.85 gully 564:
1.94 gully 565: #if defined(_GTK)
1.79 cvs 566: gdk_input_remove (persSockets[v].write);
567: persSockets[v].write = (gint) 0;
1.85 gully 568: #endif /* _GTK */
1.94 gully 569: #if defined(_WX)
570: wxAmayaSocketEvent::UnregisterSocket( persSockets[v].write );
571: persSockets[v].write = 0;
572: #endif /* _WX */
573:
1.58 cvs 574: }
1.96 vatton 575: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.18 cvs 576: }
577:
578: /*----------------------------------------------------------------------
579: RequestRegisterExceptXtevent
580: Registers with Xt the except events associated with socket sock
581: ----------------------------------------------------------------------*/
1.79 cvs 582: static void RequestRegisterExceptXtevent (SOCKET sock)
1.18 cvs 583: {
1.96 vatton 584: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 585: int v;
586:
587: v = HASH (sock);
588: if (!persSockets[v].except)
1.18 cvs 589: {
1.94 gully 590: #if defined(_GTK)
1.96 vatton 591: persSockets[v].except = gdk_input_add ((gint) sock,
592: GDK_INPUT_EXCEPTION,
593: AHTCallback_bridgeGTK,
594: (gpointer) sock);
1.85 gully 595: #endif /* _GTK */
1.94 gully 596: #if defined(_WX)
597: persSockets[v].except =
598: wxAmayaSocketEvent::RegisterSocket( sock,
599: WXAMAYASOCKET_EXCEPTION,
600: AHTCallback_bridgeWX );
601: #endif /* _WX */
602:
603: #ifdef DEBUG_LIBWWW
1.58 cvs 604: if (THD_TRACE)
605: fprintf (stderr, "RegisterExceptXtEvent: adding XtInput %lu Socket %d\n",
606: persSockets[v].except, sock);
607: #endif /* DEBUG_LIBWWW */
1.18 cvs 608: }
1.96 vatton 609: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.4 cvs 610: }
611:
1.11 cvs 612: /*----------------------------------------------------------------------
613: RequestKillExceptXtevent
614: kills any exception Xt event associated with the request pointed to
615: by "me".
616: ----------------------------------------------------------------------*/
1.79 cvs 617: static void RequestKillExceptXtevent (SOCKET sock)
1.4 cvs 618: {
1.96 vatton 619: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 620: int v;
621:
622: v = HASH (sock);
623: if (persSockets[v].except)
624: {
625: #ifdef DEBUG_LIBWWW
626: if (THD_TRACE)
627: fprintf (stderr, "UnregisterExceptXtEvent: Clearing Except XtInputs "
628: "%lu\n", persSockets[v].except);
629: #endif /* DEBUG_LIBWWW */
1.85 gully 630:
1.94 gully 631: #if defined(_GTK)
1.79 cvs 632: gdk_input_remove (persSockets[v].except);
633: persSockets[v].except = (gint) 0;
1.85 gully 634: #endif /* _GTK */
1.94 gully 635: #if defined(_WX)
636: wxAmayaSocketEvent::UnregisterSocket( persSockets[v].except );
637: persSockets[v].except = 0;
638: #endif /* _WX */
1.58 cvs 639: }
1.96 vatton 640: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.58 cvs 641: }
642:
643: /*----------------------------------------------------------------------
644: Xt Timer functions
645: ----------------------------------------------------------------------*/
646:
647: struct _HTTimer {
1.96 vatton 648: ms_t millis; /* Relative value in millis */
649: ms_t expires; /* Absolute value in millis */
650: BOOL relative;
651: BOOL repetitive;
652: void * param; /* Client supplied context */
653: HTTimerCallback * cbf;
1.58 cvs 654: };
655:
656: struct _AmayaTimer {
657: HTTimer *libwww_timer;
1.85 gully 658: #ifdef _GTK
1.79 cvs 659: guint xt_timer;
1.85 gully 660: #endif /* _GTK */
1.94 gully 661: #ifdef _WX
662: wxAmayaTimer * xt_timer;
663: #endif /* _WX */
1.85 gully 664: #ifdef _NOGUI
665: unsigned int xt_timer;
666: #endif /* #ifdef _NOGUI */
1.58 cvs 667: };
668: typedef struct _AmayaTimer AmayaTimer;
669:
670: static HTList *Timers = NULL;
671:
672: /*----------------------------------------------------------------------
1.79 cvs 673: TimerCallback
674: called by the system event loop. Timers shouldn't be restarted
675: on exiting.
1.58 cvs 676: ----------------------------------------------------------------------*/
677: void *TimerCallback (XtPointer cdata, XtIntervalId *id)
678: {
679: return (0);
680: }
1.86 gully 681:
1.85 gully 682: #ifdef _GTK
1.79 cvs 683: /*----------------------------------------------------------------------
684: TimerCallbackGTK
1.81 kahan 685: The callback returns FALSE to destroy the timer that called it.
1.79 cvs 686: ----------------------------------------------------------------------*/
687: gboolean TimerCallbackGTK (gpointer id)
688: {
689: HTList *cur, *last;
690: AmayaTimer *me;
691: HTTimer *libwww_timer;
692: AmayaTimer *data;
693:
694: data = (AmayaTimer *) id;
695:
696: if (!AmayaIsAlive ()
697: || Timers == NULL)
1.81 kahan 698: return (FALSE);
1.79 cvs 699:
700: /* find the timer from the uid */
701: last = cur = Timers;
702: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
703: {
704: if (me == data)
705: break;
706: last = cur;
707: }
708:
709: if (me)
710: {
711: libwww_timer = me->libwww_timer;
712: /* remove the element from the list @@@ can be optimized later */
713: HTList_quickRemoveElement(cur, last);
714: TtaFreeMemory (me);
715: HTTimer_dispatch (libwww_timer);
716: }
717: return (FALSE);
718: }
1.85 gully 719: #endif /* _GTK */
1.79 cvs 720:
1.58 cvs 721: /*----------------------------------------------------------------------
1.94 gully 722: TimerCallbackWX
723: called when a timer is throw
724: ----------------------------------------------------------------------*/
725: void TimerCallbackWX( void * p_context )
726: {
727: #ifdef _WX
728: HTList *cur, *last;
729: AmayaTimer *me;
730: HTTimer *libwww_timer;
731: AmayaTimer *data;
732:
733: data = (AmayaTimer *)p_context;
734:
735: if (!AmayaIsAlive ()
736: || Timers == NULL)
737: return;
738:
739: /* find the timer from the uid */
740: last = cur = Timers;
741: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
742: {
743: if (me == data)
744: break;
745: last = cur;
746: }
747:
748: if (me)
749: {
750: libwww_timer = me->libwww_timer;
751: /* remove the element from the list @@@ can be optimized later */
752: HTList_quickRemoveElement(cur, last);
753:
754: /* delete explicitely the AmayaTimer */
755: delete wxDynamicCast(me->xt_timer, wxAmayaTimer);
756:
757: TtaFreeMemory (me);
758: HTTimer_dispatch (libwww_timer);
759: }
760: #endif /* _WX */
761: }
762:
763: /*----------------------------------------------------------------------
1.59 cvs 764: KillAllTimers
1.58 cvs 765: ----------------------------------------------------------------------*/
1.59 cvs 766: void KillAllTimers (void)
1.58 cvs 767: {
1.96 vatton 768: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 769: /* @@@ maybe add something else to kill the Xt things */
770: if (Timers)
771: HTList_delete (Timers);
1.65 cvs 772: Timers = NULL;
1.96 vatton 773: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.58 cvs 774: }
775:
776: /*----------------------------------------------------------------------
1.59 cvs 777: AMAYA_SetTimer
778: ----------------------------------------------------------------------*/
779: void AMAYA_SetTimer (HTTimer *libwww_timer)
1.58 cvs 780: {
1.96 vatton 781: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 782: HTList *cur, *last;
783: AmayaTimer *me;
784:
1.90 gully 785: if (!AmayaIsAlive ()
1.58 cvs 786: || libwww_timer == NULL
787: || libwww_timer->expires == 0)
788: return;
789:
790: if (Timers == NULL)
791: Timers = HTList_new ();
792:
793: /* see if this timer existed already */
794: last = cur = Timers;
795: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
796: {
797: if (me->libwww_timer == libwww_timer)
798: break;
799: last = cur;
800: }
801:
802: if (me)
803: {
804: /* remove the old timer */
805: if (me->xt_timer)
806: {
1.85 gully 807: #ifdef _GTK
1.79 cvs 808: gtk_timeout_remove (me->xt_timer);
809: me->xt_timer = (guint) 0;
810: #endif /* !_GTK */
1.94 gully 811: #ifdef _WX
812: delete wxDynamicCast(me->xt_timer, wxTimer);
813: me->xt_timer = NULL;
814: #endif /* _WX */
815: }
1.58 cvs 816: }
817: else
818: {
819: /* create a new element */
1.91 gully 820: me = (AmayaTimer*)TtaGetMemory (sizeof (AmayaTimer));
1.58 cvs 821: /* and add it to the list */
822: HTList_addObject(last, (void *) me);
823: me->libwww_timer = libwww_timer;
824: }
825:
826: /* add a new time out */
1.85 gully 827: #ifdef _GTK
1.79 cvs 828: me->xt_timer = gtk_timeout_add ((guint32) me->libwww_timer->millis,
829: (GtkFunction) TimerCallbackGTK,
830: (gpointer) me);
1.85 gully 831: #endif /* _GTK */
1.94 gully 832: #ifdef _WX
833: me->xt_timer = new wxAmayaTimer( TimerCallbackWX, me);
834: /* start a one shot timer */
835: me->xt_timer->Start( me->libwww_timer->millis, TRUE );
836: #endif /* _WX */
837:
1.96 vatton 838: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.58 cvs 839: }
840:
841: /*----------------------------------------------------------------------
1.59 cvs 842: AMAYA_DeleteTimer
1.58 cvs 843: ----------------------------------------------------------------------*/
1.59 cvs 844: void AMAYA_DeleteTimer (HTTimer *libwww_timer)
1.58 cvs 845: {
1.96 vatton 846: #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
1.58 cvs 847: HTList *cur, *last;
848: AmayaTimer *me;
849:
1.59 cvs 850: if (Timers == NULL || libwww_timer == NULL)
1.58 cvs 851: return;
852:
853: /* find the id */
854: last = cur = Timers;
855: while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
856: {
1.59 cvs 857: if (me->libwww_timer == libwww_timer)
1.58 cvs 858: break;
859: last = cur;
860: }
861:
862: if (me)
863: {
864: /* remove the Xt timer */
1.85 gully 865: #ifdef _GTK
1.79 cvs 866: gtk_timeout_remove (me->xt_timer);
1.85 gully 867: #endif /* _GTK */
1.94 gully 868: #ifdef _WX
869: delete wxDynamicCast(me->xt_timer, wxTimer);
870: #endif /* _WX */
871:
1.58 cvs 872: /* and the element from the list */
1.65 cvs 873: HTList_removeObject (Timers, me);
1.58 cvs 874: TtaFreeMemory (me);
875: }
1.96 vatton 876: #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
1.31 cvs 877: }
1.86 gully 878:
Webmaster