henesyinit from p9fce6d0435 years agoHistory
1110 lines · 33.0 KB · C
RawDownload
/* Copyright (C) 1989, 1992, 1993, 1994 Aladdin Enterprises.  All rights reserved.    This file is part of Aladdin Ghostscript.    Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author  or distributor accepts any responsibility for the consequences of using it,  or for whether it serves any particular purpose or works at all, unless he  or she says so in writing.  Refer to the Aladdin Ghostscript Free Public  License (the "License") for full details.    Every copy of Aladdin Ghostscript must include a copy of the License,  normally in a plain ASCII text file named PUBLIC.  The License grants you  the right to copy, modify and redistribute Aladdin Ghostscript, but only  under certain conditions described in the License.  Among other things, the  License requires that the copyright notice and this notice be preserved on  all copies.*/ /* gdevx.c *//* X Windows driver for Ghostscript library *//* The X include files include <sys/types.h>, which, on some machines *//* at least, define uint, ushort, and ulong, which std.h also defines. *//* std.h has taken care of this. */#include "gx.h"			/* for gx_bitmap; includes std.h */#include "math_.h"#include "memory_.h"#include "x_.h"#include "gserrors.h"#include "gsparam.h"#include "gxdevice.h"#include "gdevx.h" /* Define whether to update after every write, for debugging. */#define ALWAYS_UPDATE 0 /* Define the maximum size of the temporary pixmap for copy_mono *//* that we are willing to leave lying around in the server *//* between uses.  (Assume 32-bit ints here!) */private int max_temp_pixmap = 20000; /* Forward references */private int set_tile(P2(gx_device *, const gx_tile_bitmap *));private void free_cp(P1(gx_device *));/* Screen updating machinery */#define update_init(dev)\  ((gx_device_X *)(dev))->up_area = 0,\  ((gx_device_X *)(dev))->up_count = 0#define update_flush(dev)\  if ( ((gx_device_X *)(dev))->up_area != 0 ) update_do_flush(dev)private void update_do_flush(P1(gx_device *));private void x_send_event(P2(gx_device *, Atom)); /* Procedures */ extern int gdev_x_open(P1(gx_device_X *));private dev_proc_open_device(x_open);private dev_proc_get_initial_matrix(x_get_initial_matrix);private dev_proc_sync_output(x_sync);private dev_proc_output_page(x_output_page);private dev_proc_close_device(x_close);private dev_proc_map_rgb_color(x_map_rgb_color);private dev_proc_map_color_rgb(x_map_color_rgb);private dev_proc_fill_rectangle(x_fill_rectangle);private dev_proc_tile_rectangle(x_tile_rectangle);private dev_proc_copy_mono(x_copy_mono);private dev_proc_copy_color(x_copy_color);private dev_proc_draw_line(x_draw_line);private dev_proc_put_params(x_put_params);dev_proc_get_xfont_procs(x_get_xfont_procs); /* The device descriptor */private gx_device_procs x_procs = {	x_open,	x_get_initial_matrix,	x_sync,	x_output_page,	x_close,	x_map_rgb_color,	x_map_color_rgb,	x_fill_rectangle,	x_tile_rectangle,	x_copy_mono,	x_copy_color,	x_draw_line,	gx_default_get_bits,	NULL,			/* get_params */	x_put_params,	NULL,	x_get_xfont_procs}; /* The instance is public. */gx_device_X gs_x11_device = {	std_device_color_body(gx_device_X, &x_procs, "x11",	  FAKE_RES*85/10, FAKE_RES*11,	/* x and y extent (nominal) */	  FAKE_RES, FAKE_RES,	/* x and y density (nominal) */	  /*dci_color(*/24, 255, 256/*)*/),	{ 0 },			/* std_procs */	{ /* image */	  0, 0,			/* width, height */	  0, XYBitmap, NULL,	/* xoffset, format, data */	  LSBFirst, 8,    	/* byte-order, bitmap-unit */	  MSBFirst, 8, 1,	/* bitmap-bit-order, bitmap-pad, depth */	  0, 1,			/* bytes_per_line, bits_per_pixel */	  0, 0, 0,		/* red_mask, green_mask, blue_mask */	  NULL,			/* *obdata */	   { NULL,			/* *(*create_image)() */	     NULL,			/* (*destroy_image)() */	     NULL,			/* (*get_pixel)() */	     NULL,			/* (*put_pixel)() */	     NULL,			/* *(*sub_image)() */	     NULL			/* (*add_pixel)() */	   },	},	NULL, NULL,		/* dpy, scr */				/* (connection not initialized) */	NULL,			/* vinfo */	(Colormap)None,		/* cmap */	(Window)None,		/* win */	NULL,			/* gc */	(Window)None,		/* pwin */	(Pixmap)0,		/* bpixmap */	0,			/* ghostview */	(Window)None,		/* mwin */#if HaveStdCMap	NULL,			/* std_cmap */#endif	{ identity_matrix_body },	/* initial matrix (filled in) */	(Atom)0, (Atom)0, (Atom)0,	/* Atoms: NEXT, PAGE, DONE */	 { 0, 0, 0, 0 }, 0, 0,	/* update, up_area, up_count */	(Pixmap)0,		/* dest */	0L, ~0L,		/* colors_or, colors_and */	 { /* cp */	   (Pixmap)0,		/* pixmap */	   NULL,		/* gc */	   -1, -1		/* raster, height */	 },	 { /* ht */	   (Pixmap)None,		/* pixmap */	   (Pixmap)None,		/* no_pixmap */	   gx_no_bitmap_id,		/* id */	   0, 0, 0,			/* width, height, raster */	   0, 0				/* fore_c, back_c */	 },	GXcopy,			/* function */	FillSolid,		/* fill_style */	0,			/* font */	0, 0,			/* back_color, fore_color */	0, 0,			/* background, foreground */	NULL,			/* dither_colors */	0, 0,			/* color_mask, num_rgb */	NULL, 0,		/* dynamic_colors, max_dynamic_colors */	0, 0,			/* dynamic_size, dynamic_allocs */	0, 0,			/* borderColor, borderWidth */	NULL,			/* geometry */	128, 5,			/* maxGrayRamp, maxRGBRamp */	NULL,			/* palette */	NULL, NULL, NULL,	/* regularFonts, symbolFonts, dingbatFonts */	NULL, NULL, NULL,	/* regular_fonts, symbol_fonts, dingbat_fonts */	1, 1,			/* useXFonts, useFontExtensions */	1, 0,			/* useScalableFonts, logXFonts */	0.0, 0.0,		/* xResolution, yResolution */	1,			/* useBackingPixmap */	1, 1,			/* useXPutImage, useXSetTile */}; /* If XPutImage doesn't work, do it ourselves. */private void alt_put_image(P11(gx_device *dev, Display *dpy, Drawable win,  GC gc, XImage *pi, int sx, int sy, int dx, int dy, unsigned w, unsigned h));#define put_image(dpy,win,gc,im,sx,sy,x,y,w,h)\  if ( xdev->useXPutImage) XPutImage(dpy,win,gc,im,sx,sy,x,y,w,h);\  else alt_put_image(dev,dpy,win,gc,im,sx,sy,x,y,w,h)  /* Open the device.  Most of the code is in gdevxini.c. */private intx_open(gx_device *dev){    gx_device_X *xdev = (gx_device_X *)dev;    int code = gdev_x_open(xdev);     if (code < 0) return code;    update_init(dev);    return 0;} /* Close the device. */private intx_close(gx_device *dev){    gx_device_X *xdev = (gx_device_X *)dev;     if (xdev->ghostview) x_send_event(dev, xdev->DONE);    if (xdev->vinfo) {	XFree((char *)xdev->vinfo);	xdev->vinfo = NULL;    }    if (xdev->dither_colors) {	if (gx_device_has_color(xdev))#define cube(r) (r*r*r)	    gs_free((char *)xdev->dither_colors, sizeof(x_pixel),		    cube(xdev->color_info.dither_colors), "x11_rgb_cube");#undef cube	else	    gs_free((char *)xdev->dither_colors, sizeof(x_pixel),		    xdev->color_info.dither_grays, "x11_gray_ramp");	xdev->dither_colors = NULL;    }    if (xdev->dynamic_colors) {	int i;	for (i = 0; i < xdev->dynamic_size; i++) {	    x11color *xcp = (*xdev->dynamic_colors)[i];	    x11color *next;	    while (xcp) {		next = xcp->next;		gs_free((char *)xcp, sizeof(x11color), 1, "x11_dynamic_color");		xcp = next;	    }	}	gs_free((char *)xdev->dynamic_colors, sizeof(x11color *),		xdev->dynamic_size, "x11_dynamic_colors");	xdev->dynamic_colors = NULL;    }    while (xdev->regular_fonts) {	x11fontmap *font = xdev->regular_fonts;	xdev->regular_fonts = font->next;	if (font->std_names) XFreeFontNames(font->std_names);	if (font->iso_names) XFreeFontNames(font->iso_names);	gs_free(font->x11_name, sizeof(char), strlen(font->x11_name)+1,		"x11_font_x11name");	gs_free(font->ps_name, sizeof(char), strlen(font->ps_name)+1,		"x11_font_psname");	gs_free((char *)font, sizeof(x11fontmap), 1, "x11_fontmap");    }    while (xdev->symbol_fonts) {	x11fontmap *font = xdev->symbol_fonts;	xdev->symbol_fonts = font->next;	if (font->std_names) XFreeFontNames(font->std_names);	if (font->iso_names) XFreeFontNames(font->iso_names);	gs_free(font->x11_name, sizeof(char), strlen(font->x11_name)+1,		"x11_font_x11name");	gs_free(font->ps_name, sizeof(char), strlen(font->ps_name)+1,		"x11_font_psname");	gs_free((char *)font, sizeof(x11fontmap), 1, "x11_fontmap");    }    while (xdev->dingbat_fonts) {	x11fontmap *font = xdev->dingbat_fonts;	xdev->dingbat_fonts = font->next;	if (font->std_names) XFreeFontNames(font->std_names);	if (font->iso_names) XFreeFontNames(font->iso_names);	gs_free(font->x11_name, sizeof(char), strlen(font->x11_name)+1,		"x11_font_x11name");	gs_free(font->ps_name, sizeof(char), strlen(font->ps_name)+1,		"x11_font_psname");	gs_free((char *)font, sizeof(x11fontmap), 1, "x11_fontmap");    }    XCloseDisplay(xdev->dpy);    return 0;} /* Map a color.  The "device colors" are just r,g,b packed together. */private gx_color_indexx_map_rgb_color(register gx_device *dev,		gx_color_value r, gx_color_value g, gx_color_value b){    gx_device_X *xdev = (gx_device_X *)dev;    /* X and ghostscript both use shorts for color values */    unsigned short dr = r & xdev->color_mask;	/* Nearest color that */    unsigned short dg = g & xdev->color_mask;	/* the X device can   */    unsigned short db = b & xdev->color_mask;	/* represent          */    unsigned short cv_max = X_max_color_value & xdev->color_mask;    int cv_denom = (gx_max_color_value + 1);     /* foreground and background get special treatment */    /* They maybe mapped to other colors. */    if (dr == 0 && dg == 0 && db == 0) {	return xdev->foreground;    }    if (dr == cv_max && dg == cv_max && db == cv_max) {	return xdev->background;    }#if HaveStdCMap    /* check the standard colormap first */    if (xdev->std_cmap) {	XStandardColormap *cmap = xdev->std_cmap; 	if (gx_device_has_color(xdev)) {	    unsigned short cr, cg, cb;		/* rgb cube indices */	    unsigned short cvr, cvg, cvb;	/* color value on cube */ 	    cr = r * (cmap->red_max + 1) / cv_denom;	    cg = g * (cmap->green_max + 1) / cv_denom;	    cb = b * (cmap->blue_max + 1) / cv_denom;	    cvr = X_max_color_value * cr / cmap->red_max;	    cvg = X_max_color_value * cg / cmap->green_max;	    cvb = X_max_color_value * cb / cmap->blue_max;	    if ((abs((int)r - (int)cvr) & xdev->color_mask) == 0 &&		(abs((int)g - (int)cvg) & xdev->color_mask) == 0 &&		(abs((int)b - (int)cvb) & xdev->color_mask) == 0)		return cr * cmap->red_mult + cg * cmap->green_mult +		       cb * cmap->blue_mult + cmap->base_pixel;	} else {	    unsigned short cr;	    unsigned short cvr;	    int dither_grays = xdev->color_info.dither_grays; 	    cr = r * dither_grays / cv_denom;	    cvr = X_max_color_value * cr / cmap->red_max;	    if ((abs((int)r - (int)cvr) & xdev->color_mask) == 0)		return cr * cmap->red_mult + cmap->base_pixel;	}    } else#endif    /* If there is no standard colormap, check the dither cube/ramp */    if (xdev->dither_colors) {	if (gx_device_has_color(xdev)) {	    unsigned short cr, cg, cb;		/* rgb cube indices */	    unsigned short cvr, cvg, cvb;	/* color value on cube */	    int dither_rgb = xdev->color_info.dither_colors;	    unsigned short max_rgb = dither_rgb - 1; 	    cr = r * dither_rgb / cv_denom;	    cg = g * dither_rgb / cv_denom;	    cb = b * dither_rgb / cv_denom;	    cvr = X_max_color_value * cr / max_rgb;	    cvg = X_max_color_value * cg / max_rgb;	    cvb = X_max_color_value * cb / max_rgb;	    if ((abs((int)r - (int)cvr) & xdev->color_mask) == 0 &&		(abs((int)g - (int)cvg) & xdev->color_mask) == 0 &&		(abs((int)b - (int)cvb) & xdev->color_mask) == 0) {		return xdev->dither_colors[cube_index(cr, cg, cb)];	    }	} else {	    unsigned short cr;	    unsigned short cvr;	    int dither_grays = xdev->color_info.dither_grays;	    unsigned short max_gray = dither_grays - 1; 	    cr = r * dither_grays / cv_denom;	    cvr = (X_max_color_value * cr / max_gray);	    if ((abs((int)r - (int)cvr) & xdev->color_mask) == 0)		return xdev->dither_colors[cr];	}    }    /* Finally look through the list of dynamic colors */    if (xdev->dynamic_colors) {	int i = (dr ^ dg ^ db) >> (16 - xdev->vinfo->bits_per_rgb);	x11color *xcp = (*xdev->dynamic_colors)[i];	x11color *last = NULL;	XColor xc; 	while (xcp) {	    if (xcp->color.red == dr && xcp->color.green == dg &&		xcp->color.blue == db) {		if (last) {		    last->next = xcp->next;		    xcp->next = (*xdev->dynamic_colors)[i];		    (*xdev->dynamic_colors)[i] = xcp;		}		if (xcp->color.pad) return xcp->color.pixel;		else return gx_no_color_index;	    }	    last = xcp;	    xcp = xcp->next;	} 	/* If not in our list of dynamic colors, */	/* ask the X server and add an entry. */	/* First check if dynamic table is exhausted */	if (xdev->dynamic_allocs > xdev->max_dynamic_colors)	    return gx_no_color_index;	xcp = (x11color *) gs_malloc(sizeof(x11color), 1, "x11_dynamic_color");	if (!xcp) return gx_no_color_index;	xc.red   = xcp->color.red   = dr;	xc.green = xcp->color.green = dg;	xc.blue  = xcp->color.blue  = db;	xcp->next = (*xdev->dynamic_colors)[i];	(*xdev->dynamic_colors)[i] = xcp;	xdev->dynamic_allocs++;	if (XAllocColor(xdev->dpy, xdev->cmap, &xc)) {	    xcp->color.pixel = xc.pixel;	    xcp->color.pad = True;	    return xc.pixel;	} else {	    xcp->color.pad = False;	    return gx_no_color_index;	}    }    return gx_no_color_index;}  /* Map a "device color" back to r-g-b. *//* This doesn't happen often, so we just ask the display *//* Foreground and background may be mapped to other colors, so *//* they are handled specially. */private intx_map_color_rgb(register gx_device *dev, gx_color_index color,		gx_color_value prgb[3]){    gx_device_X *xdev = (gx_device_X *)dev;     if (color == xdev->foreground)	prgb[0] = prgb[1] = prgb[2] = 0;    else if (color == xdev->background)	prgb[0] = prgb[1] = prgb[2] = gx_max_color_value;    else {	XColor xc; 	xc.pixel = color;	XQueryColor(xdev->dpy, xdev->cmap, &xc);	prgb[0] = xc.red;	prgb[1] = xc.green;	prgb[2] = xc.blue;    }    return 0;} /* Get initial matrix for X device */private voidx_get_initial_matrix(register gx_device *dev, register gs_matrix *pmat){    gx_device_X *xdev = (gx_device_X *)dev;     pmat->xx = xdev->initial_matrix.xx;    pmat->xy = xdev->initial_matrix.xy;    pmat->yx = xdev->initial_matrix.yx;    pmat->yy = xdev->initial_matrix.yy;    pmat->tx = xdev->initial_matrix.tx;    pmat->ty = xdev->initial_matrix.ty;} /* Synchronize the display with the commands already given */private intx_sync(register gx_device *dev){    gx_device_X *xdev = (gx_device_X *)dev;     update_flush(dev);    XFlush(xdev->dpy);    return 0;} /* Send event to ghostview process */private voidx_send_event(gx_device *dev, Atom msg){    gx_device_X *xdev = (gx_device_X *)dev;    XEvent event;     event.xclient.type = ClientMessage;    event.xclient.display = xdev->dpy;    event.xclient.window = xdev->win;    event.xclient.message_type = msg;    event.xclient.format = 32;    event.xclient.data.l[0] = xdev->mwin;    event.xclient.data.l[1] = xdev->dest;    XSendEvent(xdev->dpy, xdev->win, False, 0, &event);} /* Output "page" */private intx_output_page(gx_device *dev, int num_copies, int flush){    gx_device_X *xdev = (gx_device_X *)dev;     x_sync(dev);     /* Send ghostview a "page" client event */    /* Wait for a "next" client event */    if (xdev->ghostview) {	XEvent event; 	x_send_event(dev, xdev->PAGE);	XNextEvent(xdev->dpy, &event);	while (event.type != ClientMessage ||	       event.xclient.message_type != xdev->NEXT) {	    XNextEvent(xdev->dpy, &event);	}    }    return 0;} /* Fill a rectangle with a color. */private intx_fill_rectangle(register gx_device *dev,		 int x, int y, int w, int h, gx_color_index color){    gx_device_X *xdev = (gx_device_X *)dev;     fit_fill(dev, x, y, w, h);    set_fill_style(FillSolid);    set_fore_color(color);    set_function(GXcopy);    XFillRectangle(xdev->dpy, xdev->dest, xdev->gc, x, y, w, h);    /* If we are filling the entire screen, reset */    /* colors_or and colors_and.  It's wasteful to do this */    /* on every operation, but there's no separate driver routine */    /* for erasepage (yet). */    if (x == 0 && y == 0 && w == xdev->width && h == xdev->height) {

Lines 1–500 of 1110.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t