summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2018-07-17 10:08:33 +0100
committerKen Sharp <ken.sharp@artifex.com>2018-08-09 16:05:56 +0100
commit2642d19883e4c008f999f2872cc0a37b2268634e (patch)
treefb6e7735bbb7df15af41d2fad76021488a91938d
parent8c0d309e74526e0eb5152af05067a9b0a53892c7 (diff)
downloadghostpdl-2642d19883e4c008f999f2872cc0a37b2268634e.tar.gz
Fix the display device with subclassing devices
When the display device is chosen, the executable calls display_set_callbacks on the current device. That code then sets a member in the current device, *without* checking the device is actually the display device. It does this *before* opening the device.... This is a quick hack to resolve the problem by descending to the bottom child device if there is a chain of devices in place. We should really check the device name at each step. In addition the Windows display device keeps a pointer to the device along with each 'image'. Not sure why, but it breaks if we are using device subclassing, because the device can change. Finally; the code doesn't cope with being unable to find a matching image with the same device. It sets the 'img' to NULL and then goes ahead and tries to use it anyway. Fix that at the same time so we don't crash!
-rw-r--r--devices/gdevdsp.c31
-rw-r--r--psi/dwmain.c15
-rw-r--r--psi/idisp.c5
3 files changed, 46 insertions, 5 deletions
diff --git a/devices/gdevdsp.c b/devices/gdevdsp.c
index 17b7aa7a8..50d9d5599 100644
--- a/devices/gdevdsp.c
+++ b/devices/gdevdsp.c
@@ -248,6 +248,9 @@ display_open(gx_device * dev)
return ccode;
dev = (gx_device *)ddev;
+ while(dev->parent)
+ dev = dev->parent;
+
/* Make sure we have been passed a valid callback structure. */
if ((ccode = display_check_structure(ddev)) < 0)
return_error(ccode);
@@ -309,6 +312,9 @@ display_sync_output(gx_device * dev)
return 0; /* ignore the call */
display_set_separations(ddev);
+ while(dev->parent)
+ dev = dev->parent;
+
(*(ddev->callback->display_sync))(ddev->pHandle, dev);
return (0);
}
@@ -324,6 +330,9 @@ display_output_page(gx_device * dev, int copies, int flush)
return gs_error_Fatal;
display_set_separations(ddev);
+ while(dev->parent)
+ dev = dev->parent;
+
code = (*(ddev->callback->display_page))
(ddev->pHandle, dev, copies, flush);
@@ -346,6 +355,9 @@ display_close(gx_device * dev)
/* Release memory. */
display_free_bitmap(ddev);
+ while(dev->parent)
+ dev = dev->parent;
+
/* Tell caller that device is closed. */
/* This is always the last callback */
(*(ddev->callback->display_close))(ddev->pHandle, dev);
@@ -712,6 +724,10 @@ display_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
return 0; /* ignore -- needed for fillpage when device wasn't really opened */
dev_proc(ddev->mdev, fill_rectangle)((gx_device *)ddev->mdev,
x, y, w, h, color);
+
+ while(dev->parent)
+ dev = dev->parent;
+
if (ddev->callback->display_update)
(*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
return 0;
@@ -729,6 +745,10 @@ display_copy_mono(gx_device * dev,
return gs_error_Fatal;
dev_proc(ddev->mdev, copy_mono)((gx_device *)ddev->mdev,
base, sourcex, raster, id, x, y, w, h, zero, one);
+
+ while(dev->parent)
+ dev = dev->parent;
+
if (ddev->callback->display_update)
(*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
return 0;
@@ -745,6 +765,10 @@ display_copy_color(gx_device * dev,
return gs_error_Fatal;
dev_proc(ddev->mdev, copy_color)((gx_device *)ddev->mdev,
base, sourcex, raster, id, x, y, w, h);
+
+ while(dev->parent)
+ dev = dev->parent;
+
if (ddev->callback->display_update)
(*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
return 0;
@@ -1012,6 +1036,10 @@ display_put_params(gx_device * dev, gs_param_list * plist)
/* We can resize this device while it is open, but we cannot
* change the color format or handle.
*/
+
+ while(dev->parent)
+ dev = dev->parent;
+
/* Tell caller we are about to change the device parameters */
if ((*ddev->callback->display_presize)(ddev->pHandle, dev,
dev->width, dev->height, display_raster(ddev),
@@ -1469,6 +1497,9 @@ display_set_separations(gx_device_display *dev)
* 65535 / frac_1;
}
}
+ while(dev->parent)
+ dev = dev->parent;
+
(*dev->callback->display_separation)(dev->pHandle, dev,
comp_num, name,
(unsigned short)c, (unsigned short)m,
diff --git a/psi/dwmain.c b/psi/dwmain.c
index 9e445270e..acf1c5a82 100644
--- a/psi/dwmain.c
+++ b/psi/dwmain.c
@@ -180,8 +180,10 @@ static int display_size(void *handle, void *device, int width, int height,
text_puts(tw, buf);
#endif
img = image_find(handle, device);
- image_size(img, width, height, raster, format, pimage);
- image_updatesize(img);
+ if (img != NULL) {
+ image_size(img, width, height, raster, format, pimage);
+ image_updatesize(img);
+ }
return 0;
}
@@ -195,7 +197,8 @@ static int display_sync(void *handle, void *device)
text_puts(tw, buf);
#endif
img = image_find(handle, device);
- image_sync(img);
+ if (img != NULL)
+ image_sync(img);
return 0;
}
@@ -211,7 +214,8 @@ static int display_page(void *handle, void *device, int copies, int flush)
text_puts(tw, buf);
#endif
img = image_find(handle, device);
- image_page(img);
+ if (img != NULL)
+ image_page(img);
return 0;
}
@@ -222,7 +226,8 @@ static int display_update(void *handle, void *device,
{
IMAGE *img;
img = image_find(handle, device);
- image_poll(img); /* redraw the window periodically */
+ if (img != NULL)
+ image_poll(img); /* redraw the window periodically */
return poll();
}
diff --git a/psi/idisp.c b/psi/idisp.c
index aafeba3a7..2ca7b57c5 100644
--- a/psi/idisp.c
+++ b/psi/idisp.c
@@ -91,6 +91,11 @@ display_set_callback(gs_main_instance *minst, display_callback *callback)
}
ddev = (gx_device_display *) dev;
+
+ /* Deal with the case where we subclassed the device before we got here */
+ while (ddev->child)
+ ddev = (gx_device_display *)ddev->child;
+
ddev->callback = callback;
if (was_open) {