Ignore:
Timestamp:
Mar 4, 2008, 2:15:12 PM (17 years ago)
Author:
gah
Message:

fixes to configure.in

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/vizservers/pymolproxy/pymolproxy.c

    r721 r914  
     1
     2/*
     3 * ----------------------------------------------------------------------
     4 * proxypymol.c
     5 *
     6 *      This module creates the Tcl interface to the pymol server.  It acts as
     7 *      a go-between establishing communication between a molvisviewer widget
     8 *      and the pymol server. The communication protocol from the molvisviewer
     9 *      widget is the Tcl language.  Commands are then relayed to the pymol
     10 *      server.  Responses from the pymol server are translated into Tcl
     11 *      commands * and send to the molvisviewer widget. For example, resulting
     12 *      image rendered offscreen is returned as BMP-formatted image data.
     13 *
     14 *  Copyright (c) 2004-2006  Purdue Research Foundation
     15 *
     16 *  See the file "license.terms" for information on usage and
     17 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
     18 * ======================================================================
     19 */
     20
    121#include <stdio.h>
     22#include <assert.h>
    223#include <unistd.h>
    324#include <stdlib.h>
     
    1839#include <tcl.h>
    1940
     41#undef INLINE
     42#ifdef __GNUC__
     43#  define INLINE __inline__
     44#else
     45#  define INLINE
     46#endif
     47
    2048#define IO_TIMEOUT (30000)
    2149
    22 struct dyBuffer
    23 {
     50static FILE *flog;
     51static int debug = 1;
     52
     53static void
     54trace TCL_VARARGS_DEF(char *, arg1)
     55{
     56    if (debug) {
     57        char *format;
     58        va_list args;
     59
     60        format = TCL_VARARGS_START(char *, arg1, args);
     61        vfprintf(flog, format, args);
     62        fprintf(flog, "\n");
     63        fflush(flog);
     64    }
     65}
     66
     67typedef struct {
    2468    char *data;
    25         int   used;
    26         int   allocated;
    27 };
    28 
    29 struct pymol_proxy
    30 {
    31         int p_stdin;
    32         int p_stdout;
    33         int p_stderr;
    34         int c_stdin;
    35         int c_stdout;
    36         struct dyBuffer image;
    37         int need_update;
    38         int can_update;
    39         int immediate_update;
    40         int sync;
    41         int labels;
    42         int frame;
    43         int rock_offset;
    44         int cacheid;
    45         int invalidate_cache;
    46         int error;
    47         int status;
    48 };
     69    int   used;
     70    int   allocated;
     71} DyBuffer;
     72
     73typedef struct {
     74    int p_stdin;
     75    int p_stdout;
     76    int p_stderr;
     77    int c_stdin;
     78    int c_stdout;
     79    DyBuffer image;
     80    int need_update;
     81    int can_update;
     82    int immediate_update;
     83    int sync;
     84    int labels;
     85    int frame;
     86    int rock_offset;
     87    int cacheid;
     88    int invalidate_cache;
     89    int error;
     90    int status;
     91} PymolProxy;
     92
     93INLINE static void
     94dyBufferInit(DyBuffer *buffer)
     95{
     96    buffer->data = NULL;
     97    buffer->used = 0;
     98    buffer->allocated = 0;
     99}
     100
     101INLINE static void
     102dyBufferFree(DyBuffer *buffer)
     103{
     104    assert(buffer != NULL);
     105    free(buffer->data);
     106    dyBufferInit(buffer);
     107}
    49108
    50109void
    51 dyBufferInit(struct dyBuffer *buffer)
    52 {
    53     buffer->data = NULL;
    54         buffer->used = 0;
    55         buffer->allocated = 0;
    56 }
    57 
    58 void
    59 dyBufferFree(struct dyBuffer *buffer)
    60 {
    61     if (buffer == NULL)
    62             return;
    63 
    64         free(buffer->data);
    65 
    66         dyBufferInit(buffer);
    67 
    68         return;
    69 }
    70 
    71 void
    72 dyBufferSetLength(struct dyBuffer *buffer, int length)
    73 {
    74     char *newdata;
    75 
    76         if (buffer == NULL)
    77                 return;
    78 
    79     if (length == 0)
    80             dyBufferFree(buffer);
    81         else if (length > buffer->used) {
    82                 newdata = realloc(buffer->data, length);
    83 
    84                 if (newdata != NULL) {
    85                     buffer->data = newdata;
    86                         buffer->used = length;
    87                         buffer->allocated = length;
    88                 }
     110dyBufferSetLength(DyBuffer *buffer, int length)
     111{
     112    assert(buffer != NULL);
     113    if (length == 0) {
     114        dyBufferFree(buffer);
     115    } else if (length > buffer->used) {
     116        char *newdata;
     117       
     118        newdata = realloc(buffer->data, length);
     119        if (newdata != NULL) {
     120            buffer->data = newdata;
     121            buffer->used = length;
     122            buffer->allocated = length;
    89123        }
    90         else
    91             buffer->used = length;
    92 }
    93 
    94 void
    95 dyBufferAppend(struct dyBuffer *buffer, const char *data, int length)
     124    } else {
     125        buffer->used = length;
     126    }
     127}
     128
     129static void
     130dyBufferAppend(DyBuffer *buffer, const char *data, int length)
    96131{
    97132    int offset;
    98133
     134    assert(buffer != NULL);
    99135    offset = buffer->used;
    100 
    101136    dyBufferSetLength(buffer, offset + length);
    102 
    103137    memcpy(buffer->data + offset, data, length);
    104138}
    105139
    106 int
     140static int
    107141bwrite(int sock, char *buffer, int size)
    108142{
     
    111145    int left = size;
    112146
    113         while(1) {
    114                 result = write(sock,buffer+total,left);
    115 
    116                 if (result <= 0)
    117                         break;
    118 
    119                 total += result;
    120                 left -= result;
    121 
    122                 if (total == size)
    123                         break;
    124         }
    125 
     147    trace("bwrite: want to write %d bytes\n", size);
     148    while(1) {
     149        result = write(sock,buffer+total,left);
     150
     151        if (result <= 0)
     152            break;
     153
     154        total += result;
     155        left -= result;
     156
     157        if (total == size)
     158            break;
     159    }
     160    trace("bwrite: wrote %d bytes\n", total);
    126161    return(total);
    127162}
    128163
    129 int
     164static int
    130165bread(int sock, char *buffer, int size)
    131166{
    132167    int result, total, left;
    133168
    134         for( total = 0, left = size; left > 0; left -= result)
    135         {
    136                 result = read(sock,buffer+total,left);
    137 
    138                 if (result > 0) {
    139                         total += result;
    140                         continue;
    141                 }
    142                
    143                 if ((result < 0) && (errno != EAGAIN) && (errno != EINTR))
    144                 {
    145                         fprintf(stderr,"pymolproxy: Error reading sock(%d), %d/%s\n", sock, errno,strerror(errno));
    146                         break;
    147                 }
    148 
    149                 result = 0;
    150         }
     169    for( total = 0, left = size; left > 0; left -= result)
     170        {
     171            result = read(sock,buffer+total,left);
     172
     173            if (result > 0) {
     174                total += result;
     175                continue;
     176            }
     177               
     178            if ((result < 0) && (errno != EAGAIN) && (errno != EINTR))
     179                {
     180                    trace("pymolproxy: Error reading sock(%d), %d/%s\n",
     181                          sock, errno,strerror(errno));
     182                    break;
     183                }
     184
     185            result = 0;
     186        }
    151187
    152188    return(total);
    153189}
    154190
    155 int
     191static int
    156192bflush(int sock, char *buffer, int size, int bytes)
    157193{
    158         int bsize;
    159 
    160         while(bytes)
    161         {
    162                 if (bytes > size)
    163                         bsize = size;
    164                 else
    165                         bsize = bytes;
    166 
    167                 bsize = bread(sock,buffer,bsize);
    168        
    169                 bytes -= bsize;
    170         }
     194    int bsize;
     195
     196    while(bytes)
     197        {
     198            if (bytes > size)
     199                bsize = size;
     200            else
     201                bsize = bytes;
     202
     203            bsize = bread(sock,buffer,bsize);
     204       
     205            bytes -= bsize;     
     206        }
    171207}
    172208
     
    174210#undef timeradd
    175211
    176 void
     212static void
    177213timersub(struct timeval *a, struct timeval *b, struct timeval *result)
    178214{
    179215    result->tv_sec = a->tv_sec - b->tv_sec;
    180         result->tv_usec = a->tv_usec - b->tv_usec;
     216    result->tv_usec = a->tv_usec - b->tv_usec;
    181217
    182218    while(result->tv_usec < 0) {
    183                 result->tv_sec -= 1;
    184                 result->tv_usec += 1000000;
    185         }
    186 }
    187 
    188 void
     219        result->tv_sec -= 1;
     220        result->tv_usec += 1000000;
     221    }
     222}
     223
     224static void
    189225timersub_ms(struct timeval *a, struct timeval *b, int *result)
    190226{
    191         struct timeval tmp;
     227    struct timeval tmp;
    192228
    193229    tmp.tv_sec = a->tv_sec - b->tv_sec;
    194         tmp.tv_usec = a->tv_usec - b->tv_usec;
     230    tmp.tv_usec = a->tv_usec - b->tv_usec;
    195231
    196232    while(tmp.tv_usec < 0) {
    197                 tmp.tv_sec -= 1;
    198                 tmp.tv_usec += 1000000;
    199         }
    200 
    201         *result = (tmp.tv_sec * 1000) + (tmp.tv_usec / 1000);
    202 }
    203 
    204 
    205 void
     233        tmp.tv_sec -= 1;
     234        tmp.tv_usec += 1000000;
     235    }
     236
     237    *result = (tmp.tv_sec * 1000) + (tmp.tv_usec / 1000);
     238}
     239
     240
     241static void
    206242timeradd(struct timeval *a, struct timeval *b, struct timeval *result)
    207243{
    208         result->tv_sec = a->tv_sec + b->tv_sec;
     244    result->tv_sec = a->tv_sec + b->tv_sec;
    209245    result->tv_usec = a->tv_usec + b->tv_usec;
    210246
    211         while(result->tv_usec >= 1000000) {
    212                 result->tv_sec += 1;
    213                 result->tv_usec -= 1000000;
    214         }
    215 }
    216 
    217 void
     247    while(result->tv_usec >= 1000000) {
     248        result->tv_sec += 1;
     249        result->tv_usec -= 1000000;
     250    }
     251}
     252
     253static void
    218254timerset_ms(struct timeval *result, int timeout)
    219255{
     
    222258}
    223259
    224 int
     260static int
    225261getline(int sock, char *buffer, int size, long timeout)
    226262{
    227263    int pos = 0, status, timeo;
    228         struct timeval now, end, tmo;
     264    struct timeval now, end, tmo;
    229265    struct pollfd ufd;
    230266
    231         gettimeofday(&now,NULL);
    232         timerset_ms(&tmo, timeout);
     267    gettimeofday(&now,NULL);
     268    timerset_ms(&tmo, timeout);
    233269    timeradd(&now,&tmo,&end);
    234270
    235         ufd.fd = sock;
    236         ufd.events = POLLIN;
     271    ufd.fd = sock;
     272    ufd.events = POLLIN;
    237273
    238274    size--;
    239275
    240         while(pos < size) {
    241                 if (timeout > 0) {
    242                         gettimeofday(&now,NULL);
    243                         timersub_ms(&now,&end,&timeo);
    244                 }
    245                 else
    246                         timeo = -1;
    247 
    248         status = poll(&ufd, 1, timeo);
    249 
    250         if (status > 0)
    251                         status = read(sock,&buffer[pos],1);
    252 
    253                 if ( (status < 0) && ( (errno == EINTR) || (errno == EAGAIN) ) )
    254                         continue; /* try again, if interrupted/blocking */
    255 
    256                 if (status <= 0)
    257                         break;
    258                        
    259                 if (buffer[pos] == '\n')
    260                 {
    261                         pos++;
    262                         break;
    263                 }
    264 
    265                 pos++;
    266 
    267     }
    268 
    269         buffer[pos]=0;
    270 
    271         return(pos);
    272 }
    273 
    274 int
    275 waitForString(struct pymol_proxy *pymol, char *string, char *buffer, int length)
     276    while(pos < size) {
     277        if (timeout > 0) {
     278            gettimeofday(&now,NULL);
     279            timersub_ms(&now,&end,&timeo);
     280        }
     281        else
     282            timeo = -1;
     283
     284        status = poll(&ufd, 1, timeo);
     285
     286        if (status > 0)
     287            status = read(sock,&buffer[pos],1);
     288
     289        if ( (status < 0) && ( (errno == EINTR) || (errno == EAGAIN) ) )
     290            continue; /* try again, if interrupted/blocking */
     291
     292        if (status <= 0)
     293            break;
     294                       
     295        if (buffer[pos] == '\n')
     296            {
     297                pos++;
     298                break;
     299            }
     300
     301        pos++;
     302
     303    }
     304
     305    buffer[pos]=0;
     306
     307    return(pos);
     308}
     309
     310static int
     311waitForString(PymolProxy *pymol, char *string, char *buffer, int length)
    276312{
    277313    int sock;
    278314
    279         if ((pymol == NULL) || (buffer == NULL))
    280             return(TCL_ERROR);
    281 
    282         if (pymol->status != TCL_OK)
    283                 return(pymol->status);
    284 
    285         sock = pymol->p_stdout;
    286 
     315    assert(buffer != NULL);
     316    if (pymol->status != TCL_OK)
     317        return pymol->status;
     318
     319    sock = pymol->p_stdout;
     320    trace("want to match (%s)\n", string);
    287321    while(1) {
    288                 if (getline(sock,buffer,length,IO_TIMEOUT) == 0) {
    289                     pymol->error = 2;
    290                         pymol->status = TCL_ERROR;
    291                         break;
    292                 }
    293 
    294                 if (strncmp(buffer,string,strlen(string)) == 0) {
    295                         //fprintf(stderr,"stdout-e> %s",buffer);
    296                         pymol->error = 0;
    297                         pymol->status = TCL_OK;
    298                         break;
    299                 }
    300 
    301                 //fprintf(stderr,"stdout-u> %s",buffer);
    302     }
    303 
    304         return(pymol->status);
    305 }
    306 
    307 int
    308 clear_error(struct pymol_proxy *pymol)
    309 {
    310     if (pymol == NULL)
    311             return(TCL_ERROR);
    312 
    313         pymol->error = 0;
    314         pymol->status = TCL_OK;
    315 
    316     return(pymol->status);
    317 }
    318 
    319 int
    320 sendf(struct pymol_proxy *pymol, char *format, ...)
     322        if (getline(sock,buffer,length,IO_TIMEOUT) == 0) {
     323            pymol->error = 2;
     324            pymol->status = TCL_ERROR;
     325            break;
     326        }
     327        if (strncmp(buffer, string, strlen(string)) == 0) {
     328            trace("stdout-e> %s",buffer);
     329            pymol->error = 0;
     330            pymol->status = TCL_OK;
     331            break;
     332        }
     333        trace("stdout-u>(%s)", buffer);
     334    }
     335
     336    return pymol->status;
     337}
     338
     339INLINE static int
     340clear_error(PymolProxy *pymol)
     341{
     342    pymol->error = 0;
     343    pymol->status = TCL_OK;
     344    return pymol->status;
     345}
     346
     347static int
     348send_expect(PymolProxy *pymol, char *expect, char *cmd)
     349{
     350    char string[800];
     351
     352    if (pymol->error)
     353        return(TCL_ERROR);
     354
     355    trace("to-pymol>(%s)", cmd);
     356    write(pymol->p_stdin, cmd, strlen(cmd));
     357    if (waitForString(pymol, expect, cmd, 800)) {
     358        trace("pymolproxy: Timeout reading data [%s]\n",cmd);
     359        pymol->error = 1;
     360        pymol->status = TCL_ERROR;
     361        return pymol->status;
     362    }
     363    return( pymol->status );
     364}
     365
     366static int
     367sendf(PymolProxy *pymol, char *format, ...)
    321368{
    322369    va_list ap;
    323370    char buffer[800];
    324371
    325         if (pymol == NULL)
    326                 return(TCL_ERROR);
    327 
    328         if (pymol->error)
    329             return(TCL_ERROR);
     372    if (pymol->error)
     373        return(TCL_ERROR);
    330374
    331375    va_start(ap, format);
    332376    vsnprintf(buffer, 800, format, ap);
    333377    va_end(ap);
    334     //fprintf(stderr,"stdin> %s", buffer);
     378    trace("to-pymol>(%s)", buffer);
    335379    write(pymol->p_stdin, buffer, strlen(buffer));
    336380
    337381    if (waitForString(pymol, "PyMOL>", buffer, 800)) {
    338         fprintf(stderr,"pymolproxy: Timeout reading data [%s]\n",buffer);
    339                 pymol->error = 1;
    340                 pymol->status = TCL_ERROR;
    341         return(pymol->status);
    342     }
    343 
    344         return( pymol->status );
    345 }
    346 
    347 int
    348 BallAndStickCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     382        trace("pymolproxy: Timeout reading data [%s]\n",buffer);
     383        pymol->error = 1;
     384        pymol->status = TCL_ERROR;
     385        return pymol->status;
     386    }
     387
     388    return( pymol->status );
     389}
     390
     391static int
     392BallNStickCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    349393{
    350394    int ghost = 0, defer = 0, push = 0, arg;
    351         const char *model = "all";
    352         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
    353 
    354         if (pymol == NULL)
    355                 return(TCL_ERROR);
    356 
    357         clear_error(pymol);
     395    const char *model = "all";
     396    PymolProxy *pymol = (PymolProxy *) cdata;
     397
     398    clear_error(pymol);
    358399
    359400    for(arg = 1; arg < argc; arg++) {
    360                 if ( strcmp(argv[arg],"-defer") == 0 )
    361                     defer = 1;
    362                 else if (strcmp(argv[arg],"-push") == 0)
    363                     push = 1;
    364                 else if (strcmp(argv[arg],"-ghost") == 0)
    365                     ghost = 1;
    366                 else if (strcmp(argv[arg],"-normal") == 0)
    367                     ghost = 0;
    368                 else if (strcmp(argv[arg],"-model") == 0) {
    369                         if (++arg < argc)
    370                                 model = argv[arg];
    371                 }
    372                 else
    373                     model = argv[arg];
    374         }
    375 
    376         pymol->invalidate_cache = 1;
    377         pymol->need_update = !defer || push;
     401        if ( strcmp(argv[arg],"-defer") == 0 )
     402            defer = 1;
     403        else if (strcmp(argv[arg],"-push") == 0)
     404            push = 1;
     405        else if (strcmp(argv[arg],"-ghost") == 0)
     406            ghost = 1;
     407        else if (strcmp(argv[arg],"-normal") == 0)
     408            ghost = 0;
     409        else if (strcmp(argv[arg],"-model") == 0) {
     410            if (++arg < argc)
     411                model = argv[arg];
     412        }
     413        else
     414            model = argv[arg];
     415    }
     416
     417    pymol->invalidate_cache = 1;
     418    pymol->need_update = !defer || push;
    378419    pymol->immediate_update |= push;
    379420
    380         sendf(pymol, "hide everything,%s\n",model);
    381         sendf(pymol, "set stick_color,white,%s\n",model);
    382        
    383         if (ghost)
    384                 sendf(pymol, "set stick_radius,0.1,%s\n",model);
    385         else
    386                 sendf(pymol, "set stick_radius,0.14,%s\n",model);
    387 
    388         sendf(pymol, "set sphere_scale=0.25,%s\n", model);
     421    sendf(pymol, "hide everything,%s\n",model);
     422    sendf(pymol, "set stick_color,white,%s\n",model);
     423       
     424    if (ghost)
     425        sendf(pymol, "set stick_radius,0.1,%s\n",model);
     426    else
     427        sendf(pymol, "set stick_radius,0.14,%s\n",model);
     428
     429    sendf(pymol, "set sphere_scale=0.25,%s\n", model);
    389430
    390431    if (ghost) {
     
    392433        sendf(pymol, "set stick_transparency,0.75,%s\n", model);
    393434    }
    394         else {
     435    else {
    395436        sendf(pymol, "set sphere_transparency,0,%s\n", model);
    396437        sendf(pymol, "set stick_transparency,0,%s\n", model);
    397438    }
    398439
    399         sendf(pymol, "show sticks,%s\n",model);
    400         sendf(pymol, "show spheres,%s\n",model);
    401 
    402         if (pymol->labels)
    403                 sendf(pymol, "show labels,%s\n", model);
    404 
    405         return( pymol->status );
    406 }
    407 
    408 int
     440    sendf(pymol, "show sticks,%s\n",model);
     441    sendf(pymol, "show spheres,%s\n",model);
     442
     443    if (pymol->labels)
     444        sendf(pymol, "show labels,%s\n", model);
     445
     446    return( pymol->status );
     447}
     448
     449static int
    409450SpheresCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    410451{
    411452    int defer = 0, ghost = 0, push = 0, arg;
    412         const char *model = "all";
    413         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
    414 
    415         if (pymol == NULL)
    416                 return(TCL_ERROR);
    417 
    418         clear_error(pymol);
     453    const char *model = "all";
     454    PymolProxy *pymol = (PymolProxy *) cdata;
     455
     456    clear_error(pymol);
    419457
    420458    for(arg = 1; arg < argc; arg++) {
    421                 if ( strcmp(argv[arg],"-defer") == 0 )
    422                     defer = 1;
    423                 else if (strcmp(argv[arg],"-push") == 0)
    424                     push = 1;
    425                 else if (strcmp(argv[arg],"-ghost") == 0)
    426                     ghost = 1;
    427                 else if (strcmp(argv[arg],"-normal") == 0)
    428                     ghost = 0;
    429                 else if (strcmp(argv[arg],"-model") == 0) {
    430                         if (++arg < argc)
    431                                 model = argv[arg];
    432                 }
    433                 else
    434                     model = argv[arg];
    435         }
    436 
    437         pymol->invalidate_cache = 1;
    438         pymol->need_update = !defer || push;
    439         pymol->immediate_update |= push;
     459        if ( strcmp(argv[arg],"-defer") == 0 )
     460            defer = 1;
     461        else if (strcmp(argv[arg],"-push") == 0)
     462            push = 1;
     463        else if (strcmp(argv[arg],"-ghost") == 0)
     464            ghost = 1;
     465        else if (strcmp(argv[arg],"-normal") == 0)
     466            ghost = 0;
     467        else if (strcmp(argv[arg],"-model") == 0) {
     468            if (++arg < argc)
     469                model = argv[arg];
     470        }
     471        else
     472            model = argv[arg];
     473    }
     474
     475    pymol->invalidate_cache = 1;
     476    pymol->need_update = !defer || push;
     477    pymol->immediate_update |= push;
    440478
    441479    sendf(pymol, "hide everything, %s\n", model);
     
    446484    if (ghost)
    447485        sendf(pymol, "set sphere_transparency,.75,%s\n", model);
    448         else
     486    else
    449487        sendf(pymol, "set sphere_transparency,0,%s\n", model);
    450488
    451489    sendf(pymol, "show spheres,%s\n", model);
    452490
    453         if (pymol->labels)
    454                 sendf(pymol, "show labels,%s\n", model);
    455 
    456         return(pymol->status);
    457 }
    458 
    459 int
     491    if (pymol->labels)
     492        sendf(pymol, "show labels,%s\n", model);
     493
     494    return pymol->status;
     495}
     496
     497static int
    460498LinesCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    461499{
    462500    int ghost = 0, defer = 0, push = 0, arg;
    463         const char *model = "all";
    464         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
    465 
    466         if (pymol == NULL)
    467                 return(TCL_ERROR);
    468 
    469         clear_error(pymol);
     501    const char *model = "all";
     502    PymolProxy *pymol = (PymolProxy *) cdata;
     503
     504    clear_error(pymol);
    470505
    471506    for(arg = 1; arg < argc; arg++) {
    472                 if ( strcmp(argv[arg],"-defer") == 0 )
    473                     defer = 1;
    474                 else if (strcmp(argv[arg],"-push") == 0)
    475                     push = 1;
    476                 else if (strcmp(argv[arg],"-ghost") == 0)
    477                     ghost = 1;
    478                 else if (strcmp(argv[arg],"-normal") == 0)
    479                     ghost = 0;
    480                 else if (strcmp(argv[arg],"-model") == 0) {
    481                         if (++arg < argc)
    482                                 model = argv[arg];
    483                 }
    484                 else
    485                     model = argv[arg];
    486         }
    487 
    488         pymol->invalidate_cache = 1;
    489         pymol->need_update = !defer || push;
    490         pymol->immediate_update |= push;
     507        if ( strcmp(argv[arg],"-defer") == 0 )
     508            defer = 1;
     509        else if (strcmp(argv[arg],"-push") == 0)
     510            push = 1;
     511        else if (strcmp(argv[arg],"-ghost") == 0)
     512            ghost = 1;
     513        else if (strcmp(argv[arg],"-normal") == 0)
     514            ghost = 0;
     515        else if (strcmp(argv[arg],"-model") == 0) {
     516            if (++arg < argc)
     517                model = argv[arg];
     518        }
     519        else
     520            model = argv[arg];
     521    }
     522
     523    pymol->invalidate_cache = 1;
     524    pymol->need_update = !defer || push;
     525    pymol->immediate_update |= push;
    491526
    492527    sendf(pymol, "hide everything,%s\n",model);
    493528
    494529    if (ghost)
    495             sendf(pymol, "set line_width,.25,%s\n",model);
    496         else
    497             sendf(pymol, "set line_width,1,%s\n",model);
     530        sendf(pymol, "set line_width,.25,%s\n",model);
     531    else
     532        sendf(pymol, "set line_width,1,%s\n",model);
    498533
    499534    sendf(pymol, "show lines,%s\n",model);
    500535
    501         if (pymol->labels)
    502                 sendf(pymol, "show labels,%s\n",model);
    503 
    504         return(pymol->status);
    505 }
    506 
    507 int
     536    if (pymol->labels)
     537        sendf(pymol, "show labels,%s\n",model);
     538
     539    return pymol->status;
     540}
     541
     542static int
    508543DisableCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    509544{
    510         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
     545    PymolProxy *pymol = (PymolProxy *) cdata;
    511546    const char *model = "all";
    512         int arg, defer = 0, push = 0;
    513 
    514         if (pymol == NULL)
    515             return(TCL_ERROR);
    516 
    517         clear_error(pymol);
     547    int arg, defer = 0, push = 0;
     548
     549    clear_error(pymol);
    518550
    519551    for(arg = 1; arg < argc; arg++) {
    520552
    521             if (strcmp(argv[arg], "-defer") == 0 )
    522                         defer = 1;
    523                 else if (strcmp(argv[arg], "-push") == 0 )
    524                     push = 1;
    525                 else
    526                         model = argv[arg];
    527        
    528         }
    529 
    530         pymol->need_update = !defer || push;
    531         pymol->immediate_update |= push;
    532         pymol->invalidate_cache = 1;
    533 
    534         sendf( pymol, "disable %s\n", model);
    535 
    536         return(pymol->status);
    537 }
    538 
    539 int
     553        if (strcmp(argv[arg], "-defer") == 0 )
     554            defer = 1;
     555        else if (strcmp(argv[arg], "-push") == 0 )
     556            push = 1;
     557        else
     558            model = argv[arg];
     559       
     560    }
     561
     562    pymol->need_update = !defer || push;
     563    pymol->immediate_update |= push;
     564    pymol->invalidate_cache = 1;
     565
     566    sendf( pymol, "disable %s\n", model);
     567
     568    return pymol->status;
     569}
     570
     571static int
    540572EnableCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    541573{
    542         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
     574    PymolProxy *pymol = (PymolProxy *) cdata;
    543575    const char *model = "all";
    544         int arg, defer = 0, push = 0;
    545 
    546         if (pymol == NULL)
    547             return(TCL_ERROR);
    548 
    549         clear_error(pymol);
    550 
    551         for(arg = 1; arg < argc; arg++) {
    552                
    553                 if (strcmp(argv[arg],"-defer") == 0)
    554                         defer = 1;
    555                 else if (strcmp(argv[arg], "-push") == 0 )
    556                     push = 1;
    557                 else
    558                     model = argv[arg];
    559 
    560         }
    561 
    562         pymol->need_update = !defer || push;
    563         pymol->immediate_update |= push;
    564         pymol->invalidate_cache = 1;
    565 
    566         sendf( pymol, "enable %s\n", model);
    567 
    568         return(pymol->status);
    569 }
    570 
    571 int
     576    int arg, defer = 0, push = 0;
     577
     578    clear_error(pymol);
     579
     580    for(arg = 1; arg < argc; arg++) {
     581               
     582        if (strcmp(argv[arg],"-defer") == 0)
     583            defer = 1;
     584        else if (strcmp(argv[arg], "-push") == 0 )
     585            push = 1;
     586        else
     587            model = argv[arg];
     588
     589    }
     590
     591    pymol->need_update = !defer || push;
     592    pymol->immediate_update |= push;
     593    pymol->invalidate_cache = 1;
     594
     595    sendf( pymol, "enable %s\n", model);
     596
     597    return pymol->status;
     598}
     599
     600static int
    572601VMouseCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    573602{
    574         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
     603    PymolProxy *pymol = (PymolProxy *) cdata;
    575604    int arg, defer = 0, push = 0, varg = 1;
    576605    int arg1 = 0, arg2 = 0, arg3 = 0, arg4 = 0, arg5 = 0;
    577606
    578         if (pymol == NULL)
    579             return(TCL_ERROR);
    580 
    581         clear_error(pymol);
     607    clear_error(pymol);
    582608
    583609    for(arg = 1; arg < argc; arg++) {
    584                 if (strcmp(argv[arg], "-defer") == 0)
    585                     defer = 1;
    586                 else if (strcmp(argv[arg], "-push") == 0)
    587                     push = 1;
    588                 else if (varg == 1) {
    589                         arg1 = atoi(argv[arg]);
    590                         varg++;
    591                 }
    592                 else if (varg == 2) {
    593                         arg2 = atoi(argv[arg]);
    594                         varg++;
    595                 }
    596                 else if (varg == 3) {
    597                         arg3 = atoi(argv[arg]);
    598                         varg++;
    599                 }
    600                 else if (varg == 4) {
    601                         arg4 = atoi(argv[arg]);
    602                         varg++;
    603                 }
    604                 else if (varg == 5) {
    605                         arg5 = atoi(argv[arg]);
    606                         varg++;
    607                 }
     610        if (strcmp(argv[arg], "-defer") == 0)
     611            defer = 1;
     612        else if (strcmp(argv[arg], "-push") == 0)
     613            push = 1;
     614        else if (varg == 1) {
     615            arg1 = atoi(argv[arg]);
     616            varg++;
     617        }
     618        else if (varg == 2) {
     619            arg2 = atoi(argv[arg]);
     620            varg++;
     621        }
     622        else if (varg == 3) {
     623            arg3 = atoi(argv[arg]);
     624            varg++;
     625        }
     626        else if (varg == 4) {
     627            arg4 = atoi(argv[arg]);
     628            varg++;
     629        }
     630        else if (varg == 5) {
     631            arg5 = atoi(argv[arg]);
     632            varg++;
     633        }
    608634    }
    609635
    610636    pymol->need_update = !defer || push;
    611637    pymol->immediate_update |= push;
    612         pymol->invalidate_cache = 1;
     638    pymol->invalidate_cache = 1;
    613639
    614640    sendf(pymol, "vmouse %d,%d,%d,%d,%d\n", arg1,arg2,arg3,arg4,arg5);
    615641
    616         return(pymol->status);
    617 }
    618 
    619 int
     642    return pymol->status;
     643}
     644
     645static int
    620646RawCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    621647{
    622         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
    623     struct dyBuffer buffer;
     648    PymolProxy *pymol = (PymolProxy *) cdata;
     649    DyBuffer buffer;
    624650    int arg, defer = 0, push = 0;
    625    
    626     if (pymol == NULL)
    627             return(TCL_ERROR);
    628 
    629         clear_error(pymol);
     651    const char *cmd;
     652    clear_error(pymol);
    630653
    631654    dyBufferInit(&buffer);
    632655
    633         for(arg = 1; arg < argc; arg++) {
    634             if (strcmp(argv[arg], "-defer") == 0)
    635                     defer = 1;
    636                 else if (strcmp(argv[arg], "-push") == 0)
    637                     push = 1;
    638                 else {
    639                     dyBufferAppend(&buffer,argv[arg],(int)strlen(argv[arg]));
    640                     dyBufferAppend(&buffer," ",1);
    641             }
    642         }
    643 
    644         pymol->need_update = !defer || push;
    645         pymol->immediate_update |= push;
    646         pymol->invalidate_cache = 1;
    647 
    648     sendf(pymol,"%s\n",buffer);
    649 
    650         dyBufferFree(&buffer);
    651 
    652         return(pymol->status);
    653 }
    654 
    655 int
     656    cmd = NULL;
     657    for(arg = 1; arg < argc; arg++) {
     658        if (strcmp(argv[arg], "-defer") == 0)
     659            defer = 1;
     660        else if (strcmp(argv[arg], "-push") == 0)
     661            push = 1;
     662        else {
     663            cmd = argv[arg];
     664        }
     665    }
     666
     667    pymol->need_update = !defer || push;
     668    pymol->immediate_update |= push;
     669    pymol->invalidate_cache = 1;
     670
     671    sendf(pymol,"%s\n", cmd);
     672    dyBufferFree(&buffer);
     673
     674    return pymol->status;
     675}
     676
     677static int
    656678LabelCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    657679{
    658         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
     680    PymolProxy *pymol = (PymolProxy *) cdata;
    659681    int state = 1;
    660         int arg, push = 0, defer = 0;
    661 
    662         if (pymol == NULL)
    663                 return(TCL_ERROR);
    664 
    665         clear_error(pymol);
    666 
    667         for(arg = 1; arg < argc; arg++) {
    668                 if ( strcmp(argv[arg],"-defer") == 0 )
    669                         defer = 1;
    670                 else if (strcmp(argv[arg],"-push") == 0 )
    671                         push = 1;
    672                 else if (strcmp(argv[arg],"on") == 0 )
    673                         state = 1;
    674                 else if (strcmp(argv[arg],"off") == 0 )
    675                         state = 0;
    676                 else if (strcmp(argv[arg],"toggle") == 0 )
    677                         state =  !pymol->labels;
    678         }
    679 
    680         pymol->need_update = !defer || push;
    681         pymol->immediate_update |= push;
    682         pymol->invalidate_cache = 1;
     682    int arg, push = 0, defer = 0;
     683
     684    clear_error(pymol);
     685
     686    for(arg = 1; arg < argc; arg++) {
     687        if ( strcmp(argv[arg],"-defer") == 0 )
     688            defer = 1;
     689        else if (strcmp(argv[arg],"-push") == 0 )
     690            push = 1;
     691        else if (strcmp(argv[arg],"on") == 0 )
     692            state = 1;
     693        else if (strcmp(argv[arg],"off") == 0 )
     694            state = 0;
     695        else if (strcmp(argv[arg],"toggle") == 0 )
     696            state =  !pymol->labels;
     697    }
     698
     699    pymol->need_update = !defer || push;
     700    pymol->immediate_update |= push;
     701    pymol->invalidate_cache = 1;
    683702
    684703    if (state) {
    685                 sendf(pymol, "set label_color,white,all\n");
    686                 sendf(pymol, "set label_size,14,all\n");
    687                 sendf(pymol, "label all,\"%%s%%s\" %% (ID,name)\n");
    688     }
    689         else
    690                 sendf(pymol, "label all\n");
    691 
    692         pymol->labels = state;
    693 
    694     return(pymol->status);
    695 }
    696 
    697 int
     704        sendf(pymol, "set label_color,white,all\n");
     705        sendf(pymol, "set label_size,14,all\n");
     706        sendf(pymol, "label all,\"%%s%%s\" %% (ID,name)\n");
     707    }
     708    else
     709        sendf(pymol, "label all\n");
     710
     711    pymol->labels = state;
     712
     713    return pymol->status;
     714}
     715
     716static int
    698717FrameCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    699718{
    700         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
     719    PymolProxy *pymol = (PymolProxy *) cdata;
    701720    int frame = 0;
    702         int arg, push = 0, defer = 0;
    703 
    704         if (pymol == NULL)
    705                 return(TCL_ERROR);
    706 
    707         clear_error(pymol);
    708 
    709         for(arg = 1; arg < argc; arg++) {
    710                 if ( strcmp(argv[arg],"-defer") == 0 )
    711                     defer = 1;
    712                 else if (strcmp(argv[arg],"-push") == 0 )
    713                     push = 1;
    714                 else
    715                     frame = atoi(argv[arg]);
    716         }
    717                
    718         pymol->need_update = !defer || push;
     721    int arg, push = 0, defer = 0;
     722
     723    clear_error(pymol);
     724
     725    for(arg = 1; arg < argc; arg++) {
     726        if ( strcmp(argv[arg],"-defer") == 0 )
     727            defer = 1;
     728        else if (strcmp(argv[arg],"-push") == 0 )
     729            push = 1;
     730        else
     731            frame = atoi(argv[arg]);
     732    }
     733               
     734    pymol->need_update = !defer || push;
    719735    pymol->immediate_update |= push;
    720736
    721737    pymol->frame = frame;
    722738
    723         sendf(pymol,"frame %d\n", frame);
    724        
    725         return(pymol->status);
    726 }
    727 
    728 int
     739    sendf(pymol,"frame %d\n", frame);
     740       
     741    return pymol->status;
     742}
     743
     744static int
    729745ResetCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    730746{
    731         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
     747    PymolProxy *pymol = (PymolProxy *) cdata;
    732748    int arg, push = 0, defer = 0;
    733749
    734         if (pymol == NULL)
    735                 return(TCL_ERROR);
    736 
    737         clear_error(pymol);
    738 
    739         for(arg = 1; arg < argc; arg++) {
    740                 if ( strcmp(argv[arg],"-defer") == 0 )
    741                     defer = 1;
    742                 else if (strcmp(argv[arg],"-push") == 0 )
    743                     push = 1;
    744         }
    745                
    746         pymol->need_update = !defer || push;
    747         pymol->immediate_update |= push;
    748         pymol->invalidate_cache = 1;
    749        
    750         sendf(pymol, "reset\n");
    751         sendf(pymol, "zoom buffer=2\n");
    752 
    753         return(pymol->status);
    754 }
    755 
    756 int
     750    clear_error(pymol);
     751
     752    for(arg = 1; arg < argc; arg++) {
     753        if ( strcmp(argv[arg],"-defer") == 0 )
     754            defer = 1;
     755        else if (strcmp(argv[arg],"-push") == 0 )
     756            push = 1;
     757    }
     758               
     759    pymol->need_update = !defer || push;
     760    pymol->immediate_update |= push;
     761    pymol->invalidate_cache = 1;
     762       
     763    sendf(pymol, "reset\n");
     764    sendf(pymol, "zoom buffer=2\n");
     765
     766    return pymol->status;
     767}
     768
     769static int
    757770RockCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    758771{
    759         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
    760         float y = 0.0;
     772    PymolProxy *pymol = (PymolProxy *) cdata;
     773    float y = 0.0;
    761774    int arg, push = 0, defer = 0;
    762775
    763         if (pymol == NULL)
    764                 return(TCL_ERROR);
    765 
    766         clear_error(pymol);
    767 
    768         for(arg = 1; arg < argc; arg++) {
    769                 if ( strcmp(argv[arg],"-defer") == 0 )
    770                     defer = 1;
    771                 else if (strcmp(argv[arg],"-push") == 0 )
    772                     push = 1;
    773                 else
    774                     y = atof( argv[arg] );
    775         }
    776                
    777         pymol->need_update = !defer || push;
     776    clear_error(pymol);
     777
     778    for(arg = 1; arg < argc; arg++) {
     779        if ( strcmp(argv[arg],"-defer") == 0 )
     780            defer = 1;
     781        else if (strcmp(argv[arg],"-push") == 0 )
     782            push = 1;
     783        else
     784            y = atof( argv[arg] );
     785    }
     786               
     787    pymol->need_update = !defer || push;
    778788    pymol->immediate_update |= push;
    779789
    780         sendf(pymol,"turn y, %f\n", y - pymol->rock_offset);
    781 
    782         pymol->rock_offset = y;
    783 
    784         return(pymol->status);
    785 }
    786 
    787 int
     790    sendf(pymol,"turn y, %f\n", y - pymol->rock_offset);
     791
     792    pymol->rock_offset = y;
     793
     794    return pymol->status;
     795}
     796
     797static int
    788798ViewportCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    789799{
    790         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
     800    PymolProxy *pymol = (PymolProxy *) cdata;
    791801    int width = 640, height = 480;
    792802    int defer = 0, push = 0, arg, varg = 1;
    793803
    794         if (pymol == NULL)
    795                 return(TCL_ERROR);
    796 
    797         clear_error(pymol);
    798 
    799         for(arg = 1; arg < argc; arg++) {
    800                 if ( strcmp(argv[arg],"-defer") == 0 )
    801                         defer = 1;
    802                 else if ( strcmp(argv[arg], "-push") == 0 )
    803                     push = 1;
    804                 else if (varg == 1) {
    805                         width = atoi(argv[arg]);
    806                         height = width;
    807                         varg++;
    808                 }
    809                 else if (varg == 2) {
    810                         height = atoi(argv[arg]);
    811                         varg++;
    812                 }
     804    clear_error(pymol);
     805
     806    for(arg = 1; arg < argc; arg++) {
     807        if ( strcmp(argv[arg],"-defer") == 0 )
     808            defer = 1;
     809        else if ( strcmp(argv[arg], "-push") == 0 )
     810            push = 1;
     811        else if (varg == 1) {
     812            width = atoi(argv[arg]);
     813            height = width;
     814            varg++;
     815        }
     816        else if (varg == 2) {
     817            height = atoi(argv[arg]);
     818            varg++;
     819        }
     820    }
     821
     822    pymol->need_update = !defer || push;
     823    pymol->immediate_update |= push;
     824    pymol->invalidate_cache = 1;
     825
     826    sendf(pymol, "viewport %d,%d\n", width, height);
     827
     828    //usleep(205000); // .2s delay for pymol to update its geometry *HACK ALERT*
     829       
     830    return pymol->status;
     831}
     832
     833static int
     834LoadPDBCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     835{
     836    const char *pdbdata, *pdb, *name;
     837    char *buf;
     838    char buffer[800];
     839    PymolProxy *pymol = (PymolProxy *) cdata;
     840    int state = 1;
     841    int arg, defer = 0, push = 0, varg = 1;
     842    char filename[] = "/tmp/fileXXXXXX.pdb";
     843
     844    clear_error(pymol);
     845
     846    for(arg = 1; arg < argc; arg++) {
     847        if ( strcmp(argv[arg],"-defer") == 0 )
     848            defer = 1;
     849        else if (strcmp(argv[arg],"-push") == 0)
     850            push = 1;
     851        else if (varg == 1) {
     852            pdbdata = argv[arg];
     853            varg++;
     854        }
     855        else if (varg == 2) {
     856            name = argv[arg];
     857            varg++;
     858        }
     859        else if (varg == 3) {
     860            state = atoi( argv[arg] );
     861            varg++;
     862        }
     863    }
     864
     865    pymol->need_update = !defer || push;
     866    pymol->immediate_update |= push;
     867
     868#ifdef notdef
     869    {
     870        /* Pymol expects to load the pdb from a file.
     871         * Should create a rappture owned directory to write files.
     872         */
     873        int fd;
     874        char fileName[200];
     875
     876        sprintf(fileName, "/tmp/pymol-%d.pdb", getpid());
     877        fd = open(fileName,O_WRONLY | O_TRUNC | O_CREAT, 0600);
     878        if (fd < 0) {
     879            Tcl_AppendResult(interp, "pymolproxy: error opening \"", fileName,
     880                "\": ", strerror(errno), (char *)NULL);
     881            pymol->status = TCL_ERROR;
     882            return TCL_ERROR;
    813883        }
    814 
    815     pymol->need_update = !defer || push;
    816         pymol->immediate_update |= push;
    817         pymol->invalidate_cache = 1;
    818 
    819     sendf(pymol, "viewport %d,%d\n", width, height);
    820 
    821         //usleep(205000); // .2s delay for pymol to update its geometry *HACK ALERT*
     884        write(fd, pdbdata, strlen(pdbdata));
     885        close(fd);
     886        sendf(pymol, "load %s, %s, %d\n", fileName, name, state);
     887    }
     888#else
     889    {
     890        int count;
     891        const char *p;
     892        char *q, *newdata;
     893
     894        count = 0;
     895        for (p = pdbdata; *p != '\0'; p++) {
     896            if (*p == '\n') {
     897                count++;
     898            }
     899            count++;
     900        }
    822901       
    823         return(pymol->status);
    824 }
    825 
    826 int
    827 LoadPDBStrCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    828 {
    829     const char *pdbdata, *pdb, *name;
    830         char *buf;
    831         char buffer[800];
    832         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
    833     int state = 1;
    834     int tmpf;
    835         int arg, defer = 0, push = 0, varg = 1;
    836         char filename[] = "/tmp/fileXXXXXX.pdb";
    837 
    838         if (pymol == NULL)
    839                 return(TCL_ERROR);
    840 
    841         clear_error(pymol);
    842 
    843     for(arg = 1; arg < argc; arg++) {
    844                 if ( strcmp(argv[arg],"-defer") == 0 )
    845                         defer = 1;
    846                 else if (strcmp(argv[arg],"-push") == 0)
    847                     push = 1;
    848         else if (varg == 1) {
    849                         pdbdata = argv[arg];
    850                         varg++;
    851                 }
    852                 else if (varg == 2) {
    853                         name = argv[arg];
    854                         varg++;
    855                 }
    856                 else if (varg == 3) {
    857                         state = atoi( argv[arg] );
    858                         varg++;
    859                 }
     902        q = newdata = malloc(count + 100);
     903        strcpy(newdata, "cmd.read_pdbstr(\"\"\"\\\n");
     904        q = newdata + strlen(newdata);
     905        for (p = pdbdata; *p != '\0'; p++, q++) {
     906            if (*p == '\n') {
     907                *q++ = '\\';
     908            }
     909            *q = *p;
    860910        }
    861 
    862         pymol->need_update = !defer || push;
    863     pymol->immediate_update |= push;
    864 
    865     tmpf = open(filename,O_RDWR|O_TRUNC|O_CREAT,0700);
    866        
    867         if (tmpf <= 0)
    868             fprintf(stderr,"pymolproxy: error opening file %d\n",errno);
    869 
    870     write(tmpf,pdbdata,strlen(pdbdata));
    871         close(tmpf);
    872        
    873     sendf(pymol, "load %s, %s, %d\n", filename, name, state);
    874         sendf(pymol, "zoom buffer=2\n");
    875 
    876         return(pymol->status);
    877 }
    878 
    879 int
     911        sprintf(q, "\\\n\"\"\",\"%s\",%d)\n", name, state);
     912        {
     913            char expect[800];
     914
     915            sprintf(expect, "PyMOL>\"\"\",\"%s\",%d)\n", name, state);
     916            send_expect(pymol, expect, newdata);
     917        }
     918        free(newdata);
     919    }
     920#endif
     921    sendf(pymol, "zoom buffer=2\n");
     922
     923    return pymol->status;
     924}
     925
     926static int
    880927RotateCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    881928{
    882         double turnx = 0.0;
    883         double turny = 0.0;
    884         double turnz = 0.0;
    885         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
     929    double turnx = 0.0;
     930    double turny = 0.0;
     931    double turnz = 0.0;
     932    PymolProxy *pymol = (PymolProxy *) cdata;
    886933    int defer = 0, push = 0, arg, varg = 1;
    887934
    888         if (pymol == NULL)
    889                 return(TCL_ERROR);
    890 
    891         clear_error(pymol);
     935    clear_error(pymol);
    892936
    893937    for(arg = 1; arg < argc; arg++)
    894         {
    895             if (strcmp(argv[arg],"-defer") == 0)
    896                     defer = 1;
    897                 else if (strcmp(argv[arg],"-push") == 0)
    898                     push = 1;
    899         else  if (varg == 1) {
    900                         turnx = atof(argv[arg]);
    901                         varg++;
    902                 }
    903                 else if (varg == 2) {
    904                     turny = atof(argv[arg]);
    905                         varg++;
    906                 }
    907         else if (varg == 3) {
    908                         turnz = atof(argv[arg]);
    909                         varg++;
    910                 }
    911     }
     938        {
     939            if (strcmp(argv[arg],"-defer") == 0)
     940                defer = 1;
     941            else if (strcmp(argv[arg],"-push") == 0)
     942                push = 1;
     943            else  if (varg == 1) {
     944                turnx = atof(argv[arg]);
     945                varg++;
     946            }
     947            else if (varg == 2) {
     948                turny = atof(argv[arg]);
     949                varg++;
     950            }
     951            else if (varg == 3) {
     952                turnz = atof(argv[arg]);
     953                varg++;
     954            }
     955        }
    912956 
    913957    pymol->need_update = !defer || push;
    914         pymol->immediate_update  |= push;
    915         pymol->invalidate_cache = 1;
    916 
    917         if (turnx != 0.0)
    918                 sendf(pymol,"turn x, %f\n", turnx);
    919        
    920         if (turny != 0.0)
    921                 sendf(pymol,"turn y, %f\n", turny);
    922        
    923         if (turnz != 0.0)
    924                 sendf(pymol,"turn z, %f\n", turnz);
    925 
    926         return(pymol->status);
    927 }
    928 
    929 int
     958    pymol->immediate_update  |= push;
     959    pymol->invalidate_cache = 1;
     960
     961    if (turnx != 0.0)
     962        sendf(pymol,"turn x, %f\n", turnx);
     963       
     964    if (turny != 0.0)
     965        sendf(pymol,"turn y, %f\n", turny);
     966       
     967    if (turnz != 0.0)
     968        sendf(pymol,"turn z, %f\n", turnz);
     969
     970    return pymol->status;
     971}
     972
     973static int
    930974ZoomCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    931975{
    932976    double factor = 0.0;
    933977    double zmove = 0.0;
    934         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
     978    PymolProxy *pymol = (PymolProxy *) cdata;
    935979    int defer = 0, push = 0, arg, varg = 1;
    936980
    937         if (pymol == NULL)
    938                 return(TCL_ERROR);
    939 
    940         clear_error(pymol);
     981    clear_error(pymol);
    941982
    942983    for(arg = 1; arg < argc; arg++)
    943         {
    944             if (strcmp(argv[arg],"-defer") == 0)
    945                     defer = 1;
    946                 else if (strcmp(argv[arg],"-push") == 0)
    947                     push = 1;
    948                 else if (varg == 1) {
    949                 factor = atof(argv[arg]);
    950                         varg++;
    951                 }
    952     }
    953 
    954         zmove = factor * -75;
     984        {
     985            if (strcmp(argv[arg],"-defer") == 0)
     986                defer = 1;
     987            else if (strcmp(argv[arg],"-push") == 0)
     988                push = 1;
     989            else if (varg == 1) {
     990                factor = atof(argv[arg]);
     991                varg++;
     992            }
     993        }
     994
     995    zmove = factor * -75;
    955996 
    956997    pymol->need_update = !defer || push;
    957         pymol->immediate_update  |= push;
    958         pymol->invalidate_cache = 1;
    959 
    960         if (zmove != 0.0)
    961                 sendf(pymol,"move z, %f\n", factor);
    962 
    963         return(pymol->status);
    964 }
    965 
    966 int
     998    pymol->immediate_update  |= push;
     999    pymol->invalidate_cache = 1;
     1000
     1001    if (zmove != 0.0)
     1002        sendf(pymol,"move z, %f\n", factor);
     1003
     1004    return pymol->status;
     1005}
     1006
     1007static int
    9671008PNGCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    9681009{
    969         char buffer[800];
    970         unsigned int bytes=0;
    971         float samples = 0.0;
    972         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
    973 
    974         if (pymol == NULL)
    975                 return(TCL_ERROR);
    976 
    977         clear_error(pymol);
     1010    char buffer[800];
     1011    unsigned int bytes=0;
     1012    float samples = 0.0;
     1013    PymolProxy *pymol = (PymolProxy *) cdata;
     1014
     1015    clear_error(pymol);
    9781016
    9791017    if (pymol->invalidate_cache)
    980             pymol->cacheid++;
    981 
    982         pymol->need_update = 0;
    983         pymol->immediate_update = 0;
    984         pymol->invalidate_cache = 0;
    985 
    986         sendf(pymol,"png -\n");
    987 
    988         waitForString(pymol, "image follows: ", buffer, 800);
    989 
    990         sscanf(buffer, "image follows: %d %f\n", &bytes, &samples);
     1018        pymol->cacheid++;
     1019
     1020    pymol->need_update = 0;
     1021    pymol->immediate_update = 0;
     1022    pymol->invalidate_cache = 0;
     1023
     1024    sendf(pymol,"png -\n");
     1025
     1026    waitForString(pymol, "image follows: ", buffer, 800);
     1027
     1028    sscanf(buffer, "image follows: %d %f\n", &bytes, &samples);
    9911029 
    992         write(3,&samples,sizeof(samples));
     1030    write(3,&samples,sizeof(samples));
    9931031 
    9941032    dyBufferSetLength(&pymol->image, bytes);
    9951033
    996         bread(pymol->p_stdout, pymol->image.data, pymol->image.used);
    997 
    998         waitForString(pymol, " ScenePNG", buffer,800);
     1034    bread(pymol->p_stdout, pymol->image.data, pymol->image.used);
     1035
     1036    waitForString(pymol, " ScenePNG", buffer,800);
    9991037
    10001038    if (bytes && (pymol->image.used == bytes)) {
    1001             sprintf(buffer, "nv>image %d %d,%d,%d\n",
    1002                 bytes, pymol->cacheid, pymol->frame, pymol->rock_offset);
    1003 
    1004             write(pymol->c_stdin, buffer, strlen(buffer));
    1005             bwrite(pymol->c_stdin, pymol->image.data, bytes);
    1006     }
    1007 
    1008         return(pymol->status);
    1009 }
    1010 
    1011 int
     1039        sprintf(buffer, "nv>image %d %d %d %d\n",
     1040                bytes, pymol->cacheid, pymol->frame, pymol->rock_offset);
     1041        trace("to-molvis> %s", buffer);
     1042        write(pymol->c_stdin, buffer, strlen(buffer));
     1043        bwrite(pymol->c_stdin, pymol->image.data, bytes);
     1044    }
     1045    return pymol->status;
     1046}
     1047
     1048static int
    10121049BMPCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    10131050{
    1014         char buffer[800];
    1015         unsigned int bytes=0;
    1016         float samples = 0.0;
    1017         struct pymol_proxy *pymol = (struct pymol_proxy *) cdata;
    1018 
    1019         if (pymol == NULL)
    1020                 return(TCL_ERROR);
    1021 
    1022         clear_error(pymol);
     1051    char buffer[800];
     1052    unsigned int bytes=0;
     1053    float samples = 0.0;
     1054    PymolProxy *pymol = (PymolProxy *) cdata;
     1055
     1056    clear_error(pymol);
    10231057
    10241058    if (pymol->invalidate_cache)
    1025             pymol->cacheid++;
    1026 
    1027         pymol->need_update = 0;
    1028         pymol->immediate_update = 0;
    1029         pymol->invalidate_cache = 0;
    1030 
    1031         sendf(pymol,"bmp -\n");
    1032 
    1033         waitForString(pymol, "image follows: ", buffer, 800);
    1034 
    1035         sscanf(buffer, "image follows: %d %f\n", &bytes, &samples);
    1036         write(3,&samples,sizeof(samples));
     1059        pymol->cacheid++;
     1060
     1061    pymol->need_update = 0;
     1062    pymol->immediate_update = 0;
     1063    pymol->invalidate_cache = 0;
     1064
     1065    sendf(pymol,"bmp -\n");
     1066
     1067    waitForString(pymol, "image follows: ", buffer, 800);
     1068
     1069    sscanf(buffer, "image follows: %d %f\n", &bytes, &samples);
     1070    write(3,&samples,sizeof(samples));
    10371071
    10381072    dyBufferSetLength(&pymol->image, bytes);
    10391073
    1040         bread(pymol->p_stdout, pymol->image.data, pymol->image.used);
     1074    bread(pymol->p_stdout, pymol->image.data, pymol->image.used);
    10411075
    10421076    if (bytes && (pymol->image.used == bytes)) {
    1043             sprintf(buffer, "nv>image %d %d,%d,%d\n",
    1044                     bytes, pymol->cacheid, pymol->frame, pymol->rock_offset);
    1045             write(pymol->c_stdin, buffer, strlen(buffer));
    1046                 //fprintf(stderr,buffer);
    1047             bwrite(pymol->c_stdin, pymol->image.data, bytes);
    1048     }
    1049 
    1050         return(pymol->status);
    1051 }
    1052        
    1053 int pyMol_Proxy(int c_in, int c_out, char *command, char *argv[])
     1077        sprintf(buffer, "nv>image %d %d %d %d\n",
     1078                bytes, pymol->cacheid, pymol->frame, pymol->rock_offset);
     1079        write(pymol->c_stdin, buffer, strlen(buffer));
     1080        trace("to-molvis buffer=%s\n", buffer);
     1081        bwrite(pymol->c_stdin, pymol->image.data, bytes);
     1082    }
     1083    return pymol->status;
     1084}
     1085       
     1086static int
     1087ProxyInit(int c_in, int c_out, char *const *argv)
    10541088{
    10551089    int flags, status, result = 0;
    1056         int pairIn[2];
    1057         int pairOut[2];
    1058         int pairErr[2];
    1059         char buffer[800];
    1060         Tcl_Interp *interp;
    1061         Tcl_DString cmdbuffer;
    1062         struct dyBuffer dybuffer, dybuffer2;
    1063         struct pollfd ufd[3];
    1064         int pid;
    1065         struct pymol_proxy pymol;
    1066         struct timeval now,end;
    1067         int timeout;
    1068 
    1069         /* Create three pipes for communication with the external application   */
    1070         /* One each for the applications's: stdin, stdout, and stderr                   */
    1071 
    1072         if (pipe(pairIn) == -1)
    1073                 return(-1);
    1074 
    1075         if (pipe(pairOut) == -1) {
    1076                 close(pairIn[0]);
    1077                 close(pairIn[1]);
    1078                 return(-1);
    1079         }
    1080 
    1081         if (pipe(pairErr) == -1) {
    1082                 close(pairIn[0]);
    1083                 close(pairIn[1]);
    1084                 close(pairOut[0]);
    1085                 close(pairOut[1]);
    1086                 return(-1);
    1087         }
    1088 
    1089         /* Fork the new process.  Connect i/o to the new socket.                                */
    1090 
    1091         pid = fork();
     1090    int pairIn[2];
     1091    int pairOut[2];
     1092    int pairErr[2];
     1093    char buffer[800];
     1094    Tcl_Interp *interp;
     1095    Tcl_DString cmdbuffer;
     1096    DyBuffer dybuffer, dybuffer2;
     1097    struct pollfd ufd[3];
     1098    int pid;
     1099    PymolProxy pymol;
     1100    struct timeval now,end;
     1101    int timeout;
     1102
     1103    /* Create three pipes for communication with the external application. One
     1104     * each for the applications's: stdin, stdout, and stderr  */
     1105
     1106    if (pipe(pairIn) == -1)
     1107        return(-1);
     1108
     1109    if (pipe(pairOut) == -1) {
     1110        close(pairIn[0]);
     1111        close(pairIn[1]);
     1112        return(-1);
     1113    }
     1114
     1115    if (pipe(pairErr) == -1) {
     1116        close(pairIn[0]);
     1117        close(pairIn[1]);
     1118        close(pairOut[0]);
     1119        close(pairOut[1]);
     1120        return(-1);
     1121    }
     1122
     1123    /* Fork the new process.  Connect i/o to the new socket.  */
     1124
     1125    pid = fork();
    10921126       
    1093         if (pid < 0)
    1094                 return(-3);
    1095 
    1096         if (pid == 0)  /* child process */
    1097         {
    1098                 int i, fd;
    1099 
    1100                 /* create a new process group, so we can later kill this process and
    1101                  * all its children without affecting the process that created this one
    1102                  */
    1103 
    1104                 setpgid(pid, 0);
    1105 
    1106                 /* Redirect stdin, stdout, and stderr to pipes before execing           */
    1107 
    1108                 dup2(pairIn[0] ,0);  // stdin
    1109                 dup2(pairOut[1],1);  // stdout
    1110                 dup2(pairErr[1],2);  // stderr
    1111 
    1112                 for(fd = 3; fd < FD_SETSIZE; fd++)      /* close all other descriptors  */
    1113                         close(fd);
    1114 
    1115                 execvp(command,argv);
    1116                 fprintf(stderr,"pymolproxy: Failed to start pyMol\n");
    1117                 exit(-1);
    1118         }
     1127    if (pid < 0)
     1128        return(-3);
     1129
     1130    if (pid == 0)  /* child process */
     1131        {
     1132            int i, fd;
     1133
     1134            /* Create a new process group, so we can later kill this process
     1135             * and all its children without affecting the process that created
     1136             * this one
     1137             */
     1138
     1139            setpgid(pid, 0);
     1140
     1141            /* Redirect stdin, stdout, and stderr to pipes before execing               */
     1142
     1143            dup2(pairIn[0] ,0);  // stdin
     1144            dup2(pairOut[1],1);  // stdout
     1145            dup2(pairErr[1],2);  // stderr
     1146
     1147            for(fd = 3; fd < FD_SETSIZE; fd++)  /* close all other descriptors  */
     1148                close(fd);
     1149
     1150            execvp(argv[0], argv);
     1151            trace("pymolproxy: Failed to start pyMol\n");
     1152            exit(-1);
     1153        }
    11191154       
    1120         /* close opposite end of pipe, these now belong to the child process    */
     1155    /* close opposite end of pipe, these now belong to the child process        */
    11211156    close(pairIn[0]);
    11221157    close(pairOut[1]);
    11231158    close(pairErr[1]);
    11241159
    1125         signal(SIGPIPE, SIG_IGN); // ignore SIGPIPE (ie if nanoscale terminates)
    1126 
    1127         pymol.p_stdin = pairIn[1];
    1128         pymol.p_stdout = pairOut[0];
    1129         pymol.p_stderr = pairErr[0];
    1130         pymol.c_stdin  = c_in;
    1131         pymol.c_stdout = c_out;
    1132         pymol.labels = 0;
    1133         pymol.need_update = 0;
    1134         pymol.can_update = 1;
    1135         pymol.immediate_update = 0;
    1136         pymol.sync = 0;
     1160    signal(SIGPIPE, SIG_IGN); // ignore SIGPIPE (ie if nanoscale terminates)
     1161
     1162    pymol.p_stdin = pairIn[1];
     1163    pymol.p_stdout = pairOut[0];
     1164    pymol.p_stderr = pairErr[0];
     1165    pymol.c_stdin  = c_in;
     1166    pymol.c_stdout = c_out;
     1167    pymol.labels = 0;
     1168    pymol.need_update = 0;
     1169    pymol.can_update = 1;
     1170    pymol.immediate_update = 0;
     1171    pymol.sync = 0;
    11371172    pymol.frame = 1;
    1138         pymol.rock_offset = 0;
    1139         pymol.cacheid = 0;
    1140         pymol.invalidate_cache = 0;
    1141 
    1142         ufd[0].fd = pymol.c_stdout;
    1143         ufd[0].events = POLLIN | POLLHUP; /* ensure catching EOF */
    1144         ufd[1].fd = pymol.p_stdout;
    1145         ufd[1].events = POLLIN | POLLHUP;
    1146         ufd[2].fd = pymol.p_stderr;
    1147         ufd[2].events = POLLIN | POLLHUP;
     1173    pymol.rock_offset = 0;
     1174    pymol.cacheid = 0;
     1175    pymol.invalidate_cache = 0;
     1176
     1177    ufd[0].fd = pymol.c_stdout;
     1178    ufd[0].events = POLLIN | POLLHUP; /* ensure catching EOF */
     1179    ufd[1].fd = pymol.p_stdout;
     1180    ufd[1].events = POLLIN | POLLHUP;
     1181    ufd[2].fd = pymol.p_stderr;
     1182    ufd[2].events = POLLIN | POLLHUP;
    11481183
    11491184    flags = fcntl(pymol.p_stdout, F_GETFL);
    11501185    fcntl(pymol.p_stdout, F_SETFL, flags|O_NONBLOCK);
    11511186
    1152         interp = Tcl_CreateInterp();
    1153         Tcl_MakeSafe(interp);
    1154 
    1155         Tcl_DStringInit(&cmdbuffer);
    1156         dyBufferInit(&pymol.image);
     1187    interp = Tcl_CreateInterp();
     1188    Tcl_MakeSafe(interp);
     1189
     1190    Tcl_DStringInit(&cmdbuffer);
     1191    dyBufferInit(&pymol.image);
    11571192    dyBufferInit(&dybuffer);
    11581193    dyBufferInit(&dybuffer2);
    11591194
    1160         Tcl_CreateCommand(interp,"bmp",BMPCmd,(ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1161         Tcl_CreateCommand(interp,"png",PNGCmd,(ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1162         Tcl_CreateCommand(interp,"screen",ViewportCmd,(ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1163         Tcl_CreateCommand(interp,"viewport",ViewportCmd,(ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1164         Tcl_CreateCommand(interp,"rotate",RotateCmd,(ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1165         Tcl_CreateCommand(interp,"zoom",ZoomCmd,(ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1166         Tcl_CreateCommand(interp,"loadpdb", LoadPDBStrCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc *)NULL);
    1167         Tcl_CreateCommand(interp,"ball_and_stick", BallAndStickCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1168         Tcl_CreateCommand(interp,"spheres", SpheresCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1169         Tcl_CreateCommand(interp,"lines", LinesCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1170         Tcl_CreateCommand(interp,"raw", RawCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1171         Tcl_CreateCommand(interp,"label", LabelCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1172         Tcl_CreateCommand(interp,"reset", ResetCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1173         Tcl_CreateCommand(interp,"rock", RockCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1174         Tcl_CreateCommand(interp,"frame", FrameCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1175         Tcl_CreateCommand(interp,"vmouse", VMouseCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1176         Tcl_CreateCommand(interp,"disable", DisableCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1177         Tcl_CreateCommand(interp,"enable", EnableCmd, (ClientData)&pymol, (Tcl_CmdDeleteProc*)NULL);
    1178 
    1179         // Main Proxy Loop
    1180         //      accept tcl commands from socket
    1181         //  translate them into pyMol commands, and issue them to child proccess
    1182         //  send images back
    1183 
    1184         gettimeofday(&end, NULL);
    1185 
    1186         while(1)
    1187         {
    1188                 char ch;
    1189 
    1190             gettimeofday(&now,NULL);
    1191 
    1192         if ( (!pymol.need_update) )
    1193             timeout = -1;
    1194         else if ((now.tv_sec > end.tv_sec) || ( (now.tv_sec == end.tv_sec) && (now.tv_usec >= end.tv_usec)) )
    1195             timeout = 0;
    1196         else
     1195    Tcl_CreateCommand(interp, "bmp",     BMPCmd,        &pymol, NULL);
     1196    Tcl_CreateCommand(interp, "png",     PNGCmd,        &pymol, NULL);
     1197    Tcl_CreateCommand(interp, "screen",  ViewportCmd,   &pymol, NULL);
     1198    Tcl_CreateCommand(interp, "viewport",ViewportCmd,   &pymol, NULL);
     1199    Tcl_CreateCommand(interp, "rotate",  RotateCmd,     &pymol, NULL);
     1200    Tcl_CreateCommand(interp, "zoom",    ZoomCmd,       &pymol, NULL);
     1201    Tcl_CreateCommand(interp, "loadpdb", LoadPDBCmd,    &pymol, NULL);
     1202    Tcl_CreateCommand(interp, "ballnstick",BallNStickCmd, &pymol, NULL);
     1203    Tcl_CreateCommand(interp, "spheres", SpheresCmd,    &pymol, NULL);
     1204    Tcl_CreateCommand(interp, "lines",   LinesCmd,      &pymol, NULL);
     1205    Tcl_CreateCommand(interp, "raw",     RawCmd,        &pymol, NULL);
     1206    Tcl_CreateCommand(interp, "label",   LabelCmd,      &pymol, NULL);
     1207    Tcl_CreateCommand(interp, "reset",   ResetCmd,      &pymol, NULL);
     1208    Tcl_CreateCommand(interp, "rock",    RockCmd,       &pymol, NULL);
     1209    Tcl_CreateCommand(interp, "frame",   FrameCmd,      &pymol, NULL);
     1210    Tcl_CreateCommand(interp, "vmouse",  VMouseCmd,     &pymol, NULL);
     1211    Tcl_CreateCommand(interp, "disable", DisableCmd,    &pymol, NULL);
     1212    Tcl_CreateCommand(interp, "enable",  EnableCmd,     &pymol, NULL);
     1213
     1214    // Main Proxy Loop
     1215    //  accept tcl commands from socket
     1216    //  translate them into pyMol commands, and issue them to child proccess
     1217    //  send images back
     1218
     1219    gettimeofday(&end, NULL);
     1220
     1221    while(1)
    11971222        {
    1198             timeout = (end.tv_sec - now.tv_sec) * 1000;
    1199 
    1200             if (end.tv_usec > now.tv_usec)
    1201                 timeout += (end.tv_usec - now.tv_usec) / 1000;
     1223            char ch;
     1224
     1225            gettimeofday(&now,NULL);
     1226
     1227            if ( (!pymol.need_update) )
     1228                timeout = -1;
     1229            else if ((now.tv_sec > end.tv_sec) || ( (now.tv_sec == end.tv_sec) && (now.tv_usec >= end.tv_usec)) )
     1230                timeout = 0;
    12021231            else
    1203                 timeout += (((1000000 + end.tv_usec) - now.tv_usec) / 1000) - 1000;
    1204 
    1205         }
    1206 
    1207                 if (!pymol.immediate_update)
    1208                         status = poll(ufd, 3, timeout);
    1209             else
    1210                     status = 0;
    1211 
    1212                 if ( status < 0 )
    1213                 {
    1214                         fprintf(stderr, "pymolproxy: POLL ERROR: status = %d, errno = %d, %s \n", status,errno,strerror(errno));
    1215                 }
    1216                 else if (status > 0)
    1217                 {
    1218                         gettimeofday(&now,NULL);
    1219 
    1220             if (ufd[0].revents) { /* Client Stdout Connection: command input */
    1221                             if (read(ufd[0].fd,&ch,1) <= 0)
    1222                             {
    1223                                     if (errno != EINTR)
    1224                                         {
    1225                                         fprintf(stderr,"pymolproxy: lost client connection (%d).\n", errno);
    1226                                         break;
    1227                                         }
    1228                             }
    1229                             else
    1230                             {
    1231                                     Tcl_DStringAppend(&cmdbuffer, &ch, 1);
    1232 
    1233                                     if (ch == '\n' && Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer))) {
    1234                                     Tcl_Eval(interp, Tcl_DStringValue(&cmdbuffer));
    1235                                             //fprintf(stderr,"Executed(%d,%d): %s", pymol.need_update, pymol.immediate_update, Tcl_DStringValue(&cmdbuffer));
    1236                                     Tcl_DStringSetLength(&cmdbuffer, 0);
    1237 
    1238                                             if (timeout == 0) status = 0; // send update
    1239                             }
    1240                             }
    1241                         }
    1242 
    1243                         if (ufd[1].revents ) { /* pyMol Stdout Connection: pymol (unexpected) output */
    1244                             if (read(ufd[1].fd, &ch, 1) <= 0)
    1245                                 {
    1246                                     if (errno != EINTR) {
    1247                                         fprintf(stderr,"pymolproxy: lost connection (stdout) to pymol server\n");
    1248                                                 break;
    1249                                         }
    1250                                 }
    1251                                 else
    1252                                 {
    1253                                     dyBufferAppend(&dybuffer, &ch, 1);
    1254 
    1255                                         if (ch == '\n') {
    1256                                             ch = 0;
    1257                                             dyBufferAppend(&dybuffer, &ch, 1);
    1258                                                 fprintf(stderr,"STDOUT>%s",dybuffer.data);
    1259                                                 dyBufferSetLength(&dybuffer,0);
    1260                                         }
    1261                                 }
    1262                         }
    1263 
    1264                         if (ufd[2].revents) { /* pyMol Stderr Connection: pymol standard error output */
    1265                                 if (read(ufd[2].fd, &ch, 1) <= 0)
    1266                                 {
    1267                                     if (errno != EINTR) {
    1268                                             fprintf(stderr,"pymolproxy: lost connection (stderr) to pymol server\n");
    1269                                                 break;
    1270                                         }
    1271                                 }
    1272                                 else {
    1273                                         dyBufferAppend(&dybuffer2, &ch, 1);
    1274 
    1275                                         if (ch == '\n') {
    1276                                             ch = 0;
    1277                                                 dyBufferAppend(&dybuffer2, &ch, 1);
    1278                                                 fprintf(stderr,"stderr>%s", dybuffer2.data);
    1279                                                 dyBufferSetLength(&dybuffer2,0);
    1280                                         }
    1281                                 }
    1282                         }
    1283                 }
    1284 
    1285         if (status == 0)
    1286                 {
    1287                         gettimeofday(&now,NULL);
    1288 
    1289                         if (pymol.need_update && pymol.can_update)
    1290                                 Tcl_Eval(interp, "bmp -\n");
    1291 
    1292                         end.tv_sec = now.tv_sec;
    1293                         end.tv_usec = now.tv_usec + 150000;
    1294 
    1295             if (end.tv_usec >= 1000000)
    1296                         {
    1297                                 end.tv_sec++;
    1298                                 end.tv_usec -= 1000000;
    1299                         }
    1300 
    1301                 }
    1302 
    1303     }
    1304 
    1305         status = waitpid(pid, &result, WNOHANG);
    1306 
    1307         if (status == -1)
    1308                 fprintf(stderr, "pymolproxy: error waiting on pymol server to exit (%d)\n", errno);
    1309         else if (status == 0) {
    1310                 fprintf(stderr, "pymolproxy: attempting to SIGTERM pymol server\n");
    1311                 kill(-pid, SIGTERM); // kill process group
    1312                 alarm(5);
    1313                 status = waitpid(pid, &result, 0);
    1314                 alarm(0);
    1315 
    1316                 while ((status == -1) && (errno == EINTR))
    1317                 {
    1318                         fprintf(stderr, "pymolproxy: Attempting to SIGKILL process.\n");
    1319                         kill(-pid, SIGKILL); // kill process group
    1320                         alarm(10);
    1321                         status = waitpid(pid, &result, 0);
    1322                         alarm(0);
    1323                 }
    1324         }
    1325 
    1326         fprintf(stderr, "pymolproxy: pymol server process ended (%d)\n", result);
    1327 
    1328         dyBufferFree(&pymol.image);
    1329 
    1330         Tcl_DeleteInterp(interp);
    1331 
    1332         return( (status == pid) ? 0 : 1);
     1232                {
     1233                    timeout = (end.tv_sec - now.tv_sec) * 1000;
     1234
     1235                    if (end.tv_usec > now.tv_usec)
     1236                        timeout += (end.tv_usec - now.tv_usec) / 1000;
     1237                    else
     1238                        timeout += (((1000000 + end.tv_usec) - now.tv_usec) / 1000) - 1000;
     1239
     1240                }
     1241
     1242            if (!pymol.immediate_update)
     1243                status = poll(ufd, 3, timeout);
     1244            else
     1245                status = 0;
     1246
     1247            if ( status < 0 )
     1248                {
     1249                    trace("pymolproxy: POLL ERROR: status = %d, errno = %d, %s \n", status,errno,strerror(errno));
     1250                }
     1251            else if (status > 0)
     1252                {
     1253                    gettimeofday(&now,NULL);
     1254
     1255                    if (ufd[0].revents) { /* Client Stdout Connection: command input */
     1256                        if (read(ufd[0].fd,&ch,1) <= 0)
     1257                            {
     1258                                if (errno != EINTR)
     1259                                    {
     1260                                        trace("pymolproxy: lost client connection (%d).\n", errno);
     1261                                        break;
     1262                                    }
     1263                            }
     1264                        else
     1265                            {
     1266                                Tcl_DStringAppend(&cmdbuffer, &ch, 1);
     1267
     1268                                if (ch == '\n' && Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer))) {
     1269                                    Tcl_Eval(interp, Tcl_DStringValue(&cmdbuffer));
     1270                                    trace("Executed(%d,%d): %s", pymol.need_update, pymol.immediate_update, Tcl_DStringValue(&cmdbuffer));
     1271                                    Tcl_DStringSetLength(&cmdbuffer, 0);
     1272
     1273                                    if (timeout == 0) status = 0; // send update
     1274                                }
     1275                            }
     1276                    }
     1277
     1278                    if (ufd[1].revents ) { /* pyMol Stdout Connection: pymol (unexpected) output */
     1279                        if (read(ufd[1].fd, &ch, 1) <= 0)
     1280                            {
     1281                                if (errno != EINTR) {
     1282                                    trace("pymolproxy: lost connection (stdout) to pymol server\n");
     1283                                    break;
     1284                                }
     1285                            }
     1286                        else
     1287                            {
     1288                                dyBufferAppend(&dybuffer, &ch, 1);
     1289
     1290                                if (ch == '\n') {
     1291                                    ch = 0;
     1292                                    dyBufferAppend(&dybuffer, &ch, 1);
     1293                                    trace("STDOUT>%s",dybuffer.data);
     1294                                    dyBufferSetLength(&dybuffer,0);
     1295                                }
     1296                            }
     1297                    }
     1298
     1299                    if (ufd[2].revents) { /* pyMol Stderr Connection: pymol standard error output */
     1300                        if (read(ufd[2].fd, &ch, 1) <= 0)
     1301                            {
     1302                                if (errno != EINTR) {
     1303                                    trace("pymolproxy: lost connection (stderr) to pymol server\n");
     1304                                    break;
     1305                                }
     1306                            }
     1307                        else {
     1308                            dyBufferAppend(&dybuffer2, &ch, 1);
     1309
     1310                            if (ch == '\n') {
     1311                                ch = 0;
     1312                                dyBufferAppend(&dybuffer2, &ch, 1);
     1313                                trace("stderr>%s", dybuffer2.data);
     1314                                dyBufferSetLength(&dybuffer2,0);
     1315                            }
     1316                        }
     1317                    }
     1318                }
     1319
     1320            if (status == 0)
     1321                {
     1322                    gettimeofday(&now,NULL);
     1323
     1324                    if (pymol.need_update && pymol.can_update)
     1325                        Tcl_Eval(interp, "bmp -\n");
     1326
     1327                    end.tv_sec = now.tv_sec;
     1328                    end.tv_usec = now.tv_usec + 150000;
     1329
     1330                    if (end.tv_usec >= 1000000)
     1331                        {
     1332                            end.tv_sec++;
     1333                            end.tv_usec -= 1000000;
     1334                        }
     1335
     1336                }
     1337
     1338        }
     1339
     1340    status = waitpid(pid, &result, WNOHANG);
     1341
     1342    if (status == -1) {
     1343        trace("pymolproxy: error waiting on pymol server to exit (%d)\n", errno);
     1344    } else if (status == 0) {
     1345        trace("pymolproxy: attempting to SIGTERM pymol server\n");
     1346        kill(-pid, SIGTERM); // kill process group
     1347        alarm(5);
     1348        status = waitpid(pid, &result, 0);
     1349        alarm(0);
     1350
     1351        while ((status == -1) && (errno == EINTR))
     1352            {
     1353                trace("pymolproxy: Attempting to SIGKILL process.\n");
     1354                kill(-pid, SIGKILL); // kill process group
     1355                alarm(10);
     1356                status = waitpid(pid, &result, 0);
     1357                alarm(0);
     1358            }
     1359    }
     1360
     1361    trace("pymolproxy: pymol server process ended (%d)\n", result);
     1362
     1363    dyBufferFree(&pymol.image);
     1364
     1365    Tcl_DeleteInterp(interp);
     1366
     1367    return( (status == pid) ? 0 : 1);
    13331368}
    13341369
    13351370#ifdef STANDALONE
    1336 
    1337 #define MAX_ARGS 100
    13381371
    13391372int
    13401373main(int argc, char *argv[])
    13411374{
    1342     int arg;
    1343     char *myargv[MAX_ARGS+1];
    1344 
    1345         if (argc > MAX_ARGS+1) {
    1346         fprintf(stderr, "%s: Argument list too long (%d > %d arguments).", argv[0], argc, MAX_ARGS + 1);
    1347                 return(1);
    1348         }
    1349 
    1350     for(arg = 1; arg < argc; arg++)
    1351             myargv[arg-1] = argv[arg];
    1352 
    1353         myargv[arg-1] = NULL;
    1354 
    1355     pyMol_Proxy(fileno(stdout), fileno(stdin), myargv[0], myargv);
     1375    if (debug) {
     1376        flog = stderr;
     1377        flog = fopen("/tmp/pymolproxy.log", "w");
     1378    }   
     1379    ProxyInit(fileno(stdout), fileno(stdin), argv + 1);
     1380    return 0;
    13561381}
    13571382
Note: See TracChangeset for help on using the changeset viewer.