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