psgeom.c revision 0e20ee16
10e20ee16Smrg/* $Xorg: psgeom.c,v 1.4 2000/08/17 19:54:50 cpqbld Exp $ */
20e20ee16Smrg/************************************************************
30e20ee16Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
40e20ee16Smrg
50e20ee16Smrg Permission to use, copy, modify, and distribute this
60e20ee16Smrg software and its documentation for any purpose and without
70e20ee16Smrg fee is hereby granted, provided that the above copyright
80e20ee16Smrg notice appear in all copies and that both that copyright
90e20ee16Smrg notice and this permission notice appear in supporting
100e20ee16Smrg documentation, and that the name of Silicon Graphics not be
110e20ee16Smrg used in advertising or publicity pertaining to distribution
120e20ee16Smrg of the software without specific prior written permission.
130e20ee16Smrg Silicon Graphics makes no representation about the suitability
140e20ee16Smrg of this software for any purpose. It is provided "as is"
150e20ee16Smrg without any express or implied warranty.
160e20ee16Smrg
170e20ee16Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
180e20ee16Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
190e20ee16Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
200e20ee16Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
210e20ee16Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
220e20ee16Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
230e20ee16Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
240e20ee16Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
250e20ee16Smrg
260e20ee16Smrg ********************************************************/
270e20ee16Smrg/* $XFree86: xc/programs/xkbprint/psgeom.c,v 1.5 2001/07/25 15:05:25 dawes Exp $ */
280e20ee16Smrg
290e20ee16Smrg#define	XK_TECHNICAL
300e20ee16Smrg#define	XK_PUBLISHING
310e20ee16Smrg#define	XK_KATAKANA
320e20ee16Smrg#include <stdio.h>
330e20ee16Smrg#include <ctype.h>
340e20ee16Smrg#include <X11/X.h>
350e20ee16Smrg#include <X11/Xlib.h>
360e20ee16Smrg#include <X11/XKBlib.h>
370e20ee16Smrg#include <X11/extensions/XKBgeom.h>
380e20ee16Smrg#include <X11/extensions/XKM.h>
390e20ee16Smrg#include <X11/extensions/XKBfile.h>
400e20ee16Smrg#include <X11/keysym.h>
410e20ee16Smrg#include <X11/Xutil.h>
420e20ee16Smrg
430e20ee16Smrg#if defined(sgi)
440e20ee16Smrg#include <malloc.h>
450e20ee16Smrg#endif
460e20ee16Smrg
470e20ee16Smrg#define	DEBUG_VAR_NOT_LOCAL
480e20ee16Smrg#define	DEBUG_VAR debugFlags
490e20ee16Smrg#include <stdlib.h>
500e20ee16Smrg
510e20ee16Smrg#include "utils.h"
520e20ee16Smrg#include "xkbprint.h"
530e20ee16Smrg#include "isokeys.h"
540e20ee16Smrg
550e20ee16Smrg#define	FONT_NONE	-1
560e20ee16Smrg#define	FONT_TEXT	0
570e20ee16Smrg#define	FONT_LATIN1	1
580e20ee16Smrg#define	FONT_SYMBOL	2
590e20ee16Smrg#define	FONT_ISOCAPS	3
600e20ee16Smrg#define	FONT_MOUSECAPS	4
610e20ee16Smrg
620e20ee16Smrgtypedef struct {
630e20ee16Smrg	Display *	dpy;
640e20ee16Smrg	XkbDescPtr	xkb;
650e20ee16Smrg	XkbGeometryPtr	geom;
660e20ee16Smrg	int		totalKB;
670e20ee16Smrg	int		kbPerPage;
680e20ee16Smrg	int		black;
690e20ee16Smrg	int		white;
700e20ee16Smrg	int		color;
710e20ee16Smrg	int		font;
720e20ee16Smrg	int		fontSize;
730e20ee16Smrg	int		nPages;
740e20ee16Smrg	int		x1,y1;
750e20ee16Smrg	int		x2,y2;
760e20ee16Smrg	XKBPrintArgs *	args;
770e20ee16Smrg} PSState;
780e20ee16Smrg
790e20ee16Smrg#define	G1L1		0
800e20ee16Smrg#define	G1L2		1
810e20ee16Smrg#define	G2L1		2
820e20ee16Smrg#define	G2L2		3
830e20ee16Smrg#define	CENTER		4
840e20ee16Smrg
850e20ee16Smrg#define	G1L1_MASK	(1<<G1L1)
860e20ee16Smrg#define	G1L2_MASK	(1<<G1L2)
870e20ee16Smrg#define	G2L1_MASK	(1<<G2L1)
880e20ee16Smrg#define	G2L2_MASK	(1<<G2L2)
890e20ee16Smrg#define	CENTER_MASK	(1<<CENTER)
900e20ee16Smrg
910e20ee16Smrg#define	LABEL_MASK	(0x1f)
920e20ee16Smrg#define	GXL1_MASK	(G1L1_MASK|G2L1_MASK)
930e20ee16Smrg#define	GXL2_MASK	(G1L2_MASK|G2L2_MASK)
940e20ee16Smrg#define	G1LX_MASK	(G1L1_MASK|G1L2_MASK)
950e20ee16Smrg#define	G2LX_MASK	(G2L1_MASK|G2L2_MASK)
960e20ee16Smrg#define	GXLX_MASK	(0x0f)
970e20ee16Smrg
980e20ee16Smrg#define	NLABELS		5
990e20ee16Smrg#define	LABEL_LEN	30
1000e20ee16Smrg
1010e20ee16Smrg#define	SZ_AUTO		0
1020e20ee16Smrg#define	SZ_TINY		1
1030e20ee16Smrg#define	SZ_SMALL	2
1040e20ee16Smrg#define	SZ_MEDIUM	3
1050e20ee16Smrg#define	SZ_LARGE	4
1060e20ee16Smrg#define	SZ_XLARGE	5
1070e20ee16Smrg
1080e20ee16Smrgtypedef struct {
1090e20ee16Smrg	unsigned	present;
1100e20ee16Smrg	Bool		alpha[2];
1110e20ee16Smrg	char 		label[NLABELS][LABEL_LEN];
1120e20ee16Smrg	int		font[NLABELS];
1130e20ee16Smrg	int		size[NLABELS];
1140e20ee16Smrg} KeyTop;
1150e20ee16Smrg
1160e20ee16Smrg#define	DFLT_LABEL_FONT "Helvetica-Narrow-Bold"
1170e20ee16Smrg#define DFLT_LABEL_FONT_SIZE 10
1180e20ee16Smrg
1190e20ee16Smrg/***====================================================================***/
1200e20ee16Smrg
1210e20ee16Smrgtypedef struct _PSFontDef {
1220e20ee16Smrg    char *name;
1230e20ee16Smrg    char **def;
1240e20ee16Smrg} PSFontDef;
1250e20ee16Smrg
1260e20ee16Smrgstatic PSFontDef internalFonts[] = {
1270e20ee16Smrg	{ "IsoKeyCaps", IsoKeyCaps }
1280e20ee16Smrg};
1290e20ee16Smrgstatic int nInternalFonts =	(sizeof(internalFonts)/sizeof(PSFontDef));
1300e20ee16Smrg
1310e20ee16Smrgstatic void
1320e20ee16SmrgListInternalFonts(FILE *out, int first, int indent)
1330e20ee16Smrg{
1340e20ee16Smrgregister int i,n,nThisLine;
1350e20ee16Smrg
1360e20ee16Smrg    for (n=0;n<first;n++) {
1370e20ee16Smrg	putc(' ',out);
1380e20ee16Smrg    }
1390e20ee16Smrg
1400e20ee16Smrg    for (nThisLine=i=0;i<nInternalFonts;i++) {
1410e20ee16Smrg	if (nThisLine==4) {
1420e20ee16Smrg	    fprintf(out,",\n");
1430e20ee16Smrg	    for (n=0;n<indent;n++) {
1440e20ee16Smrg		putc(' ',out);
1450e20ee16Smrg	    }
1460e20ee16Smrg	    nThisLine= 0;
1470e20ee16Smrg	}
1480e20ee16Smrg	if (nThisLine==0)
1490e20ee16Smrg	     fprintf(out,"%s",internalFonts[i].name);
1500e20ee16Smrg	else fprintf(out,", %s",internalFonts[i].name);
1510e20ee16Smrg	nThisLine++;
1520e20ee16Smrg    }
1530e20ee16Smrg    if (nThisLine!=0)
1540e20ee16Smrg	fprintf(out,"\n");
1550e20ee16Smrg    return;
1560e20ee16Smrg}
1570e20ee16Smrg
1580e20ee16Smrgstatic Bool
1590e20ee16SmrgPSIncludeFont(FILE *out, char *font)
1600e20ee16Smrg{
1610e20ee16Smrgchar **		pstr;
1620e20ee16Smrgregister int	i;
1630e20ee16Smrg
1640e20ee16Smrg    pstr= NULL;
1650e20ee16Smrg    for (i=0;(i<nInternalFonts)&&(pstr==NULL);i++) {
1660e20ee16Smrg	if (uStringEqual(internalFonts[i].name,font))
1670e20ee16Smrg	    pstr= internalFonts[i].def;
1680e20ee16Smrg    }
1690e20ee16Smrg    if (pstr!=NULL) {
1700e20ee16Smrg	fprintf(out,"%%%%BeginFont: %s\n",font);
1710e20ee16Smrg	while (*pstr!=NULL) {
1720e20ee16Smrg	    fprintf(out,"%s\n",*pstr);
1730e20ee16Smrg	    pstr++;
1740e20ee16Smrg	}
1750e20ee16Smrg	fprintf(out,"%%%%EndFont\n");
1760e20ee16Smrg	return True;
1770e20ee16Smrg    }
1780e20ee16Smrg    return False;
1790e20ee16Smrg}
1800e20ee16Smrg
1810e20ee16SmrgBool
1820e20ee16SmrgDumpInternalFont(FILE *out, char *fontName)
1830e20ee16Smrg{
1840e20ee16Smrg    if (strcmp(fontName,"IsoKeyCaps")!=0) {
1850e20ee16Smrg	uError("No internal font named \"%s\"\n",fontName);
1860e20ee16Smrg	uAction("No font dumped\n");
1870e20ee16Smrg	fprintf(stderr,"Current internal fonts are: ");
1880e20ee16Smrg	ListInternalFonts(stderr,0,8);
1890e20ee16Smrg	return False;
1900e20ee16Smrg    }
1910e20ee16Smrg    PSIncludeFont(out,fontName);
1920e20ee16Smrg    return True;
1930e20ee16Smrg}
1940e20ee16Smrg
1950e20ee16Smrg/***====================================================================***/
1960e20ee16Smrg
1970e20ee16Smrgstatic void
1980e20ee16SmrgPSColorDef(FILE *out, PSState *state, XkbColorPtr color)
1990e20ee16Smrg{
2000e20ee16Smrgint	tmp;
2010e20ee16Smrg
2020e20ee16Smrg    fprintf(out,"/C%03d ",color->pixel);
2030e20ee16Smrg    if (uStrCaseEqual(color->spec,"black")) {
2040e20ee16Smrg	state->black= color->pixel;
2050e20ee16Smrg	fprintf(out,"{ 0 setgray } def      %% %s\n",color->spec);
2060e20ee16Smrg    }
2070e20ee16Smrg    else if (uStrCaseEqual(color->spec,"white")) {
2080e20ee16Smrg	state->white= color->pixel;
2090e20ee16Smrg	fprintf(out,"{ 1 setgray } def      %% %s\n",color->spec);
2100e20ee16Smrg    }
2110e20ee16Smrg    else if ((sscanf(color->spec,"grey%d",&tmp)==1)||
2120e20ee16Smrg	(sscanf(color->spec,"gray%d",&tmp)==1)||
2130e20ee16Smrg	(sscanf(color->spec,"Grey%d",&tmp)==1)||
2140e20ee16Smrg	(sscanf(color->spec,"Gray%d",&tmp)==1)) {
2150e20ee16Smrg	fprintf(out,"{ %f setgray } def	    %% %s\n",1.0-(((float)tmp)/100.0),
2160e20ee16Smrg								color->spec);
2170e20ee16Smrg    }
2180e20ee16Smrg    else if ((tmp=(uStrCaseEqual(color->spec,"red")*100))||
2190e20ee16Smrg	     (sscanf(color->spec,"red%d",&tmp)==1)) {
2200e20ee16Smrg	 fprintf(out,"{ %f 0 0 setrgbcolor } def %% %s\n",(((float)tmp)/100.0),
2210e20ee16Smrg								color->spec);
2220e20ee16Smrg    }
2230e20ee16Smrg    else if ((tmp=(uStrCaseEqual(color->spec,"green")*100))||
2240e20ee16Smrg	     (sscanf(color->spec,"green%d",&tmp)==1)) {
2250e20ee16Smrg	 fprintf(out,"{ 0 %f 0 setrgbcolor } def %% %s\n",(((float)tmp)/100.0),
2260e20ee16Smrg								color->spec);
2270e20ee16Smrg    }
2280e20ee16Smrg    else if ((tmp=(uStrCaseEqual(color->spec,"blue")*100))||
2290e20ee16Smrg	     (sscanf(color->spec,"blue%d",&tmp)==1)) {
2300e20ee16Smrg	 fprintf(out,"{ 0 0 %f setrgbcolor } def %% %s\n",(((float)tmp)/100.0),
2310e20ee16Smrg								color->spec);
2320e20ee16Smrg    }
2330e20ee16Smrg    else fprintf(out,"{ 0.9 setgray       } def %% BOGUS! %s\n",color->spec);
2340e20ee16Smrg}
2350e20ee16Smrg
2360e20ee16Smrgstatic void
2370e20ee16SmrgPSSetColor(FILE *out,PSState *state,int color)
2380e20ee16Smrg{
2390e20ee16Smrg    if ((state->args->wantColor)&&(state->color!=color)) {
2400e20ee16Smrg	fprintf(out,"C%03d %% set color\n",color);
2410e20ee16Smrg	state->color= color;
2420e20ee16Smrg    }
2430e20ee16Smrg    return;
2440e20ee16Smrg}
2450e20ee16Smrg
2460e20ee16Smrgstatic void
2470e20ee16SmrgPSGSave(FILE *out, PSState *state)
2480e20ee16Smrg{
2490e20ee16Smrg    fprintf(out,"gsave\n");
2500e20ee16Smrg    return;
2510e20ee16Smrg}
2520e20ee16Smrg
2530e20ee16Smrgstatic void
2540e20ee16SmrgPSGRestore(FILE *out, PSState *state)
2550e20ee16Smrg{
2560e20ee16Smrg    fprintf(out,"grestore\n");
2570e20ee16Smrg    state->color= -1;
2580e20ee16Smrg    state->font= FONT_NONE;
2590e20ee16Smrg    state->fontSize= -1;
2600e20ee16Smrg    return;
2610e20ee16Smrg}
2620e20ee16Smrg
2630e20ee16Smrgstatic void
2640e20ee16SmrgPSShapeDef(FILE *out, PSState *state, XkbShapePtr shape)
2650e20ee16Smrg{
2660e20ee16Smrgint		o,p;
2670e20ee16SmrgXkbOutlinePtr	ol;
2680e20ee16Smrg
2690e20ee16Smrg    fprintf(out,"/%s {\n",XkbAtomGetString(state->dpy,shape->name));
2700e20ee16Smrg    fprintf(out,"	gsave translate rotate /SOLID exch def\n");
2710e20ee16Smrg    for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
2720e20ee16Smrg	XkbPointPtr	pt;
2730e20ee16Smrg	if ((shape->num_outlines>1)&&(ol==shape->approx))
2740e20ee16Smrg	    continue;
2750e20ee16Smrg	pt=ol->points;
2760e20ee16Smrg	fprintf(out,"%%	Outline %d\n",o+1);
2770e20ee16Smrg	if (ol->num_points==1) {
2780e20ee16Smrg	    if (ol->corner_radius<1) {
2790e20ee16Smrg		fprintf(out,"	  0   0 moveto\n");
2800e20ee16Smrg		fprintf(out,"	%3d   0 lineto\n",pt->x);
2810e20ee16Smrg		fprintf(out,"	%3d %3d lineto\n",pt->x,pt->y);
2820e20ee16Smrg		fprintf(out,"	  0 %3d lineto\n",pt->y);
2830e20ee16Smrg		fprintf(out,"	  0   0 lineto\n");
2840e20ee16Smrg		fprintf(out,"	SOLID { fill } { stroke } ifelse\n");
2850e20ee16Smrg	    }
2860e20ee16Smrg	    else {
2870e20ee16Smrg		fprintf(out,"	mark\n");
2880e20ee16Smrg		fprintf(out,"	%3d   0 moveto\n",ol->corner_radius);
2890e20ee16Smrg		fprintf(out,"	%3d   0 %3d %3d %3d arcto\n",pt->x,pt->x,pt->y,
2900e20ee16Smrg							ol->corner_radius);
2910e20ee16Smrg		fprintf(out,"	%3d %3d   0 %3d %3d arcto\n",pt->x,pt->y,pt->y,
2920e20ee16Smrg							ol->corner_radius);
2930e20ee16Smrg		fprintf(out,"	  0 %3d   0   0 %3d arcto\n",pt->y,
2940e20ee16Smrg							ol->corner_radius);
2950e20ee16Smrg		fprintf(out,"     0   0 %3d   0 %3d arcto\n",pt->x,
2960e20ee16Smrg							ol->corner_radius);
2970e20ee16Smrg		fprintf(out,"	SOLID { fill } { stroke } ifelse\n");
2980e20ee16Smrg		fprintf(out,"	cleartomark\n");
2990e20ee16Smrg	    }
3000e20ee16Smrg	}
3010e20ee16Smrg	else if (ol->num_points==2) {
3020e20ee16Smrg	    if (ol->corner_radius<1) {
3030e20ee16Smrg		fprintf(out,"	%3d %3d moveto\n",pt[0].x,pt[0].y);
3040e20ee16Smrg		fprintf(out,"	%3d %3d lineto\n",pt[1].x,pt[0].y);
3050e20ee16Smrg		fprintf(out,"	%3d %3d lineto\n",pt[1].x,pt[1].y);
3060e20ee16Smrg		fprintf(out,"	%3d %3d lineto\n",pt[0].x,pt[1].y);
3070e20ee16Smrg		fprintf(out,"	%3d %3d lineto\n",pt[0].x,pt[0].y);
3080e20ee16Smrg		fprintf(out,"	SOLID { fill } { stroke } ifelse\n");
3090e20ee16Smrg	    }
3100e20ee16Smrg	    else {
3110e20ee16Smrg		fprintf(out,"	mark\n");
3120e20ee16Smrg		fprintf(out,"	%3d %3d moveto\n",pt[0].x,pt[0].y);
3130e20ee16Smrg		fprintf(out,"	%3d %3d %3d %3d %3d arcto\n",pt[1].x,pt[0].y,
3140e20ee16Smrg							pt[1].x,pt[1].y,
3150e20ee16Smrg							ol->corner_radius);
3160e20ee16Smrg		fprintf(out,"	%3d %3d %3d %3d %3d arcto\n",pt[1].x,pt[1].y,
3170e20ee16Smrg							pt[0].x,pt[1].y,
3180e20ee16Smrg							ol->corner_radius);
3190e20ee16Smrg		fprintf(out,"	%3d %3d %3d %3d %3d arcto\n",pt[0].x,pt[1].y,
3200e20ee16Smrg							pt[0].x,pt[0].y,
3210e20ee16Smrg							ol->corner_radius);
3220e20ee16Smrg		fprintf(out,"   %3d %3d %3d %3d %3d arcto\n",pt[0].x,pt[0].y,
3230e20ee16Smrg							pt[1].x,pt[0].y,
3240e20ee16Smrg							ol->corner_radius);
3250e20ee16Smrg		fprintf(out,"	SOLID { fill } { stroke } ifelse\n");
3260e20ee16Smrg		fprintf(out,"	cleartomark\n");
3270e20ee16Smrg	    }
3280e20ee16Smrg	}
3290e20ee16Smrg	else {
3300e20ee16Smrg	    if (ol->corner_radius<1) {
3310e20ee16Smrg		fprintf(out,"	%3d %3d moveto\n",pt->x,pt->y);
3320e20ee16Smrg		pt++;
3330e20ee16Smrg		for (p=1;p<ol->num_points;p++,pt++) {
3340e20ee16Smrg		    fprintf(out,"	%3d %3d lineto\n",pt->x,pt->y);
3350e20ee16Smrg		}
3360e20ee16Smrg		if ((pt->x!=ol->points[0].x)||(pt->y!=ol->points[0].y))
3370e20ee16Smrg		    fprintf(out,"	closepath\n");
3380e20ee16Smrg		fprintf(out,"	SOLID { fill } { stroke } ifelse\n");
3390e20ee16Smrg	    }
3400e20ee16Smrg	    else {
3410e20ee16Smrg		XkbPointPtr	last;
3420e20ee16Smrg		last= &pt[ol->num_points-1];
3430e20ee16Smrg		if ((last->x==pt->x)&&(last->y==pt->y))
3440e20ee16Smrg		    last--;
3450e20ee16Smrg		fprintf(out,"	mark\n");
3460e20ee16Smrg		fprintf(out,"	%% Determine tangent point of first corner\n");
3470e20ee16Smrg		fprintf(out,"	%3d %3d moveto %d %d %d %d %d arcto\n",
3480e20ee16Smrg					last->x,last->y,
3490e20ee16Smrg					pt[0].x,pt[0].y,pt[1].x,pt[1].y,
3500e20ee16Smrg					ol->corner_radius);
3510e20ee16Smrg		fprintf(out,"	/TY exch def /TX exch def pop pop newpath\n");
3520e20ee16Smrg		fprintf(out,"	%% Now draw the shape\n");
3530e20ee16Smrg		fprintf(out,"	TX TY moveto\n");
3540e20ee16Smrg		for (p=1;p<ol->num_points;p++) {
3550e20ee16Smrg		    if (p<(ol->num_points-1))	last= &pt[p+1];
3560e20ee16Smrg		    else			last= &pt[0];
3570e20ee16Smrg		    fprintf(out,"	%3d %3d %3d %3d %3d arcto\n",
3580e20ee16Smrg						pt[p].x,pt[p].y,
3590e20ee16Smrg						last->x,last->y,
3600e20ee16Smrg						ol->corner_radius);
3610e20ee16Smrg		}
3620e20ee16Smrg		last= &pt[ol->num_points-1];
3630e20ee16Smrg		if ((last->x!=pt->x)||(last->y!=pt->y)) {
3640e20ee16Smrg		    fprintf(out,"	%3d %3d %3d %3d %3d arcto\n",
3650e20ee16Smrg						pt[0].x,pt[0].y,
3660e20ee16Smrg						pt[1].x,pt[1].y,
3670e20ee16Smrg						ol->corner_radius);
3680e20ee16Smrg		}
3690e20ee16Smrg		fprintf(out,"	SOLID { fill } { stroke } ifelse\n");
3700e20ee16Smrg		fprintf(out,"	cleartomark\n");
3710e20ee16Smrg	    }
3720e20ee16Smrg	}
3730e20ee16Smrg    }
3740e20ee16Smrg    fprintf(out,"	grestore\n");
3750e20ee16Smrg    fprintf(out,"} def\n");
3760e20ee16Smrg    return;
3770e20ee16Smrg}
3780e20ee16Smrg
3790e20ee16Smrg/***====================================================================***/
3800e20ee16Smrg
3810e20ee16Smrgtypedef	struct {
3820e20ee16Smrg	char *		foundry;
3830e20ee16Smrg	char *		face;
3840e20ee16Smrg	char *		weight;
3850e20ee16Smrg	char *		slant;
3860e20ee16Smrg	char *		setWidth;
3870e20ee16Smrg	char *		variant;
3880e20ee16Smrg	int		pixelSize;
3890e20ee16Smrg	int		ptSize;
3900e20ee16Smrg	int		resX;
3910e20ee16Smrg	int		resY;
3920e20ee16Smrg	char *		spacing;
3930e20ee16Smrg	int		avgWidth;
3940e20ee16Smrg	char *		encoding;
3950e20ee16Smrg} FontStuff;
3960e20ee16Smrg
3970e20ee16Smrgstatic void
3980e20ee16SmrgClearFontStuff(FontStuff *stuff)
3990e20ee16Smrg{
4000e20ee16Smrg    if (stuff && stuff->foundry)
4010e20ee16Smrg	uFree(stuff->foundry);
4020e20ee16Smrg    bzero(stuff,sizeof(FontStuff));
4030e20ee16Smrg    return;
4040e20ee16Smrg}
4050e20ee16Smrg
4060e20ee16Smrgstatic Bool
4070e20ee16SmrgCrackXLFDName(char *name, FontStuff *stuff)
4080e20ee16Smrg{
4090e20ee16Smrgchar *tmp;
4100e20ee16Smrg    if ((name==NULL)||(stuff==NULL))
4110e20ee16Smrg	return False;
4120e20ee16Smrg    if (name[0]=='-')	tmp= uStringDup(&name[1]);
4130e20ee16Smrg    else		tmp= uStringDup(name);
4140e20ee16Smrg    if (tmp==NULL)
4150e20ee16Smrg	return False;
4160e20ee16Smrg    stuff->foundry= tmp;
4170e20ee16Smrg
4180e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4190e20ee16Smrg    else 						*tmp++= '\0';
4200e20ee16Smrg    stuff->face= tmp;
4210e20ee16Smrg
4220e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4230e20ee16Smrg    else 						*tmp++= '\0';
4240e20ee16Smrg    stuff->weight= tmp;
4250e20ee16Smrg
4260e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4270e20ee16Smrg    else						*tmp++= '\0';
4280e20ee16Smrg    stuff->slant= tmp;
4290e20ee16Smrg
4300e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4310e20ee16Smrg    else						*tmp++= '\0';
4320e20ee16Smrg    stuff->setWidth= tmp;
4330e20ee16Smrg
4340e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4350e20ee16Smrg    else						*tmp++= '\0';
4360e20ee16Smrg    stuff->variant= tmp;
4370e20ee16Smrg
4380e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4390e20ee16Smrg    else						*tmp++= '\0';
4400e20ee16Smrg    if (*tmp=='*')					stuff->pixelSize= 0;
4410e20ee16Smrg    else if (sscanf(tmp,"%i",&stuff->pixelSize)!=1)	goto BAILOUT;
4420e20ee16Smrg
4430e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4440e20ee16Smrg    else 						*tmp++= '\0';
4450e20ee16Smrg    if (*tmp=='*')					stuff->ptSize= 0;
4460e20ee16Smrg    else if (sscanf(tmp,"%i",&stuff->ptSize)!=1)	goto BAILOUT;
4470e20ee16Smrg
4480e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4490e20ee16Smrg    else						*tmp++= '\0';
4500e20ee16Smrg    if (*tmp=='*')					stuff->resX= 0;
4510e20ee16Smrg    else if (sscanf(tmp,"%i",&stuff->resX)!=1)		goto BAILOUT;
4520e20ee16Smrg
4530e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4540e20ee16Smrg    else 						*tmp++= '\0';
4550e20ee16Smrg    if (*tmp=='*')					stuff->resY= 0;
4560e20ee16Smrg    else if (sscanf(tmp,"%i",&stuff->resY)!=1)		goto BAILOUT;
4570e20ee16Smrg
4580e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4590e20ee16Smrg    else						*tmp++= '\0';
4600e20ee16Smrg    stuff->spacing= tmp;
4610e20ee16Smrg
4620e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4630e20ee16Smrg    else						*tmp++= '\0';
4640e20ee16Smrg    if (*tmp=='*')					stuff->avgWidth= 0;
4650e20ee16Smrg    else if (sscanf(tmp,"%i",&stuff->avgWidth)!=1)	goto BAILOUT;
4660e20ee16Smrg
4670e20ee16Smrg    if ((tmp= index(tmp,'-'))==NULL)			goto BAILOUT;
4680e20ee16Smrg    else						 *tmp++= '\0';
4690e20ee16Smrg    stuff->encoding= tmp;
4700e20ee16Smrg    return True;
4710e20ee16SmrgBAILOUT:
4720e20ee16Smrg    ClearFontStuff(stuff);
4730e20ee16Smrg    return False;
4740e20ee16Smrg}
4750e20ee16Smrg
4760e20ee16Smrgstatic void
4770e20ee16SmrgPSSetUpForLatin1(FILE *out, PSState *state)
4780e20ee16Smrg{
4790e20ee16Smrg    fprintf(out,"save\n");
4800e20ee16Smrg    fprintf(out,"/ISOLatin1Encoding where {pop save true}{false} ifelse\n");
4810e20ee16Smrg    fprintf(out,"/ISOLatin1Encoding [\n");
4820e20ee16Smrg    fprintf(out,"   /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
4830e20ee16Smrg    fprintf(out,"   /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
4840e20ee16Smrg    fprintf(out,"   /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
4850e20ee16Smrg    fprintf(out,"   /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
4860e20ee16Smrg    fprintf(out,"   /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
4870e20ee16Smrg    fprintf(out,"   /.notdef /.notdef /space /exclam /quotedbl /numbersign\n");
4880e20ee16Smrg    fprintf(out,"   /dollar /percent /ampersand /quoteright /parenleft\n");
4890e20ee16Smrg    fprintf(out,"   /parenright /asterisk /plus /comma /minus /period\n");
4900e20ee16Smrg    fprintf(out,"   /slash /zero /one /two /three /four /five /six /seven\n");
4910e20ee16Smrg    fprintf(out,"   /eight /nine /colon /semicolon /less /equal /greater\n");
4920e20ee16Smrg    fprintf(out,"   /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M\n");
4930e20ee16Smrg    fprintf(out,"   /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft\n");
4940e20ee16Smrg    fprintf(out,"   /backslash /bracketright /asciicircum /underscore\n");
4950e20ee16Smrg    fprintf(out,"   /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m\n");
4960e20ee16Smrg    fprintf(out,"   /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft\n");
4970e20ee16Smrg    fprintf(out,"   /bar /braceright /asciitilde /guilsinglright /fraction\n");
4980e20ee16Smrg    fprintf(out,"   /florin /quotesingle /quotedblleft /guilsinglleft /fi\n");
4990e20ee16Smrg    fprintf(out,"   /fl /endash /dagger /daggerdbl /bullet /quotesinglbase\n");
5000e20ee16Smrg    fprintf(out,"   /quotedblbase /quotedblright /ellipsis /trademark\n");
5010e20ee16Smrg    fprintf(out,"   /perthousand /grave /scaron /circumflex /Scaron /tilde\n");
5020e20ee16Smrg    fprintf(out,"   /breve /zcaron /dotaccent /dotlessi /Zcaron /ring\n");
5030e20ee16Smrg    fprintf(out,"   /hungarumlaut /ogonek /caron /emdash /space /exclamdown\n");
5040e20ee16Smrg    fprintf(out,"   /cent /sterling /currency /yen /brokenbar /section\n");
5050e20ee16Smrg    fprintf(out,"   /dieresis /copyright /ordfeminine /guillemotleft\n");
5060e20ee16Smrg    fprintf(out,"   /logicalnot /hyphen /registered /macron /degree\n");
5070e20ee16Smrg    fprintf(out,"   /plusminus /twosuperior /threesuperior /acute /mu\n");
5080e20ee16Smrg    fprintf(out,"   /paragraph /periodcentered /cedilla /onesuperior\n");
5090e20ee16Smrg    fprintf(out,"   /ordmasculine /guillemotright /onequarter /onehalf\n");
5100e20ee16Smrg    fprintf(out,"   /threequarters /questiondown /Agrave /Aacute\n");
5110e20ee16Smrg    fprintf(out,"   /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n");
5120e20ee16Smrg    fprintf(out,"   /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute\n");
5130e20ee16Smrg    fprintf(out,"   /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute\n");
5140e20ee16Smrg    fprintf(out,"   /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n");
5150e20ee16Smrg    fprintf(out,"   /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n");
5160e20ee16Smrg    fprintf(out,"   /germandbls /agrave /aacute /acircumflex /atilde\n");
5170e20ee16Smrg    fprintf(out,"   /adieresis /aring /ae /ccedilla /egrave /eacute\n");
5180e20ee16Smrg    fprintf(out,"   /ecircumflex /edieresis /igrave /iacute /icircumflex\n");
5190e20ee16Smrg    fprintf(out,"   /idieresis /eth /ntilde /ograve /oacute /ocircumflex\n");
5200e20ee16Smrg    fprintf(out,"   /otilde /odieresis /divide /oslash /ugrave /uacute\n");
5210e20ee16Smrg    fprintf(out,"   /ucircumflex /udieresis /yacute /thorn /ydieresis\n");
5220e20ee16Smrg    fprintf(out,"] def {restore} if\n");
5230e20ee16Smrg    fprintf(out,"/reencodeISO-1 {\n");
5240e20ee16Smrg    fprintf(out,"    dup length dict begin\n");
5250e20ee16Smrg    fprintf(out,"        {1 index /FID ne {def}{pop pop} ifelse} forall\n");
5260e20ee16Smrg    fprintf(out,"        /Encoding ISOLatin1Encoding def\n");
5270e20ee16Smrg    fprintf(out,"        currentdict\n");
5280e20ee16Smrg    fprintf(out,"    end\n");
5290e20ee16Smrg    fprintf(out,"} def\n");
5300e20ee16Smrg}
5310e20ee16Smrg
5320e20ee16Smrgstatic void
5330e20ee16SmrgPSReencodeLatin1Font(FILE *out, char *font)
5340e20ee16Smrg{
5350e20ee16Smrg    fprintf(out,"/%s findfont reencodeISO-1\n",font);
5360e20ee16Smrg    fprintf(out,"	/%s-8859-1 exch definefont pop\n",font);
5370e20ee16Smrg    return;
5380e20ee16Smrg}
5390e20ee16Smrg
5400e20ee16Smrgstatic void
5410e20ee16SmrgPSSetUpFonts(FILE *out, char *textFont, int size)
5420e20ee16Smrg{
5430e20ee16Smrg    fprintf(out,"/F%d { /%s findfont exch scalefont setfont } def\n",
5440e20ee16Smrg						FONT_TEXT,textFont);
5450e20ee16Smrg    fprintf(out,"/F%d { /%s-8859-1 findfont exch scalefont setfont } def\n",
5460e20ee16Smrg						FONT_LATIN1,textFont);
5470e20ee16Smrg    fprintf(out,"/F%d { /%s findfont exch scalefont setfont } def\n",
5480e20ee16Smrg						FONT_SYMBOL,"Symbol");
5490e20ee16Smrg    fprintf(out,"/F%d { /%s findfont exch scalefont setfont } def\n",
5500e20ee16Smrg						FONT_ISOCAPS,"IsoKeyCaps");
5510e20ee16Smrg    return;
5520e20ee16Smrg}
5530e20ee16Smrg
5540e20ee16Smrgstatic void
5550e20ee16SmrgPSSetFont(FILE *out, PSState *state, int font, int size, int pts)
5560e20ee16Smrg{
5570e20ee16Smrg    if ((state->font!=font)||(state->fontSize!=size)) {
5580e20ee16Smrg	fprintf(out,"%d %sF%d\n",size,(pts?"pts ":""),font);
5590e20ee16Smrg	state->font= font;
5600e20ee16Smrg	state->fontSize= size;
5610e20ee16Smrg    }
5620e20ee16Smrg    return;
5630e20ee16Smrg}
5640e20ee16Smrg
5650e20ee16Smrg
5660e20ee16Smrgstatic void
5670e20ee16SmrgPSProlog(FILE *out, PSState *state)
5680e20ee16Smrg{
5690e20ee16Smrgregister int	i;
5700e20ee16Smrg
5710e20ee16Smrg    if (!state->args->wantEPS) {
5720e20ee16Smrg	fprintf(out,"%%!PS-Adobe-2.0\n");
5730e20ee16Smrg	fprintf(out,"%%%%Creator: xkbprint\n");
5740e20ee16Smrg	if (state->geom->name!=None)
5750e20ee16Smrg	    fprintf(out,"%%%%Title: %s\n",
5760e20ee16Smrg				XkbAtomGetString(state->dpy,state->geom->name));
5770e20ee16Smrg	fprintf(out,"%%%%BoundingBox: (atend)\n");
5780e20ee16Smrg	fprintf(out,"%%%%Pages: 1\n");
5790e20ee16Smrg	fprintf(out,"%%%%PageOrder: Ascend\n");
5800e20ee16Smrg	fprintf(out,"%%%%DocumentFonts: (atend)\n");
5810e20ee16Smrg	fprintf(out,"%%%%DocumentData: Clean7Bit\n");
5820e20ee16Smrg	fprintf(out,"%%%%Orientation: Landscape\n");
5830e20ee16Smrg	fprintf(out,"%%%%EndComments\n");
5840e20ee16Smrg	fprintf(out,"%%%%BeginProlog\n");
5850e20ee16Smrg	fprintf(out,"%% Resolution is 1/10mm -- need pt sizes for fonts\n");
5860e20ee16Smrg	fprintf(out,"clippath pathbbox\n");
5870e20ee16Smrg	fprintf(out,"    /ury exch def /urx exch def\n");
5880e20ee16Smrg	fprintf(out,"    /llx exch def /lly exch def\n");
5890e20ee16Smrg	fprintf(out,"    newpath\n");
5900e20ee16Smrg	fprintf(out,"/devwidth  urx llx sub def\n");
5910e20ee16Smrg	fprintf(out,"/devheight ury lly sub def\n");
5920e20ee16Smrg    }
5930e20ee16Smrg    else {
5940e20ee16Smrg	int w,h;
5950e20ee16Smrg	int pw,ph;
5960e20ee16Smrg
5970e20ee16Smrg	w= (((state->geom->width_mm*72)/254)*11)/10;
5980e20ee16Smrg	h= (((state->geom->height_mm*72)/254)*11)/10;
5990e20ee16Smrg	if (state->kbPerPage>1)
6000e20ee16Smrg	    h*= (state->kbPerPage+1);
6010e20ee16Smrg
6020e20ee16Smrg	if (w<=h) {
6030e20ee16Smrg	    pw= 7.5*72;
6040e20ee16Smrg	    ph= 10*72;
6050e20ee16Smrg	}
6060e20ee16Smrg	else {
6070e20ee16Smrg	    pw= 10*72;
6080e20ee16Smrg	    ph= 7.5*72;
6090e20ee16Smrg	}
6100e20ee16Smrg	while ((w>pw)||(h>ph)) {
6110e20ee16Smrg	   w= (w*9)/10;
6120e20ee16Smrg	   h= (h*9)/10;
6130e20ee16Smrg	}
6140e20ee16Smrg
6150e20ee16Smrg	fprintf(out,"%%!PS-Adobe-2.0 EPSF-2.0\n");
6160e20ee16Smrg	fprintf(out,"%%%%BoundingBox: 0 0 %d %d\n",w,h);
6170e20ee16Smrg	fprintf(out,"%%%%Creator: xkbprint\n");
6180e20ee16Smrg	if (state->geom->name!=None)
6190e20ee16Smrg	    fprintf(out,"%%%%Title: %s\n",
6200e20ee16Smrg				XkbAtomGetString(state->dpy,state->geom->name));
6210e20ee16Smrg	fprintf(out,"%%%%Pages: 1\n");
6220e20ee16Smrg	fprintf(out,"%%%%EndComments\n");
6230e20ee16Smrg	fprintf(out,"%%%%BeginProlog\n");
6240e20ee16Smrg	fprintf(out,"/ury 0 def /urx 0 def\n");
6250e20ee16Smrg	fprintf(out,"/llx %d def /lly %d def\n",w,h);
6260e20ee16Smrg	fprintf(out,"/devwidth %d def /devheight %d def\n",w,h);
6270e20ee16Smrg    }
6280e20ee16Smrg    fprintf(out,"/kbdwidth %d def\n",state->geom->width_mm);
6290e20ee16Smrg    fprintf(out,"/kbdheight %d def\n",state->geom->height_mm);
6300e20ee16Smrg    fprintf(out,"/pts { 254 mul 72 div } def\n");
6310e20ee16Smrg    fprintf(out,"/mm10 { 72 mul 254 div } def\n");
6320e20ee16Smrg    fprintf(out,"/landscape? {\n");
6330e20ee16Smrg    fprintf(out,"	devheight devwidth gt {\n");
6340e20ee16Smrg    fprintf(out,"		/pwidth devheight def /pheight devwidth def\n");
6350e20ee16Smrg    fprintf(out,"		0 devheight translate\n");
6360e20ee16Smrg    fprintf(out,"		-90 rotate\n");
6370e20ee16Smrg    fprintf(out,"	} {\n");
6380e20ee16Smrg    fprintf(out,"		/pwidth devwidth def /pheight devheight def\n");
6390e20ee16Smrg    fprintf(out,"	} ifelse\n");
6400e20ee16Smrg    fprintf(out,"	0 pheight translate\n");
6410e20ee16Smrg    fprintf(out,"	1 -1 scale\n");
6420e20ee16Smrg    fprintf(out,"} def\n");
6430e20ee16Smrg    fprintf(out,"/centeroffset {\n");
6440e20ee16Smrg    fprintf(out,"    /S     exch def\n");
6450e20ee16Smrg    fprintf(out,"    /HEIGHT exch def\n");
6460e20ee16Smrg    fprintf(out,"    /WIDTH exch def\n");
6470e20ee16Smrg    fprintf(out,"    S stringwidth /SH exch def /SW exch def\n");
6480e20ee16Smrg    fprintf(out,"    WIDTH SW sub 2 div\n");
6490e20ee16Smrg    fprintf(out,"    HEIGHT SH sub 2 div\n");
6500e20ee16Smrg    fprintf(out,"} def\n");
6510e20ee16Smrg    PSSetUpForLatin1(out,state);
6520e20ee16Smrg    PSReencodeLatin1Font(out,DFLT_LABEL_FONT);
6530e20ee16Smrg    if (state->args->wantColor) {
6540e20ee16Smrg	XkbGeometryPtr geom= state->geom;
6550e20ee16Smrg	for (i=0;i<geom->num_colors;i++) {
6560e20ee16Smrg	    PSColorDef(out,state,&geom->colors[i]);
6570e20ee16Smrg	}
6580e20ee16Smrg	if (state->black<0) {
6590e20ee16Smrg	    XkbColorPtr	color;
6600e20ee16Smrg	    if (!(color= XkbAddGeomColor(geom,"black",geom->num_colors)))
6610e20ee16Smrg		uFatalError("Couldn't allocate black color!\n");
6620e20ee16Smrg	    PSColorDef(out,state,color);
6630e20ee16Smrg	}
6640e20ee16Smrg	if (state->white<0) {
6650e20ee16Smrg	    XkbColorPtr	color;
6660e20ee16Smrg	    if (!(color= XkbAddGeomColor(geom,"white",geom->num_colors)))
6670e20ee16Smrg		uFatalError("Couldn't allocate white color!\n");
6680e20ee16Smrg	    PSColorDef(out,state,color);
6690e20ee16Smrg	}
6700e20ee16Smrg    }
6710e20ee16Smrg    for (i=0;i<state->geom->num_shapes;i++) {
6720e20ee16Smrg	PSShapeDef(out,state,&state->geom->shapes[i]);
6730e20ee16Smrg    }
6740e20ee16Smrg    if (state->args->label==LABEL_SYMBOLS) {
6750e20ee16Smrg	PSIncludeFont(out,"IsoKeyCaps");
6760e20ee16Smrg    }
6770e20ee16Smrg    PSSetUpFonts(out,DFLT_LABEL_FONT, DFLT_LABEL_FONT_SIZE);
6780e20ee16Smrg    fprintf(out,"%%%%EndProlog\n");
6790e20ee16Smrg    return;
6800e20ee16Smrg}
6810e20ee16Smrg
6820e20ee16Smrgstatic void
6830e20ee16SmrgPSFileTrailer(FILE *out, PSState *state)
6840e20ee16Smrg{
6850e20ee16Smrg    fprintf(out,"restore\n");
6860e20ee16Smrg    if (!state->args->wantEPS)
6870e20ee16Smrg	fprintf(out,"%%%%Trailer\n");
6880e20ee16Smrg    fprintf(out,"%%%%EOF\n");
6890e20ee16Smrg#ifdef NOTYET
6900e20ee16Smrg    fprintf(out,"%%%%BoundingBox %d %d\n");
6910e20ee16Smrg    fprintf(out,"%%%%DocumentFonts: \n");
6920e20ee16Smrg#endif
6930e20ee16Smrg    return;
6940e20ee16Smrg}
6950e20ee16Smrg
6960e20ee16Smrgstatic void
6970e20ee16SmrgPSPageSetup(FILE *out, PSState *state, Bool drawBorder)
6980e20ee16Smrg{
6990e20ee16SmrgXkbGeometryPtr	geom;
7000e20ee16Smrg
7010e20ee16Smrg    geom= state->geom;
7020e20ee16Smrg    if (state->kbPerPage==1) {
7030e20ee16Smrg	fprintf(out,"%%%%Page: %d %d\n",state->nPages+1,state->nPages+1);
7040e20ee16Smrg	fprintf(out,"%%%%BeginPageSetup\n");
7050e20ee16Smrg    }
7060e20ee16Smrg    else if ((state->nPages&1)==0) { /* even page */
7070e20ee16Smrg	int realPage;
7080e20ee16Smrg	realPage= state->nPages/2+1;
7090e20ee16Smrg	fprintf(out,"%%%%Page: %d %d\n",realPage,realPage);
7100e20ee16Smrg	fprintf(out,"%%%%BeginPageSetup\n");
7110e20ee16Smrg	fprintf(out,"%% Keyboard %d\n",state->nPages+1);
7120e20ee16Smrg	if (state->nPages==0) {
7130e20ee16Smrg	    fprintf(out,"/realwidth devwidth def\n");
7140e20ee16Smrg	    fprintf(out,"/realheight devheight def\n");
7150e20ee16Smrg	    fprintf(out,"/devheight realheight 3 div def\n");
7160e20ee16Smrg	}
7170e20ee16Smrg	fprintf(out,"0 devheight dup 2 div add translate\n");
7180e20ee16Smrg    }
7190e20ee16Smrg    else  {
7200e20ee16Smrg	fprintf(out,"%% Keyboard %d\n",state->nPages+1);
7210e20ee16Smrg    }
7220e20ee16Smrg    fprintf(out,"save\n");
7230e20ee16Smrg    fprintf(out,"landscape?\n");
7240e20ee16Smrg    if (state->args->scaleToFit) {
7250e20ee16Smrg	fprintf(out,"%% Scale keyboard to fit on the page\n");
7260e20ee16Smrg	fprintf(out,"/kbdscale pwidth 72 sub kbdwidth div def\n");
7270e20ee16Smrg	fprintf(out,"/kbdscalewidth kbdwidth kbdscale mul def\n");
7280e20ee16Smrg	fprintf(out,"/kbdscaleheight kbdheight kbdscale mul def\n");
7290e20ee16Smrg	fprintf(out,"/kbx 36 def\n");
7300e20ee16Smrg	fprintf(out,"/kby pheight kbdscaleheight sub 2 div def\n");
7310e20ee16Smrg	PSGSave(out,state);
7320e20ee16Smrg	fprintf(out,"kbx kby translate\n");
7330e20ee16Smrg	fprintf(out,"kbdscale kbdscale scale\n");
7340e20ee16Smrg    }
7350e20ee16Smrg    else {
7360e20ee16Smrg	fprintf(out,"%% Draw keyboard full size\n");
7370e20ee16Smrg	fprintf(out,"/kbdscale 1 def\n");
7380e20ee16Smrg	fprintf(out,"/kbdscalewidth kbdwidth mm10 def\n");
7390e20ee16Smrg	fprintf(out,"/kbdscaleheight kbdheight mm10 def\n");
7400e20ee16Smrg	fprintf(out,"/kbx pwidth kbdscalewidth sub 2 div def\n");
7410e20ee16Smrg	fprintf(out,"/kby pheight kbdscaleheight sub 2 div def\n");
7420e20ee16Smrg	PSGSave(out,state);
7430e20ee16Smrg	fprintf(out,"kbx kby translate\n");
7440e20ee16Smrg	fprintf(out,"72 254 div dup scale\n");
7450e20ee16Smrg    }
7460e20ee16Smrg    if (drawBorder) {
7470e20ee16Smrg	if (state->args->wantColor) {
7480e20ee16Smrg	    PSSetColor(out,state,geom->base_color->pixel);
7490e20ee16Smrg	    fprintf(out,"  0   0 moveto\n");
7500e20ee16Smrg	    fprintf(out,"%3d   0 lineto\n",geom->width_mm);
7510e20ee16Smrg	    fprintf(out,"%3d %3d lineto\n",geom->width_mm,geom->height_mm);
7520e20ee16Smrg	    fprintf(out,"  0 %3d lineto\n",geom->height_mm);
7530e20ee16Smrg	    fprintf(out,"closepath fill\n");
7540e20ee16Smrg	}
7550e20ee16Smrg	PSSetColor(out,state,state->black);
7560e20ee16Smrg	fprintf(out,"  0   0 moveto\n");
7570e20ee16Smrg	fprintf(out,"%3d   0 lineto\n",geom->width_mm);
7580e20ee16Smrg    	fprintf(out,"%3d %3d lineto\n",geom->width_mm,geom->height_mm);
7590e20ee16Smrg	fprintf(out,"  0 %3d lineto\n",geom->height_mm);
7600e20ee16Smrg	fprintf(out,"closepath stroke\n");
7610e20ee16Smrg    }
7620e20ee16Smrg    fprintf(out,"%%%%EndPageSetup\n");
7630e20ee16Smrg    return;
7640e20ee16Smrg}
7650e20ee16Smrg
7660e20ee16Smrgstatic void
7670e20ee16SmrgPSPageTrailer(FILE *out, PSState *state)
7680e20ee16Smrg{
7690e20ee16Smrgchar *		name;
7700e20ee16SmrgXkbDescPtr	xkb;
7710e20ee16SmrgXkbGeometryPtr	geom;
7720e20ee16SmrgXkbPropertyPtr	prop;
7730e20ee16Smrgint		p,baseline;
7740e20ee16Smrg
7750e20ee16Smrg    xkb= state->xkb;
7760e20ee16Smrg    geom= state->geom;
7770e20ee16Smrg    if (state->args->grid>0) {
7780e20ee16Smrg	fprintf(out,"%% Draw a %dmm grid\n",state->args->grid);
7790e20ee16Smrg	fprintf(out,"0 setlinewidth\n");
7800e20ee16Smrg	fprintf(out,"0.25 setgray\n");
7810e20ee16Smrg	fprintf(out," 0 %d %d {\n",state->args->grid*10,geom->width_mm);
7820e20ee16Smrg	fprintf(out,"    /GX exch def\n");
7830e20ee16Smrg	fprintf(out,"    GX 0 moveto GX %d lineto stroke\n",geom->height_mm);
7840e20ee16Smrg	fprintf(out,"} for\n");
7850e20ee16Smrg	fprintf(out," 0 %d %d {\n",state->args->grid*10,geom->height_mm);
7860e20ee16Smrg	fprintf(out,"    /GY exch def\n");
7870e20ee16Smrg	fprintf(out,"    0 GY moveto %d GY lineto stroke\n",geom->width_mm);
7880e20ee16Smrg	fprintf(out,"} for\n");
7890e20ee16Smrg    }
7900e20ee16Smrg    PSGRestore(out,state);
7910e20ee16Smrg    name= NULL;
7920e20ee16Smrg    for (p=0,prop=geom->properties;p<geom->num_properties;p++,prop++) {
7930e20ee16Smrg	if ((prop->value!=NULL)&&(uStrCaseEqual(prop->name,"description"))) {
7940e20ee16Smrg	    name= prop->value;
7950e20ee16Smrg	    break;
7960e20ee16Smrg	}
7970e20ee16Smrg    }
7980e20ee16Smrg    if ((!state->args->wantEPS)&&
7990e20ee16Smrg			((state->kbPerPage==1)||((state->nPages&1)==1)||
8000e20ee16Smrg					(state->nPages==state->totalKB))) {
8010e20ee16Smrg	if ((name==NULL)&&(geom->name!=None))
8020e20ee16Smrg	    name= XkbAtomGetString(state->dpy,geom->name);
8030e20ee16Smrg
8040e20ee16Smrg	baseline= 16;
8050e20ee16Smrg	if ((name!=NULL)||(state->args->label==LABEL_SYMBOLS)) {
8060e20ee16Smrg	    PSSetColor(out,state,state->black);
8070e20ee16Smrg	    PSSetFont(out,state,FONT_LATIN1,14,False);
8080e20ee16Smrg	}
8090e20ee16Smrg	if (state->args->label==LABEL_SYMBOLS) {
8100e20ee16Smrg	    char buf[40],*sName= NULL, *lbuf;
8110e20ee16Smrg	    Atom sAtom;
8120e20ee16Smrg
8130e20ee16Smrg	    if (state->args->nLabelGroups==1)
8140e20ee16Smrg		sprintf(buf,"Group %d",state->args->baseLabelGroup+1);
8150e20ee16Smrg	    else sprintf(buf,"Groups %d-%d",state->args->baseLabelGroup+1,
8160e20ee16Smrg		state->args->baseLabelGroup+state->args->nLabelGroups);
8170e20ee16Smrg	    fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",buf);
8180e20ee16Smrg	    fprintf(out,"    kby kbdscaleheight add %d add\n",baseline);
8190e20ee16Smrg	    fprintf(out,"    moveto\n");
8200e20ee16Smrg	    fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",buf);
8210e20ee16Smrg	    baseline+= 16;
8220e20ee16Smrg
8230e20ee16Smrg	    if (xkb->names!=NULL)	sAtom= xkb->names->symbols;
8240e20ee16Smrg	    else			sAtom= None;
8250e20ee16Smrg	    if (sAtom!=None)
8260e20ee16Smrg		sName= XkbAtomGetString(state->dpy,sAtom);
8270e20ee16Smrg	    if (sName==NULL)
8280e20ee16Smrg		sName= "(unknown)";
8290e20ee16Smrg
8300e20ee16Smrg	    lbuf = uAlloc(10+strlen(sName));
8310e20ee16Smrg	    if (!lbuf) {
8320e20ee16Smrg	    	uFatalError("Can't allocate memory for string\n");
8330e20ee16Smrg	    }
8340e20ee16Smrg	    sprintf(lbuf,"Layout: %s",sName);
8350e20ee16Smrg	    fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",lbuf);
8360e20ee16Smrg	    fprintf(out,"    kby kbdscaleheight add %d add\n",baseline);
8370e20ee16Smrg	    fprintf(out,"    moveto\n");
8380e20ee16Smrg	    fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",lbuf);
8390e20ee16Smrg	    baseline+= 16;
8400e20ee16Smrg	    free(lbuf);
8410e20ee16Smrg	}
8420e20ee16Smrg	if (name!=NULL) {
8430e20ee16Smrg	    fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",name);
8440e20ee16Smrg	    fprintf(out,"    kby kbdscaleheight add %d add\n",baseline);
8450e20ee16Smrg	    fprintf(out,"    moveto\n");
8460e20ee16Smrg	    fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",name);
8470e20ee16Smrg	    baseline+= 16;
8480e20ee16Smrg	}
8490e20ee16Smrg	if (state->args->label==LABEL_KEYCODE) {
8500e20ee16Smrg	    char *sName= NULL, *lbuf;
8510e20ee16Smrg	    Atom sAtom;
8520e20ee16Smrg
8530e20ee16Smrg	    if (xkb->names!=NULL)	sAtom= xkb->names->keycodes;
8540e20ee16Smrg	    else			sAtom= None;
8550e20ee16Smrg	    if (sAtom!=None)
8560e20ee16Smrg		sName= XkbAtomGetString(state->dpy,sAtom);
8570e20ee16Smrg	    if (sName==NULL)
8580e20ee16Smrg		sName= "(unknown)";
8590e20ee16Smrg
8600e20ee16Smrg	    lbuf = uAlloc(12+strlen(sName));
8610e20ee16Smrg	    if (!lbuf) {
8620e20ee16Smrg	    	uFatalError("Can't allocate memory for string\n");
8630e20ee16Smrg	    }
8640e20ee16Smrg	    sprintf(lbuf,"Keycodes: %s",sName);
8650e20ee16Smrg	    fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",lbuf);
8660e20ee16Smrg	    fprintf(out,"    kby kbdscaleheight add %d add\n",baseline);
8670e20ee16Smrg	    fprintf(out,"    moveto\n");
8680e20ee16Smrg	    fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",lbuf);
8690e20ee16Smrg	    baseline+= 16;
8700e20ee16Smrg	    free(lbuf);
8710e20ee16Smrg	}
8720e20ee16Smrg	if (state->args->copies>1) {
8730e20ee16Smrg	    for (p=1;p<state->args->copies;p++)
8740e20ee16Smrg		fprintf(out,"copypage\n");
8750e20ee16Smrg	}
8760e20ee16Smrg	fprintf(out,"showpage\n");
8770e20ee16Smrg	fprintf(out,"restore\n");
8780e20ee16Smrg	fprintf(out,"%% Done with keyboard/page %d\n",state->nPages+1);
8790e20ee16Smrg    }
8800e20ee16Smrg    else {
8810e20ee16Smrg	if ((!state->args->wantEPS)&&(state->args->label==LABEL_SYMBOLS)) {
8820e20ee16Smrg	    char buf[40];
8830e20ee16Smrg	    baseline= 16;
8840e20ee16Smrg	    PSSetColor(out,state,state->black);
8850e20ee16Smrg	    PSSetFont(out,state,FONT_LATIN1,14,False);
8860e20ee16Smrg	    if (state->args->nLabelGroups==1)
8870e20ee16Smrg		sprintf(buf,"Group %d",state->args->baseLabelGroup+1);
8880e20ee16Smrg	    else sprintf(buf,"Groups %d-%d",state->args->baseLabelGroup+1,
8890e20ee16Smrg		state->args->baseLabelGroup+state->args->nLabelGroups+1);
8900e20ee16Smrg	    fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",buf);
8910e20ee16Smrg	    fprintf(out,"    kby kbdscaleheight add %d add\n",baseline);
8920e20ee16Smrg	    fprintf(out,"    moveto\n");
8930e20ee16Smrg	    fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",buf);
8940e20ee16Smrg	    baseline+= 16;
8950e20ee16Smrg	}
8960e20ee16Smrg	fprintf(out,"restore\n");
8970e20ee16Smrg	fprintf(out,"%% Done with keyboard %d\n",state->nPages+1);
8980e20ee16Smrg	fprintf(out,"0 devheight -1 mul translate %% next keyboard\n");
8990e20ee16Smrg    }
9000e20ee16Smrg    state->nPages++;
9010e20ee16Smrg    state->color= state->black;
9020e20ee16Smrg    state->font= -1;
9030e20ee16Smrg    return;
9040e20ee16Smrg}
9050e20ee16Smrg
9060e20ee16Smrgstatic void
9070e20ee16SmrgPSDoodad(FILE *out, PSState *state, XkbDoodadPtr doodad)
9080e20ee16Smrg{
9090e20ee16SmrgXkbDescPtr	xkb;
9100e20ee16Smrgchar		*name,*dname;
9110e20ee16Smrgint		sz,leading;
9120e20ee16Smrg
9130e20ee16Smrg    xkb= state->xkb;
9140e20ee16Smrg    if (doodad->any.name!=None)
9150e20ee16Smrg	 dname= XkbAtomGetString(xkb->dpy,doodad->any.name);
9160e20ee16Smrg    else dname= "NoName";
9170e20ee16Smrg    switch (doodad->any.type) {
9180e20ee16Smrg	case XkbOutlineDoodad:
9190e20ee16Smrg	case XkbSolidDoodad:
9200e20ee16Smrg	    name= XkbAtomGetString(xkb->dpy,
9210e20ee16Smrg			XkbShapeDoodadShape(xkb->geom,&doodad->shape)->name);
9220e20ee16Smrg	    if (state->args->wantColor) {
9230e20ee16Smrg		PSSetColor(out,state,doodad->shape.color_ndx);
9240e20ee16Smrg		if (doodad->any.type!=XkbOutlineDoodad) {
9250e20ee16Smrg		    fprintf(out,"true %d %d %d %s %% Doodad %s\n",
9260e20ee16Smrg					doodad->shape.angle,
9270e20ee16Smrg					doodad->shape.left,doodad->shape.top,
9280e20ee16Smrg					name,dname);
9290e20ee16Smrg		    PSSetColor(out,state,state->black);
9300e20ee16Smrg		}
9310e20ee16Smrg		fprintf(out,"false %d %d %d %s %% Doodad %s\n",
9320e20ee16Smrg			doodad->shape.angle,
9330e20ee16Smrg			doodad->shape.left,doodad->shape.top,
9340e20ee16Smrg			name,dname);
9350e20ee16Smrg	    }
9360e20ee16Smrg	    else {
9370e20ee16Smrg		fprintf(out,"false %d %d %d %s %% Doodad %s\n",
9380e20ee16Smrg			doodad->shape.angle,
9390e20ee16Smrg			doodad->shape.left,doodad->shape.top,
9400e20ee16Smrg			name,dname);
9410e20ee16Smrg	    }
9420e20ee16Smrg	    break;
9430e20ee16Smrg	case XkbTextDoodad:
9440e20ee16Smrg	    fprintf(out,"%% Doodad %s\n",dname);
9450e20ee16Smrg	    PSSetColor(out,state,doodad->text.color_ndx);
9460e20ee16Smrg	    PSGSave(out,state);
9470e20ee16Smrg	    fprintf(out,"%d %d translate\n",doodad->text.left,doodad->text.top);
9480e20ee16Smrg	    if (doodad->text.angle!=0)
9490e20ee16Smrg		fprintf(out,"%s rotate\n",
9500e20ee16Smrg				XkbGeomFPText(doodad->text.angle,XkbMessage));
9510e20ee16Smrg	    sz= 14;
9520e20ee16Smrg	    if (doodad->text.font) {
9530e20ee16Smrg		FontStuff stuff;
9540e20ee16Smrg		if (CrackXLFDName(doodad->text.font,&stuff)) {
9550e20ee16Smrg		    if (stuff.ptSize>0)
9560e20ee16Smrg			sz= stuff.ptSize/10;
9570e20ee16Smrg		    ClearFontStuff(&stuff);
9580e20ee16Smrg		}
9590e20ee16Smrg	    }
9600e20ee16Smrg	    PSSetFont(out,state,FONT_LATIN1,sz,True);
9610e20ee16Smrg	    leading= (sz*12)/10;
9620e20ee16Smrg	    if (strchr(doodad->text.text,'\n')==NULL) {
9630e20ee16Smrg		fprintf(out,"0 %d pts moveto 1 -1 scale\n",(leading*8)/10);
9640e20ee16Smrg		fprintf(out,"(%s) show\n",doodad->text.text);
9650e20ee16Smrg	    }
9660e20ee16Smrg	    else {
9670e20ee16Smrg		char *tmp,*buf,*end;
9680e20ee16Smrg		int   offset= (leading*8/10);
9690e20ee16Smrg		tmp= buf= uStringDup(doodad->text.text);
9700e20ee16Smrg		while (tmp!=NULL) {
9710e20ee16Smrg		    end= strchr(tmp,'\n');
9720e20ee16Smrg		    if (end!=NULL)
9730e20ee16Smrg			*end++= '\0';
9740e20ee16Smrg		    fprintf(out,"0 %d pts moveto 1 -1 scale\n",offset);
9750e20ee16Smrg		    fprintf(out,"(%s) show 1 -1 scale\n",tmp);
9760e20ee16Smrg		    offset+= leading;
9770e20ee16Smrg		    tmp= end;
9780e20ee16Smrg		}
9790e20ee16Smrg		free(buf);
9800e20ee16Smrg	    }
9810e20ee16Smrg	    PSGRestore(out,state);
9820e20ee16Smrg	    break;
9830e20ee16Smrg	case XkbIndicatorDoodad:
9840e20ee16Smrg	    name= XkbAtomGetString(xkb->dpy,
9850e20ee16Smrg		XkbIndicatorDoodadShape(xkb->geom,&doodad->indicator)->name);
9860e20ee16Smrg	    if (state->args->wantColor) {
9870e20ee16Smrg		PSSetColor(out,state,doodad->indicator.off_color_ndx);
9880e20ee16Smrg		fprintf(out,"true 0 %d %d %s %% Doodad %s\n",
9890e20ee16Smrg			doodad->indicator.left,doodad->indicator.top,
9900e20ee16Smrg			name,dname);
9910e20ee16Smrg		PSSetColor(out,state,state->black);
9920e20ee16Smrg	    }
9930e20ee16Smrg	    fprintf(out,"false 0 %d %d %s %% Doodad %s\n",
9940e20ee16Smrg			doodad->indicator.left,doodad->indicator.top,
9950e20ee16Smrg			name,dname);
9960e20ee16Smrg	    break;
9970e20ee16Smrg	case XkbLogoDoodad:
9980e20ee16Smrg	    name= XkbAtomGetString(xkb->dpy,
9990e20ee16Smrg			XkbLogoDoodadShape(xkb->geom,&doodad->logo)->name);
10000e20ee16Smrg	    if (state->args->wantColor)
10010e20ee16Smrg		PSSetColor(out,state,doodad->shape.color_ndx);
10020e20ee16Smrg	    fprintf(out,"false %d %d %d %s %% Doodad %s\n",
10030e20ee16Smrg			doodad->shape.angle,
10040e20ee16Smrg			doodad->shape.left,doodad->shape.top,
10050e20ee16Smrg			name,dname);
10060e20ee16Smrg	    break;
10070e20ee16Smrg    }
10080e20ee16Smrg    return;
10090e20ee16Smrg}
10100e20ee16Smrg
10110e20ee16Smrg/***====================================================================***/
10120e20ee16Smrg
10130e20ee16Smrgstatic Bool
10140e20ee16SmrgPSKeycapsSymbol(KeySym sym, unsigned char *buf,
10150e20ee16Smrg		int *font_rtrn, int *sz_rtrn, PSState *state)
10160e20ee16Smrg{
10170e20ee16Smrg    if (state->args->wantSymbols==NO_SYMBOLS)
10180e20ee16Smrg	return False;
10190e20ee16Smrg
10200e20ee16Smrg    if (font_rtrn!=NULL)
10210e20ee16Smrg	*font_rtrn= FONT_ISOCAPS;
10220e20ee16Smrg    if (sz_rtrn!=NULL)
10230e20ee16Smrg	*sz_rtrn= SZ_LARGE;
10240e20ee16Smrg    buf[1]= '\0';
10250e20ee16Smrg    switch (sym) {
10260e20ee16Smrg	case XK_Shift_L: case XK_Shift_R:
10270e20ee16Smrg		buf[0]= XKC_ISO_Shift;		return True;
10280e20ee16Smrg	case XK_Shift_Lock:
10290e20ee16Smrg		buf[0]= XKC_ISO_Shift_Lock;	return True;
10300e20ee16Smrg	case XK_ISO_Lock:
10310e20ee16Smrg		buf[0]= XKC_ISO_Caps_Lock;	return True;
10320e20ee16Smrg	case XK_BackSpace:
10330e20ee16Smrg		buf[0]= XKC_ISO_Backspace;	return True;
10340e20ee16Smrg	case XK_Return:
10350e20ee16Smrg		buf[0]= XKC_ISO_Return;		return True;
10360e20ee16Smrg	case XK_Up: case XK_KP_Up:
10370e20ee16Smrg		buf[0]= XKC_ISO_Up;		return True;
10380e20ee16Smrg	case XK_Down: case XK_KP_Down:
10390e20ee16Smrg		buf[0]= XKC_ISO_Down;		return True;
10400e20ee16Smrg	case XK_Left: case XK_KP_Left:
10410e20ee16Smrg		buf[0]= XKC_ISO_Left;		return True;
10420e20ee16Smrg	case XK_Right: case XK_KP_Right:
10430e20ee16Smrg		buf[0]= XKC_ISO_Right;		return True;
10440e20ee16Smrg	case XK_Tab:
10450e20ee16Smrg		buf[0]= XKC_ISO_Tab;		return True;
10460e20ee16Smrg	case XK_ISO_Left_Tab:
10470e20ee16Smrg		buf[0]= XKC_ISO_Left_Tab;	return True;
10480e20ee16Smrg    }
10490e20ee16Smrg    if (state->args->wantSymbols!=ALL_SYMBOLS)
10500e20ee16Smrg	return False;
10510e20ee16Smrg    switch (sym) {
10520e20ee16Smrg	case XK_Caps_Lock:
10530e20ee16Smrg		buf[0]= XKC_ISO_Caps_Lock;	return True;
10540e20ee16Smrg	case XK_Num_Lock:
10550e20ee16Smrg		buf[0]= XKC_ISO_Num_Lock;	return True;
10560e20ee16Smrg	case XK_ISO_Level3_Shift:
10570e20ee16Smrg		buf[0]= XKC_ISO_Level3_Shift;	return True;
10580e20ee16Smrg	case XK_ISO_Level3_Lock:
10590e20ee16Smrg		buf[0]= XKC_ISO_Level3_Lock;	return True;
10600e20ee16Smrg	case XK_ISO_Next_Group: case XK_ISO_Group_Shift:
10610e20ee16Smrg		buf[0]= XKC_ISO_Next_Group;	return True;
10620e20ee16Smrg	case XK_ISO_Next_Group_Lock:
10630e20ee16Smrg		buf[0]= XKC_ISO_Next_Group_Lock;return True;
10640e20ee16Smrg	case XK_space:
10650e20ee16Smrg		buf[0]= XKC_ISO_Space;		return True;
10660e20ee16Smrg	case XK_nobreakspace:
10670e20ee16Smrg		buf[0]= XKC_ISO_No_Break_Space;	return True;
10680e20ee16Smrg	case XK_Insert:
10690e20ee16Smrg		buf[0]= XKC_ISO_Insert;		return True;
10700e20ee16Smrg	case XK_ISO_Continuous_Underline:
10710e20ee16Smrg		buf[0]= XKC_ISO_Continuous_Underline;return True;
10720e20ee16Smrg	case XK_ISO_Discontinuous_Underline:
10730e20ee16Smrg		buf[0]= XKC_ISO_Discontinuous_Underline;return True;
10740e20ee16Smrg	case XK_ISO_Emphasize:
10750e20ee16Smrg		buf[0]= XKC_ISO_Emphasize;	return True;
10760e20ee16Smrg	case XK_Multi_key:
10770e20ee16Smrg		buf[0]= XKC_ISO_Compose;	return True;
10780e20ee16Smrg	case XK_ISO_Center_Object:
10790e20ee16Smrg		buf[0]= XKC_ISO_Center_Object;	return True;
10800e20ee16Smrg	case XK_Delete:
10810e20ee16Smrg		buf[0]= XKC_ISO_Delete;		return True;
10820e20ee16Smrg	case XK_Clear:
10830e20ee16Smrg		buf[0]= XKC_ISO_Clear_Screen;	return True;
10840e20ee16Smrg	case XK_Scroll_Lock:
10850e20ee16Smrg		buf[0]= XKC_ISO_Scroll_Lock;	return True;
10860e20ee16Smrg	case XK_Help:
10870e20ee16Smrg		buf[0]= XKC_ISO_Help;		return True;
10880e20ee16Smrg	case XK_Print:
10890e20ee16Smrg		buf[0]= XKC_ISO_Print_Screen;	return True;
10900e20ee16Smrg	case XK_ISO_Enter:
10910e20ee16Smrg		buf[0]= XKC_ISO_Enter;		return True;
10920e20ee16Smrg	case XK_Alt_L: case XK_Alt_R:
10930e20ee16Smrg		buf[0]= XKC_ISO_Alt;		return True;
10940e20ee16Smrg	case XK_Control_L: case XK_Control_R:
10950e20ee16Smrg		buf[0]= XKC_ISO_Control;	return True;
10960e20ee16Smrg	case XK_Pause:
10970e20ee16Smrg		buf[0]= XKC_ISO_Pause;		return True;
10980e20ee16Smrg	case XK_Break:
10990e20ee16Smrg		buf[0]= XKC_ISO_Break;		return True;
11000e20ee16Smrg	case XK_Escape:
11010e20ee16Smrg		buf[0]= XKC_ISO_Escape;		return True;
11020e20ee16Smrg	case XK_Undo:
11030e20ee16Smrg		buf[0]= XKC_ISO_Undo;		return True;
11040e20ee16Smrg	case XK_ISO_Fast_Cursor_Up:
11050e20ee16Smrg		buf[0]= XKC_ISO_Fast_Cursor_Up;	return True;
11060e20ee16Smrg	case XK_ISO_Fast_Cursor_Down:
11070e20ee16Smrg		buf[0]= XKC_ISO_Fast_Cursor_Down;return True;
11080e20ee16Smrg	case XK_ISO_Fast_Cursor_Left:
11090e20ee16Smrg		buf[0]= XKC_ISO_Fast_Cursor_Left;return True;
11100e20ee16Smrg	case XK_ISO_Fast_Cursor_Right:
11110e20ee16Smrg		buf[0]= XKC_ISO_Fast_Cursor_Right;return True;
11120e20ee16Smrg	case XK_Home:
11130e20ee16Smrg		buf[0]= XKC_ISO_Home;		return True;
11140e20ee16Smrg	case XK_End:
11150e20ee16Smrg		buf[0]= XKC_ISO_End;		return True;
11160e20ee16Smrg	case XK_Page_Up:
11170e20ee16Smrg		buf[0]= XKC_ISO_Page_Up;	return True;
11180e20ee16Smrg	case XK_Page_Down:
11190e20ee16Smrg		buf[0]= XKC_ISO_Page_Down;	return True;
11200e20ee16Smrg	case XK_ISO_Move_Line_Up:
11210e20ee16Smrg		buf[0]= XKC_ISO_Move_Line_Up;	return True;
11220e20ee16Smrg	case XK_ISO_Move_Line_Down:
11230e20ee16Smrg		buf[0]= XKC_ISO_Move_Line_Down;	return True;
11240e20ee16Smrg	case XK_ISO_Partial_Line_Up:
11250e20ee16Smrg		buf[0]= XKC_ISO_Partial_Line_Up;return True;
11260e20ee16Smrg	case XK_ISO_Partial_Line_Down:
11270e20ee16Smrg		buf[0]= XKC_ISO_Partial_Line_Down;return True;
11280e20ee16Smrg	case XK_ISO_Partial_Space_Left:
11290e20ee16Smrg		buf[0]= XKC_ISO_Partial_Space_Left;return True;
11300e20ee16Smrg	case XK_ISO_Partial_Space_Right:
11310e20ee16Smrg		buf[0]= XKC_ISO_Partial_Space_Right;return True;
11320e20ee16Smrg	case XK_ISO_Set_Margin_Left:
11330e20ee16Smrg		buf[0]= XKC_ISO_Set_Margin_Left;return True;
11340e20ee16Smrg	case XK_ISO_Set_Margin_Right:
11350e20ee16Smrg		buf[0]= XKC_ISO_Set_Margin_Right;return True;
11360e20ee16Smrg	case XK_ISO_Release_Margin_Left:
11370e20ee16Smrg		buf[0]= XKC_ISO_Release_Margin_Left;return True;
11380e20ee16Smrg	case XK_ISO_Release_Margin_Right:
11390e20ee16Smrg		buf[0]= XKC_ISO_Release_Margin_Right;return True;
11400e20ee16Smrg	case XK_ISO_Release_Both_Margins:
11410e20ee16Smrg		buf[0]= XKC_ISO_Release_Both_Margins;return True;
11420e20ee16Smrg	case XK_ISO_Prev_Group:
11430e20ee16Smrg		buf[0]= XKC_ISO_Prev_Group;	return True;
11440e20ee16Smrg	case XK_ISO_Prev_Group_Lock:
11450e20ee16Smrg		buf[0]= XKC_ISO_Prev_Group_Lock;	return True;
11460e20ee16Smrg    }
11470e20ee16Smrg#ifdef NOTYET
11480e20ee16Smrg    if (font_rtrn!=NULL)
11490e20ee16Smrg	font_rtrn= FONT_MOUSECAPS;
11500e20ee16Smrg    switch (sym) {
11510e20ee16Smrg	case XK_Pointer_Up:
11520e20ee16Smrg		buf[0]= XKC_Mouse_Pointer_Up;	return True;
11530e20ee16Smrg	case XK_Pointer_Down:
11540e20ee16Smrg		buf[0]= XKC_Mouse_Pointer_Down;	return True;
11550e20ee16Smrg	case XK_Pointer_Left:
11560e20ee16Smrg		buf[0]= XKC_Mouse_Pointer_Left;	return True;
11570e20ee16Smrg	case XK_Pointer_Right:
11580e20ee16Smrg		buf[0]= XKC_Mouse_Pointer_Right;return True;
11590e20ee16Smrg	case XK_Pointer_Button1:
11600e20ee16Smrg		buf[0]= XKC_Mouse_Pointer_Button1;return True;
11610e20ee16Smrg	case XK_Pointer_Button2:
11620e20ee16Smrg		buf[0]= XKC_Mouse_Pointer_Button2;return True;
11630e20ee16Smrg	case XK_Pointer_Button3:
11640e20ee16Smrg		buf[0]= XKC_Mouse_Pointer_Button3;return True;
11650e20ee16Smrg	case XK_Pointer_Button4:
11660e20ee16Smrg		buf[0]= XKC_Mouse_Pointer_Button4;return True;
11670e20ee16Smrg    }
11680e20ee16Smrg#endif
11690e20ee16Smrg    return False;
11700e20ee16Smrg}
11710e20ee16Smrg
11720e20ee16Smrgstatic Bool
11730e20ee16SmrgPSNonLatin1Symbol(KeySym sym, unsigned char *buf,
11740e20ee16Smrg		  int *font_rtrn, int *sz_rtrn, PSState *state)
11750e20ee16Smrg{
11760e20ee16Smrg    if (state->args->wantSymbols==NO_SYMBOLS)
11770e20ee16Smrg	return False;
11780e20ee16Smrg
11790e20ee16Smrg    if (font_rtrn!=NULL)
11800e20ee16Smrg	*font_rtrn= FONT_TEXT;
11810e20ee16Smrg    if (sz_rtrn!=NULL)
11820e20ee16Smrg	*sz_rtrn= SZ_LARGE;
11830e20ee16Smrg    buf[1]= '\0';
11840e20ee16Smrg    switch (sym) {
11850e20ee16Smrg	case XK_breve:		buf[0]= 0xC6;	return True;
11860e20ee16Smrg	case XK_abovedot:	buf[0]= 0xC7;	return True;
11870e20ee16Smrg	case XK_doubleacute:	buf[0]= 0xCD;	return True;
11880e20ee16Smrg	case XK_ogonek:		buf[0]= 0xCE;	return True;
11890e20ee16Smrg	case XK_caron:		buf[0]= 0xCF;	return True;
11900e20ee16Smrg	case XK_Lstroke:	buf[0]= 0xE8;	return True;
11910e20ee16Smrg	case XK_idotless:	buf[0]= 0xF5;	return True;
11920e20ee16Smrg	case XK_lstroke:	buf[0]= 0xF8;	return True;
11930e20ee16Smrg    }
11940e20ee16Smrg    if (font_rtrn!=NULL)
11950e20ee16Smrg	*font_rtrn= FONT_SYMBOL;
11960e20ee16Smrg    if (sz_rtrn!=NULL)
11970e20ee16Smrg	*sz_rtrn= SZ_MEDIUM;
11980e20ee16Smrg    if ((sym&(~0xff))==0x700) {
11990e20ee16Smrg	switch (sym) {
12000e20ee16Smrg	    /* Greek symbol */
12010e20ee16Smrg	    case XK_Greek_ALPHA:	buf[0]= 0x41;	return True;
12020e20ee16Smrg	    case XK_Greek_BETA:		buf[0]= 0x42;	return True;
12030e20ee16Smrg	    case XK_Greek_CHI:		buf[0]= 0x43;	return True;
12040e20ee16Smrg	    case XK_Greek_DELTA:	buf[0]= 0x44;	return True;
12050e20ee16Smrg	    case XK_Greek_EPSILON:	buf[0]= 0x45;	return True;
12060e20ee16Smrg	    case XK_Greek_PHI:		buf[0]= 0x46;	return True;
12070e20ee16Smrg	    case XK_Greek_GAMMA:	buf[0]= 0x47;	return True;
12080e20ee16Smrg	    case XK_Greek_ETA:		buf[0]= 0x48;	return True;
12090e20ee16Smrg	    case XK_Greek_IOTA:		buf[0]= 0x49;	return True;
12100e20ee16Smrg	    case XK_Greek_KAPPA:	buf[0]= 0x4B;	return True;
12110e20ee16Smrg	    case XK_Greek_LAMDA:	buf[0]= 0x4C;	return True;
12120e20ee16Smrg	    case XK_Greek_MU:		buf[0]= 0x4D;	return True;
12130e20ee16Smrg	    case XK_Greek_NU:		buf[0]= 0x4E;	return True;
12140e20ee16Smrg	    case XK_Greek_OMICRON:	buf[0]= 0x4F;	return True;
12150e20ee16Smrg	    case XK_Greek_PI:		buf[0]= 0x50;	return True;
12160e20ee16Smrg	    case XK_Greek_THETA:	buf[0]= 0x51;	return True;
12170e20ee16Smrg	    case XK_Greek_RHO:		buf[0]= 0x52;	return True;
12180e20ee16Smrg	    case XK_Greek_SIGMA:	buf[0]= 0x53;	return True;
12190e20ee16Smrg	    case XK_Greek_TAU:		buf[0]= 0x54;	return True;
12200e20ee16Smrg	    case XK_Greek_UPSILON:	buf[0]= 0x55;	return True;
12210e20ee16Smrg	    case XK_Greek_OMEGA:	buf[0]= 0x57;	return True;
12220e20ee16Smrg	    case XK_Greek_XI:		buf[0]= 0x58;	return True;
12230e20ee16Smrg	    case XK_Greek_PSI:		buf[0]= 0x59;	return True;
12240e20ee16Smrg	    case XK_Greek_ZETA:		buf[0]= 0x5A;	return True;
12250e20ee16Smrg
12260e20ee16Smrg	    case XK_Greek_alpha:	buf[0]= 0x61;	return True;
12270e20ee16Smrg	    case XK_Greek_beta:		buf[0]= 0x62;	return True;
12280e20ee16Smrg	    case XK_Greek_chi:		buf[0]= 0x63;	return True;
12290e20ee16Smrg	    case XK_Greek_delta:	buf[0]= 0x64;	return True;
12300e20ee16Smrg	    case XK_Greek_epsilon:	buf[0]= 0x65;	return True;
12310e20ee16Smrg	    case XK_Greek_phi:		buf[0]= 0x66;	return True;
12320e20ee16Smrg	    case XK_Greek_gamma:	buf[0]= 0x67;	return True;
12330e20ee16Smrg	    case XK_Greek_eta:		buf[0]= 0x68;	return True;
12340e20ee16Smrg	    case XK_Greek_iota:		buf[0]= 0x69;	return True;
12350e20ee16Smrg	    case XK_Greek_kappa:	buf[0]= 0x6B;	return True;
12360e20ee16Smrg	    case XK_Greek_lamda:	buf[0]= 0x6C;	return True;
12370e20ee16Smrg	    case XK_Greek_mu:		buf[0]= 0x6D;	return True;
12380e20ee16Smrg	    case XK_Greek_nu:		buf[0]= 0x6E;	return True;
12390e20ee16Smrg	    case XK_Greek_omicron:	buf[0]= 0x6F;	return True;
12400e20ee16Smrg	    case XK_Greek_pi:		buf[0]= 0x70;	return True;
12410e20ee16Smrg	    case XK_Greek_theta:	buf[0]= 0x71;	return True;
12420e20ee16Smrg	    case XK_Greek_rho:		buf[0]= 0x72;	return True;
12430e20ee16Smrg	    case XK_Greek_sigma:	buf[0]= 0x73;	return True;
12440e20ee16Smrg	    case XK_Greek_tau:		buf[0]= 0x74;	return True;
12450e20ee16Smrg	    case XK_Greek_upsilon:	buf[0]= 0x75;	return True;
12460e20ee16Smrg	    case XK_Greek_omega:	buf[0]= 0x77;	return True;
12470e20ee16Smrg	    case XK_Greek_xi:		buf[0]= 0x78;	return True;
12480e20ee16Smrg	    case XK_Greek_psi:		buf[0]= 0x79;	return True;
12490e20ee16Smrg	    case XK_Greek_zeta:		buf[0]= 0x7A;	return True;
12500e20ee16Smrg	}
12510e20ee16Smrg    }
12520e20ee16Smrg    switch (sym) {
12530e20ee16Smrg	case XK_leftarrow:	buf[0]= 0xAC;	return True;
12540e20ee16Smrg	case XK_uparrow:	buf[0]= 0xAD;	return True;
12550e20ee16Smrg	case XK_rightarrow:	buf[0]= 0xAE;	return True;
12560e20ee16Smrg	case XK_downarrow:	buf[0]= 0xAF;	return True;
12570e20ee16Smrg	case XK_horizconnector:	buf[0]= 0xBE;	return True;
12580e20ee16Smrg	case XK_trademark:	buf[0]= 0xE4;	return True;
12590e20ee16Smrg    }
12600e20ee16Smrg    return False;
12610e20ee16Smrg}
12620e20ee16Smrg
12630e20ee16Smrgstatic KeySym
12640e20ee16SmrgCheckSymbolAlias(KeySym sym, PSState *state)
12650e20ee16Smrg{
12660e20ee16Smrg    if (XkbKSIsKeypad(sym)) {
12670e20ee16Smrg	if ((sym>=XK_KP_0)&&(sym<=XK_KP_9))
12680e20ee16Smrg	     sym= (sym-XK_KP_0)+XK_0;
12690e20ee16Smrg	else switch (sym) {
12700e20ee16Smrg		case XK_KP_Space:	return XK_space;
12710e20ee16Smrg		case XK_KP_Tab:		return XK_Tab;
12720e20ee16Smrg		case XK_KP_Enter:	return XK_Return;
12730e20ee16Smrg		case XK_KP_F1:		return XK_F1;
12740e20ee16Smrg		case XK_KP_F2:		return XK_F2;
12750e20ee16Smrg		case XK_KP_F3:		return XK_F3;
12760e20ee16Smrg		case XK_KP_F4:		return XK_F4;
12770e20ee16Smrg		case XK_KP_Home:	return XK_Home;
12780e20ee16Smrg		case XK_KP_Left:	return XK_Left;
12790e20ee16Smrg		case XK_KP_Up:		return XK_Up;
12800e20ee16Smrg		case XK_KP_Right:	return XK_Right;
12810e20ee16Smrg		case XK_KP_Down:	return XK_Down;
12820e20ee16Smrg		case XK_KP_Page_Up:	return XK_Page_Up;
12830e20ee16Smrg		case XK_KP_Page_Down:	return XK_Page_Down;
12840e20ee16Smrg		case XK_KP_End:		return XK_End;
12850e20ee16Smrg		case XK_KP_Begin:	return XK_Begin;
12860e20ee16Smrg		case XK_KP_Insert:	return XK_Insert;
12870e20ee16Smrg		case XK_KP_Delete:	return XK_Delete;
12880e20ee16Smrg		case XK_KP_Equal:	return XK_equal;
12890e20ee16Smrg		case XK_KP_Multiply:	return XK_asterisk;
12900e20ee16Smrg		case XK_KP_Add:		return XK_plus;
12910e20ee16Smrg		case XK_KP_Subtract:	return XK_minus;
12920e20ee16Smrg		case XK_KP_Divide:	return XK_slash;
12930e20ee16Smrg	}
12940e20ee16Smrg    }
12950e20ee16Smrg    else if (XkbKSIsDeadKey(sym)) {
12960e20ee16Smrg	switch (sym) {
12970e20ee16Smrg		     case XK_dead_grave:	sym= XK_grave; break;
12980e20ee16Smrg		     case XK_dead_acute:	sym= XK_acute; break;
12990e20ee16Smrg		     case XK_dead_circumflex:	sym= XK_asciicircum; break;
13000e20ee16Smrg		     case XK_dead_tilde:	sym= XK_asciitilde; break;
13010e20ee16Smrg		     case XK_dead_macron:	sym= XK_macron; break;
13020e20ee16Smrg		     case XK_dead_breve:	sym= XK_breve; break;
13030e20ee16Smrg		     case XK_dead_abovedot:	sym= XK_abovedot; break;
13040e20ee16Smrg		     case XK_dead_diaeresis:	sym= XK_diaeresis; break;
13050e20ee16Smrg		     case XK_dead_abovering:	sym= XK_degree; break;
13060e20ee16Smrg		     case XK_dead_doubleacute:	sym= XK_doubleacute; break;
13070e20ee16Smrg		     case XK_dead_caron:	sym= XK_caron; break;
13080e20ee16Smrg		     case XK_dead_cedilla:	sym= XK_cedilla; break;
13090e20ee16Smrg		     case XK_dead_ogonek:	sym= XK_ogonek; break;
13100e20ee16Smrg		     case XK_dead_iota:		sym= XK_Greek_iota; break;
13110e20ee16Smrg		     case XK_dead_voiced_sound:
13120e20ee16Smrg				sym= XK_voicedsound;
13130e20ee16Smrg				break;
13140e20ee16Smrg		     case XK_dead_semivoiced_sound:
13150e20ee16Smrg				sym= XK_semivoicedsound;
13160e20ee16Smrg				break;
13170e20ee16Smrg	}
13180e20ee16Smrg    }
13190e20ee16Smrg    return sym;
13200e20ee16Smrg}
13210e20ee16Smrg
13220e20ee16Smrgstatic Bool
13230e20ee16SmrgFindKeysymsByName(XkbDescPtr xkb, char *name, PSState *state, KeyTop *top)
13240e20ee16Smrg{
13250e20ee16Smrgstatic unsigned char buf[30];
13260e20ee16Smrgint	kc;
13270e20ee16SmrgKeySym	sym,*syms,topSyms[NLABELS];
13280e20ee16Smrgint	level,group;
13290e20ee16Smrgint	eG,nG,gI,l,g;
13300e20ee16Smrg
13310e20ee16Smrg    bzero(top,sizeof(KeyTop));
13320e20ee16Smrg    kc= XkbFindKeycodeByName(xkb,name,True);
13330e20ee16Smrg    if (state->args!=NULL) {
13340e20ee16Smrg	level= state->args->labelLevel;
13350e20ee16Smrg	group= state->args->baseLabelGroup;
13360e20ee16Smrg    }
13370e20ee16Smrg    else level= group= 0;
13380e20ee16Smrg    syms= XkbKeySymsPtr(xkb,kc);
13390e20ee16Smrg    eG= group;
13400e20ee16Smrg    nG= XkbKeyNumGroups(xkb,kc);
13410e20ee16Smrg    gI= XkbKeyGroupInfo(xkb,kc);
13420e20ee16Smrg    if ((state->args->wantDiffs)&&(eG>=XkbKeyNumGroups(xkb,kc)))
13430e20ee16Smrg	return False;		/* XXX was a return with no value */
13440e20ee16Smrg    if (nG==0) {
13450e20ee16Smrg	return False;
13460e20ee16Smrg    }
13470e20ee16Smrg    else if (nG==1) {
13480e20ee16Smrg	eG= 0;
13490e20ee16Smrg    }
13500e20ee16Smrg    else if (eG>=XkbKeyNumGroups(xkb,kc)) {
13510e20ee16Smrg	switch (XkbOutOfRangeGroupAction(gI)) {
13520e20ee16Smrg	    default:
13530e20ee16Smrg		eG%= nG;
13540e20ee16Smrg		break;
13550e20ee16Smrg	    case XkbClampIntoRange:
13560e20ee16Smrg		eG= nG-1;
13570e20ee16Smrg	        break;
13580e20ee16Smrg	    case XkbRedirectIntoRange:
13590e20ee16Smrg		eG= XkbOutOfRangeGroupNumber(gI);
13600e20ee16Smrg		if (eG>=nG)
13610e20ee16Smrg		    eG= 0;
13620e20ee16Smrg		break;
13630e20ee16Smrg	}
13640e20ee16Smrg    }
13650e20ee16Smrg    for (g=0;g<state->args->nLabelGroups;g++) {
13660e20ee16Smrg	if ((eG+g)>=nG)
13670e20ee16Smrg	    continue;
13680e20ee16Smrg	for (l=0;l<2;l++) {
13690e20ee16Smrg	    int font,sz;
13700e20ee16Smrg	    if (level+l>=XkbKeyGroupWidth(xkb,kc,(eG+g)))
13710e20ee16Smrg		continue;
13720e20ee16Smrg	    sym= syms[((eG+g)*XkbKeyGroupsWidth(xkb,kc))+(level+l)];
13730e20ee16Smrg
13740e20ee16Smrg	    if (state->args->wantSymbols!=NO_SYMBOLS)
13750e20ee16Smrg		sym= CheckSymbolAlias(sym,state);
13760e20ee16Smrg	    topSyms[(g*2)+l]= sym;
13770e20ee16Smrg
13780e20ee16Smrg	    if (PSKeycapsSymbol(sym,buf,&font,&sz,state)) {
13790e20ee16Smrg		top->font[(g*2)+l]= font;
13800e20ee16Smrg		top->size[(g*2)+l]= sz;
13810e20ee16Smrg	    }
13820e20ee16Smrg	    else if (((sym&(~0xff))==0)&&isprint(sym)&&(!isspace(sym))) {
13830e20ee16Smrg		if (sym=='(')		sprintf((char *)buf,"\\(");
13840e20ee16Smrg		else if (sym==')')	sprintf((char *)buf,"\\)");
13850e20ee16Smrg		else if (sym=='\\')	sprintf((char *)buf,"\\\\");
13860e20ee16Smrg		else			sprintf((char *)buf,"%c",(char)sym);
13870e20ee16Smrg		top->font[(g*2)+l]= FONT_LATIN1;
13880e20ee16Smrg		top->size[(g*2)+l]= SZ_MEDIUM;
13890e20ee16Smrg		switch (buf[0]) {
13900e20ee16Smrg		    case '.': case ':': case ',': case ';':
13910e20ee16Smrg		    case '\'': case '"': case '`': case '~':
13920e20ee16Smrg 		    case '^': case '\250': case '\270': case '\267':
13930e20ee16Smrg 		    case '\260': case '\252': case '\272': case '\271':
13940e20ee16Smrg 		    case '\262': case '\263': case '\264': case '\255':
13950e20ee16Smrg 		    case '\254': case '\257':
13960e20ee16Smrg			top->size[(g*2)+l]= SZ_LARGE;
13970e20ee16Smrg			break;
13980e20ee16Smrg		}
13990e20ee16Smrg	    }
14000e20ee16Smrg	    else if (PSNonLatin1Symbol(sym,buf,&font,&sz,state)) {
14010e20ee16Smrg		top->font[(g*2)+l]= font;
14020e20ee16Smrg		top->size[(g*2)+l]= sz;
14030e20ee16Smrg	    }
14040e20ee16Smrg	    else {
14050e20ee16Smrg		char 		*tmp;
14060e20ee16Smrg		tmp= XKeysymToString(sym);
14070e20ee16Smrg		if (tmp!=NULL)	strcpy((char *)buf,tmp);
14080e20ee16Smrg		else		sprintf((char *)buf,"(%ld)",sym);
14090e20ee16Smrg		top->font[(g*2)+l]= FONT_LATIN1;
14100e20ee16Smrg		if (strlen((char *)buf)<9)
14110e20ee16Smrg		     top->size[(g*2)+l]= SZ_SMALL;
14120e20ee16Smrg		else top->size[(g*2)+l]= SZ_TINY;
14130e20ee16Smrg	    }
14140e20ee16Smrg	    top->present|= (1<<((g*2)+l));
14150e20ee16Smrg	    strncpy(top->label[(g*2)+l],(char *)buf,LABEL_LEN-1);
14160e20ee16Smrg	    top->label[(g*2)+l][LABEL_LEN-1]= '\0';
14170e20ee16Smrg	}
14180e20ee16Smrg	if (((g==0)&&(top->present&G1LX_MASK)==G1LX_MASK)||
14190e20ee16Smrg	    ((g==1)&&(top->present&G2LX_MASK)==G2LX_MASK)) {
14200e20ee16Smrg	    KeySym	lower,upper;
14210e20ee16Smrg	    XConvertCase(topSyms[(g*2)],&lower,&upper);
14220e20ee16Smrg	    if ((topSyms[(g*2)]==lower)&&(topSyms[(g*2)+1]==upper)) {
14230e20ee16Smrg		top->alpha[g]= True;
14240e20ee16Smrg	    }
14250e20ee16Smrg	}
14260e20ee16Smrg    }
14270e20ee16Smrg    return True;
14280e20ee16Smrg}
14290e20ee16Smrg
14300e20ee16Smrgstatic void
14310e20ee16SmrgPSDrawLabel(FILE *out, char *label, int x, int y, int w, int h)
14320e20ee16Smrg{
14330e20ee16Smrg    fprintf(out,"%d %d (%s) centeroffset\n",w,h,label);
14340e20ee16Smrg    fprintf(out,"%d add exch\n",y);
14350e20ee16Smrg    fprintf(out,"%d add exch moveto\n",x);
14360e20ee16Smrg    fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",label);
14370e20ee16Smrg    return;
14380e20ee16Smrg}
14390e20ee16Smrg
14400e20ee16Smrg#define	TOP_ROW		0
14410e20ee16Smrg#define	BOTTOM_ROW	1
14420e20ee16Smrg#define	CENTER_ROW	2
14430e20ee16Smrg
14440e20ee16Smrg#define	LEFT_COL	0
14450e20ee16Smrg#define	RIGHT_COL	1
14460e20ee16Smrg#define	CENTER_COL	2
14470e20ee16Smrg
14480e20ee16Smrgstatic void
14490e20ee16SmrgPSLabelKey(FILE *out, PSState *state, KeyTop *top, int x, int y,
14500e20ee16Smrg	   XkbBoundsPtr bounds, int kc, int btm)
14510e20ee16Smrg{
14520e20ee16Smrgchar	keycode[10];
14530e20ee16Smrgint	w,h,i;
14540e20ee16Smrgint	row_y[3];
14550e20ee16Smrgint	col_x[3];
14560e20ee16Smrgint	row_h[3];
14570e20ee16Smrgint	col_w[3];
14580e20ee16SmrgBool	present[NLABELS];
14590e20ee16Smrgint	sym_row[NLABELS];
14600e20ee16Smrgint	sym_col[NLABELS];
14610e20ee16Smrg
14620e20ee16Smrg    w= XkbBoundsWidth(bounds);
14630e20ee16Smrg    h= XkbBoundsHeight(bounds);
14640e20ee16Smrg    row_y[TOP_ROW]=	y+bounds->y1+(h/10);
14650e20ee16Smrg    row_y[BOTTOM_ROW]=	y+bounds->y1+(h/2)+(h/10);
14660e20ee16Smrg    row_y[CENTER_ROW]=	y+bounds->y1+(h/10);
14670e20ee16Smrg    row_h[TOP_ROW]=	h/2;
14680e20ee16Smrg    row_h[BOTTOM_ROW]=	h/2;
14690e20ee16Smrg    row_h[CENTER_ROW]=	h;
14700e20ee16Smrg
14710e20ee16Smrg    col_x[LEFT_COL]= 	x+bounds->x1;
14720e20ee16Smrg    col_x[RIGHT_COL]= 	x+bounds->x1+w/2;
14730e20ee16Smrg    col_x[CENTER_COL]= 	x+bounds->x1;
14740e20ee16Smrg    col_w[LEFT_COL]= 	w/2;
14750e20ee16Smrg    col_w[RIGHT_COL]= 	w/2;
14760e20ee16Smrg    col_w[CENTER_COL]= 	w;
14770e20ee16Smrg
14780e20ee16Smrg    present[G1L1]= False;
14790e20ee16Smrg    sym_row[G1L1]= BOTTOM_ROW;
14800e20ee16Smrg    sym_col[G1L1]= LEFT_COL;
14810e20ee16Smrg
14820e20ee16Smrg    present[G1L2]= False;
14830e20ee16Smrg    sym_row[G1L2]= TOP_ROW;
14840e20ee16Smrg    sym_col[G1L2]= LEFT_COL;
14850e20ee16Smrg
14860e20ee16Smrg    present[G2L1]= False;
14870e20ee16Smrg    sym_row[G2L1]= BOTTOM_ROW;
14880e20ee16Smrg    sym_col[G2L1]= RIGHT_COL;
14890e20ee16Smrg
14900e20ee16Smrg    present[G2L2]= False;
14910e20ee16Smrg    sym_row[G2L2]= TOP_ROW;
14920e20ee16Smrg    sym_col[G2L2]= RIGHT_COL;
14930e20ee16Smrg
14940e20ee16Smrg    present[CENTER]= False;
14950e20ee16Smrg    sym_row[CENTER]= CENTER_ROW;
14960e20ee16Smrg    sym_col[CENTER]= CENTER_COL;
14970e20ee16Smrg
14980e20ee16Smrg    if (top->present&CENTER_MASK) {
14990e20ee16Smrg	present[CENTER]= True;
15000e20ee16Smrg    }
15010e20ee16Smrg    else switch (top->present&GXLX_MASK) {
15020e20ee16Smrg	case G1L1_MASK:
15030e20ee16Smrg	    present[G1L1]= True;
15040e20ee16Smrg	    sym_row[G1L1]= CENTER_ROW;
15050e20ee16Smrg	    sym_col[G1L1]= CENTER_COL;
15060e20ee16Smrg	    break;
15070e20ee16Smrg	case G1LX_MASK:
15080e20ee16Smrg	    present[G1L2]= True;
15090e20ee16Smrg	    if (!top->alpha[0]) {
15100e20ee16Smrg		present[G1L1]= True;
15110e20ee16Smrg		if ((strlen(top->label[G1L1])>1)&&(top->label[G1L1][0]!='\\'))
15120e20ee16Smrg		    sym_col[G1L1]= CENTER_COL;
15130e20ee16Smrg		if ((strlen(top->label[G1L2])>1)&&(top->label[G1L1][0]!='\\'))
15140e20ee16Smrg		    sym_col[G1L2]= CENTER_COL;
15150e20ee16Smrg	    }
15160e20ee16Smrg	    break;
15170e20ee16Smrg	default:
15180e20ee16Smrg	    if ((top->present&G1LX_MASK)==G1LX_MASK) {
15190e20ee16Smrg		present[G1L2]= True;
15200e20ee16Smrg		if (!top->alpha[0])
15210e20ee16Smrg		    present[G1L1]= True;
15220e20ee16Smrg	    }
15230e20ee16Smrg	    else if ((top->present&G1LX_MASK)==G1L1_MASK) {
15240e20ee16Smrg		present[G1L1]= True;
15250e20ee16Smrg	    }
15260e20ee16Smrg	    else if ((top->present&G1LX_MASK)==G1L2_MASK) {
15270e20ee16Smrg		present[G1L2]= True;
15280e20ee16Smrg	    }
15290e20ee16Smrg	    if ((top->present&G2LX_MASK)==G2LX_MASK) {
15300e20ee16Smrg		present[G2L2]= True;
15310e20ee16Smrg		if (!top->alpha[1])
15320e20ee16Smrg		    present[G2L1]= True;
15330e20ee16Smrg	    }
15340e20ee16Smrg	    else if ((top->present&G2LX_MASK)==G2L1_MASK) {
15350e20ee16Smrg		present[G2L1]= True;
15360e20ee16Smrg	    }
15370e20ee16Smrg	    else if ((top->present&G2LX_MASK)==G2L2_MASK) {
15380e20ee16Smrg		present[G2L2]= True;
15390e20ee16Smrg	    }
15400e20ee16Smrg	    break;
15410e20ee16Smrg	case 0:
15420e20ee16Smrg	    return;
15430e20ee16Smrg    }
15440e20ee16Smrg    for (i=0;i<NLABELS;i++) {
15450e20ee16Smrg	if (present[i]) {
15460e20ee16Smrg	    int len,size;
15470e20ee16Smrg	    if (top->size[i]==SZ_AUTO) {
15480e20ee16Smrg		len= strlen(top->label[i]);
15490e20ee16Smrg		if (len==1) {
15500e20ee16Smrg		    if (top->font[i]==FONT_ISOCAPS)
15510e20ee16Smrg			 size= 18;
15520e20ee16Smrg		    else size= 14;
15530e20ee16Smrg		}
15540e20ee16Smrg		else if (len<10)	size= 12;
15550e20ee16Smrg		else		size= 10;
15560e20ee16Smrg	    }
15570e20ee16Smrg	    else if (top->size[i]==SZ_TINY)
15580e20ee16Smrg		 size= 10;
15590e20ee16Smrg	    else if (top->size[i]==SZ_SMALL)
15600e20ee16Smrg		 size= 12;
15610e20ee16Smrg	    else if (top->size[i]==SZ_LARGE)
15620e20ee16Smrg		 size= 18;
15630e20ee16Smrg	    else if (top->size[i]==SZ_XLARGE)
15640e20ee16Smrg		 size= 24;
15650e20ee16Smrg	    else size= 14;
15660e20ee16Smrg	    PSSetFont(out,state,top->font[i],size,True);
15670e20ee16Smrg	    PSDrawLabel(out,top->label[i],col_x[sym_col[i]],row_y[sym_row[i]],
15680e20ee16Smrg					  col_w[sym_col[i]],row_h[sym_row[i]]);
15690e20ee16Smrg	}
15700e20ee16Smrg    }
15710e20ee16Smrg    if (state->args->wantKeycodes) {
15720e20ee16Smrg	sprintf(keycode,"%d",kc);
15730e20ee16Smrg	PSSetFont(out,state,FONT_LATIN1,8,True);
15740e20ee16Smrg	PSDrawLabel(out,keycode,x+bounds->x1,y+btm-5,w,0);
15750e20ee16Smrg    }
15760e20ee16Smrg    return;
15770e20ee16Smrg}
15780e20ee16Smrg
15790e20ee16Smrgstatic void
15800e20ee16SmrgPSSection(FILE *out, PSState *state, XkbSectionPtr section)
15810e20ee16Smrg{
15820e20ee16Smrgint		r,offset;
15830e20ee16SmrgXkbRowPtr	row;
15840e20ee16SmrgDisplay *	dpy;
15850e20ee16SmrgXkbDescPtr	xkb;
15860e20ee16Smrg
15870e20ee16Smrg    xkb= state->xkb;
15880e20ee16Smrg    dpy= xkb->dpy;
15890e20ee16Smrg    fprintf(out,"%% Begin Section '%s'\n",(section->name!=None?
15900e20ee16Smrg					XkbAtomGetString(dpy,section->name):
15910e20ee16Smrg					"NoName"));
15920e20ee16Smrg    PSGSave(out,state);
15930e20ee16Smrg    fprintf(out,"%d %d translate\n",section->left,section->top);
15940e20ee16Smrg    if (section->angle!=0)
15950e20ee16Smrg	fprintf(out,"%s rotate\n",XkbGeomFPText(section->angle,XkbMessage));
15960e20ee16Smrg    if (section->doodads) {
15970e20ee16Smrg	XkbDrawablePtr	first,draw;
15980e20ee16Smrg	first= draw= XkbGetOrderedDrawables(NULL,section);
15990e20ee16Smrg	while (draw) {
16000e20ee16Smrg	    if (draw->type==XkbDW_Section)
16010e20ee16Smrg		 PSSection(out,state,draw->u.section);
16020e20ee16Smrg	    else PSDoodad(out,state,draw->u.doodad);
16030e20ee16Smrg	    draw= draw->next;
16040e20ee16Smrg	}
16050e20ee16Smrg	XkbFreeOrderedDrawables(first);
16060e20ee16Smrg    }
16070e20ee16Smrg    for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
16080e20ee16Smrg	int 		k;
16090e20ee16Smrg	XkbKeyPtr	key;
16100e20ee16Smrg	XkbShapePtr	shape;
16110e20ee16Smrg	if (row->vertical)	offset= row->top;
16120e20ee16Smrg	else			offset= row->left;
16130e20ee16Smrg	fprintf(out,"%% Begin %s %d\n",row->vertical?"column":"row",r+1);
16140e20ee16Smrg	for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
16150e20ee16Smrg	    shape= XkbKeyShape(xkb->geom,key);
16160e20ee16Smrg	    offset+= key->gap;
16170e20ee16Smrg	    if (row->vertical) {
16180e20ee16Smrg		if (state->args->wantColor) {
16190e20ee16Smrg		    if (key->color_ndx!=state->white) {
16200e20ee16Smrg			PSSetColor(out,state,key->color_ndx);
16210e20ee16Smrg			fprintf(out,"true 0 %d %d %s %% %s\n",
16220e20ee16Smrg				row->left,offset,
16230e20ee16Smrg	     			XkbAtomGetString(dpy,shape->name),
16240e20ee16Smrg				XkbKeyNameText(key->name.name,XkbMessage));
16250e20ee16Smrg		    }
16260e20ee16Smrg		    PSSetColor(out,state,state->black);
16270e20ee16Smrg		}
16280e20ee16Smrg		fprintf(out,"false 0 %d %d %s %% %s\n",row->left,offset,
16290e20ee16Smrg	     			XkbAtomGetString(dpy,shape->name),
16300e20ee16Smrg				XkbKeyNameText(key->name.name,XkbMessage));
16310e20ee16Smrg		offset+= shape->bounds.y2;
16320e20ee16Smrg	    }
16330e20ee16Smrg	    else {
16340e20ee16Smrg		if (state->args->wantColor) {
16350e20ee16Smrg		    if (key->color_ndx!=state->white) {
16360e20ee16Smrg			PSSetColor(out,state,key->color_ndx);
16370e20ee16Smrg			fprintf(out,"true 0 %d %d %s %% %s\n",offset,row->top,
16380e20ee16Smrg	     			XkbAtomGetString(dpy,shape->name),
16390e20ee16Smrg				XkbKeyNameText(key->name.name,XkbMessage));
16400e20ee16Smrg		    }
16410e20ee16Smrg		    PSSetColor(out,state,state->black);
16420e20ee16Smrg		}
16430e20ee16Smrg		fprintf(out,"false 0 %d %d %s %% %s\n",offset,row->top,
16440e20ee16Smrg	     			XkbAtomGetString(dpy,shape->name),
16450e20ee16Smrg				XkbKeyNameText(key->name.name,XkbMessage));
16460e20ee16Smrg		offset+= shape->bounds.x2;
16470e20ee16Smrg	    }
16480e20ee16Smrg	}
16490e20ee16Smrg    }
16500e20ee16Smrg    for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
16510e20ee16Smrg	int 		k,kc=0;
16520e20ee16Smrg	XkbKeyPtr	key;
16530e20ee16Smrg	XkbShapePtr	shape;
16540e20ee16Smrg	XkbBoundsRec	bounds;
16550e20ee16Smrg	if (state->args->label==LABEL_NONE)
16560e20ee16Smrg	    break;
16570e20ee16Smrg	if (row->vertical)	offset= row->top;
16580e20ee16Smrg	else			offset= row->left;
16590e20ee16Smrg	fprintf(out,"%% Begin %s %d labels\n",row->vertical?"column":"row",r+1);
16600e20ee16Smrg	PSSetColor(out,state,xkb->geom->label_color->pixel);
16610e20ee16Smrg	PSSetFont(out,state,FONT_LATIN1,12,True);
16620e20ee16Smrg	for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
16630e20ee16Smrg	    char *	name,*name2,buf[30],buf2[30];
16640e20ee16Smrg	    int		x,y;
16650e20ee16Smrg	    KeyTop	top;
16660e20ee16Smrg
16670e20ee16Smrg	    shape= XkbKeyShape(xkb->geom,key);
16680e20ee16Smrg	    XkbComputeShapeTop(shape,&bounds);
16690e20ee16Smrg	    offset+= key->gap;
16700e20ee16Smrg	    name= name2= NULL;
16710e20ee16Smrg	    if (state->args->label==LABEL_SYMBOLS) {
16720e20ee16Smrg		if (!FindKeysymsByName(xkb,key->name.name,state,&top)) {
16730e20ee16Smrg		    fprintf(out,"%% No label for %s\n",
16740e20ee16Smrg				XkbKeyNameText(key->name.name,XkbMessage));
16750e20ee16Smrg		}
16760e20ee16Smrg	    }
16770e20ee16Smrg	    else {
16780e20ee16Smrg		char *olKey;
16790e20ee16Smrg
16800e20ee16Smrg		if (section->num_overlays>0)
16810e20ee16Smrg		     olKey= XkbFindOverlayForKey(xkb->geom,section,
16820e20ee16Smrg							   key->name.name);
16830e20ee16Smrg		else olKey= NULL;
16840e20ee16Smrg
16850e20ee16Smrg		if (state->args->label==LABEL_KEYNAME) {
16860e20ee16Smrg		    name= XkbKeyNameText(key->name.name,XkbMessage);
16870e20ee16Smrg		    if (olKey)
16880e20ee16Smrg			name2= XkbKeyNameText(olKey,XkbMessage);
16890e20ee16Smrg		}
16900e20ee16Smrg		else if (state->args->label==LABEL_KEYCODE) {
16910e20ee16Smrg		    name= buf;
16920e20ee16Smrg		    sprintf(name,"%d",XkbFindKeycodeByName(xkb,key->name.name,
16930e20ee16Smrg									True));
16940e20ee16Smrg		    if (olKey) {
16950e20ee16Smrg			name2= buf2;
16960e20ee16Smrg			sprintf(name,"%d",XkbFindKeycodeByName(xkb,olKey,True));
16970e20ee16Smrg		    }
16980e20ee16Smrg		}
16990e20ee16Smrg		bzero(&top,sizeof(KeyTop));
17000e20ee16Smrg		if (name2!=NULL) {
17010e20ee16Smrg		    top.present|= G1LX_MASK;
17020e20ee16Smrg		    strncpy(top.label[G1L1],name,LABEL_LEN-1);
17030e20ee16Smrg		    top.label[G1L1][LABEL_LEN-1]= '\0';
17040e20ee16Smrg		    strncpy(top.label[G1L2],name2,LABEL_LEN-1);
17050e20ee16Smrg		    top.label[G1L2][LABEL_LEN-1]= '\0';
17060e20ee16Smrg		}
17070e20ee16Smrg		else if (name!=NULL) {
17080e20ee16Smrg		    top.present|= CENTER_MASK;
17090e20ee16Smrg		    strncpy(top.label[CENTER],name,LABEL_LEN-1);
17100e20ee16Smrg		    top.label[CENTER][LABEL_LEN-1]= '\0';
17110e20ee16Smrg		}
17120e20ee16Smrg		else {
17130e20ee16Smrg		    fprintf(out,"%% No label for %s\n",
17140e20ee16Smrg				XkbKeyNameText(key->name.name,XkbMessage));
17150e20ee16Smrg		}
17160e20ee16Smrg	    }
17170e20ee16Smrg	    if (row->vertical) {
17180e20ee16Smrg		x= row->left;
17190e20ee16Smrg		y= offset;
17200e20ee16Smrg		offset+= shape->bounds.y2;
17210e20ee16Smrg	    }
17220e20ee16Smrg	    else {
17230e20ee16Smrg		x= offset;
17240e20ee16Smrg		y= row->top;
17250e20ee16Smrg		offset+= shape->bounds.x2;
17260e20ee16Smrg	    }
17270e20ee16Smrg	    name= key->name.name;
17280e20ee16Smrg	    fprintf(out,"%% %s\n",XkbKeyNameText(name,XkbMessage));
17290e20ee16Smrg	    if (state->args->wantKeycodes)
17300e20ee16Smrg		kc= XkbFindKeycodeByName(xkb,key->name.name,True);
17310e20ee16Smrg	    PSLabelKey(out,state,&top,x,y,&bounds,kc,shape->bounds.y2);
17320e20ee16Smrg	}
17330e20ee16Smrg    }
17340e20ee16Smrg    PSGRestore(out,state);
17350e20ee16Smrg    return;
17360e20ee16Smrg}
17370e20ee16Smrg
17380e20ee16SmrgBool
17390e20ee16SmrgGeometryToPostScript(FILE *out, XkbFileInfo *pResult, XKBPrintArgs *args)
17400e20ee16Smrg{
17410e20ee16SmrgXkbDrawablePtr	first,draw;
17420e20ee16SmrgPSState		state;
17430e20ee16SmrgBool		dfltBorder;
17440e20ee16Smrgint		i;
17450e20ee16Smrg
17460e20ee16Smrg    if ((!pResult)||(!pResult->xkb)||(!pResult->xkb->geom))
17470e20ee16Smrg	return False;
17480e20ee16Smrg    state.xkb=   pResult->xkb;
17490e20ee16Smrg    state.dpy=   pResult->xkb->dpy;
17500e20ee16Smrg    state.geom=  pResult->xkb->geom;
17510e20ee16Smrg    state.color= state.black= state.white= -1;
17520e20ee16Smrg    state.font=  -1;
17530e20ee16Smrg    state.nPages= 0;
17540e20ee16Smrg    state.totalKB= 1;
17550e20ee16Smrg    state.kbPerPage= 1;
17560e20ee16Smrg    state.x1= state.y1= state.x2= state.y2= 0;
17570e20ee16Smrg    state.args= args;
17580e20ee16Smrg
17590e20ee16Smrg    if ((args->label==LABEL_SYMBOLS)&&(pResult->xkb->ctrls)) {
17600e20ee16Smrg	if (args->nTotalGroups==0)
17610e20ee16Smrg	     state.totalKB= pResult->xkb->ctrls->num_groups/args->nLabelGroups;
17620e20ee16Smrg	else state.totalKB= args->nTotalGroups;
17630e20ee16Smrg	if (state.totalKB<1)
17640e20ee16Smrg	    state.totalKB= 1;
17650e20ee16Smrg	else if (state.totalKB>1)
17660e20ee16Smrg	    state.kbPerPage= 2;
17670e20ee16Smrg    }
17680e20ee16Smrg    if (args->nKBPerPage!=0)
17690e20ee16Smrg	state.kbPerPage= args->nKBPerPage;
17700e20ee16Smrg
17710e20ee16Smrg    PSProlog(out,&state);
17720e20ee16Smrg    first= XkbGetOrderedDrawables(state.geom,NULL);
17730e20ee16Smrg
17740e20ee16Smrg    for (draw=first,dfltBorder=True;draw!=NULL;draw=draw->next) {
17750e20ee16Smrg	if ((draw->type!=XkbDW_Section)&&
17760e20ee16Smrg	    ((draw->u.doodad->any.type==XkbOutlineDoodad)||
17770e20ee16Smrg	     (draw->u.doodad->any.type==XkbSolidDoodad))) {
17780e20ee16Smrg	    char *name;
17790e20ee16Smrg	    name= XkbAtomGetString(state.dpy,draw->u.doodad->any.name);
17800e20ee16Smrg	    if ((name!=NULL)&&(uStrCaseEqual(name,"edges"))) {
17810e20ee16Smrg		dfltBorder= False;
17820e20ee16Smrg		break;
17830e20ee16Smrg	    }
17840e20ee16Smrg	}
17850e20ee16Smrg    }
17860e20ee16Smrg    for (i=0;i<state.totalKB;i++) {
17870e20ee16Smrg	PSPageSetup(out,&state,dfltBorder);
17880e20ee16Smrg	for (draw=first;draw!=NULL;draw=draw->next) {
17890e20ee16Smrg	    if (draw->type==XkbDW_Section)
17900e20ee16Smrg		PSSection(out,&state,draw->u.section);
17910e20ee16Smrg	    else {
17920e20ee16Smrg		PSDoodad(out,&state,draw->u.doodad);
17930e20ee16Smrg	    }
17940e20ee16Smrg	}
17950e20ee16Smrg	PSPageTrailer(out,&state);
17960e20ee16Smrg	state.args->baseLabelGroup+= state.args->nLabelGroups;
17970e20ee16Smrg    }
17980e20ee16Smrg    XkbFreeOrderedDrawables(first);
17990e20ee16Smrg    PSFileTrailer(out,&state);
18000e20ee16Smrg    return True;
18010e20ee16Smrg}
1802