/* Copyright (C) 1989, 2000 artofcode LLC.  All rights reserved.
  
  This program is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  59 Temple Place, Suite 330, Boston, MA, 02111-1307.

*/

/*$Id: gdevx.h,v 1.4.6.1.2.1 2003/01/17 00:49:02 giles Exp $ */
/* Definitions for X Windows drivers */
/* Requires gxdevice.h and x_.h */

#ifndef gdevx_INCLUDED
#  define gdevx_INCLUDED

/* Define the type of an X pixel. */
typedef unsigned long x_pixel;

#include "gdevbbox.h"
#include "gdevxcmp.h"

/* Declare the X resource tables compiled separately in gdevxres.c. */
extern XtResource gdev_x_resources[];
extern const int gdev_x_resource_count;
extern String gdev_x_fallback_resources[];

/* Define PostScript to X11 font name mapping */
/*
 * x11fontlist is only used within x11fontmap.
 * The names array is managed by Xlib, so the structure is simple.
 */
typedef struct x11fontlist_s {
    char **names;
    int count;
} x11fontlist;
typedef struct x11fontmap_s x11fontmap;
struct x11fontmap_s {
    char *ps_name;
    char *x11_name;
    x11fontlist std, iso;
    x11fontmap *next;
};
#define private_st_x11fontmap()	/* in gdevxini.c */\
  gs_private_st_ptrs3(st_x11fontmap, x11fontmap, "x11fontmap",\
    x11fontmap_enum_ptrs, x11fontmap_reloc_ptrs, ps_name, x11_name, next)

/* Define the X Windows device */
typedef struct gx_device_X_s {
    gx_device_bbox_common;	/* if target != 0, is image buffer */
    /*
     * Normally, an X device has an image buffer iff target != 0.  However,
     * the bbox device sometimes sets target to NULL temporarily, so we need
     * a separate flag to record whether this device is buffered.
     */
    bool is_buffered;
    bool IsPageDevice;
    long MaxBitmap;
    byte *buffer;		/* full-window image */
    long buffer_size;

    /* An XImage object for writing bitmap images to the screen */
    XImage image;

    /* Global X state */
    Display *dpy;
    Screen *scr;
    XVisualInfo *vinfo;
    Colormap cmap;
    Window win;
    GC gc;

    /* An optional Window ID supplied as a device parameter */
    Window pwin;

    /* A backing pixmap so X will handle exposure automatically */
    Pixmap bpixmap;		/* 0 if useBackingPixmap is false, */
				/* or if it can't be allocated */
    int ghostview;		/* flag to tell if ghostview is in control */
    Window mwin;		/* window to receive ghostview messages */
    gs_matrix initial_matrix;	/* the initial transformation */
    Atom NEXT, PAGE, DONE;	/* Atoms used to talk to ghostview */
    struct {
	gs_int_rect box;	/* region needing updating */
	long area;		/* total area of update */
	long total;		/* total of individual area updates */
	int count;		/* # of updates since flush */
    } update;
    Pixmap dest;		/* bpixmap if non-0, else use win */
    x_pixel colors_or;		/* 'or' of all device colors used so far */
    x_pixel colors_and;		/* 'and' ditto */

    /* An intermediate pixmap for the stencil case of copy_mono */
    struct {
	Pixmap pixmap;
	GC gc;
	int raster, height;
    } cp;

    /* Structure for dealing with the halftone tile. */
    /* Later this might become a multi-element cache. */
    struct {
	Pixmap pixmap;
	Pixmap no_pixmap;	/* kludge to get around X bug */
	gx_bitmap_id id;
	int width, height, raster;
	x_pixel fore_c, back_c;
    } ht;

    /* Cache the function and fill style from the GC */
    int function;
    int fill_style;
    Font fid;

#define X_SET_FILL_STYLE(xdev, style)\
  BEGIN\
    if (xdev->fill_style != (style))\
      XSetFillStyle(xdev->dpy, xdev->gc, (xdev->fill_style = (style)));\
  END
#define X_SET_FUNCTION(xdev, func)\
  BEGIN\
    if (xdev->function != (func))\
      XSetFunction(xdev->dpy, xdev->gc, (xdev->function = (func)));\
  END
#define X_SET_FONT(xdev, font)\
  BEGIN\
    if (xdev->fid != (font))\
      XSetFont(xdev->dpy, xdev->gc, (xdev->fid = (font)));\
  END

    x_pixel back_color, fore_color;

    Pixel background, foreground;

    /*
     * The color management structure is defined in gdevxcmp.h and is
     * managed by the code in gdevxcmp.c.
     */
    x11_cman_t cman;

#define NOTE_COLOR(xdev, pixel)\
  (xdev->colors_or |= (pixel),\
   xdev->colors_and &= (pixel))
#define X_SET_BACK_COLOR(xdev, pixel)\
  BEGIN\
    if (xdev->back_color != (pixel)) {\
      xdev->back_color = (pixel);\
      NOTE_COLOR(xdev, pixel);\
      XSetBackground(xdev->dpy, xdev->gc, (pixel));\
    }\
  END
#define X_SET_FORE_COLOR(xdev, pixel)\
  BEGIN\
    if (xdev->fore_color != (pixel)) {\
      xdev->fore_color = (pixel);\
      NOTE_COLOR(xdev, pixel);\
      XSetForeground(xdev->dpy, xdev->gc, (pixel));\
    }\
  END

    /* Defaults set by resources */
    Pixel borderColor;
    Dimension borderWidth;
    String geometry;
    int maxGrayRamp, maxRGBRamp;
    String palette;
    String regularFonts;
    String symbolFonts;
    String dingbatFonts;
    x11fontmap *regular_fonts;
    x11fontmap *symbol_fonts;
    x11fontmap *dingbat_fonts;
    Boolean useXFonts, useFontExtensions, useScalableFonts, logXFonts;
    float xResolution, yResolution;

    /* Flags work around various X server problems. */
    Boolean useBackingPixmap;
    Boolean useXPutImage;
    Boolean useXSetTile;

    /*
     * Parameters for the screen update algorithms.
     */

    /*
     * Define whether to update after every write, for debugging.
     * Note that one can obtain the same effect by setting any of
     */
    bool AlwaysUpdate;
    /*
     * Define the maximum size of the temporary pixmap for copy_mono
     * that we are willing to leave lying around in the server
     * between uses.
     */
    int MaxTempPixmap;
    /*
     * Define the maximum size of the temporary image created in memory
     * for get_bits_rectangle.
     */
    int MaxTempImage;
    /*
     * Define the maximum buffered updates before doing a screen write.
     */
    int MaxBufferedTotal;		/* sum of individual areas */
    int MaxBufferedArea;		/* area of merged bounding box */
    int MaxBufferedCount;		/* number of writes */

    /*
     * Buffered text awaiting display.
     */
    struct {
	int item_count;
#define IN_TEXT(xdev) ((xdev)->text.item_count != 0)
	int char_count;
	gs_int_point origin;
	int x;			/* after last buffered char */
#define MAX_TEXT_ITEMS 12
	XTextItem items[MAX_TEXT_ITEMS];
#define MAX_TEXT_CHARS 25
	char chars[MAX_TEXT_CHARS];
    } text;
/*
 * All the GC parameters are set correctly when we buffer the first
 * character: we must call DRAW_TEXT before resetting any of them.
 * DRAW_TEXT assumes xdev->text.{item,char}_count > 0.
 */
#define DRAW_TEXT(xdev)\
   XDrawText(xdev->dpy, xdev->dest, xdev->gc, xdev->text.origin.x,\
	     xdev->text.origin.y, xdev->text.items, xdev->text.item_count)

} gx_device_X;
#define private_st_device_X()	/* in gdevx.c */\
  gs_public_st_suffix_add4_final(st_device_X, gx_device_X,\
    "gx_device_X", device_x_enum_ptrs, device_x_reloc_ptrs,\
    gx_device_finalize, st_device_bbox, buffer, regular_fonts,\
    symbol_fonts, dingbat_fonts)

