Return to AHTBridge.c CVS log | Up to [Public] / Amaya / amaya |
1.9 cvs 1: /* 2: * 1.84 vatton 3: * (c) COPYRIGHT INRIA and W3C, 1996-2003 1.9 cvs 4: * Please first read the full copyright statement in file COPYRIGHT. 5: * 6: */ 1.75 cvs 7: 1.14 cvs 8: /* 9: * AHTBridge.c : This module implements the callback setup and 10: * handlers between the Xt, libwww, and Amaya procedures. It's responsible 11: * for assigning, modifying, and supressing Xt events to the active 12: * requests. 13: * 14: * Author: J Kahan 1.67 cvs 15: * J. K./R. Guetari. Windows NT/95 routines 1.79 cvs 16: * J. K./S. Gully GTK routines 1.14 cvs 17: * 18: */ 1.68 cvs 19: #ifdef _GTK 1.85 gully 20: #include <glib.h> 1.68 cvs 21: #endif /* _GTK */ 22: 1.16 cvs 23: #define THOT_EXPORT extern 1.4 cvs 24: #include "amaya.h" 1.10 cvs 25: #include "AHTBridge_f.h" 26: #include "AHTFWrite_f.h" 27: #include "query_f.h" 28: #include "answer_f.h" 1.64 cvs 29: #include "HTEvtLst.h" 1.4 cvs 30: 1.58 cvs 31: #if 0 32: #define DEBUG_LIBWWW 33: #define THD_TRACE 1 34: #endif 35: 1.85 gully 36: #ifdef _MOTIF 37: /* Amaya's X appcontext */ 38: extern ThotAppContext app_cont; 39: #endif /* #ifdef _MOTIF */ 40: 41: #if defined(_MOTIF) || defined(_GTK) 42: /* Private functions */ 43: static void RequestRegisterReadXtevent (SOCKET); 44: static void RequestKillReadXtevent (SOCKET); 45: static void RequestRegisterWriteXtevent ( SOCKET); 46: static void RequestKillWriteXtevent (SOCKET); 47: static void RequestRegisterExceptXtevent ( SOCKET); 48: static void RequestKillExceptXtevent (SOCKET); 49: #endif /* #if defined(_MOTIF) || defined(_GTK) */ 1.24 cvs 50: 1.32 cvs 51: /* Private variables */ 1.4 cvs 52: 53: /* 1.58 cvs 54: * this set of HTEventType map our WinSock "socket event HTEventType" into 1.4 cvs 55: * our read and write sets. Note that under the canonical Unix model, 56: * a non-blocking socket passed to an accept() call will appear as readable, 57: * whilst a non-blocking call to connect() will appear as writeable. In add. 58: * if the connection has been closed, the socket will appear readable under 59: * BSD Unix semantics 60: */ 1.32 cvs 61: 1.58 cvs 62: static const HTEventType ReadBits = HTEvent_READ | HTEvent_ACCEPT | HTEvent_CLOSE; 63: static const HTEventType WriteBits = HTEvent_WRITE | HTEvent_CONNECT; 64: static const HTEventType ExceptBits = HTEvent_OOB; 65: 1.85 gully 66: #ifdef _MOTIF 67: typedef struct sStatus { 68: XtInputId read; /* the different Xt Id's */ 69: XtInputId write; 70: XtInputId except; 71: } SocketStatus; 72: #endif /*! #ifdef _MOTIF */ 1.79 cvs 73: 74: #ifdef _GTK 1.85 gully 75: typedef struct sStatus { 76: gint read; /* the different GTK Id's */ 77: gint write; 78: gint except; 79: } SocketStatus; 1.79 cvs 80: #endif /* _GTK */ 1.4 cvs 81: 1.85 gully 82: #ifdef _NOGUI 83: typedef struct sStatus { 84: int read; 85: int write; 86: int except; 87: } SocketStatus; 1.88 cvs 88: #endif /* #ifdef _NOGUI */ 1.85 gully 89: 1.89 ! cvs 90: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) ! 91: #define SOCK_TABLE_SIZE 67 ! 92: #define HASH(s) ((s) % SOCK_TABLE_SIZE) ! 93: static SocketStatus persSockets[SOCK_TABLE_SIZE]; ! 94: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.4 cvs 95: 1.10 cvs 96: /*-------------------------------------------------------------------- 97: AHTCallback_bridge 1.11 cvs 98: this function acts as a bridge between Xt and libwww. From the Xt 99: point of view, this function is the callback handler whenever there's 100: any activity on the sockets associated with the active requests. From 101: the libwww point of view, this is the function that takes the initiative 102: to invoke the callback function associated with an active request, 103: whenever there's an activity in the socket associated to it. 104: In this latter aspect, this function is similar to the library's 105: own __DoCallback() function. 106: Upon activation, the function looks up the request associated with the 107: active socket and then looks up the cbf associated with that request. 108: Upon completion of the execution of the request's cbf, it verifies 109: the state of the request and, if it's an asynchronous request, deletes 110: the memory allocated to it. 1.10 cvs 111: -------------------------------------------------------------------*/ 1.80 kahan 112: void *AHTCallback_bridge (caddr_t cd, int *s, XtInputId * id) 1.4 cvs 113: { 1.86 gully 114: #ifdef _MOTIF 1.11 cvs 115: int status; /* the status result of the libwwww call */ 1.58 cvs 116: HTEventType type = HTEvent_ALL; 1.38 cvs 117: int v; 1.40 cvs 118: int socket = *s; 1.58 cvs 119: ms_t now = HTGetTimeInMillis(); 120: 121: v = HASH (socket); 1.4 cvs 122: 1.58 cvs 123: /* convert the FD into an HTEventType which will allow us to find the 124: request associated with the socket */ 1.47 cvs 125: 1.58 cvs 126: /* I could send some other data here, like the event itself, right */ 127: switch ((XtInputId) cd) 1.47 cvs 128: { 1.58 cvs 129: case XtInputReadMask: 130: type = HTEvent_READ; 131: break; 132: case XtInputWriteMask: 133: type = HTEvent_WRITE; 134: break; 135: case XtInputExceptMask: 136: type = HTEvent_OOB; 137: break; 138: default: 139: type = HTEvent_ALL; 140: break; 141: } /* switch */ 1.47 cvs 142: 1.32 cvs 143: /* Invokes the callback associated to the requests */ 144: 1.66 cvs 145: /** CanDoStop_set (FALSE); **/ 1.58 cvs 146: if ((status = HTEventList_dispatch (socket, type, now)) != HT_OK) 147: { 1.36 cvs 148: #ifdef DEBUG_LIBWWW 1.58 cvs 149: HTTrace ("Callback.... returned a value != HT_OK"); 1.36 cvs 150: #endif 1.58 cvs 151: } 1.41 cvs 152: 1.66 cvs 153: /*** CanDoStop_set (TRUE); **/ 1.86 gully 154: #endif /* _MOTIF */ 155: 1.7 cvs 156: return (0); 1.4 cvs 157: } 1.85 gully 158: 159: #ifdef _GTK 1.79 cvs 160: static void AHTCallback_bridgeGTK (gpointer data, gint source, GdkInputCondition condition) 161: { 162: int status; /* the status result of the libwwww call */ 163: HTEventType type = HTEvent_ALL; 164: int v; 165: int socket; 166: ms_t now = HTGetTimeInMillis(); 167: 168: socket = (SOCKET) data; 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 GDK_INPUT_READ: 178: type = HTEvent_READ; 179: break; 180: case GDK_INPUT_WRITE: 181: type = HTEvent_WRITE; 182: break; 183: case GDK_INPUT_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: } 1.85 gully 202: #endif /* _GTK */ 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.58 cvs 213: AHTReqContext *me = 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.58 cvs 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.32 cvs 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.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.85 gully 328: #endif /* _WINDOWS */ 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.85 gully 349: #if defined(_MOTIF) || defined(_GTK) 1.58 cvs 350: /* need something special for HTEvent_CLOSE */ 351: if (type & ReadBits) 352: RequestRegisterReadXtevent (sock); 353: 354: if (type & WriteBits) 355: RequestRegisterWriteXtevent (sock); 356: 357: if (type & ExceptBits) 358: RequestRegisterExceptXtevent (sock); 1.85 gully 359: #endif /* #if defined(_MOTIF) || defined(_GTK) */ 1.58 cvs 360: 1.51 cvs 361: #ifdef _WINDOWS 1.50 cvs 362: /* under windows, libwww requires an explicit FD_CLOSE registration 1.58 cvs 363: to detect HTTP responses not having a Content-Length header */ 364: status = HTEventList_register (sock, type | HTEvent_CLOSE , event); 1.85 gully 365: #endif /* _WINDOWS */ 366: 367: #if defined(_MOTIF) || defined(_GTK) 1.58 cvs 368: status = HTEventList_register (sock, type, event); 1.85 gully 369: #endif /* #if defined(_MOTIF) || defined(_GTK) */ 1.58 cvs 370: 371: return (status); 372: } 1.50 cvs 373: 1.34 cvs 374: /*---------------------------------------------------------------------- 375: AHTEvent_unregister 376: callback called by libwww each time a request is unregistered. This 377: function takes care of unregistering the pertinent Xt events 378: associated with the request's socket. In addition, it unregisters 379: the request from libwww. 380: ----------------------------------------------------------------------*/ 1.58 cvs 381: int AHTEvent_unregister (SOCKET sock, HTEventType type) 1.34 cvs 382: { 1.58 cvs 383: int status; 1.76 kahan 384: 385: if (sock == INVSOC) 386: return HT_OK; 1.38 cvs 387: 1.85 gully 388: #if defined(_MOTIF) || defined(_GTK) 1.58 cvs 389: /* remove the Xt event hooks */ 390: if (type & ReadBits) 391: RequestKillReadXtevent (sock); 392: 393: if (type & WriteBits) 394: RequestKillWriteXtevent (sock); 395: 396: if (type & ExceptBits) 397: RequestKillExceptXtevent (sock); 1.85 gully 398: #endif /* #if defined(_MOTIF) || defined(_GTK) */ 1.35 cvs 399: 1.58 cvs 400: /* @@@ if this is the default for windows, no need to have AHTEvent_.. 401: in windows!! */ 1.35 cvs 402: 1.58 cvs 403: /* call libwww's default routine */ 404: status = HTEventList_unregister (sock, type); 405: 1.7 cvs 406: return (status); 1.4 cvs 407: } 1.35 cvs 408: 1.58 cvs 409: /* Private functions */ 410: 1.11 cvs 411: /*---------------------------------------------------------------------- 412: RequestKillAllXtevents 413: front-end for kill all Xt events associated with the request pointed 414: to by "me". 415: ----------------------------------------------------------------------*/ 1.79 cvs 416: void RequestKillAllXtevents (AHTReqContext * me) 1.4 cvs 417: { 1.86 gully 418: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 419: int sock = INVSOC; 420: 421: return; 422: 423: /* @@@ what to do with this one? @@@ */ 424: if (me->read_sock != INVSOC) 425: sock = me->read_sock; 426: else 427: if (me->write_sock != INVSOC) 428: sock = me->write_sock; 429: else 430: if (me->except_sock != INVSOC) 431: sock = me->except_sock; 432: 433: #ifdef DEBUG_LIBWWW 1.7 cvs 434: if (THD_TRACE) 1.58 cvs 435: fprintf (stderr, "RequestKillAllXtEvents: Clearing XtInputs\n"); 436: #endif /* DEBUG_LIBWWW */ 1.4 cvs 437: 1.58 cvs 438: 439: RequestKillReadXtevent (sock); 440: RequestKillWriteXtevent (sock); 441: RequestKillExceptXtevent (sock); 1.86 gully 442: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.4 cvs 443: } 444: 1.11 cvs 445: /*---------------------------------------------------------------------- 1.18 cvs 446: RequestRegisterReadXtevent 447: Registers with Xt the read events associated with socket sock 448: ----------------------------------------------------------------------*/ 1.79 cvs 449: static void RequestRegisterReadXtevent (SOCKET sock) 1.18 cvs 450: { 1.86 gully 451: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 452: int v; 453: 454: v = HASH (sock); 455: 456: if (!persSockets[v].read) 1.18 cvs 457: { 1.85 gully 458: 459: #ifdef _MOTIF 1.58 cvs 460: persSockets[v].read = 461: XtAppAddInput (app_cont, 462: sock, 463: (XtPointer) XtInputReadMask, 464: (XtInputCallbackProc) AHTCallback_bridge, 465: (XtPointer) XtInputReadMask); 1.85 gully 466: #endif /* _MOTIF */ 467: 468: #ifdef _GTK 1.79 cvs 469: persSockets[v].read = 470: gdk_input_add ((gint) sock, 471: GDK_INPUT_READ, 472: AHTCallback_bridgeGTK, 473: (gpointer) sock); 474: #endif /* !_GTK */ 475: 1.58 cvs 476: #ifdef DEBUG_LIBWWW 1.18 cvs 477: if (THD_TRACE) 1.58 cvs 478: fprintf (stderr, "RegisterReadXtEvent: adding XtInput %lu Socket %d\n", 479: persSockets[v].read, sock); 480: #endif /* DEBUG_LIBWWW */ 1.18 cvs 481: } 1.86 gully 482: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.18 cvs 483: } 484: 485: /*---------------------------------------------------------------------- 1.11 cvs 486: RequestKillReadXtevent 487: kills any read Xt event associated with the request pointed to by "me". 488: ----------------------------------------------------------------------*/ 1.79 cvs 489: static void RequestKillReadXtevent (SOCKET sock) 1.4 cvs 490: { 1.86 gully 491: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 492: int v; 493: 494: v = HASH (sock); 495: 496: if (persSockets[v].read) 497: { 498: #ifdef DEBUG_LIBWWW 499: if (THD_TRACE) 500: fprintf (stderr, "UnregisterReadXtEvent: Clearing XtInput %lu\n", 501: persSockets[v].read); 502: #endif /* DEBUG_LIBWWW */ 1.85 gully 503: 504: #ifdef _MOTIF 1.58 cvs 505: XtRemoveInput (persSockets[v].read); 506: persSockets[v].read = (XtInputId) NULL; 1.85 gully 507: #endif /* _MOTIF */ 508: 509: #ifdef _GTK 1.79 cvs 510: gdk_input_remove (persSockets[v].read); 511: persSockets[v].read = (gint) 0; 512: #endif /* !_GTK */ 1.85 gully 513: 1.58 cvs 514: } 1.86 gully 515: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.18 cvs 516: } 517: 518: /*---------------------------------------------------------------------- 519: RequestRegisterWriteXtevent 520: Registers with Xt the write events associated with socket sock 521: ----------------------------------------------------------------------*/ 1.79 cvs 522: static void RequestRegisterWriteXtevent (SOCKET sock) 1.18 cvs 523: { 1.86 gully 524: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 525: int v; 526: v = HASH (sock); 1.18 cvs 527: 1.58 cvs 528: if (!persSockets[v].write) 529: { 1.85 gully 530: #ifdef _MOTIF 1.58 cvs 531: persSockets[v].write = 532: XtAppAddInput (app_cont, 533: sock, 1.18 cvs 534: (XtPointer) XtInputWriteMask, 535: (XtInputCallbackProc) AHTCallback_bridge, 536: (XtPointer) XtInputWriteMask); 1.85 gully 537: #endif /* _MOTIF */ 538: 539: #ifdef _GTK 1.79 cvs 540: persSockets[v].write = 541: gdk_input_add ((gint) sock, 542: GDK_INPUT_WRITE, 543: AHTCallback_bridgeGTK, 544: (gpointer) sock); 1.85 gully 545: #endif /* _GTK */ 1.79 cvs 546: 1.58 cvs 547: #ifdef DEBUG_LIBWWW 1.18 cvs 548: if (THD_TRACE) 1.58 cvs 549: fprintf (stderr, "RegisterWriteXtEvent: Adding XtInput %lu Socket %d\n", 550: persSockets[v].write, sock); 551: #endif /* DEBUG_LIBWWW */ 552: 553: } 1.86 gully 554: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.4 cvs 555: } 556: 1.11 cvs 557: /*---------------------------------------------------------------------- 558: RequestKillWriteXtevent 559: kills any write Xt event associated with the request pointed to 560: by "me". 561: ----------------------------------------------------------------------*/ 1.79 cvs 562: static void RequestKillWriteXtevent (SOCKET sock) 1.4 cvs 563: { 1.86 gully 564: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 565: int v; 566: 567: v = HASH (sock); 568: 569: if (persSockets[v].write) 570: { 571: #ifdef DEBUG_LIBWWW 572: if (THD_TRACE) 573: fprintf (stderr, "UnRegisterWriteXtEvent: Clearing Write XtInputs " 574: "%lu\n", 575: persSockets[v].write); 576: #endif /* DEBUG_LIBWWW */ 1.85 gully 577: 578: #ifdef _MOTIF 1.58 cvs 579: XtRemoveInput (persSockets[v].write); 580: persSockets[v].write = (XtInputId) NULL; 1.85 gully 581: #endif /* _MOTIF */ 582: 583: #ifdef _GTK 1.79 cvs 584: gdk_input_remove (persSockets[v].write); 585: persSockets[v].write = (gint) 0; 1.85 gully 586: #endif /* _GTK */ 587: 1.58 cvs 588: } 1.86 gully 589: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.18 cvs 590: } 591: 592: /*---------------------------------------------------------------------- 593: RequestRegisterExceptXtevent 594: Registers with Xt the except events associated with socket sock 595: ----------------------------------------------------------------------*/ 1.79 cvs 596: static void RequestRegisterExceptXtevent (SOCKET sock) 1.18 cvs 597: { 1.86 gully 598: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 599: int v; 600: 601: v = HASH (sock); 602: 603: if (!persSockets[v].except) 1.18 cvs 604: { 1.85 gully 605: #ifdef _MOTIF 1.58 cvs 606: persSockets[v].except = 607: XtAppAddInput (app_cont, 608: sock, 609: (XtPointer) XtInputExceptMask, 610: (XtInputCallbackProc) AHTCallback_bridge, 611: (XtPointer) XtInputExceptMask); 1.85 gully 612: #endif /* _MOTIF */ 613: 614: #ifdef _GTK 1.79 cvs 615: persSockets[v].except = 616: gdk_input_add ((gint) sock, 617: GDK_INPUT_EXCEPTION, 618: AHTCallback_bridgeGTK, 619: (gpointer) sock); 1.85 gully 620: #endif /* _GTK */ 621: 1.58 cvs 622: #ifdef DEBUG_LIBWWW 623: if (THD_TRACE) 624: fprintf (stderr, "RegisterExceptXtEvent: adding XtInput %lu Socket %d\n", 625: persSockets[v].except, sock); 626: #endif /* DEBUG_LIBWWW */ 1.18 cvs 627: } 1.86 gully 628: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.4 cvs 629: } 630: 1.11 cvs 631: /*---------------------------------------------------------------------- 632: RequestKillExceptXtevent 633: kills any exception Xt event associated with the request pointed to 634: by "me". 635: ----------------------------------------------------------------------*/ 1.79 cvs 636: static void RequestKillExceptXtevent (SOCKET sock) 1.4 cvs 637: { 1.86 gully 638: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 639: int v; 640: 641: v = HASH (sock); 642: if (persSockets[v].except) 643: { 644: #ifdef DEBUG_LIBWWW 645: if (THD_TRACE) 646: fprintf (stderr, "UnregisterExceptXtEvent: Clearing Except XtInputs " 647: "%lu\n", persSockets[v].except); 648: #endif /* DEBUG_LIBWWW */ 1.85 gully 649: 650: #ifdef _MOTIF 1.58 cvs 651: XtRemoveInput (persSockets[v].except); 652: persSockets[v].except = (XtInputId) NULL; 1.85 gully 653: #endif /* _MOTIF */ 654: 655: #ifdef _GTK 1.79 cvs 656: gdk_input_remove (persSockets[v].except); 657: persSockets[v].except = (gint) 0; 1.85 gully 658: #endif /* _GTK */ 659: 1.58 cvs 660: } 1.86 gully 661: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.58 cvs 662: } 663: 664: /*---------------------------------------------------------------------- 665: Xt Timer functions 666: ----------------------------------------------------------------------*/ 667: 668: struct _HTTimer { 669: ms_t millis; /* Relative value in millis */ 670: ms_t expires; /* Absolute value in millis */ 671: BOOL relative; 672: BOOL repetitive; 673: void * param; /* Client supplied context */ 674: HTTimerCallback * cbf; 675: }; 676: 677: struct _AmayaTimer { 678: HTTimer *libwww_timer; 1.85 gully 679: 680: #ifdef _MOTIF 1.58 cvs 681: XtIntervalId xt_timer; 1.85 gully 682: #endif /* _MOTIF */ 683: 684: #ifdef _GTK 1.79 cvs 685: guint xt_timer; 1.85 gully 686: #endif /* _GTK */ 687: 688: #ifdef _NOGUI 689: unsigned int xt_timer; 690: #endif /* #ifdef _NOGUI */ 691: 1.58 cvs 692: }; 693: 694: typedef struct _AmayaTimer AmayaTimer; 695: 696: static HTList *Timers = NULL; 697: 698: /*---------------------------------------------------------------------- 1.79 cvs 699: TimerCallback 700: called by the system event loop. Timers shouldn't be restarted 701: on exiting. 1.58 cvs 702: ----------------------------------------------------------------------*/ 703: void *TimerCallback (XtPointer cdata, XtIntervalId *id) 704: { 1.86 gully 705: #ifdef _MOTIF 1.58 cvs 706: HTList *cur, *last; 707: AmayaTimer *me; 708: HTTimer *libwww_timer; 709: 710: if (!AmayaIsAlive () 711: || Timers == NULL) 712: return (0); 713: 714: /* find the timer from the uid */ 715: last = cur = Timers; 716: while ((me = (AmayaTimer * ) HTList_nextObject (cur))) 717: { 718: if (me->xt_timer == *id) 719: break; 720: last = cur; 721: } 722: 723: if (me) 724: { 725: libwww_timer = me->libwww_timer; 726: /* remove the element from the list @@@ can be optimized later */ 727: HTList_quickRemoveElement(cur, last); 728: TtaFreeMemory (me); 729: HTTimer_dispatch (libwww_timer); 730: } 1.86 gully 731: #endif /* _MOTIF */ 732: 1.58 cvs 733: return (0); 1.86 gully 734: 1.58 cvs 735: } 1.86 gully 736: 1.58 cvs 737: 1.85 gully 738: #ifdef _GTK 1.79 cvs 739: /*---------------------------------------------------------------------- 740: TimerCallbackGTK 1.81 kahan 741: The callback returns FALSE to destroy the timer that called it. 1.79 cvs 742: ----------------------------------------------------------------------*/ 743: gboolean TimerCallbackGTK (gpointer id) 744: { 745: HTList *cur, *last; 746: AmayaTimer *me; 747: HTTimer *libwww_timer; 748: AmayaTimer *data; 749: 750: data = (AmayaTimer *) id; 751: 752: if (!AmayaIsAlive () 753: || Timers == NULL) 1.81 kahan 754: return (FALSE); 1.79 cvs 755: 756: /* find the timer from the uid */ 757: last = cur = Timers; 758: while ((me = (AmayaTimer * ) HTList_nextObject (cur))) 759: { 760: if (me == data) 761: break; 762: last = cur; 763: } 764: 765: if (me) 766: { 767: libwww_timer = me->libwww_timer; 768: /* remove the element from the list @@@ can be optimized later */ 769: HTList_quickRemoveElement(cur, last); 770: TtaFreeMemory (me); 771: HTTimer_dispatch (libwww_timer); 772: } 773: 774: return (FALSE); 775: } 1.85 gully 776: #endif /* _GTK */ 1.79 cvs 777: 1.58 cvs 778: /*---------------------------------------------------------------------- 1.59 cvs 779: KillAllTimers 1.58 cvs 780: ----------------------------------------------------------------------*/ 1.59 cvs 781: void KillAllTimers (void) 1.58 cvs 782: { 1.86 gully 783: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 784: /* @@@ maybe add something else to kill the Xt things */ 785: if (Timers) 786: HTList_delete (Timers); 1.65 cvs 787: Timers = NULL; 1.86 gully 788: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.58 cvs 789: } 790: 791: /*---------------------------------------------------------------------- 1.59 cvs 792: AMAYA_SetTimer 793: ----------------------------------------------------------------------*/ 794: void AMAYA_SetTimer (HTTimer *libwww_timer) 1.58 cvs 795: { 1.86 gully 796: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 797: HTList *cur, *last; 798: AmayaTimer *me; 799: 800: if (!AmayaIsAlive 801: || libwww_timer == NULL 802: || libwww_timer->expires == 0) 803: return; 804: 805: if (Timers == NULL) 806: Timers = HTList_new (); 807: 808: /* see if this timer existed already */ 809: last = cur = Timers; 810: while ((me = (AmayaTimer * ) HTList_nextObject (cur))) 811: { 812: if (me->libwww_timer == libwww_timer) 813: break; 814: last = cur; 815: } 816: 817: if (me) 818: { 819: /* remove the old timer */ 820: if (me->xt_timer) 821: { 1.85 gully 822: 823: #ifdef _MOTIF 1.58 cvs 824: XtRemoveTimeOut (me->xt_timer); 1.59 cvs 825: me->xt_timer = (XtIntervalId) NULL; 1.85 gully 826: #endif /* _MOTIF */ 827: 828: #ifdef _GTK 1.79 cvs 829: gtk_timeout_remove (me->xt_timer); 830: me->xt_timer = (guint) 0; 831: #endif /* !_GTK */ 1.85 gully 832: 833: } 1.58 cvs 834: } 835: else 836: { 837: /* create a new element */ 838: me = TtaGetMemory (sizeof (AmayaTimer)); 839: /* and add it to the list */ 840: HTList_addObject(last, (void *) me); 841: me->libwww_timer = libwww_timer; 842: } 843: 844: /* add a new time out */ 1.85 gully 845: #ifdef _MOTIF 1.58 cvs 846: me->xt_timer = XtAppAddTimeOut (app_cont, 847: me->libwww_timer->millis, 848: (XtTimerCallbackProc) TimerCallback, 849: (XtPointer *) (void *) me); 1.85 gully 850: #endif /* _MOTIF */ 851: 852: #ifdef _GTK 1.79 cvs 853: me->xt_timer = gtk_timeout_add ((guint32) me->libwww_timer->millis, 854: (GtkFunction) TimerCallbackGTK, 855: (gpointer) me); 1.85 gully 856: #endif /* _GTK */ 857: 1.86 gully 858: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.58 cvs 859: } 860: 861: /*---------------------------------------------------------------------- 1.59 cvs 862: AMAYA_DeleteTimer 1.58 cvs 863: ----------------------------------------------------------------------*/ 1.59 cvs 864: void AMAYA_DeleteTimer (HTTimer *libwww_timer) 1.58 cvs 865: { 1.86 gully 866: #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) 1.58 cvs 867: HTList *cur, *last; 868: AmayaTimer *me; 869: 1.59 cvs 870: if (Timers == NULL || libwww_timer == NULL) 1.58 cvs 871: return; 872: 873: /* find the id */ 874: last = cur = Timers; 875: while ((me = (AmayaTimer * ) HTList_nextObject (cur))) 876: { 1.59 cvs 877: if (me->libwww_timer == libwww_timer) 1.58 cvs 878: break; 879: last = cur; 880: } 881: 882: if (me) 883: { 884: /* remove the Xt timer */ 1.85 gully 885: #ifdef _MOTIF 1.58 cvs 886: XtRemoveTimeOut (me->xt_timer); 1.85 gully 887: #endif /* _MOTIF */ 888: 889: #ifdef _GTK 1.79 cvs 890: gtk_timeout_remove (me->xt_timer); 1.85 gully 891: #endif /* _GTK */ 892: 1.58 cvs 893: /* and the element from the list */ 1.65 cvs 894: HTList_removeObject (Timers, me); 1.58 cvs 895: TtaFreeMemory (me); 896: } 1.86 gully 897: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_NOGUI) */ 1.31 cvs 898: } 1.86 gully 899: