Annotation of Amaya/amaya/AHTBridge.c, revision 1.105

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

Webmaster