aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-03-26 17:06:55 +0000
committerrsc <devnull@localhost>2004-03-26 17:06:55 +0000
commit6325e03247751de445423156deb36fc6740b20c9 (patch)
treef59079cf177ca2897011907ac1227d51e5c986f4 /src
parent3df902ecd04c688912230dab520a12279fd5a5b9 (diff)
downloadplan9port-6325e03247751de445423156deb36fc6740b20c9.tar.gz
plan9port-6325e03247751de445423156deb36fc6740b20c9.tar.bz2
plan9port-6325e03247751de445423156deb36fc6740b20c9.zip
Be more careful about not changing screen!
Diffstat (limited to 'src')
-rw-r--r--src/libdraw/devdraw.c2
-rw-r--r--src/libdraw/x11-init.c39
2 files changed, 34 insertions, 7 deletions
diff --git a/src/libdraw/devdraw.c b/src/libdraw/devdraw.c
index 49a641b0..76b79684 100644
--- a/src/libdraw/devdraw.c
+++ b/src/libdraw/devdraw.c
@@ -1054,6 +1054,8 @@ _drawmsgwrite(Display *d, void *v, int n)
m = 1;
if(n < m)
goto Eshortdraw;
+ if(drawlookup(client, 0, 0))
+ goto Eimageexists;
drawinstall(client, 0, screenimage, 0);
client->infoid = 0;
continue;
diff --git a/src/libdraw/x11-init.c b/src/libdraw/x11-init.c
index 70bd6d45..41817161 100644
--- a/src/libdraw/x11-init.c
+++ b/src/libdraw/x11-init.c
@@ -16,7 +16,7 @@ static void plan9cmap(void);
static int setupcmap(XWindow);
static int xreplacescreenimage(void);
static XGC xgc(XDrawable, int, int);
-static Image *getimage0(Display*);
+static Image *getimage0(Display*, Image*);
Xprivate _x;
@@ -62,17 +62,27 @@ _initdisplay(void (*error)(Display*, char*), char *label)
d->error = error;
_initdisplaymemimage(d, m);
- d->screenimage = getimage0(d);
+ d->screenimage = getimage0(d, 0);
return d;
}
static Image*
-getimage0(Display *d)
+getimage0(Display *d, Image *image)
{
char info[12*12+1];
uchar *a;
int n;
- Image *image;
+ extern int _freeimage1(Image*);
+
+ /*
+ * 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';
@@ -88,7 +98,14 @@ getimage0(Display *d)
abort();
}
- image = mallocz(sizeof(Image), 1);
+ if(image == nil){
+ image = mallocz(sizeof(Image), 1);
+ if(image == nil){
+ fprint(2, "cannot allocate image: %r\n");
+ abort();
+ }
+ }
+
image->display = d;
image->id = 0;
image->chan = strtochan(info+2*12);
@@ -109,14 +126,22 @@ int
getwindow(Display *d, int ref)
{
Image *i;
+ Image *oi;
if(_x.destroyed)
postnote(PNGROUP, getpgrp(), "hangup");
if(xreplacescreenimage() == 0)
return 0;
- freeimage(d->screenimage);
- i = getimage0(d);
+
+ /*
+ * Libdraw promises not to change the value of "screen",
+ * so we have to reuse the image structure
+ * memory we already have.
+ */
+ oi = d->screenimage;
+ i = getimage0(d, oi);
screen = d->screenimage = d->image = i;
+ // fprint(2, "getwindow %p -> %p\n", oi, i);
return 0;
}