| @@ -393,10 +393,14 @@ drawfreedimage(Draw *d, DImage *dimage) · 392 unmodified lines |
| 393 | 393 | goto Return; |
| 394 | 394 | } |
| 395 | 395 | ds = dimage->dscreen; |
| 396 | + l = dimage->image; |
| 397 | + dimage->dscreen = nil; /* paranoia */ |
| 398 | + dimage->image = nil; |
| 396 | 399 | if(ds){ |
| 397 | | − l = dimage->image; |
| 400 | + // XXX TODO: this should not happen: |
| 401 | + if(l->layer == nil) return; |
| 398 | 402 | if(l->data == d->screenimage->data) |
| 399 | | − dstflush(d, l->layer->screen->image, l->layer->screenr); |
| 403 | + addflush(d, l->layer->screenr); |
| 400 | 404 | if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */ |
| 401 | 405 | free(l->layer->refreshptr); |
| 402 | 406 | l->layer->refreshptr = nil; |
| @@ -409,7 +413,7 @@ drawfreedimage(Draw *d, DImage *dimage) · 6 unmodified lines |
| 409 | 413 | // XXX TODO |
| 410 | 414 | // inferno-os/emu/port/devdraw.c:652 |
| 411 | 415 | // plan9port/src/cmd/devdraw/devdraw.c:566,569 |
| 412 | | − freememimage(dimage->image); |
| 416 | + freememimage(l); |
| 413 | 417 | } |
| 414 | 418 | Return: |
| 415 | 419 | free(dimage->fchar); |
| @@ -1589,32 +1593,58 @@ error: · 1173 unmodified lines |
| 1589 | 1593 | */ |
| 1590 | 1594 | |
| 1591 | 1595 | void |
| 1592 | | −drawreplacescreenimage(Window *w, Memimage *m) |
| 1596 | +drawreplacescreenimage(Draw *d, Memimage *m) |
| 1593 | 1597 | { |
| 1598 | + int i; |
| 1599 | + DImage *di; |
| 1600 | + |
| 1601 | + if(d->screendimage == nil) |
| 1602 | + return; |
| 1603 | + |
| 1594 | 1604 | /* |
| 1595 | 1605 | * Replace the screen image because the screen |
| 1596 | | − * was resized. |
| 1597 | | − * |
| 1598 | | − * In theory there should only be one reference |
| 1599 | | − * to the current screen image, and that's through |
| 1600 | | − * client0's image 0, installed a few lines above. |
| 1601 | | − * Once the client drops the image, the underlying backing |
| 1602 | | − * store freed properly. The client is being notified |
| 1603 | | − * about the resize through external means, so all we |
| 1604 | | − * need to do is this assignment. |
| 1606 | + * was resized. Clients still have references to the |
| 1607 | + * old screen image, so we can't free it just yet. |
| 1605 | 1608 | */ |
| 1606 | | − Memimage *om; |
| 1607 | | − Memimage *screenimage; |
| 1609 | + // drawqlock(); |
| 1610 | + di = allocdimage(m); |
| 1611 | + if(di == nil){ |
| 1612 | + print("no memory to replace screen image\n"); |
| 1613 | + freememimage(m); |
| 1614 | + // drawqunlock(); |
| 1615 | + return; |
| 1616 | + } |
| 1617 | + |
| 1618 | + /* Replace old screen image in global name lookup. */ |
| 1619 | + for(i=0; i<ndname; i++){ |
| 1620 | + if(dname[i].dimage == d->screendimage) |
| 1621 | + if(dname[i].client == nil){ |
| 1622 | + dname[i].dimage = di; |
| 1623 | + break; |
| 1624 | + } |
| 1625 | + } |
| 1608 | 1626 | |
| 1609 | | − screenimage = w->draw.screenimage; |
| 1610 | | − // qlock(&sdraw.lk); |
| 1611 | | − om = screenimage; |
| 1612 | | − w->draw.screenimage = m; |
| 1613 | | − // m->screenref = 1; |
| 1614 | | − // if(om && --om->screenref == 0){ |
| 1615 | | − // freememimage(om); |
| 1616 | | − // } |
| 1617 | | − // qunlock(&sdraw.lk); |
| 1627 | + drawfreedimage(d, d->screendimage); |
| 1628 | + d->screendimage = di; |
| 1629 | + d->screenimage = m; |
| 1630 | + |
| 1631 | + /* |
| 1632 | + * Every client, when it starts, gets a copy of the |
| 1633 | + * screen image as image 0. Clients only use it |
| 1634 | + * for drawing if there is no /dev/winname, but |
| 1635 | + * this /dev/draw provides a winname (early ones |
| 1636 | + * didn't; winname originated in rio), so the |
| 1637 | + * image only ends up used to find the screen |
| 1638 | + * resolution and pixel format during initialization. |
| 1639 | + * Silently remove the now-outdated image 0s. |
| 1640 | + */ |
| 1641 | + for(i=0; i<nclient; i++){ |
| 1642 | + if(client[i]->draw == d) |
| 1643 | + drawuninstall(client[i], 0); |
| 1644 | + } |
| 1645 | + |
| 1646 | + // drawqunlock(); |
| 1647 | + // mouseresize(); |
| 1618 | 1648 | } |
| 1619 | 1649 | |
| 1620 | 1650 | void |