/* Send an event to the Ghostview process */
void gdev_x_send_event(P2(gx_device_X *xdev, Atom msg));

/* function to keep track of screen updates */
void x_update_add(P5(gx_device_X *, int, int, int, int));
void gdev_x_clear_window(P1(gx_device_X *));
int x_catch_free_colors(P2(Display *, XErrorEvent *));

/* Number used to distinguish when resolution was set from the command line */
#define FAKE_RES (16*72)

/* ------ Inter-module procedures ------ */

/* Exported by gdevxcmp.c for gdevxini.c */
int gdev_x_setup_colors(P1(gx_device_X *));
void gdev_x_free_colors(P1(gx_device_X *));
void gdev_x_free_dynamic_colors(P1(gx_device_X *));

/* Exported by gdevxini.c for gdevx.c */
int gdev_x_open(P1(gx_device_X *));
int gdev_x_close(P1(gx_device_X *));

/* Driver procedures exported for gdevx.c */
dev_proc_map_rgb_color(gdev_x_map_rgb_color);  /* gdevxcmp.c */
dev_proc_map_color_rgb(gdev_x_map_color_rgb);  /* gdevxcmp.c */
dev_proc_get_params(gdev_x_get_params);  /* gdevxini.c */
dev_proc_put_params(gdev_x_put_params);  /* gdevxini.c */
dev_proc_get_xfont_procs(gdev_x_get_xfont_procs);  /* gdevxxf.c */
dev_proc_finish_copydevice(gdev_x_finish_copydevice);  /* gdevxini.c */

#endif /* gdevx_INCLUDED */
