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