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

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

Webmaster