}
}
+/*---------- input handling ----------*/
+
+typedef struct {
+ const char *name;
+ void (*on_eof)(void);
+ void (*on_input_line)(ParseState *ps);
+} InputStream;
+
+static void *input_iferr(oop_source *evts, oop_read *stdin_read,
+ oop_rd_event evt, const char *errmsg, int errnoval,
+ const char *data, size_t recsz, void *is_v) {
+ const InputStream *is= is_v;
+ const char *emsg;
+ emsg= oop_rd_errmsg(stdin_read, evt, errnoval, OOP_RD_STYLE_GETLINE);
+ die("%s: %s", is->name, emsg);
+}
+
+static void *input_ifok(oop_source *evts, oop_read *cl_read,
+ oop_rd_event evt, const char *errmsg, int errnoval,
+ const char *data, size_t recsz, void *is_v) {
+ const InputStream *is= is_v;
+ ParseState ps;
+
+ if (evt == OOP_RD_EOF) {
+ is->on_eof();
+ abort();
+ }
+ if (evt != OOP_RD_OK) {
+ input_iferr(evts,cl_read,evt,errmsg,errnoval,data,recsz,is_v);
+ return OOP_CONTINUE;
+ }
+
+ badcmdreport_data= data;
+ badcmdreport_recsz= recsz;
+
+ ps.remain= data;
+ is->on_input_line(&ps);
+
+ return OOP_CONTINUE;
+}
+
static void *some_exception(oop_source *evts, int fd,
- oop_event evt, void *cl_v) {
- die("poll exception on fd %d",fd);
+ oop_event evt, void *name_v) {
+ const char *name= name_v;
+ die("poll exception on %s (fd %d)",name,fd);
}
+/*---------- drawing etc. ----------*/
+
static int range_overlap(int x1, int width1, int x2, int width2) {
/* works for y's and heights too, obviously. */
int rhs1, rhs2;
XCALL( XFreePixmap, "mask", (d,pm) );
}
-/*---------- input handling ----------*/
-
-typedef struct {
- const char *name;
- void (*on_eof)(void);
- void (*on_input_line)(ParseState *ps);
-} InputStream;
-
-static void *input_iferr(oop_source *evts, oop_read *stdin_read,
- oop_rd_event evt, const char *errmsg, int errnoval,
- const char *data, size_t recsz, void *is_v) {
- const InputStream *is= is_v;
- const char *emsg;
- emsg= oop_rd_errmsg(stdin_read, evt, errnoval, OOP_RD_STYLE_GETLINE);
- die("%s: %s", is->name, emsg);
-}
-
-static void *input_ifok(oop_source *evts, oop_read *cl_read,
- oop_rd_event evt, const char *errmsg, int errnoval,
- const char *data, size_t recsz, void *is_v) {
- const InputStream *is= is_v;
- ParseState ps;
-
- if (evt == OOP_RD_EOF) {
- is->on_eof();
- abort();
- }
- if (evt != OOP_RD_OK) {
- input_iferr(evts,cl_read,evt,errmsg,errnoval,data,recsz,is_v);
- return OOP_CONTINUE;
- }
-
- badcmdreport_data= data;
- badcmdreport_recsz= recsz;
-
- ps.remain= data;
- ps_needword(&ps);
-
- is->on_input_line(&ps);
-
- return OOP_CONTINUE;
-}
-
/*---------- stdin input handling ----------*/
static void stdin_eof(void) { exit(0); }
const PlanSegmovfeatData *movfeat_d;
SegmovfeatState *fs;
+ ps_needword(ps);
+
if (!thiswordstrcmp(ps,"off")) {
invert= -1;
trainown= 0;
static void sock_eof(void) { die("EOF on multiplexer connection"); }
-static void *sock_exception(oop_source *evts, int fd,
- oop_event evt, void *cmdi_v) {
- die("multiplexer socket has exceptional condition");
-}
-
/*---------- multiplexer protocol ----------*/
static void si_detect(ParseState *ps) {
sockprintf("select-replay");
for (mxi=muxeventinfos; mxi->prefix; mxi++) {
+ if (!mxi->remainpat)
+ continue;
sockprintf(" ");
for (p=mxi->prefix; (c=*p); p++) {
switch (c) {
die("multiplexer reports problem: %.*s\n",
(int)badcmdreport_recsz, badcmdreport_data);
}
+static void si_ack(ParseState *ps) {
+ ps_needword(ps); /* command */
+ ps_needword(ps); /* status */
+ if (thiswordstrcmp(ps,"ok")) si_problem(0);
+}
static const MuxEventInfo muxeventinfos[]= {
- { "?detect ", "", si_detect },
+ { "?detect", "", si_detect },
{ "?picio out polarity", "", si_polarity },
- { "?movpos ", "*_feat", si_movpos },
- { "?enco pic on", "", si_on },
- { "?enco pic off", "", si_off },
+ { "?movpos", "_*_feat", si_movpos },
+ { "?picio out on", "", si_on },
+ { "?picio out off", "", si_off },
{ "=connected", "", si_connected },
{ "=permission", "", 0 },
{ "+executing", 0, 0 },
- { "+ack * ok", 0, 0 },
- { "+ack", 0, si_problem },
+ { "+ack", 0, si_ack },
{ "+nak", 0, si_problem },
{ "=failed", 0, si_problem },
{ "=denied", 0, si_problem },
static void sock_input_line(ParseState *ps) {
const MuxEventInfo *mxi;
+ const char *got, *expected;
int l;
+ if (!ps->remain || !ps->remain[0])
+ return;
for (mxi=muxeventinfos; mxi->prefix; mxi++) {
- l= strlen(mxi->prefix);
- if (!memcmp(mxi->prefix, ps->remain, l))
- goto found;
+ got= ps->remain;
+ expected= mxi->prefix;
+ if (*expected=='?') { got++; expected++; }
+ l= strlen(expected);
+ if (memcmp(got, expected, l)) continue;
+ if (!got[l] || got[l]==' ') goto found;
}
return;
found:
if (!mxi->fn) return;
+ ps->thisword= ps->remain;
+ ps->lthisword= l;
ps->remain += l;
- if (*ps->remain==' ') ps->remain++;
+fprintf(stderr,"calling <%s> with <%.*s|%s>\n",
+ mxi->prefix, ps->lthisword,ps->thisword, ps->remain);
mxi->fn(ps);
}
const char *arg;
XpmAttributes mattribs;
XWindowAttributes wattribs;
- int segment_ix, movfeat_ix, posn, invert, det, oor;
+ int segment_ix, movfeat_ix, posn, invert, det, oor, infd;
XGCValues gcv;
XColor colour;
SegmovfeatState *fs;
const PlanSegmentData *segment_d;
const PlanSegmovfeatData *movfeat_d;
char *ep;
+ const InputStream *instream;
+
+ sys_events= oop_sys_new(); if (!sys_events) diee("oop_sys_new");
+ events= oop_sys_source(sys_events); assert(events);
while ((arg= *++argv)) {
if (!strcmp(arg,"--sizes")) {
sock.fd= sock_clientconnect(node,service);
if (sock.fd<0) die("unable to connect to multiplexer");
obc_init(&sock);
- events->on_fd(events, sock.fd, OOP_EXCEPTION, sock_exception, 0);
if (comma) *comma= ',';
} else if (arg[0]=='-') {
die("invalid option(s)");
}
}
}
-
- sys_events= oop_sys_new(); if (!sys_events) diee("oop_sys_new");
- events= oop_sys_source(sys_events); assert(events);
- rd= oop_rd_new_fd(events, 0, 0,0);
- if (!rd) diee("oop_rd_new_fd");
-
- if (sock.fd==-1) {
- events->on_fd(events, 0, OOP_EXCEPTION, some_exception, 0);
-
- oor= oop_rd_read(rd, OOP_RD_STYLE_GETLINE, 1024,
- input_ifok, (void*)&stdin_is,
- input_iferr, (void*)&stdin_is);
+ if (sock.fd<0) {
+ infd= 0;
+ instream= &stdin_is;
} else {
- oor= oop_rd_read(rd, OOP_RD_STYLE_GETLINE, 1024,
- input_ifok, (void*)&sock_is,
- input_iferr, (void*)&sock_is);
+ infd= sock.fd;
+ instream= &sock_is;
}
+
+ events->on_fd(events, infd, OOP_EXCEPTION, some_exception,
+ (void*)instream->name);
+
+ rd= oop_rd_new_fd(events, infd, 0,0);
+ if (!rd) diee("oop_rd_new_fd");
+ oor= oop_rd_read(rd, OOP_RD_STYLE_GETLINE, 1024,
+ input_ifok, (void*)instream,
+ input_iferr, (void*)instream);
if (oor) diee("oop_rd_read");
events->on_fd(events, ConnectionNumber(d), OOP_READ, xlib_readable, 0);
- events->on_fd(events, ConnectionNumber(d), OOP_EXCEPTION, some_exception, 0);
+ events->on_fd(events, ConnectionNumber(d), OOP_EXCEPTION, some_exception,
+ (void*)"xserver connection");
XCALL( XSelectInput, 0, (d,w, ExposureMask) );