X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=view.c;h=712623c02f6667694c760b65e37cd6306f41ede8;hb=251e54ceafbd572cf2a3e9c70c5f5db07794f7c6;hp=1ce6db66d492867a869ed833b2a9e9c6931067a8;hpb=512fa4d69efa3f71c61a581c137ee6da2a9bf2f9;p=moebius2.git diff --git a/view.c b/view.c index 1ce6db6..712623c 100644 --- a/view.c +++ b/view.c @@ -5,6 +5,10 @@ #include #include +#include +#include +#include + #include "mgraph.h" #define MAXTRIS (N*2) @@ -18,16 +22,21 @@ static Vertices conformation; static double transform[D3][D3]= {{1,0,0}, {0,1,0}, {0,0,1}}; static GSL_MATRIX(transform); -const char *input_filename; +static FILE *input_f; +static struct stat input_stab; +static const char *input_filename; static void read_input(void) { - FILE *f; int r; - f= fopen(input_filename, "rb"); if (!f) diee("input file"); + if (input_f) fclose(input_f); + input_f= fopen(input_filename, "rb"); if (!input_f) diee("input file"); + + if (fstat(fileno(input_f), &input_stab)) diee("fstat input file"); + errno= 0; - r= fread(&conformation,sizeof(conformation),1,f); if (r!=1) diee("fread"); - fclose(f); + r= fread(&conformation,sizeof(conformation),1,input_f); + if (r!=1) diee("fread"); } static void transform_coordinates(void) { @@ -111,6 +120,8 @@ XVisualInfo visinfo; static double sizeadj_scale= 0.3, eyes_apart, scale_wmindim; static double eye_z= -10, eye_x=0; static double cut_z= -9; +static const double eyes_apart_preferred=0.05, eyes_apart_min= -0.02; + static void drawtriangle(const Triangle *t) { XPoint points[4]; @@ -137,7 +148,8 @@ static void drawtriangle(const Triangle *t) { } static const unsigned long core_event_mask= - ButtonPressMask|ButtonReleaseMask|StructureNotifyMask|ButtonMotionMask; + ButtonPressMask|ButtonReleaseMask|StructureNotifyMask|ButtonMotionMask| + KeyPressMask; static void mkpixmaps(void) { for (currentbuffer=0; currentbuffer<2; currentbuffer++) { @@ -205,11 +217,13 @@ static void display_conformation(void) { XA( XFillRectangle(display,pixmap,dmwhite.fillgc,0,0,wwidth,wheight) ); if (eyes_apart > 0) { - const double preferred=0.05, beyond=0.07; + const double stationary= 0.07; - eye_x= eyes_apart < preferred ? eyes_apart : - eyes_apart < beyond ? preferred : - eyes_apart - (beyond - preferred); + eye_x= eyes_apart < eyes_apart_preferred + ? eyes_apart : + eyes_apart < (eyes_apart_preferred + stationary) + ? eyes_apart_preferred + : eyes_apart - stationary; eye_x /= sizeadj_scale; drawtriangles(&dmblue); eye_x= -eye_x; @@ -398,9 +412,8 @@ static void drag_sizeadj_delta(double dx, double dy) { DRAG_SAVING(sizeadj, sizeadj_scale); static void drag_3d_delta(double dx, double dy) { - const double min_eyes_apart= -0.02; eyes_apart += dx * 0.1; - if (eyes_apart < min_eyes_apart) eyes_apart= min_eyes_apart; + if (eyes_apart < eyes_apart_min) eyes_apart= eyes_apart_min; printf("sizeadj eyes_apart %g\n", eyes_apart); show(); } @@ -452,6 +465,26 @@ static void event_motion(int x, int y) { drag_position(x,y); } +static void event_key(XKeyEvent *e) { + KeySym ks; + char buf[10]; + int r; + + r= XLookupString(e,buf,sizeof(buf)-1,&ks,0); + if (!r) { + printf("XLookupString keycode=%u state=0x%x gave %d\n", + e->keycode, e->state, r); + return; + } + + if (!strcmp(buf,"q")) exit(0); + if (!strcmp(buf,"d")) { + eyes_apart= eyes_apart>0 ? eyes_apart_min : eyes_apart_preferred; + show(); + return; + } +} + static void event_config(XConfigureEvent *e) { if (e->width == wwidth && e->height == wheight) return; @@ -468,9 +501,31 @@ static void event_config(XConfigureEvent *e) { show(); } +static void check_input(void) { + struct stat newstab; + int r; + + r= stat(input_filename, &newstab); + if (r<0) diee("could not check input"); + +#define CI(x) if (newstab.st_##x == input_stab.st_##x) ; else goto changed + CI(dev); + CI(ino); + CI(size); + CI(mtime); +#undef CI + return; + + changed: + show(); +} + int main(int argc, const char *const *argv) { + static const int wantedevents= POLLIN|POLLPRI|POLLERR|POLLHUP; + XEvent event; - int k; + int k, i, r, *xfds, nxfds, polls_alloc=0; + struct pollfd *polls=0; int motion_deferred=0, motion_x=-1, motion_y=-1; if (argc != 2 || argv[1][0]=='-') { @@ -485,21 +540,47 @@ int main(int argc, const char *const *argv) { XMapWindow(display,window); for (;;) { - if (motion_deferred) { - int r= XCheckMaskEvent(display,~0UL,&event); - if (!r) { + + XA( XInternalConnectionNumbers(display, &xfds, &nxfds) ); + if (polls_alloc <= nxfds) { + polls_alloc= nxfds + polls_alloc + 1; + polls= realloc(polls, sizeof(*polls) * polls_alloc); + if (!polls) diee("realloc for pollfds"); + } + for (i=0; i