psgeom.c revision e6bced22
10e20ee16Smrg/************************************************************ 20e20ee16Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 30e20ee16Smrg 40e20ee16Smrg Permission to use, copy, modify, and distribute this 50e20ee16Smrg software and its documentation for any purpose and without 60e20ee16Smrg fee is hereby granted, provided that the above copyright 70e20ee16Smrg notice appear in all copies and that both that copyright 80e20ee16Smrg notice and this permission notice appear in supporting 92f167a42Smrg documentation, and that the name of Silicon Graphics not be 102f167a42Smrg used in advertising or publicity pertaining to distribution 110e20ee16Smrg of the software without specific prior written permission. 122f167a42Smrg Silicon Graphics makes no representation about the suitability 130e20ee16Smrg of this software for any purpose. It is provided "as is" 140e20ee16Smrg without any express or implied warranty. 152f167a42Smrg 162f167a42Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 172f167a42Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 180e20ee16Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 192f167a42Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 202f167a42Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 212f167a42Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 220e20ee16Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 230e20ee16Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 240e20ee16Smrg 250e20ee16Smrg ********************************************************/ 262f167a42Smrg 272f167a42Smrg#ifdef HAVE_CONFIG_H 282f167a42Smrg#include "config.h" 292f167a42Smrg#endif 300e20ee16Smrg 310e20ee16Smrg#define XK_TECHNICAL 320e20ee16Smrg#define XK_PUBLISHING 330e20ee16Smrg#define XK_KATAKANA 340e20ee16Smrg#include <stdio.h> 350e20ee16Smrg#include <ctype.h> 360e20ee16Smrg#include <X11/X.h> 370e20ee16Smrg#include <X11/Xlib.h> 380e20ee16Smrg#include <X11/XKBlib.h> 390e20ee16Smrg#include <X11/extensions/XKBgeom.h> 400e20ee16Smrg#include <X11/extensions/XKM.h> 410e20ee16Smrg#include <X11/extensions/XKBfile.h> 420e20ee16Smrg#include <X11/keysym.h> 430e20ee16Smrg#include <X11/Xutil.h> 440e20ee16Smrg 450e20ee16Smrg#if defined(sgi) 460e20ee16Smrg#include <malloc.h> 470e20ee16Smrg#endif 480e20ee16Smrg 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 { 632f167a42Smrg Display * dpy; 642f167a42Smrg XkbDescPtr xkb; 652f167a42Smrg XkbGeometryPtr geom; 662f167a42Smrg int totalKB; 672f167a42Smrg int kbPerPage; 682f167a42Smrg int black; 692f167a42Smrg int white; 702f167a42Smrg int color; 712f167a42Smrg int font; 722f167a42Smrg int fontSize; 732f167a42Smrg int nPages; 742f167a42Smrg int x1, y1; 752f167a42Smrg int x2, y2; 762f167a42Smrg 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 { 1092f167a42Smrg unsigned present; 1102f167a42Smrg Bool alpha[2]; 1112f167a42Smrg char label[NLABELS][LABEL_LEN]; 1122f167a42Smrg int font[NLABELS]; 1132f167a42Smrg 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 { 1222f167a42Smrg const char *name; 1232f167a42Smrg const char **def; 1240e20ee16Smrg} PSFontDef; 1250e20ee16Smrg 1260e20ee16Smrgstatic PSFontDef internalFonts[] = { 1272f167a42Smrg { "IsoKeyCaps", &IsoKeyCaps } 1280e20ee16Smrg}; 1292f167a42Smrgstatic int nInternalFonts = (sizeof(internalFonts) / sizeof(PSFontDef)); 1300e20ee16Smrg 1310e20ee16Smrgstatic void 1320e20ee16SmrgListInternalFonts(FILE *out, int first, int indent) 1330e20ee16Smrg{ 1342f167a42Smrg register int i, n, nThisLine; 1350e20ee16Smrg 1362f167a42Smrg for (n = 0; n < first; n++) { 1372f167a42Smrg putc(' ', out); 1380e20ee16Smrg } 1390e20ee16Smrg 1402f167a42Smrg for (nThisLine = i = 0; i < nInternalFonts; i++) { 1412f167a42Smrg if (nThisLine == 4) { 1422f167a42Smrg fprintf(out, ",\n"); 1432f167a42Smrg for (n = 0; n < indent; n++) { 1442f167a42Smrg putc(' ', out); 1452f167a42Smrg } 1462f167a42Smrg nThisLine = 0; 1472f167a42Smrg } 1482f167a42Smrg if (nThisLine == 0) 1492f167a42Smrg fprintf(out, "%s", internalFonts[i].name); 1502f167a42Smrg else 1512f167a42Smrg fprintf(out, ", %s", internalFonts[i].name); 1522f167a42Smrg nThisLine++; 1530e20ee16Smrg } 1542f167a42Smrg if (nThisLine != 0) 1552f167a42Smrg fprintf(out, "\n"); 1560e20ee16Smrg return; 1570e20ee16Smrg} 1580e20ee16Smrg 1590e20ee16Smrgstatic Bool 1602f167a42SmrgPSIncludeFont(FILE *out, const char *font) 1610e20ee16Smrg{ 1622f167a42Smrg const char **pstr; 1632f167a42Smrg register int i; 1640e20ee16Smrg 1652f167a42Smrg pstr = NULL; 1662f167a42Smrg for (i = 0; (i < nInternalFonts) && (pstr == NULL); i++) { 1672f167a42Smrg if (uStringEqual(internalFonts[i].name, font)) 1682f167a42Smrg pstr = internalFonts[i].def; 1690e20ee16Smrg } 1702f167a42Smrg if (pstr != NULL) { 1712f167a42Smrg fprintf(out, "%%%%BeginFont: %s\n", font); 1722f167a42Smrg fprintf(out, "%s", *pstr); 1732f167a42Smrg fprintf(out, "%%%%EndFont\n"); 1742f167a42Smrg return True; 1750e20ee16Smrg } 1760e20ee16Smrg return False; 1770e20ee16Smrg} 1780e20ee16Smrg 1790e20ee16SmrgBool 1802f167a42SmrgDumpInternalFont(FILE *out, const char *fontName) 1810e20ee16Smrg{ 1822f167a42Smrg if (strcmp(fontName, "IsoKeyCaps") != 0) { 1832f167a42Smrg uError("No internal font named \"%s\"\n", fontName); 1842f167a42Smrg uAction("No font dumped\n"); 1852f167a42Smrg fprintf(stderr, "Current internal fonts are: "); 1862f167a42Smrg ListInternalFonts(stderr, 0, 8); 1872f167a42Smrg return False; 1880e20ee16Smrg } 1892f167a42Smrg PSIncludeFont(out, fontName); 1900e20ee16Smrg return True; 1910e20ee16Smrg} 1920e20ee16Smrg 1930e20ee16Smrg/***====================================================================***/ 1940e20ee16Smrg 1950e20ee16Smrgstatic void 1960e20ee16SmrgPSColorDef(FILE *out, PSState *state, XkbColorPtr color) 1970e20ee16Smrg{ 1982f167a42Smrg int tmp; 1990e20ee16Smrg 2002f167a42Smrg fprintf(out, "/C%03d ", color->pixel); 2012f167a42Smrg if (uStrCaseEqual(color->spec, "black")) { 2022f167a42Smrg state->black = color->pixel; 2032f167a42Smrg fprintf(out, "{ 0 setgray } def %% %s\n", color->spec); 2040e20ee16Smrg } 2052f167a42Smrg else if (uStrCaseEqual(color->spec, "white")) { 2062f167a42Smrg state->white = color->pixel; 2072f167a42Smrg fprintf(out, "{ 1 setgray } def %% %s\n", color->spec); 2080e20ee16Smrg } 2092f167a42Smrg else if ((sscanf(color->spec, "grey%d", &tmp) == 1) || 2102f167a42Smrg (sscanf(color->spec, "gray%d", &tmp) == 1) || 2112f167a42Smrg (sscanf(color->spec, "Grey%d", &tmp) == 1) || 2122f167a42Smrg (sscanf(color->spec, "Gray%d", &tmp) == 1)) { 2132f167a42Smrg fprintf(out, "{ %f setgray } def %% %s\n", 2142f167a42Smrg 1.0 - (((float) tmp) / 100.0), color->spec); 2150e20ee16Smrg } 2162f167a42Smrg else if ((tmp = (uStrCaseEqual(color->spec, "red") * 100)) || 2172f167a42Smrg (sscanf(color->spec, "red%d", &tmp) == 1)) { 2182f167a42Smrg fprintf(out, "{ %f 0 0 setrgbcolor } def %% %s\n", 2192f167a42Smrg (((float) tmp) / 100.0), color->spec); 2200e20ee16Smrg } 2212f167a42Smrg else if ((tmp = (uStrCaseEqual(color->spec, "green") * 100)) || 2222f167a42Smrg (sscanf(color->spec, "green%d", &tmp) == 1)) { 2232f167a42Smrg fprintf(out, "{ 0 %f 0 setrgbcolor } def %% %s\n", 2242f167a42Smrg (((float) tmp) / 100.0), color->spec); 2250e20ee16Smrg } 2262f167a42Smrg else if ((tmp = (uStrCaseEqual(color->spec, "blue") * 100)) || 2272f167a42Smrg (sscanf(color->spec, "blue%d", &tmp) == 1)) { 2282f167a42Smrg fprintf(out, "{ 0 0 %f setrgbcolor } def %% %s\n", 2292f167a42Smrg (((float) tmp) / 100.0), color->spec); 2300e20ee16Smrg } 2312f167a42Smrg else 2322f167a42Smrg fprintf(out, "{ 0.9 setgray } def %% BOGUS! %s\n", color->spec); 2330e20ee16Smrg} 2340e20ee16Smrg 2350e20ee16Smrgstatic void 2362f167a42SmrgPSSetColor(FILE *out, PSState *state, int color) 2370e20ee16Smrg{ 2382f167a42Smrg if ((state->args->wantColor) && (state->color != color)) { 2392f167a42Smrg fprintf(out, "C%03d %% set color\n", color); 2402f167a42Smrg state->color = color; 2410e20ee16Smrg } 2420e20ee16Smrg return; 2430e20ee16Smrg} 2440e20ee16Smrg 2450e20ee16Smrgstatic void 2460e20ee16SmrgPSGSave(FILE *out, PSState *state) 2470e20ee16Smrg{ 2482f167a42Smrg fprintf(out, "gsave\n"); 2490e20ee16Smrg return; 2500e20ee16Smrg} 2510e20ee16Smrg 2520e20ee16Smrgstatic void 2530e20ee16SmrgPSGRestore(FILE *out, PSState *state) 2540e20ee16Smrg{ 2552f167a42Smrg fprintf(out, "grestore\n"); 2562f167a42Smrg state->color = -1; 2572f167a42Smrg state->font = FONT_NONE; 2582f167a42Smrg state->fontSize = -1; 2590e20ee16Smrg return; 2600e20ee16Smrg} 2610e20ee16Smrg 2620e20ee16Smrgstatic void 2630e20ee16SmrgPSShapeDef(FILE *out, PSState *state, XkbShapePtr shape) 2640e20ee16Smrg{ 2652f167a42Smrg int o, p; 2662f167a42Smrg XkbOutlinePtr ol; 2672f167a42Smrg 268e6bced22Smrg { 269e6bced22Smrg char *a = XkbAtomGetString(state->dpy, shape->name); 270e6bced22Smrg fprintf(out, "/%s {\n", a); 271e6bced22Smrg XFree(a); 272e6bced22Smrg } 2732f167a42Smrg fprintf(out, " gsave translate rotate /SOLID exch def\n"); 2742f167a42Smrg for (o = 0, ol = shape->outlines; o < shape->num_outlines; o++, ol++) { 2752f167a42Smrg XkbPointPtr pt; 2762f167a42Smrg 2772f167a42Smrg if ((shape->num_outlines > 1) && (ol == shape->approx)) 2782f167a42Smrg continue; 2792f167a42Smrg pt = ol->points; 2802f167a42Smrg fprintf(out, "%% Outline %d\n", o + 1); 2812f167a42Smrg if (ol->num_points == 1) { 2822f167a42Smrg if (ol->corner_radius < 1) { 2832f167a42Smrg fprintf(out, " 0 0 moveto\n"); 2842f167a42Smrg fprintf(out, " %3d 0 lineto\n", pt->x); 2852f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt->x, pt->y); 2862f167a42Smrg fprintf(out, " 0 %3d lineto\n", pt->y); 2872f167a42Smrg fprintf(out, " 0 0 lineto\n"); 2882f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 2892f167a42Smrg } 2902f167a42Smrg else { 2912f167a42Smrg fprintf(out, " mark\n"); 2922f167a42Smrg fprintf(out, " %3d 0 moveto\n", ol->corner_radius); 2932f167a42Smrg fprintf(out, " %3d 0 %3d %3d %3d arcto\n", pt->x, pt->x, 2942f167a42Smrg pt->y, ol->corner_radius); 2952f167a42Smrg fprintf(out, " %3d %3d 0 %3d %3d arcto\n", pt->x, pt->y, 2962f167a42Smrg pt->y, ol->corner_radius); 2972f167a42Smrg fprintf(out, " 0 %3d 0 0 %3d arcto\n", pt->y, 2982f167a42Smrg ol->corner_radius); 2992f167a42Smrg fprintf(out, " 0 0 %3d 0 %3d arcto\n", pt->x, 3002f167a42Smrg ol->corner_radius); 3012f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 3022f167a42Smrg fprintf(out, " cleartomark\n"); 3032f167a42Smrg } 3042f167a42Smrg } 3052f167a42Smrg else if (ol->num_points == 2) { 3062f167a42Smrg if (ol->corner_radius < 1) { 3072f167a42Smrg fprintf(out, " %3d %3d moveto\n", pt[0].x, pt[0].y); 3082f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt[1].x, pt[0].y); 3092f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt[1].x, pt[1].y); 3102f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt[0].x, pt[1].y); 3112f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt[0].x, pt[0].y); 3122f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 3132f167a42Smrg } 3142f167a42Smrg else { 3152f167a42Smrg fprintf(out, " mark\n"); 3162f167a42Smrg fprintf(out, " %3d %3d moveto\n", pt[0].x + ol->corner_radius, 3172f167a42Smrg pt[0].y); 3182f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", pt[1].x, pt[0].y, 3192f167a42Smrg pt[1].x, pt[1].y, ol->corner_radius); 3202f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", pt[1].x, pt[1].y, 3212f167a42Smrg pt[0].x, pt[1].y, ol->corner_radius); 3222f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", pt[0].x, pt[1].y, 3232f167a42Smrg pt[0].x, pt[0].y, ol->corner_radius); 3242f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", pt[0].x, pt[0].y, 3252f167a42Smrg pt[1].x, pt[0].y, ol->corner_radius); 3262f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 3272f167a42Smrg fprintf(out, " cleartomark\n"); 3282f167a42Smrg } 3292f167a42Smrg } 3302f167a42Smrg else { 3312f167a42Smrg if (ol->corner_radius < 1) { 3322f167a42Smrg fprintf(out, " %3d %3d moveto\n", pt->x, pt->y); 3332f167a42Smrg pt++; 3342f167a42Smrg for (p = 1; p < ol->num_points; p++, pt++) { 3352f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt->x, pt->y); 3362f167a42Smrg } 3372f167a42Smrg if ((pt->x != ol->points[0].x) || (pt->y != ol->points[0].y)) 3382f167a42Smrg fprintf(out, " closepath\n"); 3392f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 3402f167a42Smrg } 3412f167a42Smrg else { 3422f167a42Smrg XkbPointPtr last; 3432f167a42Smrg 3442f167a42Smrg last = &pt[ol->num_points - 1]; 3452f167a42Smrg if ((last->x == pt->x) && (last->y == pt->y)) 3462f167a42Smrg last--; 3472f167a42Smrg fprintf(out, " mark\n"); 3482f167a42Smrg fprintf(out, " %% Determine tangent point of first corner\n"); 3492f167a42Smrg fprintf(out, " %3d %3d moveto %d %d %d %d %d arcto\n", 3502f167a42Smrg last->x, last->y, 3512f167a42Smrg pt[0].x, pt[0].y, pt[1].x, pt[1].y, ol->corner_radius); 3522f167a42Smrg fprintf(out, " /TY exch def /TX exch def pop pop newpath\n"); 3532f167a42Smrg fprintf(out, " %% Now draw the shape\n"); 3542f167a42Smrg fprintf(out, " TX TY moveto\n"); 3552f167a42Smrg for (p = 1; p < ol->num_points; p++) { 3562f167a42Smrg if (p < (ol->num_points - 1)) 3572f167a42Smrg last = &pt[p + 1]; 3582f167a42Smrg else 3592f167a42Smrg last = &pt[0]; 3602f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", 3612f167a42Smrg pt[p].x, pt[p].y, 3622f167a42Smrg last->x, last->y, ol->corner_radius); 3632f167a42Smrg } 3642f167a42Smrg last = &pt[ol->num_points - 1]; 3652f167a42Smrg if ((last->x != pt->x) || (last->y != pt->y)) { 3662f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", 3672f167a42Smrg pt[0].x, pt[0].y, 3682f167a42Smrg pt[1].x, pt[1].y, ol->corner_radius); 3692f167a42Smrg } 3702f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 3712f167a42Smrg fprintf(out, " cleartomark\n"); 3722f167a42Smrg } 3732f167a42Smrg } 3740e20ee16Smrg } 3752f167a42Smrg fprintf(out, " grestore\n"); 3762f167a42Smrg fprintf(out, "} def\n"); 3770e20ee16Smrg return; 3780e20ee16Smrg} 3790e20ee16Smrg 3800e20ee16Smrg/***====================================================================***/ 3810e20ee16Smrg 3822f167a42Smrgtypedef struct { 3832f167a42Smrg char * foundry; 3842f167a42Smrg char * face; 3852f167a42Smrg char * weight; 3862f167a42Smrg char * slant; 3872f167a42Smrg char * setWidth; 3882f167a42Smrg char * variant; 3892f167a42Smrg int pixelSize; 3902f167a42Smrg int ptSize; 3912f167a42Smrg int resX; 3922f167a42Smrg int resY; 3932f167a42Smrg char * spacing; 3942f167a42Smrg int avgWidth; 3952f167a42Smrg char * encoding; 3960e20ee16Smrg} FontStuff; 3970e20ee16Smrg 3980e20ee16Smrgstatic void 3990e20ee16SmrgClearFontStuff(FontStuff *stuff) 4000e20ee16Smrg{ 4010e20ee16Smrg if (stuff && stuff->foundry) 4022f167a42Smrg free(stuff->foundry); 4032f167a42Smrg bzero(stuff, sizeof(FontStuff)); 4040e20ee16Smrg return; 4050e20ee16Smrg} 4060e20ee16Smrg 4070e20ee16Smrgstatic Bool 4082f167a42SmrgCrackXLFDName(const char *name, FontStuff *stuff) 4090e20ee16Smrg{ 4102f167a42Smrg char *tmp; 4112f167a42Smrg 4122f167a42Smrg if ((name == NULL) || (stuff == NULL)) 4132f167a42Smrg return False; 4142f167a42Smrg if (name[0] == '-') 4152f167a42Smrg tmp = strdup(&name[1]); 4162f167a42Smrg else 4172f167a42Smrg tmp = strdup(name); 4182f167a42Smrg if (tmp == NULL) 4192f167a42Smrg return False; 4202f167a42Smrg stuff->foundry = tmp; 4212f167a42Smrg 4222f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4232f167a42Smrg goto BAILOUT; 4242f167a42Smrg else 4252f167a42Smrg *tmp++ = '\0'; 4262f167a42Smrg stuff->face = tmp; 4272f167a42Smrg 4282f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4292f167a42Smrg goto BAILOUT; 4302f167a42Smrg else 4312f167a42Smrg *tmp++ = '\0'; 4322f167a42Smrg stuff->weight = tmp; 4332f167a42Smrg 4342f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4352f167a42Smrg goto BAILOUT; 4362f167a42Smrg else 4372f167a42Smrg *tmp++ = '\0'; 4382f167a42Smrg stuff->slant = tmp; 4392f167a42Smrg 4402f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4412f167a42Smrg goto BAILOUT; 4422f167a42Smrg else 4432f167a42Smrg *tmp++ = '\0'; 4442f167a42Smrg stuff->setWidth = tmp; 4452f167a42Smrg 4462f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4472f167a42Smrg goto BAILOUT; 4482f167a42Smrg else 4492f167a42Smrg *tmp++ = '\0'; 4502f167a42Smrg stuff->variant = tmp; 4512f167a42Smrg 4522f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4532f167a42Smrg goto BAILOUT; 4542f167a42Smrg else 4552f167a42Smrg *tmp++ = '\0'; 4562f167a42Smrg if (*tmp == '*') 4572f167a42Smrg stuff->pixelSize = 0; 4582f167a42Smrg else if (sscanf(tmp, "%i", &stuff->pixelSize) != 1) 4592f167a42Smrg goto BAILOUT; 4602f167a42Smrg 4612f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4622f167a42Smrg goto BAILOUT; 4632f167a42Smrg else 4642f167a42Smrg *tmp++ = '\0'; 4652f167a42Smrg if (*tmp == '*') 4662f167a42Smrg stuff->ptSize = 0; 4672f167a42Smrg else if (sscanf(tmp, "%i", &stuff->ptSize) != 1) 4682f167a42Smrg goto BAILOUT; 4692f167a42Smrg 4702f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4712f167a42Smrg goto BAILOUT; 4722f167a42Smrg else 4732f167a42Smrg *tmp++ = '\0'; 4742f167a42Smrg if (*tmp == '*') 4752f167a42Smrg stuff->resX = 0; 4762f167a42Smrg else if (sscanf(tmp, "%i", &stuff->resX) != 1) 4772f167a42Smrg goto BAILOUT; 4782f167a42Smrg 4792f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4802f167a42Smrg goto BAILOUT; 4812f167a42Smrg else 4822f167a42Smrg *tmp++ = '\0'; 4832f167a42Smrg if (*tmp == '*') 4842f167a42Smrg stuff->resY = 0; 4852f167a42Smrg else if (sscanf(tmp, "%i", &stuff->resY) != 1) 4862f167a42Smrg goto BAILOUT; 4872f167a42Smrg 4882f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4892f167a42Smrg goto BAILOUT; 4902f167a42Smrg else 4912f167a42Smrg *tmp++ = '\0'; 4922f167a42Smrg stuff->spacing = tmp; 4932f167a42Smrg 4942f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4952f167a42Smrg goto BAILOUT; 4962f167a42Smrg else 4972f167a42Smrg *tmp++ = '\0'; 4982f167a42Smrg if (*tmp == '*') 4992f167a42Smrg stuff->avgWidth = 0; 5002f167a42Smrg else if (sscanf(tmp, "%i", &stuff->avgWidth) != 1) 5012f167a42Smrg goto BAILOUT; 5022f167a42Smrg 5032f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 5042f167a42Smrg goto BAILOUT; 5052f167a42Smrg else 5062f167a42Smrg *tmp++ = '\0'; 5072f167a42Smrg stuff->encoding = tmp; 5080e20ee16Smrg return True; 5092f167a42Smrg BAILOUT: 5100e20ee16Smrg ClearFontStuff(stuff); 5110e20ee16Smrg return False; 5120e20ee16Smrg} 5130e20ee16Smrg 5140e20ee16Smrgstatic void 5150e20ee16SmrgPSSetUpForLatin1(FILE *out, PSState *state) 5160e20ee16Smrg{ 5172f167a42Smrg fprintf(out, "%s", 5182f167a42Smrg "save\n" 5192f167a42Smrg "/ISOLatin1Encoding where {pop save true}{false} ifelse\n" 5202f167a42Smrg "/ISOLatin1Encoding [\n" 5212f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5222f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5232f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5242f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5252f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5262f167a42Smrg " /.notdef /.notdef /space /exclam /quotedbl /numbersign\n" 5272f167a42Smrg " /dollar /percent /ampersand /quoteright /parenleft\n" 5282f167a42Smrg " /parenright /asterisk /plus /comma /minus /period\n" 5292f167a42Smrg " /slash /zero /one /two /three /four /five /six /seven\n" 5302f167a42Smrg " /eight /nine /colon /semicolon /less /equal /greater\n" 5312f167a42Smrg " /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M\n" 5322f167a42Smrg " /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft\n" 5332f167a42Smrg " /backslash /bracketright /asciicircum /underscore\n" 5342f167a42Smrg " /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m\n" 5352f167a42Smrg " /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft\n" 5362f167a42Smrg " /bar /braceright /asciitilde /guilsinglright /fraction\n" 5372f167a42Smrg " /florin /quotesingle /quotedblleft /guilsinglleft /fi\n" 5382f167a42Smrg " /fl /endash /dagger /daggerdbl /bullet /quotesinglbase\n" 5392f167a42Smrg " /quotedblbase /quotedblright /ellipsis /trademark\n" 5402f167a42Smrg " /perthousand /grave /scaron /circumflex /Scaron /tilde\n" 5412f167a42Smrg " /breve /zcaron /dotaccent /dotlessi /Zcaron /ring\n" 5422f167a42Smrg " /hungarumlaut /ogonek /caron /emdash /space /exclamdown\n" 5432f167a42Smrg " /cent /sterling /currency /yen /brokenbar /section\n" 5442f167a42Smrg " /dieresis /copyright /ordfeminine /guillemotleft\n" 5452f167a42Smrg " /logicalnot /hyphen /registered /macron /degree\n" 5462f167a42Smrg " /plusminus /twosuperior /threesuperior /acute /mu\n" 5472f167a42Smrg " /paragraph /periodcentered /cedilla /onesuperior\n" 5482f167a42Smrg " /ordmasculine /guillemotright /onequarter /onehalf\n" 5492f167a42Smrg " /threequarters /questiondown /Agrave /Aacute\n" 5502f167a42Smrg " /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n" 5512f167a42Smrg " /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute\n" 5522f167a42Smrg " /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute\n" 5532f167a42Smrg " /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n" 5542f167a42Smrg " /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n" 5552f167a42Smrg " /germandbls /agrave /aacute /acircumflex /atilde\n" 5562f167a42Smrg " /adieresis /aring /ae /ccedilla /egrave /eacute\n" 5572f167a42Smrg " /ecircumflex /edieresis /igrave /iacute /icircumflex\n" 5582f167a42Smrg " /idieresis /eth /ntilde /ograve /oacute /ocircumflex\n" 5592f167a42Smrg " /otilde /odieresis /divide /oslash /ugrave /uacute\n" 5602f167a42Smrg " /ucircumflex /udieresis /yacute /thorn /ydieresis\n" 5612f167a42Smrg "] def {restore} if\n" 5622f167a42Smrg "/reencodeISO-1 {\n" 5632f167a42Smrg " dup length dict begin\n" 5642f167a42Smrg " {1 index /FID ne {def}{pop pop} ifelse} forall\n" 5652f167a42Smrg " /Encoding ISOLatin1Encoding def\n" 5662f167a42Smrg " currentdict\n" 5672f167a42Smrg " end\n" 5682f167a42Smrg "} def\n" 5692f167a42Smrg ); 5700e20ee16Smrg} 5710e20ee16Smrg 5720e20ee16Smrgstatic void 5732f167a42SmrgPSReencodeLatin1Font(FILE *out, const char *font) 5740e20ee16Smrg{ 5752f167a42Smrg fprintf(out, "/%s findfont reencodeISO-1\n", font); 5762f167a42Smrg fprintf(out, " /%s-8859-1 exch definefont pop\n", font); 5770e20ee16Smrg return; 5780e20ee16Smrg} 5790e20ee16Smrg 5800e20ee16Smrgstatic void 5812f167a42SmrgPSSetUpFonts(FILE *out, const char *textFont, int size) 5820e20ee16Smrg{ 5832f167a42Smrg fprintf(out, "/F%d { /%s findfont exch scalefont setfont } def\n", 5842f167a42Smrg FONT_TEXT, textFont); 5852f167a42Smrg fprintf(out, "/F%d { /%s-8859-1 findfont exch scalefont setfont } def\n", 5862f167a42Smrg FONT_LATIN1, textFont); 5872f167a42Smrg fprintf(out, "/F%d { /%s findfont exch scalefont setfont } def\n", 5882f167a42Smrg FONT_SYMBOL, "Symbol"); 5892f167a42Smrg fprintf(out, "/F%d { /%s findfont exch scalefont setfont } def\n", 5902f167a42Smrg FONT_ISOCAPS, "IsoKeyCaps"); 5910e20ee16Smrg return; 5920e20ee16Smrg} 5930e20ee16Smrg 5940e20ee16Smrgstatic void 5950e20ee16SmrgPSSetFont(FILE *out, PSState *state, int font, int size, int pts) 5960e20ee16Smrg{ 5972f167a42Smrg if ((state->font != font) || (state->fontSize != size)) { 5982f167a42Smrg fprintf(out, "%d %sF%d\n", size, (pts ? "pts " : ""), font); 5992f167a42Smrg state->font = font; 6002f167a42Smrg state->fontSize = size; 6010e20ee16Smrg } 6020e20ee16Smrg return; 6030e20ee16Smrg} 6040e20ee16Smrg 6050e20ee16Smrgstatic void 6060e20ee16SmrgPSProlog(FILE *out, PSState *state) 6070e20ee16Smrg{ 6082f167a42Smrg register int i; 6090e20ee16Smrg 6100e20ee16Smrg if (!state->args->wantEPS) { 6112f167a42Smrg fprintf(out, 6122f167a42Smrg "%%!PS-Adobe-2.0\n" 6132f167a42Smrg "%%%%Creator: xkbprint\n"); 614e6bced22Smrg if (state->geom->name != None) { 615e6bced22Smrg char *a = XkbAtomGetString(state->dpy, state->geom->name); 616e6bced22Smrg fprintf(out, "%%%%Title: %s\n", a); 617e6bced22Smrg XFree(a); 618e6bced22Smrg } 6192f167a42Smrg fprintf(out, 6202f167a42Smrg "%%%%BoundingBox: (atend)\n" 6212f167a42Smrg "%%%%Pages: 1\n" 6222f167a42Smrg "%%%%PageOrder: Ascend\n" 6232f167a42Smrg "%%%%DocumentFonts: (atend)\n" 6242f167a42Smrg "%%%%DocumentData: Clean7Bit\n" 6252f167a42Smrg "%%%%Orientation: Landscape\n" 6262f167a42Smrg "%%%%EndComments\n" 6272f167a42Smrg "%%%%BeginProlog\n" 6282f167a42Smrg "%% Resolution is 1/10mm -- need pt sizes for fonts\n" 6292f167a42Smrg "clippath pathbbox\n" 6302f167a42Smrg " /ury exch def /urx exch def\n" 6312f167a42Smrg " /llx exch def /lly exch def\n" 6322f167a42Smrg " newpath\n" 6332f167a42Smrg "/devwidth urx llx sub def\n" 6342f167a42Smrg "/devheight ury lly sub def\n"); 6350e20ee16Smrg } 6360e20ee16Smrg else { 6372f167a42Smrg int w, h; 6382f167a42Smrg int pw, ph; 6392f167a42Smrg 6402f167a42Smrg w = (((state->geom->width_mm * 72) / 254) * 11) / 10; 6412f167a42Smrg h = (((state->geom->height_mm * 72) / 254) * 11) / 10; 6422f167a42Smrg if (state->kbPerPage > 1) 6432f167a42Smrg h *= (state->kbPerPage + 1); 6442f167a42Smrg 6452f167a42Smrg if (w <= h) { 6462f167a42Smrg pw = 7.5 * 72; 6472f167a42Smrg ph = 10 * 72; 6482f167a42Smrg } 6492f167a42Smrg else { 6502f167a42Smrg pw = 10 * 72; 6512f167a42Smrg ph = 7.5 * 72; 6522f167a42Smrg } 6532f167a42Smrg while ((w > pw) || (h > ph)) { 6542f167a42Smrg w = (w * 9) / 10; 6552f167a42Smrg h = (h * 9) / 10; 6562f167a42Smrg } 6572f167a42Smrg 6582f167a42Smrg fprintf(out, "%%!PS-Adobe-2.0 EPSF-2.0\n"); 6592f167a42Smrg fprintf(out, "%%%%BoundingBox: 0 0 %d %d\n", w, h); 6602f167a42Smrg fprintf(out, "%%%%Creator: xkbprint\n"); 661e6bced22Smrg if (state->geom->name != None) { 662e6bced22Smrg char *a = XkbAtomGetString(state->dpy, state->geom->name); 663e6bced22Smrg fprintf(out, "%%%%Title: %s\n", a); 664e6bced22Smrg XFree(a); 665e6bced22Smrg } 6662f167a42Smrg fprintf(out, "%%%%Pages: 1\n"); 6672f167a42Smrg fprintf(out, "%%%%EndComments\n"); 6682f167a42Smrg fprintf(out, "%%%%BeginProlog\n"); 6692f167a42Smrg fprintf(out, "/ury 0 def /urx 0 def\n"); 6702f167a42Smrg fprintf(out, "/llx %d def /lly %d def\n", w, h); 6712f167a42Smrg fprintf(out, "/devwidth %d def /devheight %d def\n", w, h); 6720e20ee16Smrg } 6732f167a42Smrg fprintf(out, "/kbdwidth %d def\n", state->geom->width_mm); 6742f167a42Smrg fprintf(out, "/kbdheight %d def\n", state->geom->height_mm); 6752f167a42Smrg fprintf(out, "%s", 6762f167a42Smrg "/pts { 254 mul 72 div } def\n" 6772f167a42Smrg "/mm10 { 72 mul 254 div } def\n" 6782f167a42Smrg "/landscape? {\n" 6792f167a42Smrg " devheight devwidth gt {\n" 6802f167a42Smrg " /pwidth devheight def /pheight devwidth def\n" 6812f167a42Smrg " 0 devheight translate\n" 6822f167a42Smrg " -90 rotate\n" 6832f167a42Smrg " } {\n" 6842f167a42Smrg " /pwidth devwidth def /pheight devheight def\n" 6852f167a42Smrg " } ifelse\n" 6862f167a42Smrg " 0 pheight translate\n" 6872f167a42Smrg " 1 -1 scale\n" 6882f167a42Smrg "} def\n" 6892f167a42Smrg "/centeroffset {\n" 6902f167a42Smrg " /S exch def\n" 6912f167a42Smrg " /HEIGHT exch def\n" 6922f167a42Smrg " /WIDTH exch def\n" 6932f167a42Smrg " S stringwidth /SH exch def /SW exch def\n" 6942f167a42Smrg " WIDTH SW sub 2 div\n" 6952f167a42Smrg " HEIGHT SH sub 2 div\n" 6962f167a42Smrg "} def\n"); 6972f167a42Smrg PSSetUpForLatin1(out, state); 6982f167a42Smrg PSReencodeLatin1Font(out, DFLT_LABEL_FONT); 6990e20ee16Smrg if (state->args->wantColor) { 7002f167a42Smrg XkbGeometryPtr geom = state->geom; 7012f167a42Smrg 7022f167a42Smrg for (i = 0; i < geom->num_colors; i++) { 7032f167a42Smrg PSColorDef(out, state, &geom->colors[i]); 7042f167a42Smrg } 7052f167a42Smrg if (state->black < 0) { 7062f167a42Smrg XkbColorPtr color; 7072f167a42Smrg 7082f167a42Smrg if (!(color = XkbAddGeomColor(geom, "black", geom->num_colors))) 7092f167a42Smrg uFatalError("Couldn't allocate black color!\n"); 7102f167a42Smrg PSColorDef(out, state, color); 7112f167a42Smrg } 7122f167a42Smrg if (state->white < 0) { 7132f167a42Smrg XkbColorPtr color; 7142f167a42Smrg 7152f167a42Smrg if (!(color = XkbAddGeomColor(geom, "white", geom->num_colors))) 7162f167a42Smrg uFatalError("Couldn't allocate white color!\n"); 7172f167a42Smrg PSColorDef(out, state, color); 7182f167a42Smrg } 7190e20ee16Smrg } 7202f167a42Smrg for (i = 0; i < state->geom->num_shapes; i++) { 7212f167a42Smrg PSShapeDef(out, state, &state->geom->shapes[i]); 7220e20ee16Smrg } 7232f167a42Smrg if (state->args->label == LABEL_SYMBOLS) { 7242f167a42Smrg PSIncludeFont(out, "IsoKeyCaps"); 7250e20ee16Smrg } 7262f167a42Smrg PSSetUpFonts(out, DFLT_LABEL_FONT, DFLT_LABEL_FONT_SIZE); 7272f167a42Smrg fprintf(out, "%%%%EndProlog\n"); 7280e20ee16Smrg return; 7290e20ee16Smrg} 7300e20ee16Smrg 7310e20ee16Smrgstatic void 7320e20ee16SmrgPSFileTrailer(FILE *out, PSState *state) 7330e20ee16Smrg{ 7342f167a42Smrg fprintf(out, "restore\n"); 7350e20ee16Smrg if (!state->args->wantEPS) 7362f167a42Smrg fprintf(out, "%%%%Trailer\n"); 7372f167a42Smrg fprintf(out, "%%%%EOF\n"); 7380e20ee16Smrg return; 7390e20ee16Smrg} 7400e20ee16Smrg 7410e20ee16Smrgstatic void 7420e20ee16SmrgPSPageSetup(FILE *out, PSState *state, Bool drawBorder) 7430e20ee16Smrg{ 7442f167a42Smrg XkbGeometryPtr geom; 7450e20ee16Smrg 7462f167a42Smrg geom = state->geom; 7472f167a42Smrg if (state->kbPerPage == 1) { 7482f167a42Smrg fprintf(out, "%%%%Page: %d %d\n", state->nPages + 1, state->nPages + 1); 7492f167a42Smrg fprintf(out, "%%%%BeginPageSetup\n"); 7500e20ee16Smrg } 7512f167a42Smrg else if ((state->nPages & 1) == 0) { /* even page */ 7522f167a42Smrg int realPage; 7532f167a42Smrg 7542f167a42Smrg realPage = state->nPages / 2 + 1; 7552f167a42Smrg fprintf(out, "%%%%Page: %d %d\n", realPage, realPage); 7562f167a42Smrg fprintf(out, "%%%%BeginPageSetup\n"); 7572f167a42Smrg fprintf(out, "%% Keyboard %d\n", state->nPages + 1); 7582f167a42Smrg if (state->nPages == 0) { 7592f167a42Smrg fprintf(out, 7602f167a42Smrg "/realwidth devwidth def\n" 7612f167a42Smrg "/realheight devheight def\n" 7622f167a42Smrg "/devheight realheight 3 div def\n"); 7632f167a42Smrg } 7642f167a42Smrg fprintf(out, "0 devheight dup 2 div add translate\n"); 7650e20ee16Smrg } 7662f167a42Smrg else { 7672f167a42Smrg fprintf(out, "%% Keyboard %d\n", state->nPages + 1); 7680e20ee16Smrg } 7692f167a42Smrg fprintf(out, "save\n"); 7702f167a42Smrg fprintf(out, "landscape?\n"); 7710e20ee16Smrg if (state->args->scaleToFit) { 7722f167a42Smrg fprintf(out, 7732f167a42Smrg "%% Scale keyboard to fit on the page\n" 7742f167a42Smrg "/kbdscale pwidth 72 sub kbdwidth div def\n" 7752f167a42Smrg "/kbdscalewidth kbdwidth kbdscale mul def\n" 7762f167a42Smrg "/kbdscaleheight kbdheight kbdscale mul def\n" 7772f167a42Smrg "/kbx 36 def\n" 7782f167a42Smrg "/kby pheight kbdscaleheight sub 2 div def\n"); 7792f167a42Smrg PSGSave(out, state); 7802f167a42Smrg fprintf(out, 7812f167a42Smrg "kbx kby translate\n" 7822f167a42Smrg "kbdscale kbdscale scale\n"); 7830e20ee16Smrg } 7840e20ee16Smrg else { 7852f167a42Smrg fprintf(out, 7862f167a42Smrg "%% Draw keyboard full size\n" 7872f167a42Smrg "/kbdscale 1 def\n" 7882f167a42Smrg "/kbdscalewidth kbdwidth mm10 def\n" 7892f167a42Smrg "/kbdscaleheight kbdheight mm10 def\n" 7902f167a42Smrg "/kbx pwidth kbdscalewidth sub 2 div def\n" 7912f167a42Smrg "/kby pheight kbdscaleheight sub 2 div def\n"); 7922f167a42Smrg PSGSave(out, state); 7932f167a42Smrg fprintf(out, 7942f167a42Smrg "kbx kby translate\n" 7952f167a42Smrg "72 254 div dup scale\n"); 7960e20ee16Smrg } 7970e20ee16Smrg if (drawBorder) { 7982f167a42Smrg if (state->args->wantColor) { 7992f167a42Smrg PSSetColor(out, state, geom->base_color->pixel); 8002f167a42Smrg fprintf(out, " 0 0 moveto\n"); 8012f167a42Smrg fprintf(out, "%3d 0 lineto\n", geom->width_mm); 8022f167a42Smrg fprintf(out, "%3d %3d lineto\n", geom->width_mm, geom->height_mm); 8032f167a42Smrg fprintf(out, " 0 %3d lineto\n", geom->height_mm); 8042f167a42Smrg fprintf(out, "closepath fill\n"); 8052f167a42Smrg } 8062f167a42Smrg PSSetColor(out, state, state->black); 8072f167a42Smrg fprintf(out, " 0 0 moveto\n"); 8082f167a42Smrg fprintf(out, "%3d 0 lineto\n", geom->width_mm); 8092f167a42Smrg fprintf(out, "%3d %3d lineto\n", geom->width_mm, geom->height_mm); 8102f167a42Smrg fprintf(out, " 0 %3d lineto\n", geom->height_mm); 8112f167a42Smrg fprintf(out, "closepath stroke\n"); 8120e20ee16Smrg } 8132f167a42Smrg fprintf(out, "%%%%EndPageSetup\n"); 8140e20ee16Smrg return; 8150e20ee16Smrg} 8160e20ee16Smrg 8170e20ee16Smrgstatic void 8180e20ee16SmrgPSPageTrailer(FILE *out, PSState *state) 8190e20ee16Smrg{ 8202f167a42Smrg char *name; 8212f167a42Smrg XkbDescPtr xkb; 8222f167a42Smrg XkbGeometryPtr geom; 8232f167a42Smrg XkbPropertyPtr prop; 8242f167a42Smrg int p, baseline; 8252f167a42Smrg 8262f167a42Smrg xkb = state->xkb; 8272f167a42Smrg geom = state->geom; 8282f167a42Smrg if (state->args->grid > 0) { 8292f167a42Smrg fprintf(out, "%% Draw a %dmm grid\n", state->args->grid); 8302f167a42Smrg fprintf(out, "0 setlinewidth\n"); 8312f167a42Smrg fprintf(out, "0.25 setgray\n"); 8322f167a42Smrg fprintf(out, " 0 %d %d {\n", state->args->grid * 10, geom->width_mm); 8332f167a42Smrg fprintf(out, " /GX exch def\n"); 8342f167a42Smrg fprintf(out, " GX 0 moveto GX %d lineto stroke\n", geom->height_mm); 8352f167a42Smrg fprintf(out, "} for\n"); 8362f167a42Smrg fprintf(out, " 0 %d %d {\n", state->args->grid * 10, geom->height_mm); 8372f167a42Smrg fprintf(out, " /GY exch def\n"); 8382f167a42Smrg fprintf(out, " 0 GY moveto %d GY lineto stroke\n", geom->width_mm); 8392f167a42Smrg fprintf(out, "} for\n"); 8400e20ee16Smrg } 8412f167a42Smrg PSGRestore(out, state); 8422f167a42Smrg name = NULL; 8432f167a42Smrg for (p = 0, prop = geom->properties; p < geom->num_properties; p++, prop++) { 8442f167a42Smrg if ((prop->value != NULL) && (uStrCaseEqual(prop->name, "description"))) { 8452f167a42Smrg name = prop->value; 8462f167a42Smrg break; 8472f167a42Smrg } 8480e20ee16Smrg } 8492f167a42Smrg if ((!state->args->wantEPS) && 8502f167a42Smrg ((state->kbPerPage == 1) || ((state->nPages & 1) == 1) || 8512f167a42Smrg (state->nPages == state->totalKB))) { 852e6bced22Smrg char *a1 = NULL; 853e6bced22Smrg 8542f167a42Smrg if ((name == NULL) && (geom->name != None)) 855e6bced22Smrg name = a1 = XkbAtomGetString(state->dpy, geom->name); 8562f167a42Smrg 8572f167a42Smrg baseline = 16; 8582f167a42Smrg if ((name != NULL) || (state->args->label == LABEL_SYMBOLS)) { 8592f167a42Smrg PSSetColor(out, state, state->black); 8602f167a42Smrg PSSetFont(out, state, FONT_LATIN1, 14, False); 8612f167a42Smrg } 8622f167a42Smrg if (state->args->label == LABEL_SYMBOLS) { 8632f167a42Smrg char buf[40], *lbuf; 8642f167a42Smrg const char *sName = NULL; 865e6bced22Smrg char *a2 = NULL; 8662f167a42Smrg Atom sAtom; 8672f167a42Smrg 8682f167a42Smrg if (state->args->nLabelGroups == 1) 8692f167a42Smrg snprintf(buf, sizeof(buf), "Group %d", 8702f167a42Smrg state->args->baseLabelGroup + 1); 8712f167a42Smrg else 8722f167a42Smrg snprintf(buf, sizeof(buf), "Groups %d-%d", 8732f167a42Smrg state->args->baseLabelGroup + 1, 8742f167a42Smrg state->args->baseLabelGroup + 8752f167a42Smrg state->args->nLabelGroups); 8762f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 8772f167a42Smrg buf); 8782f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 8792f167a42Smrg fprintf(out, " moveto\n"); 8802f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", buf); 8812f167a42Smrg baseline += 16; 8822f167a42Smrg 8832f167a42Smrg if (xkb->names != NULL) 8842f167a42Smrg sAtom = xkb->names->symbols; 8852f167a42Smrg else 8862f167a42Smrg sAtom = None; 8872f167a42Smrg if (sAtom != None) 888e6bced22Smrg sName = a2 = XkbAtomGetString(state->dpy, sAtom); 8892f167a42Smrg if (sName == NULL) 8902f167a42Smrg sName = "(unknown)"; 8912f167a42Smrg 8922f167a42Smrg if (asprintf(&lbuf, "Layout: %s", sName) == -1) { 8932f167a42Smrg uFatalError("Can't allocate memory for string\n"); 8942f167a42Smrg } 8952f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 8962f167a42Smrg lbuf); 8972f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 8982f167a42Smrg fprintf(out, " moveto\n"); 8992f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", lbuf); 9002f167a42Smrg baseline += 16; 9012f167a42Smrg free(lbuf); 902e6bced22Smrg XFree(a2); 9032f167a42Smrg } 9042f167a42Smrg if (name != NULL) { 9052f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 9062f167a42Smrg name); 9072f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 9082f167a42Smrg fprintf(out, " moveto\n"); 9092f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", name); 9102f167a42Smrg baseline += 16; 911e6bced22Smrg name = NULL; 912e6bced22Smrg XFree(a1); 9132f167a42Smrg } 9142f167a42Smrg if (state->args->label == LABEL_KEYCODE) { 9152f167a42Smrg const char *sName = NULL; 9162f167a42Smrg char *lbuf; 917e6bced22Smrg char *a3 = NULL; 9182f167a42Smrg Atom sAtom; 9192f167a42Smrg 9202f167a42Smrg if (xkb->names != NULL) 9212f167a42Smrg sAtom = xkb->names->keycodes; 9222f167a42Smrg else 9232f167a42Smrg sAtom = None; 9242f167a42Smrg if (sAtom != None) 925e6bced22Smrg sName = a3 = XkbAtomGetString(state->dpy, sAtom); 9262f167a42Smrg if (sName == NULL) 9272f167a42Smrg sName = "(unknown)"; 9282f167a42Smrg 9292f167a42Smrg if (asprintf(&lbuf, "Keycodes: %s", sName) == -1) { 9302f167a42Smrg uFatalError("Can't allocate memory for string\n"); 9312f167a42Smrg } 9322f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 9332f167a42Smrg lbuf); 9342f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 9352f167a42Smrg fprintf(out, " moveto\n"); 9362f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", lbuf); 9372f167a42Smrg baseline += 16; 9382f167a42Smrg free(lbuf); 939e6bced22Smrg XFree(a3); 9402f167a42Smrg } 9412f167a42Smrg if (state->args->copies > 1) { 9422f167a42Smrg for (p = 1; p < state->args->copies; p++) 9432f167a42Smrg fprintf(out, "copypage\n"); 9442f167a42Smrg } 9452f167a42Smrg fprintf(out, "showpage\n"); 9462f167a42Smrg fprintf(out, "restore\n"); 9472f167a42Smrg fprintf(out, "%% Done with keyboard/page %d\n", state->nPages + 1); 9480e20ee16Smrg } 9490e20ee16Smrg else { 9502f167a42Smrg if ((!state->args->wantEPS) && (state->args->label == LABEL_SYMBOLS)) { 9512f167a42Smrg char buf[40]; 9522f167a42Smrg 9532f167a42Smrg baseline = 16; 9542f167a42Smrg PSSetColor(out, state, state->black); 9552f167a42Smrg PSSetFont(out, state, FONT_LATIN1, 14, False); 9562f167a42Smrg if (state->args->nLabelGroups == 1) 9572f167a42Smrg snprintf(buf, sizeof(buf), "Group %d", 9582f167a42Smrg state->args->baseLabelGroup + 1); 9592f167a42Smrg else 9602f167a42Smrg snprintf(buf, sizeof(buf), "Groups %d-%d", 9612f167a42Smrg state->args->baseLabelGroup + 1, 9622f167a42Smrg state->args->baseLabelGroup + 9632f167a42Smrg state->args->nLabelGroups + 1); 9642f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 9652f167a42Smrg buf); 9662f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 9672f167a42Smrg fprintf(out, " moveto\n"); 9682f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", buf); 9692f167a42Smrg baseline += 16; 9702f167a42Smrg } 9712f167a42Smrg fprintf(out, "restore\n"); 9722f167a42Smrg fprintf(out, "%% Done with keyboard %d\n", state->nPages + 1); 9732f167a42Smrg fprintf(out, "0 devheight -1 mul translate %% next keyboard\n"); 9740e20ee16Smrg } 9750e20ee16Smrg state->nPages++; 9762f167a42Smrg state->color = state->black; 9772f167a42Smrg state->font = -1; 9780e20ee16Smrg return; 9790e20ee16Smrg} 9800e20ee16Smrg 9810e20ee16Smrgstatic void 9820e20ee16SmrgPSDoodad(FILE *out, PSState *state, XkbDoodadPtr doodad) 9830e20ee16Smrg{ 9842f167a42Smrg XkbDescPtr xkb; 9852f167a42Smrg const char *name, *dname; 986e6bced22Smrg char *a1 = NULL, *a2 = NULL; 9872f167a42Smrg int sz, leading; 9882f167a42Smrg 9892f167a42Smrg xkb = state->xkb; 9902f167a42Smrg if (doodad->any.name != None) 991e6bced22Smrg dname = a1 = XkbAtomGetString(xkb->dpy, doodad->any.name); 9922f167a42Smrg else 9932f167a42Smrg dname = "NoName"; 9940e20ee16Smrg switch (doodad->any.type) { 9952f167a42Smrg case XkbOutlineDoodad: 9962f167a42Smrg case XkbSolidDoodad: 997e6bced22Smrg name = a2 = XkbAtomGetString(xkb->dpy, 9982f167a42Smrg XkbShapeDoodadShape(xkb->geom, 9992f167a42Smrg &doodad->shape)->name); 10002f167a42Smrg if (state->args->wantColor) { 10012f167a42Smrg PSSetColor(out, state, doodad->shape.color_ndx); 10022f167a42Smrg if (doodad->any.type != XkbOutlineDoodad) { 10032f167a42Smrg fprintf(out, "true %d %d %d %s %% Doodad %s\n", 10042f167a42Smrg doodad->shape.angle, 10052f167a42Smrg doodad->shape.left, doodad->shape.top, name, dname); 10062f167a42Smrg PSSetColor(out, state, state->black); 10072f167a42Smrg } 10082f167a42Smrg fprintf(out, "false %d %d %d %s %% Doodad %s\n", 10092f167a42Smrg doodad->shape.angle, 10102f167a42Smrg doodad->shape.left, doodad->shape.top, name, dname); 10112f167a42Smrg } 10122f167a42Smrg else { 10132f167a42Smrg fprintf(out, "false %d %d %d %s %% Doodad %s\n", 10142f167a42Smrg doodad->shape.angle, 10152f167a42Smrg doodad->shape.left, doodad->shape.top, name, dname); 10162f167a42Smrg } 1017e6bced22Smrg name = NULL; 1018e6bced22Smrg XFree(a2); 10192f167a42Smrg break; 10202f167a42Smrg case XkbTextDoodad: 10212f167a42Smrg fprintf(out, "%% Doodad %s\n", dname); 10222f167a42Smrg PSSetColor(out, state, doodad->text.color_ndx); 10232f167a42Smrg PSGSave(out, state); 10242f167a42Smrg fprintf(out, "%d %d translate\n", doodad->text.left, doodad->text.top); 10252f167a42Smrg if (doodad->text.angle != 0) 10262f167a42Smrg fprintf(out, "%s rotate\n", 10272f167a42Smrg XkbGeomFPText(doodad->text.angle, XkbMessage)); 10282f167a42Smrg sz = 14; 10292f167a42Smrg if (doodad->text.font) { 10302f167a42Smrg FontStuff stuff; 10312f167a42Smrg 10322f167a42Smrg if (CrackXLFDName(doodad->text.font, &stuff)) { 10332f167a42Smrg if (stuff.ptSize > 0) 10342f167a42Smrg sz = stuff.ptSize / 10; 10352f167a42Smrg ClearFontStuff(&stuff); 10362f167a42Smrg } 10372f167a42Smrg } 10382f167a42Smrg PSSetFont(out, state, FONT_LATIN1, sz, True); 10392f167a42Smrg leading = (sz * 12) / 10; 10402f167a42Smrg if (strchr(doodad->text.text, '\n') == NULL) { 10412f167a42Smrg fprintf(out, "0 %d pts moveto 1 -1 scale\n", (leading * 8) / 10); 10422f167a42Smrg fprintf(out, "(%s) show\n", doodad->text.text); 10432f167a42Smrg } 10442f167a42Smrg else { 10452f167a42Smrg char *tmp, *buf, *end; 10462f167a42Smrg int offset = (leading * 8 / 10); 10472f167a42Smrg 10482f167a42Smrg tmp = buf = strdup(doodad->text.text); 10492f167a42Smrg while (tmp != NULL) { 10502f167a42Smrg end = strchr(tmp, '\n'); 10512f167a42Smrg if (end != NULL) 10522f167a42Smrg *end++ = '\0'; 10532f167a42Smrg fprintf(out, "0 %d pts moveto 1 -1 scale\n", offset); 10542f167a42Smrg fprintf(out, "(%s) show 1 -1 scale\n", tmp); 10552f167a42Smrg offset += leading; 10562f167a42Smrg tmp = end; 10572f167a42Smrg } 10582f167a42Smrg free(buf); 10592f167a42Smrg } 10602f167a42Smrg PSGRestore(out, state); 10612f167a42Smrg break; 10622f167a42Smrg case XkbIndicatorDoodad: 1063e6bced22Smrg name = a2 = XkbAtomGetString(xkb->dpy, 10642f167a42Smrg XkbIndicatorDoodadShape(xkb->geom, 10652f167a42Smrg &doodad->indicator)-> 10662f167a42Smrg name); 10672f167a42Smrg if (state->args->wantColor) { 10682f167a42Smrg PSSetColor(out, state, doodad->indicator.off_color_ndx); 10692f167a42Smrg fprintf(out, "true 0 %d %d %s %% Doodad %s\n", 10702f167a42Smrg doodad->indicator.left, doodad->indicator.top, name, dname); 10712f167a42Smrg PSSetColor(out, state, state->black); 10722f167a42Smrg } 10732f167a42Smrg fprintf(out, "false 0 %d %d %s %% Doodad %s\n", 10742f167a42Smrg doodad->indicator.left, doodad->indicator.top, name, dname); 1075e6bced22Smrg name = NULL; 1076e6bced22Smrg XFree(a2); 10772f167a42Smrg break; 10782f167a42Smrg case XkbLogoDoodad: 1079e6bced22Smrg name = a2 = XkbAtomGetString(xkb->dpy, 10802f167a42Smrg XkbLogoDoodadShape(xkb->geom, 10812f167a42Smrg &doodad->logo)->name); 10822f167a42Smrg if (state->args->wantColor) 10832f167a42Smrg PSSetColor(out, state, doodad->shape.color_ndx); 10842f167a42Smrg fprintf(out, "false %d %d %d %s %% Doodad %s\n", 10852f167a42Smrg doodad->shape.angle, 10862f167a42Smrg doodad->shape.left, doodad->shape.top, name, dname); 1087e6bced22Smrg name = NULL; 1088e6bced22Smrg XFree(a2); 10892f167a42Smrg break; 10900e20ee16Smrg } 1091e6bced22Smrg XFree(a1); 10920e20ee16Smrg return; 10930e20ee16Smrg} 10940e20ee16Smrg 10950e20ee16Smrg/***====================================================================***/ 10960e20ee16Smrg 10970e20ee16Smrgstatic Bool 10982f167a42SmrgPSKeycapsSymbol(KeySym sym, unsigned char *buf, 10992f167a42Smrg int *font_rtrn, int *sz_rtrn, PSState *state) 11000e20ee16Smrg{ 11012f167a42Smrg if (state->args->wantSymbols == NO_SYMBOLS) 11022f167a42Smrg return False; 11032f167a42Smrg 11042f167a42Smrg if (font_rtrn != NULL) 11052f167a42Smrg *font_rtrn = FONT_ISOCAPS; 11062f167a42Smrg if (sz_rtrn != NULL) 11072f167a42Smrg *sz_rtrn = SZ_LARGE; 11082f167a42Smrg buf[1] = '\0'; 11090e20ee16Smrg switch (sym) { 11102f167a42Smrg case XK_Shift_L: 11112f167a42Smrg case XK_Shift_R: 11122f167a42Smrg buf[0] = XKC_ISO_Shift; 11132f167a42Smrg return True; 11142f167a42Smrg case XK_Shift_Lock: 11152f167a42Smrg buf[0] = XKC_ISO_Shift_Lock; 11162f167a42Smrg return True; 11172f167a42Smrg case XK_ISO_Lock: 11182f167a42Smrg buf[0] = XKC_ISO_Caps_Lock; 11192f167a42Smrg return True; 11202f167a42Smrg case XK_BackSpace: 11212f167a42Smrg buf[0] = XKC_ISO_Backspace; 11222f167a42Smrg return True; 11232f167a42Smrg case XK_Return: 11242f167a42Smrg buf[0] = XKC_ISO_Return; 11252f167a42Smrg return True; 11262f167a42Smrg case XK_Up: 11272f167a42Smrg case XK_KP_Up: 11282f167a42Smrg buf[0] = XKC_ISO_Up; 11292f167a42Smrg return True; 11302f167a42Smrg case XK_Down: 11312f167a42Smrg case XK_KP_Down: 11322f167a42Smrg buf[0] = XKC_ISO_Down; 11332f167a42Smrg return True; 11342f167a42Smrg case XK_Left: 11352f167a42Smrg case XK_KP_Left: 11362f167a42Smrg buf[0] = XKC_ISO_Left; 11372f167a42Smrg return True; 11382f167a42Smrg case XK_Right: 11392f167a42Smrg case XK_KP_Right: 11402f167a42Smrg buf[0] = XKC_ISO_Right; 11412f167a42Smrg return True; 11422f167a42Smrg case XK_Tab: 11432f167a42Smrg buf[0] = XKC_ISO_Tab; 11442f167a42Smrg return True; 11452f167a42Smrg case XK_ISO_Left_Tab: 11462f167a42Smrg buf[0] = XKC_ISO_Left_Tab; 11472f167a42Smrg return True; 11480e20ee16Smrg } 11492f167a42Smrg if (state->args->wantSymbols != ALL_SYMBOLS) 11502f167a42Smrg return False; 11510e20ee16Smrg switch (sym) { 11522f167a42Smrg case XK_Caps_Lock: 11532f167a42Smrg buf[0] = XKC_ISO_Caps_Lock; 11542f167a42Smrg return True; 11552f167a42Smrg case XK_Num_Lock: 11562f167a42Smrg buf[0] = XKC_ISO_Num_Lock; 11572f167a42Smrg return True; 11582f167a42Smrg case XK_ISO_Level3_Shift: 11592f167a42Smrg buf[0] = XKC_ISO_Level3_Shift; 11602f167a42Smrg return True; 11612f167a42Smrg case XK_ISO_Level3_Lock: 11622f167a42Smrg buf[0] = XKC_ISO_Level3_Lock; 11632f167a42Smrg return True; 11642f167a42Smrg case XK_ISO_Next_Group: 11652f167a42Smrg case XK_ISO_Group_Shift: 11662f167a42Smrg buf[0] = XKC_ISO_Next_Group; 11672f167a42Smrg return True; 11682f167a42Smrg case XK_ISO_Next_Group_Lock: 11692f167a42Smrg buf[0] = XKC_ISO_Next_Group_Lock; 11702f167a42Smrg return True; 11712f167a42Smrg case XK_space: 11722f167a42Smrg buf[0] = XKC_ISO_Space; 11732f167a42Smrg return True; 11742f167a42Smrg case XK_nobreakspace: 11752f167a42Smrg buf[0] = XKC_ISO_No_Break_Space; 11762f167a42Smrg return True; 11772f167a42Smrg case XK_Insert: 11782f167a42Smrg buf[0] = XKC_ISO_Insert; 11792f167a42Smrg return True; 11802f167a42Smrg case XK_ISO_Continuous_Underline: 11812f167a42Smrg buf[0] = XKC_ISO_Continuous_Underline; 11822f167a42Smrg return True; 11832f167a42Smrg case XK_ISO_Discontinuous_Underline: 11842f167a42Smrg buf[0] = XKC_ISO_Discontinuous_Underline; 11852f167a42Smrg return True; 11862f167a42Smrg case XK_ISO_Emphasize: 11872f167a42Smrg buf[0] = XKC_ISO_Emphasize; 11882f167a42Smrg return True; 11892f167a42Smrg case XK_Multi_key: 11902f167a42Smrg buf[0] = XKC_ISO_Compose; 11912f167a42Smrg return True; 11922f167a42Smrg case XK_ISO_Center_Object: 11932f167a42Smrg buf[0] = XKC_ISO_Center_Object; 11942f167a42Smrg return True; 11952f167a42Smrg case XK_Delete: 11962f167a42Smrg buf[0] = XKC_ISO_Delete; 11972f167a42Smrg return True; 11982f167a42Smrg case XK_Clear: 11992f167a42Smrg buf[0] = XKC_ISO_Clear_Screen; 12002f167a42Smrg return True; 12012f167a42Smrg case XK_Scroll_Lock: 12022f167a42Smrg buf[0] = XKC_ISO_Scroll_Lock; 12032f167a42Smrg return True; 12042f167a42Smrg case XK_Help: 12052f167a42Smrg buf[0] = XKC_ISO_Help; 12062f167a42Smrg return True; 12072f167a42Smrg case XK_Print: 12082f167a42Smrg buf[0] = XKC_ISO_Print_Screen; 12092f167a42Smrg return True; 12102f167a42Smrg case XK_ISO_Enter: 12112f167a42Smrg buf[0] = XKC_ISO_Enter; 12122f167a42Smrg return True; 12132f167a42Smrg case XK_Alt_L: 12142f167a42Smrg case XK_Alt_R: 12152f167a42Smrg buf[0] = XKC_ISO_Alt; 12162f167a42Smrg return True; 12172f167a42Smrg case XK_Control_L: 12182f167a42Smrg case XK_Control_R: 12192f167a42Smrg buf[0] = XKC_ISO_Control; 12202f167a42Smrg return True; 12212f167a42Smrg case XK_Pause: 12222f167a42Smrg buf[0] = XKC_ISO_Pause; 12232f167a42Smrg return True; 12242f167a42Smrg case XK_Break: 12252f167a42Smrg buf[0] = XKC_ISO_Break; 12262f167a42Smrg return True; 12272f167a42Smrg case XK_Escape: 12282f167a42Smrg buf[0] = XKC_ISO_Escape; 12292f167a42Smrg return True; 12302f167a42Smrg case XK_Undo: 12312f167a42Smrg buf[0] = XKC_ISO_Undo; 12322f167a42Smrg return True; 12332f167a42Smrg case XK_ISO_Fast_Cursor_Up: 12342f167a42Smrg buf[0] = XKC_ISO_Fast_Cursor_Up; 12352f167a42Smrg return True; 12362f167a42Smrg case XK_ISO_Fast_Cursor_Down: 12372f167a42Smrg buf[0] = XKC_ISO_Fast_Cursor_Down; 12382f167a42Smrg return True; 12392f167a42Smrg case XK_ISO_Fast_Cursor_Left: 12402f167a42Smrg buf[0] = XKC_ISO_Fast_Cursor_Left; 12412f167a42Smrg return True; 12422f167a42Smrg case XK_ISO_Fast_Cursor_Right: 12432f167a42Smrg buf[0] = XKC_ISO_Fast_Cursor_Right; 12442f167a42Smrg return True; 12452f167a42Smrg case XK_Home: 12462f167a42Smrg buf[0] = XKC_ISO_Home; 12472f167a42Smrg return True; 12482f167a42Smrg case XK_End: 12492f167a42Smrg buf[0] = XKC_ISO_End; 12502f167a42Smrg return True; 12512f167a42Smrg case XK_Page_Up: 12522f167a42Smrg buf[0] = XKC_ISO_Page_Up; 12532f167a42Smrg return True; 12542f167a42Smrg case XK_Page_Down: 12552f167a42Smrg buf[0] = XKC_ISO_Page_Down; 12562f167a42Smrg return True; 12572f167a42Smrg case XK_ISO_Move_Line_Up: 12582f167a42Smrg buf[0] = XKC_ISO_Move_Line_Up; 12592f167a42Smrg return True; 12602f167a42Smrg case XK_ISO_Move_Line_Down: 12612f167a42Smrg buf[0] = XKC_ISO_Move_Line_Down; 12622f167a42Smrg return True; 12632f167a42Smrg case XK_ISO_Partial_Line_Up: 12642f167a42Smrg buf[0] = XKC_ISO_Partial_Line_Up; 12652f167a42Smrg return True; 12662f167a42Smrg case XK_ISO_Partial_Line_Down: 12672f167a42Smrg buf[0] = XKC_ISO_Partial_Line_Down; 12682f167a42Smrg return True; 12692f167a42Smrg case XK_ISO_Partial_Space_Left: 12702f167a42Smrg buf[0] = XKC_ISO_Partial_Space_Left; 12712f167a42Smrg return True; 12722f167a42Smrg case XK_ISO_Partial_Space_Right: 12732f167a42Smrg buf[0] = XKC_ISO_Partial_Space_Right; 12742f167a42Smrg return True; 12752f167a42Smrg case XK_ISO_Set_Margin_Left: 12762f167a42Smrg buf[0] = XKC_ISO_Set_Margin_Left; 12772f167a42Smrg return True; 12782f167a42Smrg case XK_ISO_Set_Margin_Right: 12792f167a42Smrg buf[0] = XKC_ISO_Set_Margin_Right; 12802f167a42Smrg return True; 12812f167a42Smrg case XK_ISO_Release_Margin_Left: 12822f167a42Smrg buf[0] = XKC_ISO_Release_Margin_Left; 12832f167a42Smrg return True; 12842f167a42Smrg case XK_ISO_Release_Margin_Right: 12852f167a42Smrg buf[0] = XKC_ISO_Release_Margin_Right; 12862f167a42Smrg return True; 12872f167a42Smrg case XK_ISO_Release_Both_Margins: 12882f167a42Smrg buf[0] = XKC_ISO_Release_Both_Margins; 12892f167a42Smrg return True; 12902f167a42Smrg case XK_ISO_Prev_Group: 12912f167a42Smrg buf[0] = XKC_ISO_Prev_Group; 12922f167a42Smrg return True; 12932f167a42Smrg case XK_ISO_Prev_Group_Lock: 12942f167a42Smrg buf[0] = XKC_ISO_Prev_Group_Lock; 12952f167a42Smrg return True; 12960e20ee16Smrg } 12970e20ee16Smrg return False; 12980e20ee16Smrg} 12990e20ee16Smrg 13000e20ee16Smrgstatic Bool 13010e20ee16SmrgPSNonLatin1Symbol(KeySym sym, unsigned char *buf, 13022f167a42Smrg int *font_rtrn, int *sz_rtrn, PSState *state) 13030e20ee16Smrg{ 13042f167a42Smrg if (state->args->wantSymbols == NO_SYMBOLS) 13052f167a42Smrg return False; 13062f167a42Smrg 13072f167a42Smrg if (font_rtrn != NULL) 13082f167a42Smrg *font_rtrn = FONT_TEXT; 13092f167a42Smrg if (sz_rtrn != NULL) 13102f167a42Smrg *sz_rtrn = SZ_LARGE; 13112f167a42Smrg buf[1] = '\0'; 13120e20ee16Smrg switch (sym) { 13132f167a42Smrg case XK_breve: 13142f167a42Smrg buf[0] = 0xC6; 13152f167a42Smrg return True; 13162f167a42Smrg case XK_abovedot: 13172f167a42Smrg buf[0] = 0xC7; 13182f167a42Smrg return True; 13192f167a42Smrg case XK_doubleacute: 13202f167a42Smrg buf[0] = 0xCD; 13212f167a42Smrg return True; 13222f167a42Smrg case XK_ogonek: 13232f167a42Smrg buf[0] = 0xCE; 13242f167a42Smrg return True; 13252f167a42Smrg case XK_caron: 13262f167a42Smrg buf[0] = 0xCF; 13272f167a42Smrg return True; 13282f167a42Smrg case XK_Lstroke: 13292f167a42Smrg buf[0] = 0xE8; 13302f167a42Smrg return True; 13312f167a42Smrg case XK_idotless: 13322f167a42Smrg buf[0] = 0xF5; 13332f167a42Smrg return True; 13342f167a42Smrg case XK_lstroke: 13352f167a42Smrg buf[0] = 0xF8; 13362f167a42Smrg return True; 13370e20ee16Smrg } 13382f167a42Smrg if (font_rtrn != NULL) 13392f167a42Smrg *font_rtrn = FONT_SYMBOL; 13402f167a42Smrg if (sz_rtrn != NULL) 13412f167a42Smrg *sz_rtrn = SZ_MEDIUM; 13422f167a42Smrg if ((sym & (~0xffUL)) == 0x700) { 13432f167a42Smrg switch (sym) { 13442f167a42Smrg /* Greek symbol */ 13452f167a42Smrg case XK_Greek_ALPHA: 13462f167a42Smrg buf[0] = 0x41; 13472f167a42Smrg return True; 13482f167a42Smrg case XK_Greek_BETA: 13492f167a42Smrg buf[0] = 0x42; 13502f167a42Smrg return True; 13512f167a42Smrg case XK_Greek_CHI: 13522f167a42Smrg buf[0] = 0x43; 13532f167a42Smrg return True; 13542f167a42Smrg case XK_Greek_DELTA: 13552f167a42Smrg buf[0] = 0x44; 13562f167a42Smrg return True; 13572f167a42Smrg case XK_Greek_EPSILON: 13582f167a42Smrg buf[0] = 0x45; 13592f167a42Smrg return True; 13602f167a42Smrg case XK_Greek_PHI: 13612f167a42Smrg buf[0] = 0x46; 13622f167a42Smrg return True; 13632f167a42Smrg case XK_Greek_GAMMA: 13642f167a42Smrg buf[0] = 0x47; 13652f167a42Smrg return True; 13662f167a42Smrg case XK_Greek_ETA: 13672f167a42Smrg buf[0] = 0x48; 13682f167a42Smrg return True; 13692f167a42Smrg case XK_Greek_IOTA: 13702f167a42Smrg buf[0] = 0x49; 13712f167a42Smrg return True; 13722f167a42Smrg case XK_Greek_KAPPA: 13732f167a42Smrg buf[0] = 0x4B; 13742f167a42Smrg return True; 13752f167a42Smrg case XK_Greek_LAMDA: 13762f167a42Smrg buf[0] = 0x4C; 13772f167a42Smrg return True; 13782f167a42Smrg case XK_Greek_MU: 13792f167a42Smrg buf[0] = 0x4D; 13802f167a42Smrg return True; 13812f167a42Smrg case XK_Greek_NU: 13822f167a42Smrg buf[0] = 0x4E; 13832f167a42Smrg return True; 13842f167a42Smrg case XK_Greek_OMICRON: 13852f167a42Smrg buf[0] = 0x4F; 13862f167a42Smrg return True; 13872f167a42Smrg case XK_Greek_PI: 13882f167a42Smrg buf[0] = 0x50; 13892f167a42Smrg return True; 13902f167a42Smrg case XK_Greek_THETA: 13912f167a42Smrg buf[0] = 0x51; 13922f167a42Smrg return True; 13932f167a42Smrg case XK_Greek_RHO: 13942f167a42Smrg buf[0] = 0x52; 13952f167a42Smrg return True; 13962f167a42Smrg case XK_Greek_SIGMA: 13972f167a42Smrg buf[0] = 0x53; 13982f167a42Smrg return True; 13992f167a42Smrg case XK_Greek_TAU: 14002f167a42Smrg buf[0] = 0x54; 14012f167a42Smrg return True; 14022f167a42Smrg case XK_Greek_UPSILON: 14032f167a42Smrg buf[0] = 0x55; 14042f167a42Smrg return True; 14052f167a42Smrg case XK_Greek_OMEGA: 14062f167a42Smrg buf[0] = 0x57; 14072f167a42Smrg return True; 14082f167a42Smrg case XK_Greek_XI: 14092f167a42Smrg buf[0] = 0x58; 14102f167a42Smrg return True; 14112f167a42Smrg case XK_Greek_PSI: 14122f167a42Smrg buf[0] = 0x59; 14132f167a42Smrg return True; 14142f167a42Smrg case XK_Greek_ZETA: 14152f167a42Smrg buf[0] = 0x5A; 14162f167a42Smrg return True; 14172f167a42Smrg 14182f167a42Smrg case XK_Greek_alpha: 14192f167a42Smrg buf[0] = 0x61; 14202f167a42Smrg return True; 14212f167a42Smrg case XK_Greek_beta: 14222f167a42Smrg buf[0] = 0x62; 14232f167a42Smrg return True; 14242f167a42Smrg case XK_Greek_chi: 14252f167a42Smrg buf[0] = 0x63; 14262f167a42Smrg return True; 14272f167a42Smrg case XK_Greek_delta: 14282f167a42Smrg buf[0] = 0x64; 14292f167a42Smrg return True; 14302f167a42Smrg case XK_Greek_epsilon: 14312f167a42Smrg buf[0] = 0x65; 14322f167a42Smrg return True; 14332f167a42Smrg case XK_Greek_phi: 14342f167a42Smrg buf[0] = 0x66; 14352f167a42Smrg return True; 14362f167a42Smrg case XK_Greek_gamma: 14372f167a42Smrg buf[0] = 0x67; 14382f167a42Smrg return True; 14392f167a42Smrg case XK_Greek_eta: 14402f167a42Smrg buf[0] = 0x68; 14412f167a42Smrg return True; 14422f167a42Smrg case XK_Greek_iota: 14432f167a42Smrg buf[0] = 0x69; 14442f167a42Smrg return True; 14452f167a42Smrg case XK_Greek_kappa: 14462f167a42Smrg buf[0] = 0x6B; 14472f167a42Smrg return True; 14482f167a42Smrg case XK_Greek_lamda: 14492f167a42Smrg buf[0] = 0x6C; 14502f167a42Smrg return True; 14512f167a42Smrg case XK_Greek_mu: 14522f167a42Smrg buf[0] = 0x6D; 14532f167a42Smrg return True; 14542f167a42Smrg case XK_Greek_nu: 14552f167a42Smrg buf[0] = 0x6E; 14562f167a42Smrg return True; 14572f167a42Smrg case XK_Greek_omicron: 14582f167a42Smrg buf[0] = 0x6F; 14592f167a42Smrg return True; 14602f167a42Smrg case XK_Greek_pi: 14612f167a42Smrg buf[0] = 0x70; 14622f167a42Smrg return True; 14632f167a42Smrg case XK_Greek_theta: 14642f167a42Smrg buf[0] = 0x71; 14652f167a42Smrg return True; 14662f167a42Smrg case XK_Greek_rho: 14672f167a42Smrg buf[0] = 0x72; 14682f167a42Smrg return True; 14692f167a42Smrg case XK_Greek_sigma: 14702f167a42Smrg buf[0] = 0x73; 14712f167a42Smrg return True; 14722f167a42Smrg case XK_Greek_tau: 14732f167a42Smrg buf[0] = 0x74; 14742f167a42Smrg return True; 14752f167a42Smrg case XK_Greek_upsilon: 14762f167a42Smrg buf[0] = 0x75; 14772f167a42Smrg return True; 14782f167a42Smrg case XK_Greek_omega: 14792f167a42Smrg buf[0] = 0x77; 14802f167a42Smrg return True; 14812f167a42Smrg case XK_Greek_xi: 14822f167a42Smrg buf[0] = 0x78; 14832f167a42Smrg return True; 14842f167a42Smrg case XK_Greek_psi: 14852f167a42Smrg buf[0] = 0x79; 14862f167a42Smrg return True; 14872f167a42Smrg case XK_Greek_zeta: 14882f167a42Smrg buf[0] = 0x7A; 14892f167a42Smrg return True; 14902f167a42Smrg } 14910e20ee16Smrg } 14920e20ee16Smrg switch (sym) { 14932f167a42Smrg case XK_leftarrow: 14942f167a42Smrg buf[0] = 0xAC; 14952f167a42Smrg return True; 14962f167a42Smrg case XK_uparrow: 14972f167a42Smrg buf[0] = 0xAD; 14982f167a42Smrg return True; 14992f167a42Smrg case XK_rightarrow: 15002f167a42Smrg buf[0] = 0xAE; 15012f167a42Smrg return True; 15022f167a42Smrg case XK_downarrow: 15032f167a42Smrg buf[0] = 0xAF; 15042f167a42Smrg return True; 15052f167a42Smrg case XK_horizconnector: 15062f167a42Smrg buf[0] = 0xBE; 15072f167a42Smrg return True; 15082f167a42Smrg case XK_trademark: 15092f167a42Smrg buf[0] = 0xE4; 15102f167a42Smrg return True; 15110e20ee16Smrg } 15120e20ee16Smrg return False; 15130e20ee16Smrg} 15140e20ee16Smrg 15150e20ee16Smrgstatic KeySym 15160e20ee16SmrgCheckSymbolAlias(KeySym sym, PSState *state) 15170e20ee16Smrg{ 15180e20ee16Smrg if (XkbKSIsKeypad(sym)) { 15192f167a42Smrg if ((sym >= XK_KP_0) && (sym <= XK_KP_9)) 15202f167a42Smrg sym = (sym - XK_KP_0) + XK_0; 15212f167a42Smrg else 15222f167a42Smrg switch (sym) { 15232f167a42Smrg case XK_KP_Space: 15242f167a42Smrg return XK_space; 15252f167a42Smrg case XK_KP_Tab: 15262f167a42Smrg return XK_Tab; 15272f167a42Smrg case XK_KP_Enter: 15282f167a42Smrg return XK_Return; 15292f167a42Smrg case XK_KP_F1: 15302f167a42Smrg return XK_F1; 15312f167a42Smrg case XK_KP_F2: 15322f167a42Smrg return XK_F2; 15332f167a42Smrg case XK_KP_F3: 15342f167a42Smrg return XK_F3; 15352f167a42Smrg case XK_KP_F4: 15362f167a42Smrg return XK_F4; 15372f167a42Smrg case XK_KP_Home: 15382f167a42Smrg return XK_Home; 15392f167a42Smrg case XK_KP_Left: 15402f167a42Smrg return XK_Left; 15412f167a42Smrg case XK_KP_Up: 15422f167a42Smrg return XK_Up; 15432f167a42Smrg case XK_KP_Right: 15442f167a42Smrg return XK_Right; 15452f167a42Smrg case XK_KP_Down: 15462f167a42Smrg return XK_Down; 15472f167a42Smrg case XK_KP_Page_Up: 15482f167a42Smrg return XK_Page_Up; 15492f167a42Smrg case XK_KP_Page_Down: 15502f167a42Smrg return XK_Page_Down; 15512f167a42Smrg case XK_KP_End: 15522f167a42Smrg return XK_End; 15532f167a42Smrg case XK_KP_Begin: 15542f167a42Smrg return XK_Begin; 15552f167a42Smrg case XK_KP_Insert: 15562f167a42Smrg return XK_Insert; 15572f167a42Smrg case XK_KP_Delete: 15582f167a42Smrg return XK_Delete; 15592f167a42Smrg case XK_KP_Equal: 15602f167a42Smrg return XK_equal; 15612f167a42Smrg case XK_KP_Multiply: 15622f167a42Smrg return XK_asterisk; 15632f167a42Smrg case XK_KP_Add: 15642f167a42Smrg return XK_plus; 15652f167a42Smrg case XK_KP_Subtract: 15662f167a42Smrg return XK_minus; 15672f167a42Smrg case XK_KP_Divide: 15682f167a42Smrg return XK_slash; 15692f167a42Smrg } 15700e20ee16Smrg } 15710e20ee16Smrg else if (XkbKSIsDeadKey(sym)) { 15722f167a42Smrg switch (sym) { 15732f167a42Smrg case XK_dead_grave: 15742f167a42Smrg sym = XK_grave; 15752f167a42Smrg break; 15762f167a42Smrg case XK_dead_acute: 15772f167a42Smrg sym = XK_acute; 15782f167a42Smrg break; 15792f167a42Smrg case XK_dead_circumflex: 15802f167a42Smrg sym = XK_asciicircum; 15812f167a42Smrg break; 15822f167a42Smrg case XK_dead_tilde: 15832f167a42Smrg sym = XK_asciitilde; 15842f167a42Smrg break; 15852f167a42Smrg case XK_dead_macron: 15862f167a42Smrg sym = XK_macron; 15872f167a42Smrg break; 15882f167a42Smrg case XK_dead_breve: 15892f167a42Smrg sym = XK_breve; 15902f167a42Smrg break; 15912f167a42Smrg case XK_dead_abovedot: 15922f167a42Smrg sym = XK_abovedot; 15932f167a42Smrg break; 15942f167a42Smrg case XK_dead_diaeresis: 15952f167a42Smrg sym = XK_diaeresis; 15962f167a42Smrg break; 15972f167a42Smrg case XK_dead_abovering: 15982f167a42Smrg sym = XK_degree; 15992f167a42Smrg break; 16002f167a42Smrg case XK_dead_doubleacute: 16012f167a42Smrg sym = XK_doubleacute; 16022f167a42Smrg break; 16032f167a42Smrg case XK_dead_caron: 16042f167a42Smrg sym = XK_caron; 16052f167a42Smrg break; 16062f167a42Smrg case XK_dead_cedilla: 16072f167a42Smrg sym = XK_cedilla; 16082f167a42Smrg break; 16092f167a42Smrg case XK_dead_ogonek: 16102f167a42Smrg sym = XK_ogonek; 16112f167a42Smrg break; 16122f167a42Smrg case XK_dead_iota: 16132f167a42Smrg sym = XK_Greek_iota; 16142f167a42Smrg break; 16152f167a42Smrg case XK_dead_voiced_sound: 16162f167a42Smrg sym = XK_voicedsound; 16172f167a42Smrg break; 16182f167a42Smrg case XK_dead_semivoiced_sound: 16192f167a42Smrg sym = XK_semivoicedsound; 16202f167a42Smrg break; 16212f167a42Smrg } 16220e20ee16Smrg } 16230e20ee16Smrg return sym; 16240e20ee16Smrg} 16250e20ee16Smrg 16260e20ee16Smrgstatic Bool 16270e20ee16SmrgFindKeysymsByName(XkbDescPtr xkb, char *name, PSState *state, KeyTop *top) 16280e20ee16Smrg{ 16292f167a42Smrg static unsigned char buf[30]; 16302f167a42Smrg int kc; 16312f167a42Smrg KeySym sym, *syms, topSyms[NLABELS]; 16322f167a42Smrg int level, group; 16332f167a42Smrg int eG, nG, gI, l, g; 16342f167a42Smrg 16352f167a42Smrg bzero(top, sizeof(KeyTop)); 16362f167a42Smrg kc = XkbFindKeycodeByName(xkb, name, True); 16372f167a42Smrg if (state->args != NULL) { 16382f167a42Smrg level = state->args->labelLevel; 16392f167a42Smrg group = state->args->baseLabelGroup; 16400e20ee16Smrg } 16412f167a42Smrg else 16422f167a42Smrg level = group = 0; 16432f167a42Smrg syms = XkbKeySymsPtr(xkb, kc); 16442f167a42Smrg eG = group; 16452f167a42Smrg nG = XkbKeyNumGroups(xkb, kc); 16462f167a42Smrg gI = XkbKeyGroupInfo(xkb, kc); 16472f167a42Smrg if ((state->args->wantDiffs) && (eG >= XkbKeyNumGroups(xkb, kc))) 16482f167a42Smrg return False; /* XXX was a return with no value */ 16492f167a42Smrg if (nG == 0) { 16502f167a42Smrg return False; 16510e20ee16Smrg } 16522f167a42Smrg else if (nG == 1) { 16532f167a42Smrg eG = 0; 16540e20ee16Smrg } 16552f167a42Smrg else if (eG >= XkbKeyNumGroups(xkb, kc)) { 16562f167a42Smrg switch (XkbOutOfRangeGroupAction(gI)) { 16572f167a42Smrg default: 16582f167a42Smrg eG %= nG; 16592f167a42Smrg break; 16602f167a42Smrg case XkbClampIntoRange: 16612f167a42Smrg eG = nG - 1; 16622f167a42Smrg break; 16632f167a42Smrg case XkbRedirectIntoRange: 16642f167a42Smrg eG = XkbOutOfRangeGroupNumber(gI); 16652f167a42Smrg if (eG >= nG) 16662f167a42Smrg eG = 0; 16672f167a42Smrg break; 16682f167a42Smrg } 16690e20ee16Smrg } 16702f167a42Smrg for (g = 0; g < state->args->nLabelGroups; g++) { 16712f167a42Smrg if ((eG + g) >= nG) 16722f167a42Smrg continue; 16732f167a42Smrg for (l = 0; l < 2; l++) { 16742f167a42Smrg int font, sz; 16752f167a42Smrg 16762f167a42Smrg if (level + l >= XkbKeyGroupWidth(xkb, kc, (eG + g))) 16772f167a42Smrg continue; 16782f167a42Smrg sym = syms[((eG + g) * XkbKeyGroupsWidth(xkb, kc)) + (level + l)]; 16792f167a42Smrg 16802f167a42Smrg if (state->args->wantSymbols != NO_SYMBOLS) 16812f167a42Smrg sym = CheckSymbolAlias(sym, state); 16822f167a42Smrg topSyms[(g * 2) + l] = sym; 16832f167a42Smrg 16842f167a42Smrg if (PSKeycapsSymbol(sym, buf, &font, &sz, state)) { 16852f167a42Smrg top->font[(g * 2) + l] = font; 16862f167a42Smrg top->size[(g * 2) + l] = sz; 16872f167a42Smrg } 16882f167a42Smrg else if (((sym & (~0xffUL)) == 0) && isprint(sym) && (!isspace(sym))) { 16892f167a42Smrg if (sym == '(') 16902f167a42Smrg snprintf((char *) buf, sizeof(buf), "\\("); 16912f167a42Smrg else if (sym == ')') 16922f167a42Smrg snprintf((char *) buf, sizeof(buf), "\\)"); 16932f167a42Smrg else if (sym == '\\') 16942f167a42Smrg snprintf((char *) buf, sizeof(buf), "\\\\"); 16952f167a42Smrg else 16962f167a42Smrg snprintf((char *) buf, sizeof(buf), "%c", (char) sym); 16972f167a42Smrg top->font[(g * 2) + l] = FONT_LATIN1; 16982f167a42Smrg top->size[(g * 2) + l] = SZ_MEDIUM; 16992f167a42Smrg switch (buf[0]) { 17002f167a42Smrg case '.': 17012f167a42Smrg case ':': 17022f167a42Smrg case ',': 17032f167a42Smrg case ';': 17042f167a42Smrg case '\'': 17052f167a42Smrg case '"': 17062f167a42Smrg case '`': 17072f167a42Smrg case '~': 17082f167a42Smrg case '^': 17092f167a42Smrg case 0250: 17102f167a42Smrg case 0270: 17112f167a42Smrg case 0267: 17122f167a42Smrg case 0260: 17132f167a42Smrg case 0252: 17142f167a42Smrg case 0272: 17152f167a42Smrg case 0271: 17162f167a42Smrg case 0262: 17172f167a42Smrg case 0263: 17182f167a42Smrg case 0264: 17192f167a42Smrg case 0255: 17202f167a42Smrg case 0254: 17212f167a42Smrg case 0257: 17222f167a42Smrg top->size[(g * 2) + l] = SZ_LARGE; 17232f167a42Smrg break; 17242f167a42Smrg } 17252f167a42Smrg } 17262f167a42Smrg else if (PSNonLatin1Symbol(sym, buf, &font, &sz, state)) { 17272f167a42Smrg top->font[(g * 2) + l] = font; 17282f167a42Smrg top->size[(g * 2) + l] = sz; 17292f167a42Smrg } 17302f167a42Smrg else { 17312f167a42Smrg char *tmp; 17322f167a42Smrg 17332f167a42Smrg tmp = XKeysymToString(sym); 17342f167a42Smrg if (tmp != NULL) 17352f167a42Smrg strcpy((char *) buf, tmp); 17362f167a42Smrg else 17372f167a42Smrg snprintf((char *) buf, sizeof(buf), "(%ld)", sym); 17382f167a42Smrg top->font[(g * 2) + l] = FONT_LATIN1; 17392f167a42Smrg if (strlen((char *) buf) < 9) 17402f167a42Smrg top->size[(g * 2) + l] = SZ_SMALL; 17412f167a42Smrg else 17422f167a42Smrg top->size[(g * 2) + l] = SZ_TINY; 17432f167a42Smrg } 17442f167a42Smrg top->present |= (1 << ((g * 2) + l)); 17452f167a42Smrg strncpy(top->label[(g * 2) + l], (char *) buf, LABEL_LEN - 1); 17462f167a42Smrg top->label[(g * 2) + l][LABEL_LEN - 1] = '\0'; 17472f167a42Smrg } 17482f167a42Smrg if (((g == 0) && (top->present & G1LX_MASK) == G1LX_MASK) || 17492f167a42Smrg ((g == 1) && (top->present & G2LX_MASK) == G2LX_MASK)) { 17502f167a42Smrg KeySym lower, upper; 17512f167a42Smrg 17522f167a42Smrg XConvertCase(topSyms[(g * 2)], &lower, &upper); 17532f167a42Smrg if ((topSyms[(g * 2)] == lower) && (topSyms[(g * 2) + 1] == upper)) { 17542f167a42Smrg top->alpha[g] = True; 17552f167a42Smrg } 17562f167a42Smrg } 17570e20ee16Smrg } 17580e20ee16Smrg return True; 17590e20ee16Smrg} 17600e20ee16Smrg 17610e20ee16Smrgstatic void 17622f167a42SmrgPSDrawLabel(FILE *out, const char *label, int x, int y, int w, int h) 17630e20ee16Smrg{ 17642f167a42Smrg fprintf(out, "%d %d (%s) centeroffset\n", w, h, label); 17652f167a42Smrg fprintf(out, "%d add exch\n", y); 17662f167a42Smrg fprintf(out, "%d add exch moveto\n", x); 17672f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", label); 17680e20ee16Smrg return; 17690e20ee16Smrg} 17700e20ee16Smrg 17710e20ee16Smrg#define TOP_ROW 0 17720e20ee16Smrg#define BOTTOM_ROW 1 17730e20ee16Smrg#define CENTER_ROW 2 17740e20ee16Smrg 17750e20ee16Smrg#define LEFT_COL 0 17760e20ee16Smrg#define RIGHT_COL 1 17770e20ee16Smrg#define CENTER_COL 2 17780e20ee16Smrg 17790e20ee16Smrgstatic void 17800e20ee16SmrgPSLabelKey(FILE *out, PSState *state, KeyTop *top, int x, int y, 17812f167a42Smrg XkbBoundsPtr bounds, int kc, int btm) 17820e20ee16Smrg{ 17832f167a42Smrg int w, h, i; 17842f167a42Smrg int row_y[3]; 17852f167a42Smrg int col_x[3]; 17862f167a42Smrg int row_h[3]; 17872f167a42Smrg int col_w[3]; 17882f167a42Smrg Bool present[NLABELS]; 17892f167a42Smrg int sym_row[NLABELS]; 17902f167a42Smrg int sym_col[NLABELS]; 17912f167a42Smrg 17922f167a42Smrg w = XkbBoundsWidth(bounds); 17932f167a42Smrg h = XkbBoundsHeight(bounds); 17942f167a42Smrg row_y[TOP_ROW] = y + bounds->y1 + (h / 10); 17952f167a42Smrg row_y[BOTTOM_ROW] = y + bounds->y1 + (h / 2) + (h / 10); 17962f167a42Smrg row_y[CENTER_ROW] = y + bounds->y1 + (h / 10); 17972f167a42Smrg row_h[TOP_ROW] = h / 2; 17982f167a42Smrg row_h[BOTTOM_ROW] = h / 2; 17992f167a42Smrg row_h[CENTER_ROW] = h; 18002f167a42Smrg 18012f167a42Smrg col_x[LEFT_COL] = x + bounds->x1; 18022f167a42Smrg col_x[RIGHT_COL] = x + bounds->x1 + w / 2; 18032f167a42Smrg col_x[CENTER_COL] = x + bounds->x1; 18042f167a42Smrg col_w[LEFT_COL] = w / 2; 18052f167a42Smrg col_w[RIGHT_COL] = w / 2; 18062f167a42Smrg col_w[CENTER_COL] = w; 18072f167a42Smrg 18082f167a42Smrg present[G1L1] = False; 18092f167a42Smrg sym_row[G1L1] = BOTTOM_ROW; 18102f167a42Smrg sym_col[G1L1] = LEFT_COL; 18112f167a42Smrg 18122f167a42Smrg present[G1L2] = False; 18132f167a42Smrg sym_row[G1L2] = TOP_ROW; 18142f167a42Smrg sym_col[G1L2] = LEFT_COL; 18152f167a42Smrg 18162f167a42Smrg present[G2L1] = False; 18172f167a42Smrg sym_row[G2L1] = BOTTOM_ROW; 18182f167a42Smrg sym_col[G2L1] = RIGHT_COL; 18192f167a42Smrg 18202f167a42Smrg present[G2L2] = False; 18212f167a42Smrg sym_row[G2L2] = TOP_ROW; 18222f167a42Smrg sym_col[G2L2] = RIGHT_COL; 18232f167a42Smrg 18242f167a42Smrg present[CENTER] = False; 18252f167a42Smrg sym_row[CENTER] = CENTER_ROW; 18262f167a42Smrg sym_col[CENTER] = CENTER_COL; 18272f167a42Smrg 18282f167a42Smrg if (top->present & CENTER_MASK) { 18292f167a42Smrg present[CENTER] = True; 18300e20ee16Smrg } 18312f167a42Smrg else 18322f167a42Smrg switch (top->present & GXLX_MASK) { 18332f167a42Smrg case G1L1_MASK: 18342f167a42Smrg present[G1L1] = True; 18352f167a42Smrg sym_row[G1L1] = CENTER_ROW; 18362f167a42Smrg sym_col[G1L1] = CENTER_COL; 18372f167a42Smrg break; 18382f167a42Smrg case G1LX_MASK: 18392f167a42Smrg present[G1L2] = True; 18402f167a42Smrg if (!top->alpha[0]) { 18412f167a42Smrg present[G1L1] = True; 18422f167a42Smrg if ((strlen(top->label[G1L1]) > 1) && 18432f167a42Smrg (top->label[G1L1][0] != '\\')) 18442f167a42Smrg sym_col[G1L1] = CENTER_COL; 18452f167a42Smrg if ((strlen(top->label[G1L2]) > 1) && 18462f167a42Smrg (top->label[G1L1][0] != '\\')) 18472f167a42Smrg sym_col[G1L2] = CENTER_COL; 18482f167a42Smrg } 18492f167a42Smrg break; 18502f167a42Smrg default: 18512f167a42Smrg if ((top->present & G1LX_MASK) == G1LX_MASK) { 18522f167a42Smrg present[G1L2] = True; 18532f167a42Smrg if (!top->alpha[0]) 18542f167a42Smrg present[G1L1] = True; 18552f167a42Smrg } 18562f167a42Smrg else if ((top->present & G1LX_MASK) == G1L1_MASK) { 18572f167a42Smrg present[G1L1] = True; 18582f167a42Smrg } 18592f167a42Smrg else if ((top->present & G1LX_MASK) == G1L2_MASK) { 18602f167a42Smrg present[G1L2] = True; 18612f167a42Smrg } 18622f167a42Smrg if ((top->present & G2LX_MASK) == G2LX_MASK) { 18632f167a42Smrg present[G2L2] = True; 18642f167a42Smrg if (!top->alpha[1]) 18652f167a42Smrg present[G2L1] = True; 18662f167a42Smrg } 18672f167a42Smrg else if ((top->present & G2LX_MASK) == G2L1_MASK) { 18682f167a42Smrg present[G2L1] = True; 18692f167a42Smrg } 18702f167a42Smrg else if ((top->present & G2LX_MASK) == G2L2_MASK) { 18712f167a42Smrg present[G2L2] = True; 18722f167a42Smrg } 18732f167a42Smrg break; 18742f167a42Smrg case 0: 18752f167a42Smrg return; 18762f167a42Smrg } 18772f167a42Smrg for (i = 0; i < NLABELS; i++) { 18782f167a42Smrg if (present[i]) { 18792f167a42Smrg int size; 18802f167a42Smrg 18812f167a42Smrg if (top->size[i] == SZ_AUTO) { 18822f167a42Smrg size_t len = strlen(top->label[i]); 18832f167a42Smrg if (len == 1) { 18842f167a42Smrg if (top->font[i] == FONT_ISOCAPS) 18852f167a42Smrg size = 18; 18862f167a42Smrg else 18872f167a42Smrg size = 14; 18882f167a42Smrg } 18892f167a42Smrg else if (len < 10) 18902f167a42Smrg size = 12; 18912f167a42Smrg else 18922f167a42Smrg size = 10; 18932f167a42Smrg } 18942f167a42Smrg else if (top->size[i] == SZ_TINY) 18952f167a42Smrg size = 10; 18962f167a42Smrg else if (top->size[i] == SZ_SMALL) 18972f167a42Smrg size = 12; 18982f167a42Smrg else if (top->size[i] == SZ_LARGE) 18992f167a42Smrg size = 18; 19002f167a42Smrg else if (top->size[i] == SZ_XLARGE) 19012f167a42Smrg size = 24; 19022f167a42Smrg else 19032f167a42Smrg size = 14; 19042f167a42Smrg PSSetFont(out, state, top->font[i], size, True); 19052f167a42Smrg PSDrawLabel(out, top->label[i], col_x[sym_col[i]], 19062f167a42Smrg row_y[sym_row[i]], col_w[sym_col[i]], 19072f167a42Smrg row_h[sym_row[i]]); 19082f167a42Smrg } 19090e20ee16Smrg } 19100e20ee16Smrg if (state->args->wantKeycodes) { 19112f167a42Smrg char keycode[10]; 19122f167a42Smrg 19132f167a42Smrg snprintf(keycode, sizeof(keycode), "%d", kc); 19142f167a42Smrg PSSetFont(out, state, FONT_LATIN1, 8, True); 19152f167a42Smrg PSDrawLabel(out, keycode, x + bounds->x1, y + btm - 5, w, 0); 19160e20ee16Smrg } 19170e20ee16Smrg return; 19180e20ee16Smrg} 19190e20ee16Smrg 19200e20ee16Smrgstatic void 19210e20ee16SmrgPSSection(FILE *out, PSState *state, XkbSectionPtr section) 19220e20ee16Smrg{ 19232f167a42Smrg int r, offset; 19242f167a42Smrg XkbRowPtr row; 19252f167a42Smrg Display *dpy; 19262f167a42Smrg XkbDescPtr xkb; 19272f167a42Smrg 19282f167a42Smrg xkb = state->xkb; 19292f167a42Smrg dpy = xkb->dpy; 1930e6bced22Smrg { 1931e6bced22Smrg const char *section_name; 1932e6bced22Smrg char *atom_name = NULL; 1933e6bced22Smrg 1934e6bced22Smrg if (section->name != None) 1935e6bced22Smrg section_name = atom_name = XkbAtomGetString(dpy, section->name); 1936e6bced22Smrg else 1937e6bced22Smrg section_name = "NoName"; 1938e6bced22Smrg fprintf(out, "%% Begin Section '%s'\n", section_name); 1939e6bced22Smrg XFree(atom_name); 1940e6bced22Smrg } 19412f167a42Smrg PSGSave(out, state); 19422f167a42Smrg fprintf(out, "%d %d translate\n", section->left, section->top); 19432f167a42Smrg if (section->angle != 0) 19442f167a42Smrg fprintf(out, "%s rotate\n", XkbGeomFPText(section->angle, XkbMessage)); 19450e20ee16Smrg if (section->doodads) { 19462f167a42Smrg XkbDrawablePtr first, draw; 19472f167a42Smrg 19482f167a42Smrg first = draw = XkbGetOrderedDrawables(NULL, section); 19492f167a42Smrg while (draw) { 19502f167a42Smrg if (draw->type == XkbDW_Section) 19512f167a42Smrg PSSection(out, state, draw->u.section); 19522f167a42Smrg else 19532f167a42Smrg PSDoodad(out, state, draw->u.doodad); 19542f167a42Smrg draw = draw->next; 19552f167a42Smrg } 19562f167a42Smrg XkbFreeOrderedDrawables(first); 19570e20ee16Smrg } 19582f167a42Smrg for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { 19592f167a42Smrg int k; 19602f167a42Smrg XkbKeyPtr key; 19612f167a42Smrg 19622f167a42Smrg if (row->vertical) 19632f167a42Smrg offset = row->top; 19642f167a42Smrg else 19652f167a42Smrg offset = row->left; 19662f167a42Smrg fprintf(out, "%% Begin %s %d\n", row->vertical ? "column" : "row", 19672f167a42Smrg r + 1); 19682f167a42Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 1969e6bced22Smrg XkbShapePtr shape = XkbKeyShape(xkb->geom, key); 1970e6bced22Smrg char *shape_name = XkbAtomGetString(dpy, shape->name); 1971e6bced22Smrg 19722f167a42Smrg offset += key->gap; 19732f167a42Smrg if (row->vertical) { 19742f167a42Smrg if (state->args->wantColor) { 19752f167a42Smrg if (key->color_ndx != state->white) { 19762f167a42Smrg PSSetColor(out, state, key->color_ndx); 19772f167a42Smrg fprintf(out, "true 0 %d %d %s %% %s\n", 1978e6bced22Smrg row->left, offset, shape_name, 19792f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 19802f167a42Smrg } 19812f167a42Smrg PSSetColor(out, state, state->black); 19822f167a42Smrg } 19832f167a42Smrg fprintf(out, "false 0 %d %d %s %% %s\n", row->left, offset, 1984e6bced22Smrg shape_name, 19852f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 19862f167a42Smrg offset += shape->bounds.y2; 19872f167a42Smrg } 19882f167a42Smrg else { 19892f167a42Smrg if (state->args->wantColor) { 19902f167a42Smrg if (key->color_ndx != state->white) { 19912f167a42Smrg PSSetColor(out, state, key->color_ndx); 19922f167a42Smrg fprintf(out, "true 0 %d %d %s %% %s\n", offset, 1993e6bced22Smrg row->top, shape_name, 19942f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 19952f167a42Smrg } 19962f167a42Smrg PSSetColor(out, state, state->black); 19972f167a42Smrg } 19982f167a42Smrg fprintf(out, "false 0 %d %d %s %% %s\n", offset, row->top, 1999e6bced22Smrg shape_name, 20002f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 20012f167a42Smrg offset += shape->bounds.x2; 20022f167a42Smrg } 2003e6bced22Smrg XFree(shape_name); 20042f167a42Smrg } 20050e20ee16Smrg } 20062f167a42Smrg for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { 20072f167a42Smrg int k, kc = 0; 20082f167a42Smrg XkbKeyPtr key; 20092f167a42Smrg XkbShapePtr shape; 20102f167a42Smrg XkbBoundsRec bounds; 20112f167a42Smrg 20122f167a42Smrg if (state->args->label == LABEL_NONE) 20132f167a42Smrg break; 20142f167a42Smrg if (row->vertical) 20152f167a42Smrg offset = row->top; 20162f167a42Smrg else 20172f167a42Smrg offset = row->left; 20182f167a42Smrg fprintf(out, "%% Begin %s %d labels\n", 20192f167a42Smrg row->vertical ? "column" : "row", r + 1); 20202f167a42Smrg PSSetColor(out, state, xkb->geom->label_color->pixel); 20212f167a42Smrg PSSetFont(out, state, FONT_LATIN1, 12, True); 20222f167a42Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 20232f167a42Smrg char *name, *name2, buf[30], buf2[30]; 20242f167a42Smrg int x, y; 20252f167a42Smrg KeyTop top; 20262f167a42Smrg 20272f167a42Smrg shape = XkbKeyShape(xkb->geom, key); 20282f167a42Smrg XkbComputeShapeTop(shape, &bounds); 20292f167a42Smrg offset += key->gap; 20302f167a42Smrg name = name2 = NULL; 20312f167a42Smrg if (state->args->label == LABEL_SYMBOLS) { 20322f167a42Smrg if (!FindKeysymsByName(xkb, key->name.name, state, &top)) { 20332f167a42Smrg fprintf(out, "%% No label for %s\n", 20342f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 20352f167a42Smrg } 20362f167a42Smrg } 20372f167a42Smrg else { 20382f167a42Smrg char *olKey; 20392f167a42Smrg 20402f167a42Smrg if (section->num_overlays > 0) 20412f167a42Smrg olKey = XkbFindOverlayForKey(xkb->geom, section, 20422f167a42Smrg key->name.name); 20432f167a42Smrg else 20442f167a42Smrg olKey = NULL; 20452f167a42Smrg 20462f167a42Smrg if (state->args->label == LABEL_KEYNAME) { 20472f167a42Smrg name = XkbKeyNameText(key->name.name, XkbMessage); 20482f167a42Smrg if (olKey) 20492f167a42Smrg name2 = XkbKeyNameText(olKey, XkbMessage); 20502f167a42Smrg } 20512f167a42Smrg else if (state->args->label == LABEL_KEYCODE) { 20522f167a42Smrg name = buf; 20532f167a42Smrg snprintf(name, sizeof(buf), "%d", 20542f167a42Smrg XkbFindKeycodeByName(xkb, key->name.name, True)); 20552f167a42Smrg if (olKey) { 20562f167a42Smrg name2 = buf2; 20572f167a42Smrg snprintf(name2, sizeof(buf2), "%d", 20582f167a42Smrg XkbFindKeycodeByName(xkb, olKey, True)); 20592f167a42Smrg } 20602f167a42Smrg } 20612f167a42Smrg bzero(&top, sizeof(KeyTop)); 20622f167a42Smrg if (name2 != NULL) { 20632f167a42Smrg top.present |= G1LX_MASK; 20642f167a42Smrg strncpy(top.label[G1L1], name, LABEL_LEN - 1); 20652f167a42Smrg top.label[G1L1][LABEL_LEN - 1] = '\0'; 20662f167a42Smrg strncpy(top.label[G1L2], name2, LABEL_LEN - 1); 20672f167a42Smrg top.label[G1L2][LABEL_LEN - 1] = '\0'; 20682f167a42Smrg } 20692f167a42Smrg else if (name != NULL) { 20702f167a42Smrg top.present |= CENTER_MASK; 20712f167a42Smrg strncpy(top.label[CENTER], name, LABEL_LEN - 1); 20722f167a42Smrg top.label[CENTER][LABEL_LEN - 1] = '\0'; 20732f167a42Smrg } 20742f167a42Smrg else { 20752f167a42Smrg fprintf(out, "%% No label for %s\n", 20762f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 20772f167a42Smrg } 20782f167a42Smrg } 20792f167a42Smrg if (row->vertical) { 20802f167a42Smrg x = row->left; 20812f167a42Smrg y = offset; 20822f167a42Smrg offset += shape->bounds.y2; 20832f167a42Smrg } 20842f167a42Smrg else { 20852f167a42Smrg x = offset; 20862f167a42Smrg y = row->top; 20872f167a42Smrg offset += shape->bounds.x2; 20882f167a42Smrg } 20892f167a42Smrg name = key->name.name; 20902f167a42Smrg fprintf(out, "%% %s\n", XkbKeyNameText(name, XkbMessage)); 20912f167a42Smrg if (state->args->wantKeycodes) 20922f167a42Smrg kc = XkbFindKeycodeByName(xkb, key->name.name, True); 20932f167a42Smrg PSLabelKey(out, state, &top, x, y, &bounds, kc, shape->bounds.y2); 20942f167a42Smrg } 20950e20ee16Smrg } 20962f167a42Smrg PSGRestore(out, state); 20970e20ee16Smrg return; 20980e20ee16Smrg} 20990e20ee16Smrg 21000e20ee16SmrgBool 21010e20ee16SmrgGeometryToPostScript(FILE *out, XkbFileInfo *pResult, XKBPrintArgs *args) 21020e20ee16Smrg{ 21032f167a42Smrg XkbDrawablePtr first, draw; 21042f167a42Smrg PSState state; 21052f167a42Smrg Bool dfltBorder; 21062f167a42Smrg int i; 21072f167a42Smrg 21082f167a42Smrg if ((!pResult) || (!pResult->xkb) || (!pResult->xkb->geom)) 21092f167a42Smrg return False; 21102f167a42Smrg state.xkb = pResult->xkb; 21112f167a42Smrg state.dpy = pResult->xkb->dpy; 21122f167a42Smrg state.geom = pResult->xkb->geom; 21132f167a42Smrg state.color = state.black = state.white = -1; 21142f167a42Smrg state.font = -1; 21152f167a42Smrg state.nPages = 0; 21162f167a42Smrg state.totalKB = 1; 21172f167a42Smrg state.kbPerPage = 1; 21182f167a42Smrg state.x1 = state.y1 = state.x2 = state.y2 = 0; 21192f167a42Smrg state.args = args; 21202f167a42Smrg 21212f167a42Smrg if ((args->label == LABEL_SYMBOLS) && (pResult->xkb->ctrls)) { 21222f167a42Smrg if (args->nTotalGroups == 0) 21232f167a42Smrg state.totalKB = 21242f167a42Smrg pResult->xkb->ctrls->num_groups / args->nLabelGroups; 21252f167a42Smrg else 21262f167a42Smrg state.totalKB = args->nTotalGroups; 21272f167a42Smrg if (state.totalKB < 1) 21282f167a42Smrg state.totalKB = 1; 21292f167a42Smrg else if (state.totalKB > 1) 21302f167a42Smrg state.kbPerPage = 2; 21310e20ee16Smrg } 21322f167a42Smrg if (args->nKBPerPage != 0) 21332f167a42Smrg state.kbPerPage = args->nKBPerPage; 21342f167a42Smrg 21352f167a42Smrg PSProlog(out, &state); 21362f167a42Smrg first = XkbGetOrderedDrawables(state.geom, NULL); 21372f167a42Smrg 21382f167a42Smrg for (draw = first, dfltBorder = True; draw != NULL; draw = draw->next) { 21392f167a42Smrg if ((draw->type != XkbDW_Section) && 21402f167a42Smrg ((draw->u.doodad->any.type == XkbOutlineDoodad) || 21412f167a42Smrg (draw->u.doodad->any.type == XkbSolidDoodad))) { 21422f167a42Smrg char *name; 21432f167a42Smrg 21442f167a42Smrg name = XkbAtomGetString(state.dpy, draw->u.doodad->any.name); 21452f167a42Smrg if ((name != NULL) && (uStrCaseEqual(name, "edges"))) { 21462f167a42Smrg dfltBorder = False; 2147e6bced22Smrg XFree(name); 21482f167a42Smrg break; 21492f167a42Smrg } 2150e6bced22Smrg XFree(name); 21512f167a42Smrg } 21520e20ee16Smrg } 21532f167a42Smrg for (i = 0; i < state.totalKB; i++) { 21542f167a42Smrg PSPageSetup(out, &state, dfltBorder); 21552f167a42Smrg for (draw = first; draw != NULL; draw = draw->next) { 21562f167a42Smrg if (draw->type == XkbDW_Section) 21572f167a42Smrg PSSection(out, &state, draw->u.section); 21582f167a42Smrg else { 21592f167a42Smrg PSDoodad(out, &state, draw->u.doodad); 21602f167a42Smrg } 21612f167a42Smrg } 21622f167a42Smrg PSPageTrailer(out, &state); 21632f167a42Smrg state.args->baseLabelGroup += state.args->nLabelGroups; 21640e20ee16Smrg } 21650e20ee16Smrg XkbFreeOrderedDrawables(first); 21662f167a42Smrg PSFileTrailer(out, &state); 21670e20ee16Smrg return True; 21680e20ee16Smrg} 2169