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