idisp.c 3.28 KB
Newer Older
1
/* Copyright (C) 2001-2019 Artifex Software, Inc.
2
   All Rights Reserved.
3

4 5 6
   This software is provided AS-IS with no warranty, either express or
   implied.

7 8 9 10 11
   This software is distributed under license and may not be copied,
   modified or distributed except as expressly authorized under the terms
   of the license contained in the file LICENSE in this distribution.

   Refer to licensing information at http://www.artifex.com or contact
12 13
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14 15
*/

16

17 18 19
/* idisp.c */

/*
20 21
 * This allows the interpreter to set the callback structure
 * of the "display" device.  This must set at the end of
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
 * initialization and before the device is used.
 * This is harmless if the 'display' device is not included.
 * If gsapi_set_display_callback() is not called, this code
 * won't even be used.
 */

#include "stdio_.h"
#include "stdpre.h"
#include "iapi.h"
#include "ghost.h"
#include "gp.h"
#include "gscdefs.h"
#include "gsmemory.h"
#include "gstypes.h"
#include "gsdevice.h"
#include "iref.h"
#include "imain.h"
#include "iminst.h"
#include "oper.h"
#include "ostack.h"
#include "gx.h"
#include "gxdevice.h"
#include "gxdevmem.h"
#include "idisp.h"
#include "gdevdevn.h"
#include "gsequivc.h"
#include "gdevdsp.h"
#include "gdevdsp2.h"

int
display_set_callback(gs_main_instance *minst, display_callback *callback)
{
54
    i_ctx_t *i_ctx_p;
55 56 57
    bool was_open;
    int code;
    int exit_code = 0;
58
    os_ptr op;
59 60 61 62 63 64 65 66
    gx_device *dev;
    gx_device_display *ddev;

    /* If display device exists, copy prototype if needed and return
     *  device true
     * If it doesn't exist, return
     *  false
     */
67
    const char getdisplay[] =
68
      "devicedict /display known dup { /display finddevice exch } if";
69 70
    code = gs_main_run_string(minst, getdisplay, 0, &exit_code,
        &minst->error_object);
71 72 73
    if (code < 0)
       return code;

74
    i_ctx_p = minst->i_ctx_p;	/* run_string may change i_ctx_p if GC */
75 76 77
    op = osp;
    check_type(*op, t_boolean);
    if (op->value.boolval) {
78 79 80 81 82 83
        /* display device was included in Ghostscript so we need
         * to set the callback structure pointer within it.
         * If the device is already open, close it before
         * setting callback, then reopen it.
         */
        check_read_type(op[-1], t_device);
84 85 86 87
        if (op[-1].value.pdevice == NULL)
            /* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
            return_error(gs_error_undefined);

88 89 90 91 92 93
        dev = op[-1].value.pdevice;

        was_open = dev->is_open;
        if (was_open) {
            code = gs_closedevice(dev);
            if (code < 0)
94
                return code;
95
        }
96

97
        ddev = (gx_device_display *) dev;
98 99 100 101 102

        /* Deal with the case where we subclassed the device before we got here */
        while (ddev->child)
            ddev = (gx_device_display *)ddev->child;

103
        ddev->callback = callback;
104

105 106 107
        if (was_open) {
            code = gs_opendevice(dev);
            if (code < 0) {
108
                dmprintf(dev->memory, "**** Unable to open the display device, quitting.\n");
109
                return code;
110 111 112
            }
        }
        pop(1);	/* device */
113 114 115 116
    }
    pop(1);	/* boolean */
    return 0;
}