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