wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 3728e6420f91c308b552dba25d393d7f9378453b
parent 385860251d234cd14722aa8d2f21e1d9fc262747
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Fri,  3 Feb 2006 17:15:36 +0200

various changes in libixp/server.c, cmd/wmiibar.c and added id;s to Page, Client, and Area


Diffstat:
cmd/wm/Makefile | 2+-
cmd/wm/area.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
cmd/wm/client.c | 66++++++++++++++++++++++++++++++++++++++++++++----------------------
cmd/wm/event.c | 8++++----
cmd/wm/fs.c | 24++++--------------------
cmd/wm/page.c | 16++++++++++------
cmd/wm/wm.h | 15++++++++++++---
cmd/wmiibar.c | 447+++++++++++++++++++++++++++++++------------------------------------------------
libixp/ixp.h | 13++++++++++---
libixp/server.c | 84++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
10 files changed, 395 insertions(+), 330 deletions(-)

diff --git a/cmd/wm/Makefile b/cmd/wm/Makefile @@ -10,7 +10,7 @@ LDFLAGS += -L../../liblitz -llitz -L../../libwmii -lwmii \ # Solaris # LDFLAGS += -lsocket -SRC = fs.c wm.c client.c event.c mouse.c page.c column.c +SRC = area.c fs.c wm.c client.c event.c mouse.c page.c column.c OBJ = ${SRC:.c=.o} all: wmiiwm diff --git a/cmd/wm/area.c b/cmd/wm/area.c @@ -0,0 +1,50 @@ +/* + * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <stdlib.h> + +#include "wm.h" + +Area * +alloc_area() +{ + static unsigned short id = 0; + Area *a = cext_emallocz(sizeof(Area)); + + a->id = id++; + return a; +} + +void +destroy_area(Area *a) +{ + size_t i; + while(a->nclient) + detach_client(client[i], False); + free(a->client); + free(a); +} + +int +index_of_area(Page *p, Area *a) +{ + int i; + for(i = 0; i < p->narea; i++) + if(p->area[i] == a) + return i; + return -1; +} + +int +index_of_area_id(Page *p, unsigned short id) +{ + int i; + if(id == NEW_OBJ) + return p->narea; + for(i = 0; i < p->narea; i++) + if(p->area[i]->id == id) + return i; + return -1; +} diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -26,8 +26,10 @@ alloc_client(Window w, XWindowAttributes *wa) XSetWindowAttributes fwa; int bw = def.border, bh; long msize; + static unsigned short id = 0; /* client itself */ + c->id = id++; c->win = w; c->rect.x = wa->x; c->rect.y = wa->y; @@ -68,6 +70,7 @@ alloc_client(Window w, XWindowAttributes *wa) XSync(dpy, False); client = (Client **)cext_array_attach((void **)client, c, sizeof(Client *), &clientsz); + nclient++; return c; } @@ -139,7 +142,6 @@ unmap_client(Client * c) void reparent_client(Client *c, Window w, int x, int y) { - c->attached = w == c->frame.win; XReparentWindow(dpy, c->win, w, x, y); c->ignore_unmap++; } @@ -176,7 +178,7 @@ configure_client(Client * c) e.window = c->win; e.x = c->rect.x; e.y = c->rect.y; - if(c->attached) { + if(c->page) { e.x += c->frame.rect.x; e.y += c->frame.rect.y; } @@ -218,7 +220,7 @@ handle_client_property(Client *c, XPropertyEvent *e) cext_strlcpy(c->name, (char*) name.value, sizeof(c->name)); free(name.value); } - if(c->attached) + if(c->page) draw_client(c); /* TODO: client update */ break; @@ -237,10 +239,17 @@ handle_client_property(Client *c, XPropertyEvent *e) void destroy_client(Client * c) { + size_t i; + for(i = 0; i < ndet; i++) + if(det[i] == c) { + cext_array_detach((void **)det, c, &detsz); + ndet--; + break; + } XFreeGC(dpy, c->frame.gc); XDestroyWindow(dpy, c->frame.win); - cext_array_detach((void **)det, c, &detsz); - ndet--; + cext_array_detach((void **)client, c, &clientsz); + nclient--; free(c); } @@ -382,23 +391,25 @@ attach_client(Client *c) void detach_client(Client *c, Bool unmap) { - if(index_of_area(c->page, c->area) > 0) - detach_column(c); - else { - Area *a = c->page->area[0]; - cext_array_detach((void **)a->client, c, &a->clientsz); - a->nclient--; - if(!c->destroyed) { - if(!unmap) { - det = (Client **)cext_array_attach((void **)det, c, - sizeof(Client *), &detsz); - ndet++; - unmap_client(c); - } - c->rect.x = c->frame.rect.x; - c->rect.y = c->frame.rect.y; - reparent_client(c, root, c->rect.x, c->rect.y); - } + if(c->page) { + if(index_of_area(c->page, c->area) > 0) + detach_column(c); + else { + Area *a = c->page->area[0]; + cext_array_detach((void **)a->client, c, &a->clientsz); + a->nclient--; + if(!c->destroyed) { + if(!unmap) { + det = (Client **)cext_array_attach((void **)det, c, + sizeof(Client *), &detsz); + ndet++; + unmap_client(c); + } + c->rect.x = c->frame.rect.x; + c->rect.y = c->frame.rect.y; + reparent_client(c, root, c->rect.x, c->rect.y); + } + } } c->page = nil; if(c->destroyed) @@ -526,3 +537,14 @@ max_client(void *obj, char *arg) c->maximized = !c->maximized; } +int +index_of_client_id(Area *a, unsigned short id) +{ + int i; + if(id == NEW_OBJ) + return a->nclient; + for(i = 0; i < a->nclient; i++) + if(a->client[i]->id == id) + return i; + return -1; +} diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -110,7 +110,7 @@ handle_configurerequest(XEvent * e) ev->value_mask &= ~CWSibling; if(c) { - if(c->attached) { + if(c->page) { bw = c->frame.border; bh = bar_height(c); } @@ -135,7 +135,7 @@ handle_configurerequest(XEvent * e) gravitate(c, bh ? bh : bw, bw, 0); - if(c->attached) { + if(c->page) { c->frame.rect.x = wc.x = c->rect.x - bw; c->frame.rect.y = wc.y = c->rect.y - (bh ? bh : bw); c->frame.rect.width = wc.width = c->rect.width + 2 * bw; @@ -150,7 +150,7 @@ handle_configurerequest(XEvent * e) wc.x = ev->x; wc.y = ev->y; - if(c && c->attached) { + if(c && c->page) { /* if so, then bw and tabh are already initialized */ wc.x = bw; wc.y = bh ? bh : bw; @@ -217,7 +217,7 @@ handle_maprequest(XEvent * e) c = win_to_client(ev->window); if(!c) c = alloc_client(ev->window, &wa); - if(!c->attached) + if(!c->page) attach_client(c); } diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c @@ -45,7 +45,6 @@ * /1/float/1/ Dclient * /1/float/1/border Fborder 0..n * /1/float/1/bar Fbar 0, 1 - * /1/float/1/inc Finc 0, 1 * /1/float/1/name Fname name of client * /1/float/1/geom Fgeom geometry of client * /1/float/1/ctl Fctl command interface (client) @@ -55,7 +54,6 @@ * /1/1/1/1/ Dclient * /1/1/1/border Fborder 0..n * /1/1/1/bar Fbar 0, 1 - * /1/1/1/inc Finc 0, 1 * /1/1/1/name Fname name of client * /1/1/1/geom Fgeom geometry of client * /1/1/1/ctl Fctl command interface (client) @@ -448,14 +446,7 @@ type_to_stat(Stat *stat, char *name, Qid *dir) return mkstat(stat, dir, name, strlen(buf), DMREAD | DMWRITE); break; case Finc: - if(dtyp == Ddefault) - snprintf(buf, sizeof(buf), "%d", def.inc); - else { - idx = cext_strtonum(name, 0, 0xffff, &err); - if(err) - return 0; - snprintf(buf, sizeof(buf), "%d", page[dpg]->area[darea]->client[idx]->inc); - } + snprintf(buf, sizeof(buf), "%d", def.inc); return mkstat(stat, dir, name, strlen(buf), DMREAD | DMWRITE); break; case Fgeom: @@ -720,10 +711,7 @@ xread(IXPConn *c) memcpy(p, buf, c->fcall->count); break; case Finc: - if(m->qid.dtype == Ddefault) - snprintf(buf, sizeof(buf), "%u", def.inc); - else - snprintf(buf, sizeof(buf), "%u", page[pg]->area[area]->client[cl]->inc); + snprintf(buf, sizeof(buf), "%u", def.inc); c->fcall->count = strlen(buf); memcpy(p, buf, c->fcall->count); break; @@ -902,12 +890,8 @@ xwrite(IXPConn *c) errstr = "increment value out of range 0, 1"; return -1; } - if(m->qid.dtype == Ddefault) - def.inc = i; - else { - page[pg]->area[area]->client[cl]->inc = i; - /* TODO: resize client */ - } + def.inc = i; + /* TODO: resize all clients */ break; case Fgeom: if(c->fcall->count > sizeof(buf)) diff --git a/cmd/wm/page.c b/cmd/wm/page.c @@ -27,9 +27,11 @@ Action page_acttbl[] = { Page * alloc_page() { + static unsigned short id = 0; Page *p = cext_emallocz(sizeof(Page)); Area *a = cext_emallocz(sizeof(Area)); + p->id = id++; p->area = (Area **)cext_array_attach((void **)p->area, a, sizeof(Area *), &p->areasz); p->narea++; do_pend_fcall("NewPage\n"); @@ -53,9 +55,9 @@ destroy_page(Page *p) for(i = 0; i < naqueue; i++) cext_array_detach((void **)aq, p, &aqsz); - for(i = 0; i < nclient; i++) - if(client[i]->page == p) - detach_client(client[i], False); + for(i = 0; i < p->narea; i++) + destroy_area(p->area[i]); + free(p->area); for(i = 0; (i < npage) && (p != page[i]); i++); if(sel && (sel == i)) @@ -229,11 +231,13 @@ select_client(void *obj, char *arg) } int -index_of_area(Page *p, Area *a) +index_of_page_id(unsigned short id) { int i; - for(i = 0; i < p->narea; i++) - if(p->area[i] == a) + if(id == NEW_OBJ) + return npage; + for(i = 0; i < npage; i++) + if(page[i]->id == id) return i; return -1; } diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -47,11 +47,14 @@ enum { #define ROOT_MASK SubstructureRedirectMask #define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask) +#define NEW_OBJ (unsigned short)0xffff + typedef struct Area Area; typedef struct Page Page; typedef struct Client Client; struct Area { + unsigned short id; Client **client; size_t clientsz; size_t sel; @@ -60,6 +63,7 @@ struct Area { }; struct Page { + unsigned short id; Area **area; size_t areasz; size_t narea; @@ -67,6 +71,7 @@ struct Page { }; struct Client { + unsigned short id; char name[256]; int proto; unsigned int border; @@ -74,8 +79,6 @@ struct Client { Bool inc; Bool destroyed; Bool maximized; - Bool attached; - Bool managed; Page *page; Area *area; Window win; @@ -157,6 +160,11 @@ Cursor se_cursor; unsigned int valid_mask, num_lock_mask; +/* area.c */ +Area *alloc_area(); +void destroy_area(Area *a); +int index_of_area(Page *p, Area *a); +int index_of_area_id(Page *p, unsigned short id); /* client.c */ Client *alloc_client(Window w, XWindowAttributes *wa); @@ -179,6 +187,7 @@ void focus_client(Client *c); Client *win_to_frame(Window w); void resize_client(Client *c, XRectangle * r, XPoint * pt); unsigned int bar_height(Client *c); +int index_of_client_id(Area *a, unsigned short id); /* event.c */ void init_x_event_handler(); @@ -204,7 +213,7 @@ Page *alloc_page(); void destroy_page(Page *p); void focus_page(Page *p); XRectangle *rectangles(unsigned int *num); -int index_of_area(Page *p, Area *a); +int index_of_page_id(unsigned short id); /* column.c */ void arrange_page(Page *p); diff --git a/cmd/wmiibar.c b/cmd/wmiibar.c @@ -65,8 +65,6 @@ static char Enomode[] = "mode not supported"; static char Enofunc[] = "function not supported"; static char Enocommand[] = "command not supported"; -static unsigned char *msg[IXP_MAX_MSG]; -char *errstr = 0; static size_t nitem = 0; static size_t itemsz = 0; static size_t iexpand = 0; @@ -217,7 +215,7 @@ handle_buttonpress(XButtonPressedEvent * e) } static void -check_x_event(IXPServer *s, IXPConn *c) +check_x_event(IXPConn *c) { XEvent e; @@ -365,89 +363,82 @@ mkqid(Qid *dir, char *wname, Qid *new) return 0; } -static int -xversion(IXPConn *c) + +static char * +xversion(IXPConn *c, Fcall *fcall) { - if(strncmp(c->fcall->version, IXP_VERSION, strlen(IXP_VERSION))) { - errstr = E9pversion; - return -1; - } else if(c->fcall->maxmsg > IXP_MAX_MSG) - c->fcall->maxmsg = IXP_MAX_MSG; - c->fcall->id = RVERSION; - return 0; + if(strncmp(fcall->version, IXP_VERSION, strlen(IXP_VERSION))) + return E9pversion; + else if(fcall->maxmsg > IXP_MAX_MSG) + fcall->maxmsg = IXP_MAX_MSG; + fcall->id = RVERSION; + ixp_server_respond_fcall(c, fcall); + return nil; } -static int -xattach(IXPConn *c) +static char * +xattach(IXPConn *c, Fcall *fcall) { IXPMap *new = cext_emallocz(sizeof(IXPMap)); new->qid = root_qid; - new->fid = c->fcall->fid; + new->fid = fcall->fid; c->map = (IXPMap **)cext_array_attach((void **)c->map, new, sizeof(IXPMap *), &c->mapsz); - c->fcall->id = RATTACH; - c->fcall->qid = root_qid; - return 0; + fcall->id = RATTACH; + fcall->qid = root_qid; + ixp_server_respond_fcall(c, fcall); + return nil; } -static int -xwalk(IXPConn *c) +static char * +xwalk(IXPConn *c, Fcall *fcall) { unsigned short nwqid = 0; Qid dir = root_qid; IXPMap *m; - if(!(m = ixp_server_fid2map(c, c->fcall->fid))) { - errstr = Enofid; - return -1; - } - if(c->fcall->fid != c->fcall->newfid - && (ixp_server_fid2map(c, c->fcall->newfid))) { - errstr = Enofid; - return -1; - } - if(c->fcall->nwname) { + if(!(m = ixp_server_fid2map(c, fcall->fid))) + return Enofid; + if(fcall->fid != fcall->newfid && (ixp_server_fid2map(c, fcall->newfid))) + return Enofid; + if(fcall->nwname) { dir = m->qid; - for(nwqid = 0; (nwqid < c->fcall->nwname) - && !mkqid(&dir, c->fcall->wname[nwqid], &c->fcall->wqid[nwqid]); nwqid++) - dir = c->fcall->wqid[nwqid]; - if(!nwqid) { - errstr = Enofile; - return -1; - } + for(nwqid = 0; (nwqid < fcall->nwname) + && !mkqid(&dir, fcall->wname[nwqid], &fcall->wqid[nwqid]); nwqid++) + dir = fcall->wqid[nwqid]; + if(!nwqid) + return Enofile; } /* a fid will only be valid, if the walk was complete */ - if(nwqid == c->fcall->nwname) { - if(c->fcall->fid != c->fcall->newfid) { + if(nwqid == fcall->nwname) { + if(fcall->fid != fcall->newfid) { m = cext_emallocz(sizeof(IXPMap)); - c->map = (IXPMap **)cext_array_attach((void **)c->map, m, - sizeof(IXPMap *), &c->mapsz); + c->map = (IXPMap **)cext_array_attach((void **)c->map, + m, sizeof(IXPMap *), &c->mapsz); } m->qid = dir; - m->fid = c->fcall->newfid; + m->fid = fcall->newfid; } - c->fcall->id = RWALK; - c->fcall->nwqid = nwqid; - return 0; + fcall->id = RWALK; + fcall->nwqid = nwqid; + ixp_server_respond_fcall(c, fcall); + return nil; } -static int -xopen(IXPConn *c) +static char * +xopen(IXPConn *c, Fcall *fcall) { - IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, fcall->fid); - if(!m) { - errstr = Enofid; - return -1; - } - if(!(c->fcall->mode | IXP_OREAD) && !(c->fcall->mode | IXP_OWRITE)) { - errstr = Enomode; - return -1; - } - c->fcall->id = ROPEN; - c->fcall->qid = m->qid; - c->fcall->iounit = 256; - return 0; + if(!m) + return Enofid; + if(!(fcall->mode | IXP_OREAD) && !(fcall->mode | IXP_OWRITE)) + return Enomode; + fcall->id = ROPEN; + fcall->qid = m->qid; + fcall->iounit = 256; + ixp_server_respond_fcall(c, fcall); + return nil; } static unsigned int @@ -504,28 +495,21 @@ type_to_stat(Stat *stat, char *name, Qid *dir) i = 0; return mkstat(stat, dir, name, 24, DMREAD | DMWRITE); break; - default: - errstr = "invalid stat"; - break; } return 0; } -static int -xremove(IXPConn *c) +static char * +xremove(IXPConn *c, Fcall *fcall) { - IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, fcall->fid); int i; - if(!m) { - errstr = Enofid; - return -1; - } + if(!m) + return Enofid; i = index_of_id(qpath_id(m->qid.path)); - if(i == -1) { - errstr = Enofile; - return -1; - } + if(i == -1) + return Enofile; if((qpath_type(m->qid.path) == Ditem) && i && (i < nitem)) { Item *it = item[i]; /* clunk */ @@ -534,38 +518,34 @@ xremove(IXPConn *c) /* now detach the item */ detach_item(it); free(it); - c->fcall->id = RREMOVE; if(iexpand >= nitem) iexpand = 0; draw(); - return 0; + fcall->id = RREMOVE; + ixp_server_respond_fcall(c, fcall); + return nil; } - errstr = Enoperm; - return -1; + return Enoperm; } -static int -xread(IXPConn *c) +static char * +xread(IXPConn *c, Fcall *fcall) { Stat stat; - IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); - unsigned char *p = c->fcall->data; + IXPMap *m = ixp_server_fid2map(c, fcall->fid); + unsigned char *p = fcall->data; unsigned int len; int i; char buf[32]; - if(!m) { - errstr = Enofid; - return -1; - } + if(!m) + return Enofid; i = index_of_id(qpath_id(m->qid.path)); - if(i == -1) { - errstr = Enofile; - return -1; - } + if(i == -1) + return Enofile; - c->fcall->count = 0; - if(c->fcall->offset) { + fcall->count = 0; + if(fcall->offset) { switch (qpath_type(m->qid.path)) { case Droot: /* jump to offset */ @@ -577,7 +557,7 @@ xread(IXPConn *c) for(i = 1; i < nitem; i++) { snprintf(buf, sizeof(buf), "%u", i); len += type_to_stat(&stat, buf, &m->qid); - if(len <= c->fcall->offset) + if(len <= fcall->offset) continue; break; } @@ -585,14 +565,15 @@ xread(IXPConn *c) for(; i < nitem; i++) { snprintf(buf, sizeof(buf), "%u", i); len = type_to_stat(&stat, buf, &m->qid); - if(c->fcall->count + len > c->fcall->iounit) + if(fcall->count + len > fcall->iounit) break; - c->fcall->count += len; + fcall->count += len; p = ixp_enc_stat(p, &stat); } break; case Fevent: - return 1; + ixp_server_enqueue_fcall(c, fcall); + return nil; break; default: break; @@ -601,22 +582,22 @@ xread(IXPConn *c) else { switch (qpath_type(m->qid.path)) { case Droot: - c->fcall->count = type_to_stat(&stat, "ctl", &m->qid); + fcall->count = type_to_stat(&stat, "ctl", &m->qid); p = ixp_enc_stat(p, &stat); - c->fcall->count += type_to_stat(&stat, "font", &m->qid); + fcall->count += type_to_stat(&stat, "font", &m->qid); p = ixp_enc_stat(p, &stat); - c->fcall->count += type_to_stat(&stat, "color", &m->qid); + fcall->count += type_to_stat(&stat, "color", &m->qid); p = ixp_enc_stat(p, &stat); - c->fcall->count += type_to_stat(&stat, "new", &m->qid); + fcall->count += type_to_stat(&stat, "new", &m->qid); p = ixp_enc_stat(p, &stat); - c->fcall->count += type_to_stat(&stat, "event", &m->qid); + fcall->count += type_to_stat(&stat, "event", &m->qid); p = ixp_enc_stat(p, &stat); for(i = 1; i < nitem; i++) { snprintf(buf, sizeof(buf), "%u", i); len = type_to_stat(&stat, buf, &m->qid); - if(c->fcall->count + len > c->fcall->iounit) + if(fcall->count + len > fcall->iounit) break; - c->fcall->count += len; + fcall->count += len; p = ixp_enc_stat(p, &stat); } break; @@ -625,108 +606,100 @@ xread(IXPConn *c) goto error_xread; if(i == nitem) new_item(); - c->fcall->count = type_to_stat(&stat, "color", &m->qid); + fcall->count = type_to_stat(&stat, "color", &m->qid); p = ixp_enc_stat(p, &stat); - c->fcall->count += type_to_stat(&stat, "data", &m->qid); + fcall->count += type_to_stat(&stat, "data", &m->qid); p = ixp_enc_stat(p, &stat); break; case Fctl: - errstr = Enoperm; - return -1; + return Enoperm; break; case Ffont: - if((c->fcall->count = strlen(font))) - memcpy(p, font, c->fcall->count); + if((fcall->count = strlen(font))) + memcpy(p, font, fcall->count); break; case Fexpand: snprintf(buf, sizeof(buf), "%u", iexpand); - c->fcall->count = strlen(buf); - memcpy(p, buf, c->fcall->count); - break; - case Fevent: - return 1; + fcall->count = strlen(buf); + memcpy(p, buf, fcall->count); break; case Fdata: if(i == nitem) new_item(); if(i >= nitem) goto error_xread; - if((c->fcall->count = strlen(item[i]->data))) - memcpy(p, item[i]->data, c->fcall->count); + if((fcall->count = strlen(item[i]->data))) + memcpy(p, item[i]->data, fcall->count); break; case Fcolor: if(i == nitem) new_item(); if(i >= nitem) goto error_xread; - if((c->fcall->count = strlen(item[i]->colstr))) - memcpy(p, item[i]->colstr, c->fcall->count); + if((fcall->count = strlen(item[i]->colstr))) + memcpy(p, item[i]->colstr, fcall->count); + break; + case Fevent: + ixp_server_enqueue_fcall(c, fcall); + return nil; break; default: error_xread: - if(!errstr) - errstr = "invalid read"; - return -1; + return "invalid read"; break; } } - c->fcall->id = RREAD; - return 0; + fcall->id = RREAD; + ixp_server_respond_fcall(c, fcall); + return nil; } -static int -xstat(IXPConn *c) +static char * +xstat(IXPConn *c, Fcall *fcall) { - IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, fcall->fid); char *name; - if(!m) { - errstr = Enofid; - return -1; - } - + if(!m) + return Enofid; name = qid_to_name(&m->qid); - if(!type_to_stat(&c->fcall->stat, name, &m->qid)) - return -1; - c->fcall->id = RSTAT; - return 0; + if(!type_to_stat(&fcall->stat, name, &m->qid)) + return Enofile; + fcall->id = RSTAT; + ixp_server_respond_fcall(c, fcall); + return nil; } -static int -xwrite(IXPConn *c) +static char * +xwrite(IXPConn *c, Fcall *fcall) { char buf[256]; - IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, fcall->fid); int i; - if(!m) { - errstr = Enofid; - return -1; - } + if(!m) + return Enofid; i = index_of_id(qpath_id(m->qid.path)); - if(i == -1) { - errstr = Enofile; - return -1; - } + if(i == -1) + return Enofile; switch (qpath_type(m->qid.path)) { case Fctl: - if(c->fcall->count == 4) { - memcpy(buf, c->fcall->data, 4); + if(fcall->count == 4) { + memcpy(buf, fcall->data, 4); buf[4] = 0; if(!strncmp(buf, "quit", 5)) { srv.running = 0; break; } } - errstr = Enocommand; - return -1; + return Enocommand; break; case Ffont: if(font) free(font); - font = cext_emallocz(c->fcall->count + 1); - memcpy(font, c->fcall->data, c->fcall->count); + font = cext_emallocz(fcall->count + 1); + memcpy(font, fcall->data, fcall->count); XFreeFont(dpy, xfont); xfont = blitz_getfont(dpy, font); update_geometry(); @@ -734,9 +707,9 @@ xwrite(IXPConn *c) case Fexpand: { const char *err; - if(c->fcall->count && c->fcall->count < 16) { - memcpy(buf, c->fcall->data, c->fcall->count); - buf[c->fcall->count] = 0; + if(fcall->count && fcall->count < 16) { + memcpy(buf, fcall->data, fcall->count); + buf[fcall->count] = 0; i = (unsigned short) cext_strtonum(buf, 1, 0xffff, &err); if(i < nitem) { iexpand = i; @@ -745,19 +718,18 @@ xwrite(IXPConn *c) } } } - errstr = "item not found"; - return -1; + return "item not found"; break; case Fdata: { - unsigned int len = c->fcall->count; + unsigned int len = fcall->count; if(i == nitem) new_item(); if(!i || (i >= nitem)) goto error_xwrite; if(len >= sizeof(item[i]->data)) len = sizeof(item[i]->data) - 1; - memcpy(item[i]->data, c->fcall->data, len); + memcpy(item[i]->data, fcall->data, len); item[i]->data[len] = 0; draw(); } @@ -765,105 +737,62 @@ xwrite(IXPConn *c) case Fcolor: if(i == nitem) new_item(); - if((i >= nitem) || (c->fcall->count != 24) - || (c->fcall->data[0] != '#') || (c->fcall->data[8] != '#') - || (c->fcall->data[16] != '#')) - { - errstr = "wrong color format"; - goto error_xwrite; - } - memcpy(item[i]->colstr, c->fcall->data, c->fcall->count); - item[i]->colstr[c->fcall->count] = 0; + if((i >= nitem) || (fcall->count != 24) + || (fcall->data[0] != '#') || (fcall->data[8] != '#') + || (fcall->data[16] != '#') + ) + return "wrong color format"; + memcpy(item[i]->colstr, fcall->data, fcall->count); + item[i]->colstr[fcall->count] = 0; blitz_loadcolor(dpy, screen, item[i]->colstr, &item[i]->color); draw(); break; default: error_xwrite: - if(!errstr) - errstr = "invalid write"; - return -1; + return "invalid write"; break; } - c->fcall->id = RWRITE; - return 0; + fcall->id = RWRITE; + ixp_server_respond_fcall(c, fcall); + return nil; } -static int -xclunk(IXPConn *c) +static char * +xclunk(IXPConn *c, Fcall *fcall) { - IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, fcall->fid); - if(!m) { - errstr = Enofid; - return -1; - } + if(!m) + return Enofid; cext_array_detach((void **)c->map, m, &c->mapsz); free(m); - c->fcall->id = RCLUNK; + fcall->id = RCLUNK; return 0; } static void -close_ixp_conn(IXPServer *s, IXPConn *c) -{ - size_t i; - cext_array_detach((void **)s->conn, c, &s->connsz); - if(c->map) { - for(i = 0; (i < c->mapsz) && c->map[i]; i++) - free(c->map[i]); - free(c->map); - } - if(c->pend) { - for(i = 0; (i < c->pendsz) && c->pend[i]; i++) - free(c->pend[i]); - free(c->pend); - } - shutdown(c->fd, SHUT_RDWR); - close(c->fd); - free(c); -} - -static void -do_fcall(IXPServer *s, IXPConn *c) +do_fcall(IXPConn *c) { + static Fcall fcall; unsigned int msize; - int ret = -1; - errstr = 0; - if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &errstr))) { - close_ixp_conn(s, c); - return; - } - if(!c->fcall) - c->fcall = cext_emallocz(sizeof(Fcall)); - if((msize = ixp_msg_to_fcall(msg, IXP_MAX_MSG, c->fcall))) { - switch(c->fcall->id) { - case TVERSION: ret = xversion(c); break; - case TATTACH: ret = xattach(c); break; - case TWALK: ret = xwalk(c); break; - case TREMOVE: ret = xremove(c); break; - case TOPEN: ret = xopen(c); break; - case TREAD: ret = xread(c); break; - case TWRITE: ret = xwrite(c); break; - case TCLUNK: ret = xclunk(c); break; - case TSTAT: ret = xstat(c); break; - default: - break; + char *errstr; + + if((msize = ixp_server_receive_fcall(c, &fcall))) { + switch(fcall.id) { + case TVERSION: errstr = xversion(c, &fcall); break; + case TATTACH: errstr = xattach(c, &fcall); break; + case TWALK: errstr = xwalk(c, &fcall); break; + case TREMOVE: errstr = xremove(c, &fcall); break; + case TOPEN: errstr = xopen(c, &fcall); break; + case TREAD: errstr = xread(c, &fcall); break; + case TWRITE: errstr = xwrite(c, &fcall); break; + case TCLUNK: errstr = xclunk(c, &fcall); break; + case TSTAT: errstr = xstat(c, &fcall); break; + default: errstr = Enofunc; break; } + if(errstr) + ixp_server_respond_error(c, &fcall, errstr); } - if(ret == -1) { - if(!errstr) - errstr = Enofunc; - c->fcall->id = RERROR; - cext_strlcpy(c->fcall->errstr, errstr, sizeof(c->fcall->errstr)); - } - else if(ret == 1) { - c->pend = (Fcall **)cext_array_attach((void **)c->pend, c->fcall, sizeof(Fcall *), &c->pendsz); - c->fcall = nil; - return; /* response asynchroneously */ - } - msize = ixp_fcall_to_msg(c->fcall, msg, IXP_MAX_MSG); - if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) - close_ixp_conn(s, c); } static Fcall * @@ -887,53 +816,40 @@ do_pend_fcall(char *event) while((fcall = pending(c, TREAD))) { IXPMap *m = ixp_server_fid2map(c, fcall->fid); unsigned char *p = fcall->data; - unsigned int msize; if(!m) { - errstr = Enofid; - fcall->id = RERROR; + if(ixp_server_respond_error(c, fcall, Enofid)) + break; } else if(qpath_type(m->qid.path) == Fevent) { fcall->count = strlen(event); memcpy(p, event, fcall->count); fcall->id = RREAD; + if(ixp_server_respond_fcall(c, fcall)) + break; } - msize = ixp_fcall_to_msg(fcall, msg, IXP_MAX_MSG); - /* remove pending request */ cext_array_detach((void **)c->pend, fcall, &c->pendsz); free(fcall); - if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) { - close_ixp_conn(&srv, c); - break; - } } } } static void -new_ixp_conn(IXPServer *s, IXPConn *c) +new_ixp_conn(IXPConn *c) { - IXPConn *new; int fd = ixp_accept_sock(c->fd); - if(fd >= 0) { - new = cext_emallocz(sizeof(IXPConn)); - new->fd = fd; - new->read = do_fcall; - new->close = close_ixp_conn; - s->conn = (IXPConn **)cext_array_attach((void **)s->conn, new, - sizeof(IXPConn *), &s->connsz); - } + if(fd >= 0) + ixp_server_open_conn(c->srv, fd, do_fcall, ixp_server_close_conn); } - /* main */ int main(int argc, char *argv[]) { int i; - IXPConn *c; + char *errstr; XSetWindowAttributes wa; XGCValues gcv; @@ -973,18 +889,9 @@ main(int argc, char *argv[]) } /* IXP server */ - c = cext_emallocz(sizeof(IXPConn)); - c->fd = i; - c->read = new_ixp_conn; - c->close = close_ixp_conn; - srv.conn = (IXPConn **)cext_array_attach((void **)srv.conn, c, - sizeof(IXPConn *), &srv.connsz); + ixp_server_open_conn(&srv, i, new_ixp_conn, ixp_server_close_conn); /* X server */ - c = cext_emallocz(sizeof(IXPConn)); - c->fd = ConnectionNumber(dpy); - c->read = check_x_event; - srv.conn = (IXPConn **)cext_array_attach((void **)srv.conn, c, - sizeof(IXPConn *), &srv.connsz); + ixp_server_open_conn(&srv, ConnectionNumber(dpy), check_x_event, nil); root_qid.type = IXP_QTDIR; root_qid.version = 0; @@ -1035,7 +942,7 @@ main(int argc, char *argv[]) /* cleanup */ for(i = 0; (i < srv.connsz) && srv.conn[i]; i++) if(srv.conn[i]->close) - srv.conn[i]->close(&srv, srv.conn[i]); + srv.conn[i]->close(srv.conn[i]); XCloseDisplay(dpy); return errstr ? 1 : 0; diff --git a/libixp/ixp.h b/libixp/ixp.h @@ -206,11 +206,11 @@ struct IXPMap { struct IXPConn { int fd; - void (*read) (IXPServer *, IXPConn *); - void (*close) (IXPServer *, IXPConn *); + IXPServer *srv; + void (*read) (IXPConn *); + void (*close) (IXPConn *); IXPMap **map; size_t mapsz; - Fcall *fcall; Fcall **pend; size_t pendsz; }; @@ -279,8 +279,15 @@ unsigned int ixp_fcall_to_msg(Fcall *fcall, void *msg, unsigned int msglen); unsigned int ixp_msg_to_fcall(void *msg, unsigned int msglen, Fcall *fcall); /* server.c */ +IXPConn *ixp_server_open_conn(IXPServer *s, int fd, + void (*read)(IXPConn *c), void (*close)(IXPConn *c)); +void ixp_server_close_conn(IXPConn *c); char *ixp_server_loop(IXPServer *s); IXPMap *ixp_server_fid2map(IXPConn *c, unsigned int fid); +void ixp_server_enqueue_fcall(IXPConn *c, Fcall *fcall); +unsigned int ixp_server_receive_fcall(IXPConn *c, Fcall *fcall); +int ixp_server_respond_fcall(IXPConn *c, Fcall *fcall); +int ixp_server_respond_error(IXPConn *c, Fcall *fcall, char *errstr); /* socket.c */ int ixp_connect_sock(char *address); diff --git a/libixp/server.c b/libixp/server.c @@ -17,6 +17,42 @@ #include "ixp.h" #include "cext.h" +static unsigned char *msg[IXP_MAX_MSG]; + +IXPConn *ixp_server_open_conn(IXPServer *s, int fd, void (*read)(IXPConn *c), + void (*close)(IXPConn *c)) +{ + IXPConn *c = cext_emallocz(sizeof(IXPConn)); + c->fd = fd; + c->srv = s; + c->read = read; + c->close = close; + s->conn = (IXPConn **)cext_array_attach((void **)s->conn, c, + sizeof(IXPConn *), &s->connsz); + return c; +} + +void +ixp_server_close_conn(IXPConn *c) +{ + size_t i; + IXPServer *s = c->srv; + cext_array_detach((void **)s->conn, c, &s->connsz); + if(c->map) { + for(i = 0; (i < c->mapsz) && c->map[i]; i++) + free(c->map[i]); + free(c->map); + } + if(c->pend) { + for(i = 0; (i < c->pendsz) && c->pend[i]; i++) + free(c->pend[i]); + free(c->pend); + } + shutdown(c->fd, SHUT_RDWR); + close(c->fd); + free(c); +} + static void prepare_select(IXPServer *s) { @@ -37,7 +73,7 @@ handle_conns(IXPServer *s) for(i = 0; (i < s->connsz) && s->conn[i]; i++) if(FD_ISSET(s->conn[i]->fd, &s->rd) && s->conn[i]->read) /* call read handler */ - s->conn[i]->read(s, s->conn[i]); + s->conn[i]->read(s->conn[i]); } char * @@ -71,3 +107,49 @@ ixp_server_fid2map(IXPConn *c, unsigned int fid) return c->map[i]; return nil; } + +void ixp_server_enqueue_fcall(IXPConn *c, Fcall *fcall) +{ + c->pend = (Fcall **)cext_array_attach((void **)c->pend, fcall, sizeof(Fcall *), &c->pendsz); +} + +unsigned int +ixp_server_receive_fcall(IXPConn *c, Fcall *fcall) +{ + unsigned int msize; + char *errstr = 0; + if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &errstr))) { + if(c->close) + c->close(c); + return 0; + } + return ixp_msg_to_fcall(msg, IXP_MAX_MSG, fcall); +} + +int +ixp_server_respond_fcall(IXPConn *c, Fcall *fcall) +{ + char *errstr; + unsigned int msize = ixp_fcall_to_msg(fcall, msg, IXP_MAX_MSG); + if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) { + if(c->close) + c->close(c); + return -1; + } + return 0; +} + +int +ixp_server_respond_error(IXPConn *c, Fcall *fcall, char *errstr) +{ + unsigned int msize; + fcall->id = RERROR; + cext_strlcpy(fcall->errstr, errstr, sizeof(fcall->errstr)); + msize = ixp_fcall_to_msg(fcall, msg, IXP_MAX_MSG); + if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) { + if(c->close) + c->close(c); + return -1; + } + return 0; +}