1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 #include "gx.h"
17 #include "gxdcolor.h"
18 #include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and object filter */
19 
20 /* If set to '1' ths forces all devices to be loaded, even if they won't do anything.
21  * This is useful for cluster testing that the very presence of a device doesn't
22  * break anything.
23  */
24 #define FORCE_TESTING_SUBCLASSING 0
25 
install_internal_subclass_devices(gx_device ** ppdev,int * devices_loaded)26 int install_internal_subclass_devices(gx_device **ppdev, int *devices_loaded)
27 {
28     int code = 0;
29     gx_device *dev = (gx_device *)*ppdev, *saved;
30 
31 #if FORCE_TESTING_SUBCLASSING
32     if (!dev->PageHandlerPushed) {
33 #else
34     if (!dev->PageHandlerPushed && (dev->FirstPage != 0 || dev->LastPage != 0 || dev->PageList != 0)) {
35 #endif
36         code = gx_device_subclass(dev, (gx_device *)&gs_flp_device, sizeof(first_last_subclass_data));
37         if (code < 0)
38             return code;
39 
40         saved = dev = dev->child;
41 
42         /* Open all devices *after* the new current device */
43         do {
44             dev->is_open = true;
45             dev = dev->child;
46         }while(dev);
47 
48         dev = saved;
49 
50         /* Rewind to top device in chain */
51         while(dev->parent)
52             dev = dev->parent;
53 
54         /* Note in all devices in chain that we have loaded the PageHandler */
55         do {
56             dev->PageHandlerPushed = true;
57             dev = dev->child;
58         }while(dev);
59 
60         dev = saved;
61         if (devices_loaded)
62             *devices_loaded = true;
63     }
64 #if FORCE_TESTING_SUBCLASSING
65     if (!dev->ObjectHandlerPushed) {
66 #else
67     if (!dev->ObjectHandlerPushed && dev->ObjectFilter != 0) {
68 #endif
69         code = gx_device_subclass(dev, (gx_device *)&gs_obj_filter_device, sizeof(obj_filter_subclass_data));
70         if (code < 0)
71             return code;
72 
73         saved = dev = dev->child;
74 
75         /* Open all devices *after* the new current device */
76         do {
77             dev->is_open = true;
78             dev = dev->child;
79         }while(dev);
80 
81         dev = saved;
82 
83         /* Rewind to top device in chain */
84         while(dev->parent)
85             dev = dev->parent;
86 
87         /* Note in all devices in chain that we have loaded the ObjectHandler */
88         do {
89             dev->ObjectHandlerPushed = true;
90             dev = dev->child;
91         }while(dev);
92 
93         dev = saved;
94         if (devices_loaded)
95             *devices_loaded = true;
96     }
97     *ppdev = dev;
98     return code;
99 }
100