aboutsummaryrefslogtreecommitdiff
path: root/src/libdraw/init.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2006-06-25 18:59:29 +0000
committerrsc <devnull@localhost>2006-06-25 18:59:29 +0000
commit74dc60da74c62e07f0d63179da9724d705794a6d (patch)
treebfb0bcf94115ebc5b142c3ad4d80157288ee8368 /src/libdraw/init.c
parent324891a5579d6f504201a6107369c64dab245a98 (diff)
downloadplan9port-74dc60da74c62e07f0d63179da9724d705794a6d.tar.gz
plan9port-74dc60da74c62e07f0d63179da9724d705794a6d.tar.bz2
plan9port-74dc60da74c62e07f0d63179da9724d705794a6d.zip
bye
Diffstat (limited to 'src/libdraw/init.c')
-rw-r--r--src/libdraw/init.c196
1 files changed, 176 insertions, 20 deletions
diff --git a/src/libdraw/init.c b/src/libdraw/init.c
index 0f8cc766..bbce668b 100644
--- a/src/libdraw/init.c
+++ b/src/libdraw/init.c
@@ -11,6 +11,7 @@ static char deffontname[] = "*default*";
Screen *_screen;
int debuglockdisplay = 1;
+char *winsize;
/*
static void
@@ -27,19 +28,17 @@ drawshutdown(void)
*/
int
-initdraw(void (*error)(Display*, char*), char *fontname, char *label)
+geninitdraw(char *devdir, void(*error)(Display*, char*), char *fontname, char *label, char *windir, int ref)
{
Subfont *df;
char buf[128];
- rfork(RFNOTEG); /* x11-event.c will postnote hangup */
- display = _initdisplay(error, label); /* sets screen too */
+ if(label == nil)
+ label = argv0;
+ display = _initdisplay(error, label);
if(display == nil)
return -1;
- lockdisplay(display);
- display->screenimage = display->image;
-
/*
* Set up default font
*/
@@ -53,7 +52,7 @@ initdraw(void (*error)(Display*, char*), char *fontname, char *label)
return -1;
}
if(fontname == nil)
- fontname = getenv("font"); /* leak */
+ fontname = getenv("font");
/*
* Build fonts with caches==depth of screen, for speed.
@@ -62,32 +61,28 @@ initdraw(void (*error)(Display*, char*), char *fontname, char *label)
if(fontname == nil){
snprint(buf, sizeof buf, "%d %d\n0 %d\t%s\n", df->height, df->ascent,
df->n-1, deffontname);
-/*BUG: Need something better for this installsubfont("*default*", df); */
+//BUG: Need something better for this installsubfont("*default*", df);
font = buildfont(display, buf, deffontname);
if(font == nil){
- fprint(2, "initdraw: can't open default font: %r\n");
+ fprint(2, "imageinit: can't open default font: %r\n");
goto Error;
}
}else{
font = openfont(display, fontname); /* BUG: grey fonts */
if(font == nil){
- fprint(2, "initdraw: can't open font %s: %r\n", fontname);
+ fprint(2, "imageinit: can't open font %s: %r\n", fontname);
goto Error;
}
}
display->defaultfont = font;
- display->white = allocimage(display, Rect(0,0,1,1), GREY1, 1, DWhite);
- display->black = allocimage(display, Rect(0,0,1,1), GREY1, 1, DBlack);
- if(display->white == nil || display->black == nil){
- fprint(2, "initdraw: can't allocate white and black");
- goto Error;
- }
- display->opaque = display->white;
- display->transparent = display->black;
-
_screen = allocscreen(display->image, display->white, 0);
+ display->screenimage = display->image; /* _allocwindow wants screenimage->chan */
screen = _allocwindow(nil, _screen, display->image->r, Refnone, DWhite);
+ if(screen == nil){
+ fprint(2, "_allocwindow: %r\n");
+ goto Error;
+ }
display->screenimage = screen;
draw(screen, screen->r, display->white, nil, ZP);
flushimage(display, 1);
@@ -102,6 +97,165 @@ initdraw(void (*error)(Display*, char*), char *fontname, char *label)
return 1;
}
+int
+initdraw(void (*error)(Display*, char*), char *fontname, char *label)
+{
+ return geninitdraw("/dev", error, fontname, label, "/dev", Refnone);
+}
+
+extern int _freeimage1(Image*);
+
+static Image*
+getimage0(Display *d, Image *image)
+{
+ char info[12*12+1];
+ uchar *a;
+ int n;
+
+ /*
+ * If there's an old screen, it has id 0. The 'J' request below
+ * will try to install the new screen as id 0, so the old one
+ * must be freed first.
+ */
+ if(image){
+ _freeimage1(image);
+ memset(image, 0, sizeof(Image));
+ }
+
+ a = bufimage(d, 2);
+ a[0] = 'J';
+ a[1] = 'I';
+ if(flushimage(d, 0) < 0){
+ fprint(2, "cannot read screen info: %r\n");
+ return nil;
+ }
+
+ n = _displayrddraw(d, info, sizeof info);
+ if(n != 12*12){
+ fprint(2, "short screen info\n");
+ return nil;
+ }
+
+ if(image == nil){
+ image = mallocz(sizeof(Image), 1);
+ if(image == nil){
+ fprint(2, "cannot allocate image: %r\n");
+ return nil;
+ }
+ }
+
+ image->display = d;
+ image->id = 0;
+ image->chan = strtochan(info+2*12);
+ image->depth = chantodepth(image->chan);
+ image->repl = atoi(info+3*12);
+ image->r.min.x = atoi(info+4*12);
+ image->r.min.y = atoi(info+5*12);
+ image->r.max.x = atoi(info+6*12);
+ image->r.max.y = atoi(info+7*12);
+ image->clipr.min.x = atoi(info+8*12);
+ image->clipr.min.y = atoi(info+9*12);
+ image->clipr.max.x = atoi(info+10*12);
+ image->clipr.max.y = atoi(info+11*12);
+ return image;
+}
+
+/*
+ * Attach, or possibly reattach, to window.
+ * If reattaching, maintain value of screen pointer.
+ */
+int
+getwindow(Display *d, int ref)
+{
+ Image *i, *oi;
+
+ /* XXX check for destroyed? */
+
+ /*
+ * Libdraw promises not to change the value of "screen",
+ * so we have to reuse the image structure
+ * memory we already have.
+ */
+ oi = d->image;
+ i = getimage0(d, oi);
+ if(i == nil)
+ sysfatal("getwindow failed");
+ d->image = i;
+ /* fprint(2, "getwindow %p -> %p\n", oi, i); */
+
+ freescreen(_screen);
+ _screen = allocscreen(i, d->white, 0);
+ _freeimage1(screen);
+ screen = _allocwindow(screen, _screen, i->r, ref, DWhite);
+ d->screenimage = screen;
+ return 0;
+}
+
+Display*
+_initdisplay(void (*error)(Display*, char*), char *label)
+{
+ Display *disp;
+ Image *image;
+
+ fmtinstall('P', Pfmt);
+ fmtinstall('R', Rfmt);
+
+ disp = mallocz(sizeof(Display), 1);
+ if(disp == nil){
+ Error1:
+ return nil;
+ }
+ disp->srvfd = -1;
+ image = nil;
+ if(0){
+ Error2:
+ free(image);
+ free(disp);
+ goto Error1;
+ }
+ disp->bufsize = 65500;
+ disp->buf = malloc(disp->bufsize+5); /* +5 for flush message */
+ disp->bufp = disp->buf;
+ disp->error = error;
+ qlock(&disp->qlock);
+
+ if(disp->buf == nil)
+ goto Error2;
+ if(0){
+ Error3:
+ free(disp->buf);
+ goto Error2;
+ }
+
+ if(_displaymux(disp) < 0
+ || _displayconnect(disp) < 0
+ || _displayinit(disp, label, winsize) < 0)
+ goto Error3;
+ if(0){
+ Error4:
+ close(disp->srvfd);
+ goto Error3;
+ }
+
+ image = getimage0(disp, nil);
+ if(image == nil)
+ goto Error4;
+
+ disp->image = image;
+ disp->white = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DWhite);
+ disp->black = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DBlack);
+ if(disp->white == nil || disp->black == nil){
+ free(disp->white);
+ free(disp->black);
+ goto Error4;
+ }
+
+ disp->opaque = disp->white;
+ disp->transparent = disp->black;
+
+ return disp;
+}
+
/*
* Call with d unlocked.
* Note that disp->defaultfont and defaultsubfont are not freed here.
@@ -131,6 +285,8 @@ closedisplay(Display *disp)
freeimage(disp->white);
if(disp->black)
freeimage(disp->black);
+ if(disp->srvfd >= 0)
+ close(disp->srvfd);
free(disp);
}
@@ -177,7 +333,7 @@ doflush(Display *d)
if(n <= 0)
return 1;
- if(_drawmsgwrite(d, d->buf, n) != n){
+ if(_displaywrdraw(d, d->buf, n) != n){
if(_drawdebug)
fprint(2, "flushimage fail: d=%p: %r\n", d); /**/
d->bufp = d->buf; /* might as well; chance of continuing */