mirror of
https://github.com/0intro/wmii
synced 2024-11-27 16:20:45 +03:00
various changes in libixp/server.c, cmd/wmiibar.c and added id;s to Page, Client, and Area
This commit is contained in:
parent
385860251d
commit
3728e6420f
@ -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
|
||||
|
50
cmd/wm/area.c
Normal file
50
cmd/wm/area.c
Normal file
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
24
cmd/wm/fs.c
24
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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
15
cmd/wm/wm.h
15
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);
|
||||
|
447
cmd/wmiibar.c
447
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;
|
||||
|
13
libixp/ixp.h
13
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user