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