Return to AHTBridge.c CVS log | Up to [Public] / Amaya / amaya |
1.9 cvs 1: /* 2: * 1.93 vatton 3: * (c) COPYRIGHT INRIA and W3C, 1996-2004 1.9 cvs 4: * Please first read the full copyright statement in file COPYRIGHT. 5: * 6: */ 1.75 cvs 7: 1.14 cvs 8: /* 9: * AHTBridge.c : This module implements the callback setup and 10: * handlers between the Xt, libwww, and Amaya procedures. It's responsible 11: * for assigning, modifying, and supressing Xt events to the active 12: * requests. 13: * 14: * Author: J Kahan 1.67 cvs 15: * J. K./R. Guetari. Windows NT/95 routines 1.79 cvs 16: * J. K./S. Gully GTK routines 1.14 cvs 17: * 18: */ 1.94 ! gully 19: ! 20: #if defined(_GTK) 1.85 gully 21: #include <glib.h> 1.68 cvs 22: #endif /* _GTK */ 23: 1.94 ! gully 24: #ifdef _WX ! 25: #include "wxAmayaTimer.h" ! 26: #include "wxAmayaSocketEvent.h" ! 27: #endif /* _WX */ ! 28: 1.16 cvs 29: #define THOT_EXPORT extern 1.4 cvs 30: #include "amaya.h" 1.10 cvs 31: #include "AHTBridge_f.h" 32: #include "AHTFWrite_f.h" 33: #include "query_f.h" 34: #include "answer_f.h" 1.64 cvs 35: #include "HTEvtLst.h" 1.4 cvs 36: 1.58 cvs 37: #if 0 38: #define DEBUG_LIBWWW 39: #define THD_TRACE 1 40: #endif 41: 1.85 gully 42: #ifdef _MOTIF 43: /* Amaya's X appcontext */ 44: extern ThotAppContext app_cont; 45: #endif /* #ifdef _MOTIF */ 46: 1.94 ! gully 47: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.85 gully 48: /* Private functions */ 49: static void RequestRegisterReadXtevent (SOCKET); 50: static void RequestKillReadXtevent (SOCKET); 51: static void RequestRegisterWriteXtevent ( SOCKET); 52: static void RequestKillWriteXtevent (SOCKET); 53: static void RequestRegisterExceptXtevent ( SOCKET); 54: static void RequestKillExceptXtevent (SOCKET); 55: #endif /* #if defined(_MOTIF) || defined(_GTK) */ 1.24 cvs 56: 1.32 cvs 57: /* Private variables */ 1.4 cvs 58: 59: /* 1.58 cvs 60: * this set of HTEventType map our WinSock "socket event HTEventType" into 1.4 cvs 61: * our read and write sets. Note that under the canonical Unix model, 62: * a non-blocking socket passed to an accept() call will appear as readable, 63: * whilst a non-blocking call to connect() will appear as writeable. In add. 64: * if the connection has been closed, the socket will appear readable under 65: * BSD Unix semantics 66: */ 1.32 cvs 67: 1.91 gully 68: static const HTEventType ReadBits = (HTEventType)(HTEvent_READ | HTEvent_ACCEPT | HTEvent_CLOSE); 69: static const HTEventType WriteBits = (HTEventType)(HTEvent_WRITE | HTEvent_CONNECT); 70: static const HTEventType ExceptBits = (HTEventType)HTEvent_OOB; 1.58 cvs 71: 1.85 gully 72: #ifdef _MOTIF 73: typedef struct sStatus { 74: XtInputId read; /* the different Xt Id's */ 75: XtInputId write; 76: XtInputId except; 77: } SocketStatus; 78: #endif /*! #ifdef _MOTIF */ 1.79 cvs 79: 1.94 ! gully 80: #if defined(_GTK) 1.85 gully 81: typedef struct sStatus { 82: gint read; /* the different GTK Id's */ 83: gint write; 84: gint except; 85: } SocketStatus; 1.79 cvs 86: #endif /* _GTK */ 1.4 cvs 87: 1.94 ! gully 88: #if defined(_WX) ! 89: typedef struct sStatus { ! 90: int read; ! 91: int write; ! 92: int except; ! 93: } SocketStatus; ! 94: #endif /* _WX */ ! 95: ! 96: #if defined(_NOGUI) 1.85 gully 97: typedef struct sStatus { 98: int read; 99: int write; 100: int except; 101: } SocketStatus; 1.88 cvs 102: #endif /* #ifdef _NOGUI */ 1.85 gully 103: 1.94 ! gully 104: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.89 cvs 105: #define SOCK_TABLE_SIZE 67 106: #define HASH(s) ((s) % SOCK_TABLE_SIZE) 107: static SocketStatus persSockets[SOCK_TABLE_SIZE]; 1.94 ! gully 108: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.4 cvs 109: 1.10 cvs 110: /*-------------------------------------------------------------------- 111: AHTCallback_bridge 1.11 cvs 112: this function acts as a bridge between Xt and libwww. From the Xt 113: point of view, this function is the callback handler whenever there's 114: any activity on the sockets associated with the active requests. From 115: the libwww point of view, this is the function that takes the initiative 116: to invoke the callback function associated with an active request, 117: whenever there's an activity in the socket associated to it. 118: In this latter aspect, this function is similar to the library's 119: own __DoCallback() function. 120: Upon activation, the function looks up the request associated with the 121: active socket and then looks up the cbf associated with that request. 122: Upon completion of the execution of the request's cbf, it verifies 123: the state of the request and, if it's an asynchronous request, deletes 124: the memory allocated to it. 1.10 cvs 125: -------------------------------------------------------------------*/ 1.80 kahan 126: void *AHTCallback_bridge (caddr_t cd, int *s, XtInputId * id) 1.4 cvs 127: { 1.86 gully 128: #ifdef _MOTIF 1.11 cvs 129: int status; /* the status result of the libwwww call */ 1.58 cvs 130: HTEventType type = HTEvent_ALL; 1.38 cvs 131: int v; 1.40 cvs 132: int socket = *s; 1.58 cvs 133: ms_t now = HTGetTimeInMillis(); 134: 135: v = HASH (socket); 1.4 cvs 136: 1.58 cvs 137: /* convert the FD into an HTEventType which will allow us to find the 138: request associated with the socket */ 1.47 cvs 139: 1.58 cvs 140: /* I could send some other data here, like the event itself, right */ 141: switch ((XtInputId) cd) 1.47 cvs 142: { 1.58 cvs 143: case XtInputReadMask: 144: type = HTEvent_READ; 145: break; 146: case XtInputWriteMask: 147: type = HTEvent_WRITE; 148: break; 149: case XtInputExceptMask: 150: type = HTEvent_OOB; 151: break; 152: default: 153: type = HTEvent_ALL; 154: break; 155: } /* switch */ 1.47 cvs 156: 1.32 cvs 157: /* Invokes the callback associated to the requests */ 158: 1.66 cvs 159: /** CanDoStop_set (FALSE); **/ 1.58 cvs 160: if ((status = HTEventList_dispatch (socket, type, now)) != HT_OK) 161: { 1.36 cvs 162: #ifdef DEBUG_LIBWWW 1.58 cvs 163: HTTrace ("Callback.... returned a value != HT_OK"); 1.36 cvs 164: #endif 1.58 cvs 165: } 1.41 cvs 166: 1.66 cvs 167: /*** CanDoStop_set (TRUE); **/ 1.86 gully 168: #endif /* _MOTIF */ 169: 1.7 cvs 170: return (0); 1.4 cvs 171: } 1.85 gully 172: 1.94 ! gully 173: #if defined(_GTK) 1.79 cvs 174: static void AHTCallback_bridgeGTK (gpointer data, gint source, GdkInputCondition condition) 175: { 176: int status; /* the status result of the libwwww call */ 177: HTEventType type = HTEvent_ALL; 178: int v; 179: int socket; 180: ms_t now = HTGetTimeInMillis(); 181: 182: socket = (SOCKET) data; 183: v = HASH (socket); 184: 185: /* convert the FD into an HTEventType which will allow us to find the 186: request associated with the socket */ 187: 188: /* I could send some other data here, like the event itself, right */ 189: switch (condition) 190: { 191: case GDK_INPUT_READ: 192: type = HTEvent_READ; 193: break; 194: case GDK_INPUT_WRITE: 195: type = HTEvent_WRITE; 196: break; 197: case GDK_INPUT_EXCEPTION: 198: type = HTEvent_OOB; 199: break; 200: default: 201: type = HTEvent_ALL; 202: break; 203: } /* switch */ 204: 205: /* Invokes the callback associated to the requests */ 206: 207: /** CanDoStop_set (FALSE); **/ 208: if ((status = HTEventList_dispatch (socket, type, now)) != HT_OK) 209: { 210: #ifdef DEBUG_LIBWWW 211: HTTrace ("Callback.... returned a value != HT_OK"); 212: #endif 213: } 214: /*** CanDoStop_set (TRUE); **/ 215: } 1.94 ! gully 216: #endif /* _GTK */ ! 217: ! 218: ! 219: #if defined(_WX) ! 220: static void AHTCallback_bridgeWX ( int register_id, int socket, wxAmayaSocketCondition condition) ! 221: { ! 222: int status; /* the status result of the libwwww call */ ! 223: HTEventType type = HTEvent_ALL; ! 224: int v; ! 225: ms_t now = HTGetTimeInMillis(); ! 226: ! 227: v = HASH (socket); ! 228: ! 229: /* convert the FD into an HTEventType which will allow us to find the ! 230: request associated with the socket */ ! 231: ! 232: /* I could send some other data here, like the event itself, right */ ! 233: switch (condition) ! 234: { ! 235: case WXAMAYASOCKET_READ: ! 236: type = HTEvent_READ; ! 237: break; ! 238: case WXAMAYASOCKET_WRITE: ! 239: type = HTEvent_WRITE; ! 240: break; ! 241: case WXAMAYASOCKET_EXCEPTION: ! 242: type = HTEvent_OOB; ! 243: break; ! 244: default: ! 245: type = HTEvent_ALL; ! 246: break; ! 247: } /* switch */ ! 248: ! 249: /* Invokes the callback associated to the requests */ ! 250: ! 251: /** CanDoStop_set (FALSE); **/ ! 252: if ((status = HTEventList_dispatch (socket, type, now)) != HT_OK) ! 253: { ! 254: #ifdef DEBUG_LIBWWW ! 255: HTTrace ("Callback.... returned a value != HT_OK"); ! 256: #endif ! 257: } ! 258: /*** CanDoStop_set (TRUE); **/ ! 259: } ! 260: #endif /* _WX */ 1.41 cvs 261: 262: /*-------------------------------------------------------------------- 263: ProcessTerminateRequest 264: This function is called whenever a request has ended. If the requested 265: ended normally, the function will call any callback associated to the 266: request. Otherwise, it will just mark the request as over. 267: -------------------------------------------------------------------*/ 1.82 vatton 268: void ProcessTerminateRequest (HTRequest *request, HTResponse *response, 269: void *param, int status) 1.41 cvs 270: { 1.91 gully 271: AHTReqContext *me = (AHTReqContext *)HTRequest_context (request); 1.56 cvs 272: 1.58 cvs 273: /* choose a correct treatment in function of the request's 1.41 cvs 274: being associated with an error, with an interruption, or with a 275: succesful completion */ 1.64 cvs 276: 277: #ifdef DEBUG_LIBWWW 278: if (THD_TRACE) 1.82 vatton 279: fprintf (stderr,"ProcessTerminateRequest: processing req %p, url %s,\ 280: status %d\n", me, me->urlName, me->reqStatus); 1.64 cvs 281: #endif /* DEBUG_LIBWWW */ 1.83 kahan 282: if (me->reqStatus == HT_END) 1.41 cvs 283: { 1.58 cvs 284: if (AmayaIsAlive () && me->terminate_cbf) 1.82 vatton 285: (*me->terminate_cbf) (me->docid, 0, me->urlName, me->outputfile, 286: &(me->http_headers), me->context_tcbf); 1.58 cvs 287: 1.41 cvs 288: } 1.42 cvs 289: else if (me->reqStatus == HT_ABORT) 1.41 cvs 290: /* either the application ended or the user pressed the stop 291: button. We erase the incoming file, if it exists */ 292: { 1.52 cvs 293: if (AmayaIsAlive () && me->terminate_cbf) 1.82 vatton 294: (*me->terminate_cbf) (me->docid, -1, me->urlName, me->outputfile, 295: &(me->http_headers), me->context_tcbf); 1.78 cvs 296: if (me->outputfile && me->outputfile[0] != EOS) 1.41 cvs 297: { 1.70 cvs 298: TtaFileUnlink (me->outputfile); 1.78 cvs 299: me->outputfile[0] = EOS; 1.70 cvs 300: } 1.41 cvs 301: } 1.83 kahan 302: else if (me->reqStatus == HT_ERR) 1.41 cvs 303: { 304: /* there was an error */ 1.90 gully 305: if (AmayaIsAlive () && me->terminate_cbf) 1.82 vatton 306: (*me->terminate_cbf) (me->docid, -2, me->urlName, me->outputfile, 307: &(me->http_headers), me->context_tcbf); 1.41 cvs 308: 1.78 cvs 309: if (me->outputfile && me->outputfile[0] != EOS) 1.41 cvs 310: { 1.70 cvs 311: TtaFileUnlink (me->outputfile); 1.78 cvs 312: me->outputfile[0] = EOS; 1.41 cvs 313: } 314: } 1.58 cvs 315: 1.41 cvs 316: /* we erase the context if we're dealing with an asynchronous request */ 1.61 cvs 317: if ((me->mode & AMAYA_ASYNC) 318: || (me->mode & AMAYA_IASYNC)) 1.58 cvs 319: { 1.63 cvs 320: Document doc = me->docid; 1.58 cvs 321: me->reqStatus = HT_END; 322: /*** @@@ do we need this? yes!! **/ 323: AHTLoadTerminate_handler (request, response, param, status); 324: AHTReqContext_delete (me); 1.63 cvs 325: AHTPrintPendingRequestStatus (doc, YES); 1.58 cvs 326: } 327: } 1.4 cvs 328: 1.92 cvs 329: #ifdef _WINGUI 1.29 cvs 330: /*---------------------------------------------------------------- 1.32 cvs 331: WIN_Activate_Request 1.29 cvs 332: when there are more open requests than available sockets, the 333: requests are put in a "pending state." When a socket becomes 334: available, libwww associates it with a pending request and then 335: calls this callback function. This function is responsible for 336: opening the temporary file where the GET and POST results 337: will be stored. The function is also responsible for 338: registering the socket with the Xt event loop. 339: Consult the libwww manual for more details on the signature 340: of this function. 341: ----------------------------------------------------------------*/ 1.79 cvs 342: int WIN_Activate_Request (HTRequest * request, HTAlertOpcode op, int msgnum, const char *dfault, void *input, HTAlertPar * reply) 1.29 cvs 343: { 344: AHTReqContext *me = HTRequest_context (request); 345: 1.58 cvs 346: if (me->reqStatus == HT_NEW) 347: { 348: if (!(me->output) 349: && (me->output != stdout) 350: && me->outputfile 1.78 cvs 351: && (me->output = fopen (me->outputfile, "wb")) == NULL) { 1.58 cvs 352: /* the request is associated with a file */ 1.78 cvs 353: me->outputfile[0] = EOS; /* file could not be opened */ 1.70 cvs 354: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE), me->outputfile); 1.58 cvs 355: me->reqStatus = HT_ERR; 356: 357: if (me->error_html) 358: DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR; /* so we can show the error message */ 359: } 360: else 361: { 362: #ifdef DEBUG_LIBWWW 363: if (THD_TRACE) 364: fprintf (stderr, "WIN_Activate_Request: Activating pending %s. " 365: "Open fd %d\n", me->urlName, (int) me->output); 366: #endif /* DEBUG_LIBWWW */ 367: HTRequest_setOutputStream (me->request, AHTFWriter_new (me->request, me->output, YES)); 368: /*change the status of the request */ 369: me->reqStatus = HT_WAITING; 370: } 371: } 372: else if (me->reqStatus == HT_WAITING) 373: { 374: /*change the status of the request */ 375: rewind (me->output); 376: if (HTRequest_outputStream (me->request) == NULL) 377: HTRequest_setOutputStream (me->request, AHTFWriter_new (me->request, me->output, YES)); 378: } 1.32 cvs 379: else { 1.36 cvs 380: me->reqStatus = HT_ERR; 1.32 cvs 381: } 382: 1.36 cvs 383: return ((me->reqStatus != HT_ERR) ? HT_OK : HT_ERROR); 1.32 cvs 384: } 385: 1.92 cvs 386: #endif /* _WINGUI */ 1.60 cvs 387: 1.11 cvs 388: /*---------------------------------------------------------------------- 389: AHTEvent_register 390: callback called by libwww whenever a socket is open and associated 391: to a request. It sets the pertinent Xt events so that the Xt Event 392: loops gets an interruption whenever there's action of the socket. 393: In addition, it registers the request with libwww. 394: ----------------------------------------------------------------------*/ 1.58 cvs 395: int AHTEvent_register (SOCKET sock, HTEventType type, HTEvent *event) 1.4 cvs 396: { 1.85 gully 397: int status = 0; 1.7 cvs 398: 1.40 cvs 399: if (sock == INVSOC) 400: { 1.36 cvs 401: #ifdef DEBUG_LIBWWW 1.58 cvs 402: fprintf(stderr, "AHTEvent_register: sock = INVSOC\n"); 1.37 cvs 403: #endif /* DEBUG_LIBWWW */ 1.58 cvs 404: return (0); 405: } 1.43 cvs 406: 1.94 ! gully 407: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) ! 408: /* need something special for HTEvent_CLOSE */ 1.58 cvs 409: if (type & ReadBits) 410: RequestRegisterReadXtevent (sock); 411: 412: if (type & WriteBits) 413: RequestRegisterWriteXtevent (sock); 414: 415: if (type & ExceptBits) 416: RequestRegisterExceptXtevent (sock); 1.94 ! gully 417: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) */ 1.58 cvs 418: 1.94 ! gully 419: #ifdef _WINDOWS 1.50 cvs 420: /* under windows, libwww requires an explicit FD_CLOSE registration 1.58 cvs 421: to detect HTTP responses not having a Content-Length header */ 422: status = HTEventList_register (sock, type | HTEvent_CLOSE , event); 1.94 ! gully 423: #endif /* _WINDOWS */ 1.85 gully 424: 1.94 ! gully 425: #if defined(_UNIX) 1.58 cvs 426: status = HTEventList_register (sock, type, event); 1.94 ! gully 427: #endif /* #if defined(_UNIX) */ 1.58 cvs 428: 429: return (status); 430: } 1.50 cvs 431: 1.34 cvs 432: /*---------------------------------------------------------------------- 433: AHTEvent_unregister 434: callback called by libwww each time a request is unregistered. This 435: function takes care of unregistering the pertinent Xt events 436: associated with the request's socket. In addition, it unregisters 437: the request from libwww. 438: ----------------------------------------------------------------------*/ 1.58 cvs 439: int AHTEvent_unregister (SOCKET sock, HTEventType type) 1.34 cvs 440: { 1.58 cvs 441: int status; 1.76 kahan 442: 443: if (sock == INVSOC) 444: return HT_OK; 1.38 cvs 445: 1.94 ! gully 446: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) 1.58 cvs 447: /* remove the Xt event hooks */ 448: if (type & ReadBits) 449: RequestKillReadXtevent (sock); 450: 451: if (type & WriteBits) 452: RequestKillWriteXtevent (sock); 453: 454: if (type & ExceptBits) 455: RequestKillExceptXtevent (sock); 1.94 ! gully 456: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) */ 1.35 cvs 457: 1.58 cvs 458: /* @@@ if this is the default for windows, no need to have AHTEvent_.. 459: in windows!! */ 1.35 cvs 460: 1.58 cvs 461: /* call libwww's default routine */ 462: status = HTEventList_unregister (sock, type); 463: 1.7 cvs 464: return (status); 1.4 cvs 465: } 1.35 cvs 466: 1.58 cvs 467: /* Private functions */ 468: 1.11 cvs 469: /*---------------------------------------------------------------------- 470: RequestKillAllXtevents 471: front-end for kill all Xt events associated with the request pointed 472: to by "me". 473: ----------------------------------------------------------------------*/ 1.79 cvs 474: void RequestKillAllXtevents (AHTReqContext * me) 1.4 cvs 475: { 1.94 ! gully 476: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 477: int sock = INVSOC; 478: 479: return; 480: 481: /* @@@ what to do with this one? @@@ */ 482: if (me->read_sock != INVSOC) 483: sock = me->read_sock; 484: else 485: if (me->write_sock != INVSOC) 486: sock = me->write_sock; 487: else 488: if (me->except_sock != INVSOC) 489: sock = me->except_sock; 490: 491: #ifdef DEBUG_LIBWWW 1.7 cvs 492: if (THD_TRACE) 1.58 cvs 493: fprintf (stderr, "RequestKillAllXtEvents: Clearing XtInputs\n"); 494: #endif /* DEBUG_LIBWWW */ 1.4 cvs 495: 1.58 cvs 496: 497: RequestKillReadXtevent (sock); 498: RequestKillWriteXtevent (sock); 499: RequestKillExceptXtevent (sock); 1.94 ! gully 500: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.4 cvs 501: } 502: 1.11 cvs 503: /*---------------------------------------------------------------------- 1.18 cvs 504: RequestRegisterReadXtevent 505: Registers with Xt the read events associated with socket sock 506: ----------------------------------------------------------------------*/ 1.79 cvs 507: static void RequestRegisterReadXtevent (SOCKET sock) 1.18 cvs 508: { 1.94 ! gully 509: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 510: int v; 511: 512: v = HASH (sock); 513: 514: if (!persSockets[v].read) 1.18 cvs 515: { 1.85 gully 516: 517: #ifdef _MOTIF 1.58 cvs 518: persSockets[v].read = 519: XtAppAddInput (app_cont, 520: sock, 521: (XtPointer) XtInputReadMask, 522: (XtInputCallbackProc) AHTCallback_bridge, 523: (XtPointer) XtInputReadMask); 1.85 gully 524: #endif /* _MOTIF */ 525: 1.94 ! gully 526: #if defined(_GTK) 1.79 cvs 527: persSockets[v].read = 528: gdk_input_add ((gint) sock, 529: GDK_INPUT_READ, 530: AHTCallback_bridgeGTK, 531: (gpointer) sock); 1.94 ! gully 532: #endif /* _GTK */ ! 533: ! 534: #if defined(_WX) ! 535: persSockets[v].read = ! 536: wxAmayaSocketEvent::RegisterSocket( sock, ! 537: WXAMAYASOCKET_READ, ! 538: AHTCallback_bridgeWX ); ! 539: #endif /* _WX */ 1.79 cvs 540: 1.58 cvs 541: #ifdef DEBUG_LIBWWW 1.18 cvs 542: if (THD_TRACE) 1.58 cvs 543: fprintf (stderr, "RegisterReadXtEvent: adding XtInput %lu Socket %d\n", 544: persSockets[v].read, sock); 545: #endif /* DEBUG_LIBWWW */ 1.18 cvs 546: } 1.94 ! gully 547: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.18 cvs 548: } 549: 550: /*---------------------------------------------------------------------- 1.11 cvs 551: RequestKillReadXtevent 552: kills any read Xt event associated with the request pointed to by "me". 553: ----------------------------------------------------------------------*/ 1.79 cvs 554: static void RequestKillReadXtevent (SOCKET sock) 1.4 cvs 555: { 1.94 ! gully 556: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 557: int v; 558: 559: v = HASH (sock); 560: 561: if (persSockets[v].read) 562: { 563: #ifdef DEBUG_LIBWWW 564: if (THD_TRACE) 565: fprintf (stderr, "UnregisterReadXtEvent: Clearing XtInput %lu\n", 566: persSockets[v].read); 567: #endif /* DEBUG_LIBWWW */ 1.85 gully 568: 569: #ifdef _MOTIF 1.58 cvs 570: XtRemoveInput (persSockets[v].read); 571: persSockets[v].read = (XtInputId) NULL; 1.85 gully 572: #endif /* _MOTIF */ 573: 1.94 ! gully 574: #if defined(_GTK) 1.79 cvs 575: gdk_input_remove (persSockets[v].read); 576: persSockets[v].read = (gint) 0; 577: #endif /* !_GTK */ 1.85 gully 578: 1.94 ! gully 579: #if defined(_WX) ! 580: wxAmayaSocketEvent::UnregisterSocket( persSockets[v].read ); ! 581: persSockets[v].read = 0; ! 582: #endif /* _WX */ ! 583: 1.58 cvs 584: } 1.94 ! gully 585: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.18 cvs 586: } 587: 588: /*---------------------------------------------------------------------- 589: RequestRegisterWriteXtevent 590: Registers with Xt the write events associated with socket sock 591: ----------------------------------------------------------------------*/ 1.79 cvs 592: static void RequestRegisterWriteXtevent (SOCKET sock) 1.18 cvs 593: { 1.94 ! gully 594: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 595: int v; 596: v = HASH (sock); 1.18 cvs 597: 1.58 cvs 598: if (!persSockets[v].write) 599: { 1.85 gully 600: #ifdef _MOTIF 1.58 cvs 601: persSockets[v].write = 602: XtAppAddInput (app_cont, 603: sock, 1.18 cvs 604: (XtPointer) XtInputWriteMask, 605: (XtInputCallbackProc) AHTCallback_bridge, 606: (XtPointer) XtInputWriteMask); 1.85 gully 607: #endif /* _MOTIF */ 608: 1.94 ! gully 609: #if defined(_GTK) 1.79 cvs 610: persSockets[v].write = 611: gdk_input_add ((gint) sock, 612: GDK_INPUT_WRITE, 613: AHTCallback_bridgeGTK, 614: (gpointer) sock); 1.94 ! gully 615: #endif /* _GTK */ ! 616: ! 617: #if defined(_WX) ! 618: persSockets[v].write = ! 619: wxAmayaSocketEvent::RegisterSocket( sock, ! 620: WXAMAYASOCKET_WRITE, ! 621: AHTCallback_bridgeWX ); ! 622: #endif /* _WX */ 1.79 cvs 623: 1.58 cvs 624: #ifdef DEBUG_LIBWWW 1.18 cvs 625: if (THD_TRACE) 1.58 cvs 626: fprintf (stderr, "RegisterWriteXtEvent: Adding XtInput %lu Socket %d\n", 627: persSockets[v].write, sock); 628: #endif /* DEBUG_LIBWWW */ 629: 630: } 1.94 ! gully 631: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.4 cvs 632: } 633: 1.11 cvs 634: /*---------------------------------------------------------------------- 635: RequestKillWriteXtevent 636: kills any write Xt event associated with the request pointed to 637: by "me". 638: ----------------------------------------------------------------------*/ 1.79 cvs 639: static void RequestKillWriteXtevent (SOCKET sock) 1.4 cvs 640: { 1.94 ! gully 641: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 642: int v; 643: 644: v = HASH (sock); 645: 646: if (persSockets[v].write) 647: { 648: #ifdef DEBUG_LIBWWW 649: if (THD_TRACE) 650: fprintf (stderr, "UnRegisterWriteXtEvent: Clearing Write XtInputs " 651: "%lu\n", 652: persSockets[v].write); 653: #endif /* DEBUG_LIBWWW */ 1.85 gully 654: 655: #ifdef _MOTIF 1.58 cvs 656: XtRemoveInput (persSockets[v].write); 657: persSockets[v].write = (XtInputId) NULL; 1.85 gully 658: #endif /* _MOTIF */ 659: 1.94 ! gully 660: #if defined(_GTK) 1.79 cvs 661: gdk_input_remove (persSockets[v].write); 662: persSockets[v].write = (gint) 0; 1.85 gully 663: #endif /* _GTK */ 664: 1.94 ! gully 665: #if defined(_WX) ! 666: wxAmayaSocketEvent::UnregisterSocket( persSockets[v].write ); ! 667: persSockets[v].write = 0; ! 668: #endif /* _WX */ ! 669: 1.58 cvs 670: } 1.94 ! gully 671: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.18 cvs 672: } 673: 674: /*---------------------------------------------------------------------- 675: RequestRegisterExceptXtevent 676: Registers with Xt the except events associated with socket sock 677: ----------------------------------------------------------------------*/ 1.79 cvs 678: static void RequestRegisterExceptXtevent (SOCKET sock) 1.18 cvs 679: { 1.94 ! gully 680: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 681: int v; 682: 683: v = HASH (sock); 684: 685: if (!persSockets[v].except) 1.18 cvs 686: { 1.85 gully 687: #ifdef _MOTIF 1.58 cvs 688: persSockets[v].except = 689: XtAppAddInput (app_cont, 690: sock, 691: (XtPointer) XtInputExceptMask, 692: (XtInputCallbackProc) AHTCallback_bridge, 693: (XtPointer) XtInputExceptMask); 1.85 gully 694: #endif /* _MOTIF */ 695: 1.94 ! gully 696: #if defined(_GTK) 1.79 cvs 697: persSockets[v].except = 698: gdk_input_add ((gint) sock, 699: GDK_INPUT_EXCEPTION, 700: AHTCallback_bridgeGTK, 701: (gpointer) sock); 1.85 gully 702: #endif /* _GTK */ 1.94 ! gully 703: ! 704: #if defined(_WX) ! 705: persSockets[v].except = ! 706: wxAmayaSocketEvent::RegisterSocket( sock, ! 707: WXAMAYASOCKET_EXCEPTION, ! 708: AHTCallback_bridgeWX ); ! 709: #endif /* _WX */ ! 710: ! 711: #ifdef DEBUG_LIBWWW 1.58 cvs 712: if (THD_TRACE) 713: fprintf (stderr, "RegisterExceptXtEvent: adding XtInput %lu Socket %d\n", 714: persSockets[v].except, sock); 715: #endif /* DEBUG_LIBWWW */ 1.18 cvs 716: } 1.94 ! gully 717: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.4 cvs 718: } 719: 1.11 cvs 720: /*---------------------------------------------------------------------- 721: RequestKillExceptXtevent 722: kills any exception Xt event associated with the request pointed to 723: by "me". 724: ----------------------------------------------------------------------*/ 1.79 cvs 725: static void RequestKillExceptXtevent (SOCKET sock) 1.4 cvs 726: { 1.94 ! gully 727: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 728: int v; 729: 730: v = HASH (sock); 731: if (persSockets[v].except) 732: { 733: #ifdef DEBUG_LIBWWW 734: if (THD_TRACE) 735: fprintf (stderr, "UnregisterExceptXtEvent: Clearing Except XtInputs " 736: "%lu\n", persSockets[v].except); 737: #endif /* DEBUG_LIBWWW */ 1.85 gully 738: 739: #ifdef _MOTIF 1.58 cvs 740: XtRemoveInput (persSockets[v].except); 741: persSockets[v].except = (XtInputId) NULL; 1.85 gully 742: #endif /* _MOTIF */ 743: 1.94 ! gully 744: #if defined(_GTK) 1.79 cvs 745: gdk_input_remove (persSockets[v].except); 746: persSockets[v].except = (gint) 0; 1.85 gully 747: #endif /* _GTK */ 1.94 ! gully 748: ! 749: #if defined(_WX) ! 750: wxAmayaSocketEvent::UnregisterSocket( persSockets[v].except ); ! 751: persSockets[v].except = 0; ! 752: #endif /* _WX */ 1.85 gully 753: 1.58 cvs 754: } 1.94 ! gully 755: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.58 cvs 756: } 757: 758: /*---------------------------------------------------------------------- 759: Xt Timer functions 760: ----------------------------------------------------------------------*/ 761: 762: struct _HTTimer { 763: ms_t millis; /* Relative value in millis */ 764: ms_t expires; /* Absolute value in millis */ 765: BOOL relative; 766: BOOL repetitive; 767: void * param; /* Client supplied context */ 768: HTTimerCallback * cbf; 769: }; 770: 771: struct _AmayaTimer { 772: HTTimer *libwww_timer; 1.85 gully 773: 774: #ifdef _MOTIF 1.58 cvs 775: XtIntervalId xt_timer; 1.85 gully 776: #endif /* _MOTIF */ 777: 778: #ifdef _GTK 1.79 cvs 779: guint xt_timer; 1.85 gully 780: #endif /* _GTK */ 781: 1.94 ! gully 782: #ifdef _WX ! 783: wxAmayaTimer * xt_timer; ! 784: #endif /* _WX */ ! 785: 1.85 gully 786: #ifdef _NOGUI 787: unsigned int xt_timer; 788: #endif /* #ifdef _NOGUI */ 789: 1.58 cvs 790: }; 791: 792: typedef struct _AmayaTimer AmayaTimer; 793: 794: static HTList *Timers = NULL; 795: 796: /*---------------------------------------------------------------------- 1.79 cvs 797: TimerCallback 798: called by the system event loop. Timers shouldn't be restarted 799: on exiting. 1.58 cvs 800: ----------------------------------------------------------------------*/ 801: void *TimerCallback (XtPointer cdata, XtIntervalId *id) 802: { 1.86 gully 803: #ifdef _MOTIF 1.58 cvs 804: HTList *cur, *last; 805: AmayaTimer *me; 806: HTTimer *libwww_timer; 807: 808: if (!AmayaIsAlive () 809: || Timers == NULL) 810: return (0); 811: 812: /* find the timer from the uid */ 813: last = cur = Timers; 814: while ((me = (AmayaTimer * ) HTList_nextObject (cur))) 815: { 816: if (me->xt_timer == *id) 817: break; 818: last = cur; 819: } 820: 821: if (me) 822: { 823: libwww_timer = me->libwww_timer; 824: /* remove the element from the list @@@ can be optimized later */ 825: HTList_quickRemoveElement(cur, last); 826: TtaFreeMemory (me); 827: HTTimer_dispatch (libwww_timer); 828: } 1.86 gully 829: #endif /* _MOTIF */ 830: 1.58 cvs 831: return (0); 1.86 gully 832: 1.58 cvs 833: } 1.86 gully 834: 1.85 gully 835: #ifdef _GTK 1.79 cvs 836: /*---------------------------------------------------------------------- 837: TimerCallbackGTK 1.81 kahan 838: The callback returns FALSE to destroy the timer that called it. 1.79 cvs 839: ----------------------------------------------------------------------*/ 840: gboolean TimerCallbackGTK (gpointer id) 841: { 842: HTList *cur, *last; 843: AmayaTimer *me; 844: HTTimer *libwww_timer; 845: AmayaTimer *data; 846: 847: data = (AmayaTimer *) id; 848: 849: if (!AmayaIsAlive () 850: || Timers == NULL) 1.81 kahan 851: return (FALSE); 1.79 cvs 852: 853: /* find the timer from the uid */ 854: last = cur = Timers; 855: while ((me = (AmayaTimer * ) HTList_nextObject (cur))) 856: { 857: if (me == data) 858: break; 859: last = cur; 860: } 861: 862: if (me) 863: { 864: libwww_timer = me->libwww_timer; 865: /* remove the element from the list @@@ can be optimized later */ 866: HTList_quickRemoveElement(cur, last); 867: TtaFreeMemory (me); 868: HTTimer_dispatch (libwww_timer); 869: } 870: return (FALSE); 871: } 1.85 gully 872: #endif /* _GTK */ 1.79 cvs 873: 1.58 cvs 874: /*---------------------------------------------------------------------- 1.94 ! gully 875: TimerCallbackWX ! 876: called when a timer is throw ! 877: ----------------------------------------------------------------------*/ ! 878: void TimerCallbackWX( void * p_context ) ! 879: { ! 880: #ifdef _WX ! 881: HTList *cur, *last; ! 882: AmayaTimer *me; ! 883: HTTimer *libwww_timer; ! 884: AmayaTimer *data; ! 885: ! 886: data = (AmayaTimer *)p_context; ! 887: ! 888: if (!AmayaIsAlive () ! 889: || Timers == NULL) ! 890: return; ! 891: ! 892: /* find the timer from the uid */ ! 893: last = cur = Timers; ! 894: while ((me = (AmayaTimer * ) HTList_nextObject (cur))) ! 895: { ! 896: if (me == data) ! 897: break; ! 898: last = cur; ! 899: } ! 900: ! 901: if (me) ! 902: { ! 903: libwww_timer = me->libwww_timer; ! 904: /* remove the element from the list @@@ can be optimized later */ ! 905: HTList_quickRemoveElement(cur, last); ! 906: ! 907: /* delete explicitely the AmayaTimer */ ! 908: delete wxDynamicCast(me->xt_timer, wxAmayaTimer); ! 909: ! 910: TtaFreeMemory (me); ! 911: HTTimer_dispatch (libwww_timer); ! 912: } ! 913: #endif /* _WX */ ! 914: } ! 915: ! 916: /*---------------------------------------------------------------------- 1.59 cvs 917: KillAllTimers 1.58 cvs 918: ----------------------------------------------------------------------*/ 1.59 cvs 919: void KillAllTimers (void) 1.58 cvs 920: { 1.94 ! gully 921: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 922: /* @@@ maybe add something else to kill the Xt things */ 923: if (Timers) 924: HTList_delete (Timers); 1.65 cvs 925: Timers = NULL; 1.94 ! gully 926: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.58 cvs 927: } 928: 929: /*---------------------------------------------------------------------- 1.59 cvs 930: AMAYA_SetTimer 931: ----------------------------------------------------------------------*/ 932: void AMAYA_SetTimer (HTTimer *libwww_timer) 1.58 cvs 933: { 1.94 ! gully 934: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 935: HTList *cur, *last; 936: AmayaTimer *me; 937: 1.90 gully 938: if (!AmayaIsAlive () 1.58 cvs 939: || libwww_timer == NULL 940: || libwww_timer->expires == 0) 941: return; 942: 943: if (Timers == NULL) 944: Timers = HTList_new (); 945: 946: /* see if this timer existed already */ 947: last = cur = Timers; 948: while ((me = (AmayaTimer * ) HTList_nextObject (cur))) 949: { 950: if (me->libwww_timer == libwww_timer) 951: break; 952: last = cur; 953: } 954: 955: if (me) 956: { 957: /* remove the old timer */ 958: if (me->xt_timer) 959: { 1.85 gully 960: #ifdef _MOTIF 1.58 cvs 961: XtRemoveTimeOut (me->xt_timer); 1.59 cvs 962: me->xt_timer = (XtIntervalId) NULL; 1.85 gully 963: #endif /* _MOTIF */ 964: 965: #ifdef _GTK 1.79 cvs 966: gtk_timeout_remove (me->xt_timer); 967: me->xt_timer = (guint) 0; 968: #endif /* !_GTK */ 1.85 gully 969: 1.94 ! gully 970: #ifdef _WX ! 971: delete wxDynamicCast(me->xt_timer, wxTimer); ! 972: me->xt_timer = NULL; ! 973: #endif /* _WX */ ! 974: } 1.58 cvs 975: } 976: else 977: { 978: /* create a new element */ 1.91 gully 979: me = (AmayaTimer*)TtaGetMemory (sizeof (AmayaTimer)); 1.58 cvs 980: /* and add it to the list */ 981: HTList_addObject(last, (void *) me); 982: me->libwww_timer = libwww_timer; 983: } 984: 985: /* add a new time out */ 1.85 gully 986: #ifdef _MOTIF 1.58 cvs 987: me->xt_timer = XtAppAddTimeOut (app_cont, 988: me->libwww_timer->millis, 989: (XtTimerCallbackProc) TimerCallback, 990: (XtPointer *) (void *) me); 1.85 gully 991: #endif /* _MOTIF */ 992: 993: #ifdef _GTK 1.79 cvs 994: me->xt_timer = gtk_timeout_add ((guint32) me->libwww_timer->millis, 995: (GtkFunction) TimerCallbackGTK, 996: (gpointer) me); 1.85 gully 997: #endif /* _GTK */ 1.94 ! gully 998: ! 999: #ifdef _WX ! 1000: me->xt_timer = new wxAmayaTimer( TimerCallbackWX, me); ! 1001: /* start a one shot timer */ ! 1002: me->xt_timer->Start( me->libwww_timer->millis, TRUE ); ! 1003: #endif /* _WX */ ! 1004: ! 1005: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.58 cvs 1006: } 1007: 1008: /*---------------------------------------------------------------------- 1.59 cvs 1009: AMAYA_DeleteTimer 1.58 cvs 1010: ----------------------------------------------------------------------*/ 1.59 cvs 1011: void AMAYA_DeleteTimer (HTTimer *libwww_timer) 1.58 cvs 1012: { 1.94 ! gully 1013: #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) 1.58 cvs 1014: HTList *cur, *last; 1015: AmayaTimer *me; 1016: 1.59 cvs 1017: if (Timers == NULL || libwww_timer == NULL) 1.58 cvs 1018: return; 1019: 1020: /* find the id */ 1021: last = cur = Timers; 1022: while ((me = (AmayaTimer * ) HTList_nextObject (cur))) 1023: { 1.59 cvs 1024: if (me->libwww_timer == libwww_timer) 1.58 cvs 1025: break; 1026: last = cur; 1027: } 1028: 1029: if (me) 1030: { 1031: /* remove the Xt timer */ 1.85 gully 1032: #ifdef _MOTIF 1.58 cvs 1033: XtRemoveTimeOut (me->xt_timer); 1.85 gully 1034: #endif /* _MOTIF */ 1035: 1036: #ifdef _GTK 1.79 cvs 1037: gtk_timeout_remove (me->xt_timer); 1.85 gully 1038: #endif /* _GTK */ 1.94 ! gully 1039: ! 1040: #ifdef _WX ! 1041: delete wxDynamicCast(me->xt_timer, wxTimer); ! 1042: #endif /* _WX */ ! 1043: 1.58 cvs 1044: /* and the element from the list */ 1.65 cvs 1045: HTList_removeObject (Timers, me); 1.58 cvs 1046: TtaFreeMemory (me); 1047: } 1.94 ! gully 1048: #endif /* #if defined(_MOTIF) || defined(_GTK) || defined(_WX) || defined(_NOGUI) */ 1.31 cvs 1049: } 1.86 gully 1050: