psgeom.c revision 2f167a42
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 2682f167a42Smrg fprintf(out, "/%s {\n", XkbAtomGetString(state->dpy, shape->name)); 2692f167a42Smrg fprintf(out, " gsave translate rotate /SOLID exch def\n"); 2702f167a42Smrg for (o = 0, ol = shape->outlines; o < shape->num_outlines; o++, ol++) { 2712f167a42Smrg XkbPointPtr pt; 2722f167a42Smrg 2732f167a42Smrg if ((shape->num_outlines > 1) && (ol == shape->approx)) 2742f167a42Smrg continue; 2752f167a42Smrg pt = ol->points; 2762f167a42Smrg fprintf(out, "%% Outline %d\n", o + 1); 2772f167a42Smrg if (ol->num_points == 1) { 2782f167a42Smrg if (ol->corner_radius < 1) { 2792f167a42Smrg fprintf(out, " 0 0 moveto\n"); 2802f167a42Smrg fprintf(out, " %3d 0 lineto\n", pt->x); 2812f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt->x, pt->y); 2822f167a42Smrg fprintf(out, " 0 %3d lineto\n", pt->y); 2832f167a42Smrg fprintf(out, " 0 0 lineto\n"); 2842f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 2852f167a42Smrg } 2862f167a42Smrg else { 2872f167a42Smrg fprintf(out, " mark\n"); 2882f167a42Smrg fprintf(out, " %3d 0 moveto\n", ol->corner_radius); 2892f167a42Smrg fprintf(out, " %3d 0 %3d %3d %3d arcto\n", pt->x, pt->x, 2902f167a42Smrg pt->y, ol->corner_radius); 2912f167a42Smrg fprintf(out, " %3d %3d 0 %3d %3d arcto\n", pt->x, pt->y, 2922f167a42Smrg pt->y, ol->corner_radius); 2932f167a42Smrg fprintf(out, " 0 %3d 0 0 %3d arcto\n", pt->y, 2942f167a42Smrg ol->corner_radius); 2952f167a42Smrg fprintf(out, " 0 0 %3d 0 %3d arcto\n", pt->x, 2962f167a42Smrg ol->corner_radius); 2972f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 2982f167a42Smrg fprintf(out, " cleartomark\n"); 2992f167a42Smrg } 3002f167a42Smrg } 3012f167a42Smrg else if (ol->num_points == 2) { 3022f167a42Smrg if (ol->corner_radius < 1) { 3032f167a42Smrg fprintf(out, " %3d %3d moveto\n", pt[0].x, pt[0].y); 3042f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt[1].x, pt[0].y); 3052f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt[1].x, pt[1].y); 3062f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt[0].x, pt[1].y); 3072f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt[0].x, pt[0].y); 3082f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 3092f167a42Smrg } 3102f167a42Smrg else { 3112f167a42Smrg fprintf(out, " mark\n"); 3122f167a42Smrg fprintf(out, " %3d %3d moveto\n", pt[0].x + ol->corner_radius, 3132f167a42Smrg pt[0].y); 3142f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", pt[1].x, pt[0].y, 3152f167a42Smrg pt[1].x, pt[1].y, ol->corner_radius); 3162f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", pt[1].x, pt[1].y, 3172f167a42Smrg pt[0].x, pt[1].y, ol->corner_radius); 3182f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", pt[0].x, pt[1].y, 3192f167a42Smrg pt[0].x, pt[0].y, ol->corner_radius); 3202f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", pt[0].x, pt[0].y, 3212f167a42Smrg pt[1].x, pt[0].y, ol->corner_radius); 3222f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 3232f167a42Smrg fprintf(out, " cleartomark\n"); 3242f167a42Smrg } 3252f167a42Smrg } 3262f167a42Smrg else { 3272f167a42Smrg if (ol->corner_radius < 1) { 3282f167a42Smrg fprintf(out, " %3d %3d moveto\n", pt->x, pt->y); 3292f167a42Smrg pt++; 3302f167a42Smrg for (p = 1; p < ol->num_points; p++, pt++) { 3312f167a42Smrg fprintf(out, " %3d %3d lineto\n", pt->x, pt->y); 3322f167a42Smrg } 3332f167a42Smrg if ((pt->x != ol->points[0].x) || (pt->y != ol->points[0].y)) 3342f167a42Smrg fprintf(out, " closepath\n"); 3352f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 3362f167a42Smrg } 3372f167a42Smrg else { 3382f167a42Smrg XkbPointPtr last; 3392f167a42Smrg 3402f167a42Smrg last = &pt[ol->num_points - 1]; 3412f167a42Smrg if ((last->x == pt->x) && (last->y == pt->y)) 3422f167a42Smrg last--; 3432f167a42Smrg fprintf(out, " mark\n"); 3442f167a42Smrg fprintf(out, " %% Determine tangent point of first corner\n"); 3452f167a42Smrg fprintf(out, " %3d %3d moveto %d %d %d %d %d arcto\n", 3462f167a42Smrg last->x, last->y, 3472f167a42Smrg pt[0].x, pt[0].y, pt[1].x, pt[1].y, ol->corner_radius); 3482f167a42Smrg fprintf(out, " /TY exch def /TX exch def pop pop newpath\n"); 3492f167a42Smrg fprintf(out, " %% Now draw the shape\n"); 3502f167a42Smrg fprintf(out, " TX TY moveto\n"); 3512f167a42Smrg for (p = 1; p < ol->num_points; p++) { 3522f167a42Smrg if (p < (ol->num_points - 1)) 3532f167a42Smrg last = &pt[p + 1]; 3542f167a42Smrg else 3552f167a42Smrg last = &pt[0]; 3562f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", 3572f167a42Smrg pt[p].x, pt[p].y, 3582f167a42Smrg last->x, last->y, ol->corner_radius); 3592f167a42Smrg } 3602f167a42Smrg last = &pt[ol->num_points - 1]; 3612f167a42Smrg if ((last->x != pt->x) || (last->y != pt->y)) { 3622f167a42Smrg fprintf(out, " %3d %3d %3d %3d %3d arcto\n", 3632f167a42Smrg pt[0].x, pt[0].y, 3642f167a42Smrg pt[1].x, pt[1].y, ol->corner_radius); 3652f167a42Smrg } 3662f167a42Smrg fprintf(out, " SOLID { fill } { stroke } ifelse\n"); 3672f167a42Smrg fprintf(out, " cleartomark\n"); 3682f167a42Smrg } 3692f167a42Smrg } 3700e20ee16Smrg } 3712f167a42Smrg fprintf(out, " grestore\n"); 3722f167a42Smrg fprintf(out, "} def\n"); 3730e20ee16Smrg return; 3740e20ee16Smrg} 3750e20ee16Smrg 3760e20ee16Smrg/***====================================================================***/ 3770e20ee16Smrg 3782f167a42Smrgtypedef struct { 3792f167a42Smrg char * foundry; 3802f167a42Smrg char * face; 3812f167a42Smrg char * weight; 3822f167a42Smrg char * slant; 3832f167a42Smrg char * setWidth; 3842f167a42Smrg char * variant; 3852f167a42Smrg int pixelSize; 3862f167a42Smrg int ptSize; 3872f167a42Smrg int resX; 3882f167a42Smrg int resY; 3892f167a42Smrg char * spacing; 3902f167a42Smrg int avgWidth; 3912f167a42Smrg char * encoding; 3920e20ee16Smrg} FontStuff; 3930e20ee16Smrg 3940e20ee16Smrgstatic void 3950e20ee16SmrgClearFontStuff(FontStuff *stuff) 3960e20ee16Smrg{ 3970e20ee16Smrg if (stuff && stuff->foundry) 3982f167a42Smrg free(stuff->foundry); 3992f167a42Smrg bzero(stuff, sizeof(FontStuff)); 4000e20ee16Smrg return; 4010e20ee16Smrg} 4020e20ee16Smrg 4030e20ee16Smrgstatic Bool 4042f167a42SmrgCrackXLFDName(const char *name, FontStuff *stuff) 4050e20ee16Smrg{ 4062f167a42Smrg char *tmp; 4072f167a42Smrg 4082f167a42Smrg if ((name == NULL) || (stuff == NULL)) 4092f167a42Smrg return False; 4102f167a42Smrg if (name[0] == '-') 4112f167a42Smrg tmp = strdup(&name[1]); 4122f167a42Smrg else 4132f167a42Smrg tmp = strdup(name); 4142f167a42Smrg if (tmp == NULL) 4152f167a42Smrg return False; 4162f167a42Smrg stuff->foundry = tmp; 4172f167a42Smrg 4182f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4192f167a42Smrg goto BAILOUT; 4202f167a42Smrg else 4212f167a42Smrg *tmp++ = '\0'; 4222f167a42Smrg stuff->face = tmp; 4232f167a42Smrg 4242f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4252f167a42Smrg goto BAILOUT; 4262f167a42Smrg else 4272f167a42Smrg *tmp++ = '\0'; 4282f167a42Smrg stuff->weight = tmp; 4292f167a42Smrg 4302f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4312f167a42Smrg goto BAILOUT; 4322f167a42Smrg else 4332f167a42Smrg *tmp++ = '\0'; 4342f167a42Smrg stuff->slant = tmp; 4352f167a42Smrg 4362f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4372f167a42Smrg goto BAILOUT; 4382f167a42Smrg else 4392f167a42Smrg *tmp++ = '\0'; 4402f167a42Smrg stuff->setWidth = tmp; 4412f167a42Smrg 4422f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4432f167a42Smrg goto BAILOUT; 4442f167a42Smrg else 4452f167a42Smrg *tmp++ = '\0'; 4462f167a42Smrg stuff->variant = tmp; 4472f167a42Smrg 4482f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4492f167a42Smrg goto BAILOUT; 4502f167a42Smrg else 4512f167a42Smrg *tmp++ = '\0'; 4522f167a42Smrg if (*tmp == '*') 4532f167a42Smrg stuff->pixelSize = 0; 4542f167a42Smrg else if (sscanf(tmp, "%i", &stuff->pixelSize) != 1) 4552f167a42Smrg goto BAILOUT; 4562f167a42Smrg 4572f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4582f167a42Smrg goto BAILOUT; 4592f167a42Smrg else 4602f167a42Smrg *tmp++ = '\0'; 4612f167a42Smrg if (*tmp == '*') 4622f167a42Smrg stuff->ptSize = 0; 4632f167a42Smrg else if (sscanf(tmp, "%i", &stuff->ptSize) != 1) 4642f167a42Smrg goto BAILOUT; 4652f167a42Smrg 4662f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4672f167a42Smrg goto BAILOUT; 4682f167a42Smrg else 4692f167a42Smrg *tmp++ = '\0'; 4702f167a42Smrg if (*tmp == '*') 4712f167a42Smrg stuff->resX = 0; 4722f167a42Smrg else if (sscanf(tmp, "%i", &stuff->resX) != 1) 4732f167a42Smrg goto BAILOUT; 4742f167a42Smrg 4752f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4762f167a42Smrg goto BAILOUT; 4772f167a42Smrg else 4782f167a42Smrg *tmp++ = '\0'; 4792f167a42Smrg if (*tmp == '*') 4802f167a42Smrg stuff->resY = 0; 4812f167a42Smrg else if (sscanf(tmp, "%i", &stuff->resY) != 1) 4822f167a42Smrg goto BAILOUT; 4832f167a42Smrg 4842f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4852f167a42Smrg goto BAILOUT; 4862f167a42Smrg else 4872f167a42Smrg *tmp++ = '\0'; 4882f167a42Smrg stuff->spacing = tmp; 4892f167a42Smrg 4902f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 4912f167a42Smrg goto BAILOUT; 4922f167a42Smrg else 4932f167a42Smrg *tmp++ = '\0'; 4942f167a42Smrg if (*tmp == '*') 4952f167a42Smrg stuff->avgWidth = 0; 4962f167a42Smrg else if (sscanf(tmp, "%i", &stuff->avgWidth) != 1) 4972f167a42Smrg goto BAILOUT; 4982f167a42Smrg 4992f167a42Smrg if ((tmp = strchr(tmp, '-')) == NULL) 5002f167a42Smrg goto BAILOUT; 5012f167a42Smrg else 5022f167a42Smrg *tmp++ = '\0'; 5032f167a42Smrg stuff->encoding = tmp; 5040e20ee16Smrg return True; 5052f167a42Smrg BAILOUT: 5060e20ee16Smrg ClearFontStuff(stuff); 5070e20ee16Smrg return False; 5080e20ee16Smrg} 5090e20ee16Smrg 5100e20ee16Smrgstatic void 5110e20ee16SmrgPSSetUpForLatin1(FILE *out, PSState *state) 5120e20ee16Smrg{ 5132f167a42Smrg fprintf(out, "%s", 5142f167a42Smrg "save\n" 5152f167a42Smrg "/ISOLatin1Encoding where {pop save true}{false} ifelse\n" 5162f167a42Smrg "/ISOLatin1Encoding [\n" 5172f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5182f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5192f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5202f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5212f167a42Smrg " /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 5222f167a42Smrg " /.notdef /.notdef /space /exclam /quotedbl /numbersign\n" 5232f167a42Smrg " /dollar /percent /ampersand /quoteright /parenleft\n" 5242f167a42Smrg " /parenright /asterisk /plus /comma /minus /period\n" 5252f167a42Smrg " /slash /zero /one /two /three /four /five /six /seven\n" 5262f167a42Smrg " /eight /nine /colon /semicolon /less /equal /greater\n" 5272f167a42Smrg " /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M\n" 5282f167a42Smrg " /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft\n" 5292f167a42Smrg " /backslash /bracketright /asciicircum /underscore\n" 5302f167a42Smrg " /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m\n" 5312f167a42Smrg " /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft\n" 5322f167a42Smrg " /bar /braceright /asciitilde /guilsinglright /fraction\n" 5332f167a42Smrg " /florin /quotesingle /quotedblleft /guilsinglleft /fi\n" 5342f167a42Smrg " /fl /endash /dagger /daggerdbl /bullet /quotesinglbase\n" 5352f167a42Smrg " /quotedblbase /quotedblright /ellipsis /trademark\n" 5362f167a42Smrg " /perthousand /grave /scaron /circumflex /Scaron /tilde\n" 5372f167a42Smrg " /breve /zcaron /dotaccent /dotlessi /Zcaron /ring\n" 5382f167a42Smrg " /hungarumlaut /ogonek /caron /emdash /space /exclamdown\n" 5392f167a42Smrg " /cent /sterling /currency /yen /brokenbar /section\n" 5402f167a42Smrg " /dieresis /copyright /ordfeminine /guillemotleft\n" 5412f167a42Smrg " /logicalnot /hyphen /registered /macron /degree\n" 5422f167a42Smrg " /plusminus /twosuperior /threesuperior /acute /mu\n" 5432f167a42Smrg " /paragraph /periodcentered /cedilla /onesuperior\n" 5442f167a42Smrg " /ordmasculine /guillemotright /onequarter /onehalf\n" 5452f167a42Smrg " /threequarters /questiondown /Agrave /Aacute\n" 5462f167a42Smrg " /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n" 5472f167a42Smrg " /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute\n" 5482f167a42Smrg " /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute\n" 5492f167a42Smrg " /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n" 5502f167a42Smrg " /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n" 5512f167a42Smrg " /germandbls /agrave /aacute /acircumflex /atilde\n" 5522f167a42Smrg " /adieresis /aring /ae /ccedilla /egrave /eacute\n" 5532f167a42Smrg " /ecircumflex /edieresis /igrave /iacute /icircumflex\n" 5542f167a42Smrg " /idieresis /eth /ntilde /ograve /oacute /ocircumflex\n" 5552f167a42Smrg " /otilde /odieresis /divide /oslash /ugrave /uacute\n" 5562f167a42Smrg " /ucircumflex /udieresis /yacute /thorn /ydieresis\n" 5572f167a42Smrg "] def {restore} if\n" 5582f167a42Smrg "/reencodeISO-1 {\n" 5592f167a42Smrg " dup length dict begin\n" 5602f167a42Smrg " {1 index /FID ne {def}{pop pop} ifelse} forall\n" 5612f167a42Smrg " /Encoding ISOLatin1Encoding def\n" 5622f167a42Smrg " currentdict\n" 5632f167a42Smrg " end\n" 5642f167a42Smrg "} def\n" 5652f167a42Smrg ); 5660e20ee16Smrg} 5670e20ee16Smrg 5680e20ee16Smrgstatic void 5692f167a42SmrgPSReencodeLatin1Font(FILE *out, const char *font) 5700e20ee16Smrg{ 5712f167a42Smrg fprintf(out, "/%s findfont reencodeISO-1\n", font); 5722f167a42Smrg fprintf(out, " /%s-8859-1 exch definefont pop\n", font); 5730e20ee16Smrg return; 5740e20ee16Smrg} 5750e20ee16Smrg 5760e20ee16Smrgstatic void 5772f167a42SmrgPSSetUpFonts(FILE *out, const char *textFont, int size) 5780e20ee16Smrg{ 5792f167a42Smrg fprintf(out, "/F%d { /%s findfont exch scalefont setfont } def\n", 5802f167a42Smrg FONT_TEXT, textFont); 5812f167a42Smrg fprintf(out, "/F%d { /%s-8859-1 findfont exch scalefont setfont } def\n", 5822f167a42Smrg FONT_LATIN1, textFont); 5832f167a42Smrg fprintf(out, "/F%d { /%s findfont exch scalefont setfont } def\n", 5842f167a42Smrg FONT_SYMBOL, "Symbol"); 5852f167a42Smrg fprintf(out, "/F%d { /%s findfont exch scalefont setfont } def\n", 5862f167a42Smrg FONT_ISOCAPS, "IsoKeyCaps"); 5870e20ee16Smrg return; 5880e20ee16Smrg} 5890e20ee16Smrg 5900e20ee16Smrgstatic void 5910e20ee16SmrgPSSetFont(FILE *out, PSState *state, int font, int size, int pts) 5920e20ee16Smrg{ 5932f167a42Smrg if ((state->font != font) || (state->fontSize != size)) { 5942f167a42Smrg fprintf(out, "%d %sF%d\n", size, (pts ? "pts " : ""), font); 5952f167a42Smrg state->font = font; 5962f167a42Smrg state->fontSize = size; 5970e20ee16Smrg } 5980e20ee16Smrg return; 5990e20ee16Smrg} 6000e20ee16Smrg 6010e20ee16Smrgstatic void 6020e20ee16SmrgPSProlog(FILE *out, PSState *state) 6030e20ee16Smrg{ 6042f167a42Smrg register int i; 6050e20ee16Smrg 6060e20ee16Smrg if (!state->args->wantEPS) { 6072f167a42Smrg fprintf(out, 6082f167a42Smrg "%%!PS-Adobe-2.0\n" 6092f167a42Smrg "%%%%Creator: xkbprint\n"); 6102f167a42Smrg if (state->geom->name != None) 6112f167a42Smrg fprintf(out, "%%%%Title: %s\n", 6122f167a42Smrg XkbAtomGetString(state->dpy, state->geom->name)); 6132f167a42Smrg fprintf(out, 6142f167a42Smrg "%%%%BoundingBox: (atend)\n" 6152f167a42Smrg "%%%%Pages: 1\n" 6162f167a42Smrg "%%%%PageOrder: Ascend\n" 6172f167a42Smrg "%%%%DocumentFonts: (atend)\n" 6182f167a42Smrg "%%%%DocumentData: Clean7Bit\n" 6192f167a42Smrg "%%%%Orientation: Landscape\n" 6202f167a42Smrg "%%%%EndComments\n" 6212f167a42Smrg "%%%%BeginProlog\n" 6222f167a42Smrg "%% Resolution is 1/10mm -- need pt sizes for fonts\n" 6232f167a42Smrg "clippath pathbbox\n" 6242f167a42Smrg " /ury exch def /urx exch def\n" 6252f167a42Smrg " /llx exch def /lly exch def\n" 6262f167a42Smrg " newpath\n" 6272f167a42Smrg "/devwidth urx llx sub def\n" 6282f167a42Smrg "/devheight ury lly sub def\n"); 6290e20ee16Smrg } 6300e20ee16Smrg else { 6312f167a42Smrg int w, h; 6322f167a42Smrg int pw, ph; 6332f167a42Smrg 6342f167a42Smrg w = (((state->geom->width_mm * 72) / 254) * 11) / 10; 6352f167a42Smrg h = (((state->geom->height_mm * 72) / 254) * 11) / 10; 6362f167a42Smrg if (state->kbPerPage > 1) 6372f167a42Smrg h *= (state->kbPerPage + 1); 6382f167a42Smrg 6392f167a42Smrg if (w <= h) { 6402f167a42Smrg pw = 7.5 * 72; 6412f167a42Smrg ph = 10 * 72; 6422f167a42Smrg } 6432f167a42Smrg else { 6442f167a42Smrg pw = 10 * 72; 6452f167a42Smrg ph = 7.5 * 72; 6462f167a42Smrg } 6472f167a42Smrg while ((w > pw) || (h > ph)) { 6482f167a42Smrg w = (w * 9) / 10; 6492f167a42Smrg h = (h * 9) / 10; 6502f167a42Smrg } 6512f167a42Smrg 6522f167a42Smrg fprintf(out, "%%!PS-Adobe-2.0 EPSF-2.0\n"); 6532f167a42Smrg fprintf(out, "%%%%BoundingBox: 0 0 %d %d\n", w, h); 6542f167a42Smrg fprintf(out, "%%%%Creator: xkbprint\n"); 6552f167a42Smrg if (state->geom->name != None) 6562f167a42Smrg fprintf(out, "%%%%Title: %s\n", 6572f167a42Smrg XkbAtomGetString(state->dpy, state->geom->name)); 6582f167a42Smrg fprintf(out, "%%%%Pages: 1\n"); 6592f167a42Smrg fprintf(out, "%%%%EndComments\n"); 6602f167a42Smrg fprintf(out, "%%%%BeginProlog\n"); 6612f167a42Smrg fprintf(out, "/ury 0 def /urx 0 def\n"); 6622f167a42Smrg fprintf(out, "/llx %d def /lly %d def\n", w, h); 6632f167a42Smrg fprintf(out, "/devwidth %d def /devheight %d def\n", w, h); 6640e20ee16Smrg } 6652f167a42Smrg fprintf(out, "/kbdwidth %d def\n", state->geom->width_mm); 6662f167a42Smrg fprintf(out, "/kbdheight %d def\n", state->geom->height_mm); 6672f167a42Smrg fprintf(out, "%s", 6682f167a42Smrg "/pts { 254 mul 72 div } def\n" 6692f167a42Smrg "/mm10 { 72 mul 254 div } def\n" 6702f167a42Smrg "/landscape? {\n" 6712f167a42Smrg " devheight devwidth gt {\n" 6722f167a42Smrg " /pwidth devheight def /pheight devwidth def\n" 6732f167a42Smrg " 0 devheight translate\n" 6742f167a42Smrg " -90 rotate\n" 6752f167a42Smrg " } {\n" 6762f167a42Smrg " /pwidth devwidth def /pheight devheight def\n" 6772f167a42Smrg " } ifelse\n" 6782f167a42Smrg " 0 pheight translate\n" 6792f167a42Smrg " 1 -1 scale\n" 6802f167a42Smrg "} def\n" 6812f167a42Smrg "/centeroffset {\n" 6822f167a42Smrg " /S exch def\n" 6832f167a42Smrg " /HEIGHT exch def\n" 6842f167a42Smrg " /WIDTH exch def\n" 6852f167a42Smrg " S stringwidth /SH exch def /SW exch def\n" 6862f167a42Smrg " WIDTH SW sub 2 div\n" 6872f167a42Smrg " HEIGHT SH sub 2 div\n" 6882f167a42Smrg "} def\n"); 6892f167a42Smrg PSSetUpForLatin1(out, state); 6902f167a42Smrg PSReencodeLatin1Font(out, DFLT_LABEL_FONT); 6910e20ee16Smrg if (state->args->wantColor) { 6922f167a42Smrg XkbGeometryPtr geom = state->geom; 6932f167a42Smrg 6942f167a42Smrg for (i = 0; i < geom->num_colors; i++) { 6952f167a42Smrg PSColorDef(out, state, &geom->colors[i]); 6962f167a42Smrg } 6972f167a42Smrg if (state->black < 0) { 6982f167a42Smrg XkbColorPtr color; 6992f167a42Smrg 7002f167a42Smrg if (!(color = XkbAddGeomColor(geom, "black", geom->num_colors))) 7012f167a42Smrg uFatalError("Couldn't allocate black color!\n"); 7022f167a42Smrg PSColorDef(out, state, color); 7032f167a42Smrg } 7042f167a42Smrg if (state->white < 0) { 7052f167a42Smrg XkbColorPtr color; 7062f167a42Smrg 7072f167a42Smrg if (!(color = XkbAddGeomColor(geom, "white", geom->num_colors))) 7082f167a42Smrg uFatalError("Couldn't allocate white color!\n"); 7092f167a42Smrg PSColorDef(out, state, color); 7102f167a42Smrg } 7110e20ee16Smrg } 7122f167a42Smrg for (i = 0; i < state->geom->num_shapes; i++) { 7132f167a42Smrg PSShapeDef(out, state, &state->geom->shapes[i]); 7140e20ee16Smrg } 7152f167a42Smrg if (state->args->label == LABEL_SYMBOLS) { 7162f167a42Smrg PSIncludeFont(out, "IsoKeyCaps"); 7170e20ee16Smrg } 7182f167a42Smrg PSSetUpFonts(out, DFLT_LABEL_FONT, DFLT_LABEL_FONT_SIZE); 7192f167a42Smrg fprintf(out, "%%%%EndProlog\n"); 7200e20ee16Smrg return; 7210e20ee16Smrg} 7220e20ee16Smrg 7230e20ee16Smrgstatic void 7240e20ee16SmrgPSFileTrailer(FILE *out, PSState *state) 7250e20ee16Smrg{ 7262f167a42Smrg fprintf(out, "restore\n"); 7270e20ee16Smrg if (!state->args->wantEPS) 7282f167a42Smrg fprintf(out, "%%%%Trailer\n"); 7292f167a42Smrg fprintf(out, "%%%%EOF\n"); 7300e20ee16Smrg return; 7310e20ee16Smrg} 7320e20ee16Smrg 7330e20ee16Smrgstatic void 7340e20ee16SmrgPSPageSetup(FILE *out, PSState *state, Bool drawBorder) 7350e20ee16Smrg{ 7362f167a42Smrg XkbGeometryPtr geom; 7370e20ee16Smrg 7382f167a42Smrg geom = state->geom; 7392f167a42Smrg if (state->kbPerPage == 1) { 7402f167a42Smrg fprintf(out, "%%%%Page: %d %d\n", state->nPages + 1, state->nPages + 1); 7412f167a42Smrg fprintf(out, "%%%%BeginPageSetup\n"); 7420e20ee16Smrg } 7432f167a42Smrg else if ((state->nPages & 1) == 0) { /* even page */ 7442f167a42Smrg int realPage; 7452f167a42Smrg 7462f167a42Smrg realPage = state->nPages / 2 + 1; 7472f167a42Smrg fprintf(out, "%%%%Page: %d %d\n", realPage, realPage); 7482f167a42Smrg fprintf(out, "%%%%BeginPageSetup\n"); 7492f167a42Smrg fprintf(out, "%% Keyboard %d\n", state->nPages + 1); 7502f167a42Smrg if (state->nPages == 0) { 7512f167a42Smrg fprintf(out, 7522f167a42Smrg "/realwidth devwidth def\n" 7532f167a42Smrg "/realheight devheight def\n" 7542f167a42Smrg "/devheight realheight 3 div def\n"); 7552f167a42Smrg } 7562f167a42Smrg fprintf(out, "0 devheight dup 2 div add translate\n"); 7570e20ee16Smrg } 7582f167a42Smrg else { 7592f167a42Smrg fprintf(out, "%% Keyboard %d\n", state->nPages + 1); 7600e20ee16Smrg } 7612f167a42Smrg fprintf(out, "save\n"); 7622f167a42Smrg fprintf(out, "landscape?\n"); 7630e20ee16Smrg if (state->args->scaleToFit) { 7642f167a42Smrg fprintf(out, 7652f167a42Smrg "%% Scale keyboard to fit on the page\n" 7662f167a42Smrg "/kbdscale pwidth 72 sub kbdwidth div def\n" 7672f167a42Smrg "/kbdscalewidth kbdwidth kbdscale mul def\n" 7682f167a42Smrg "/kbdscaleheight kbdheight kbdscale mul def\n" 7692f167a42Smrg "/kbx 36 def\n" 7702f167a42Smrg "/kby pheight kbdscaleheight sub 2 div def\n"); 7712f167a42Smrg PSGSave(out, state); 7722f167a42Smrg fprintf(out, 7732f167a42Smrg "kbx kby translate\n" 7742f167a42Smrg "kbdscale kbdscale scale\n"); 7750e20ee16Smrg } 7760e20ee16Smrg else { 7772f167a42Smrg fprintf(out, 7782f167a42Smrg "%% Draw keyboard full size\n" 7792f167a42Smrg "/kbdscale 1 def\n" 7802f167a42Smrg "/kbdscalewidth kbdwidth mm10 def\n" 7812f167a42Smrg "/kbdscaleheight kbdheight mm10 def\n" 7822f167a42Smrg "/kbx pwidth kbdscalewidth sub 2 div def\n" 7832f167a42Smrg "/kby pheight kbdscaleheight sub 2 div def\n"); 7842f167a42Smrg PSGSave(out, state); 7852f167a42Smrg fprintf(out, 7862f167a42Smrg "kbx kby translate\n" 7872f167a42Smrg "72 254 div dup scale\n"); 7880e20ee16Smrg } 7890e20ee16Smrg if (drawBorder) { 7902f167a42Smrg if (state->args->wantColor) { 7912f167a42Smrg PSSetColor(out, state, geom->base_color->pixel); 7922f167a42Smrg fprintf(out, " 0 0 moveto\n"); 7932f167a42Smrg fprintf(out, "%3d 0 lineto\n", geom->width_mm); 7942f167a42Smrg fprintf(out, "%3d %3d lineto\n", geom->width_mm, geom->height_mm); 7952f167a42Smrg fprintf(out, " 0 %3d lineto\n", geom->height_mm); 7962f167a42Smrg fprintf(out, "closepath fill\n"); 7972f167a42Smrg } 7982f167a42Smrg PSSetColor(out, state, state->black); 7992f167a42Smrg fprintf(out, " 0 0 moveto\n"); 8002f167a42Smrg fprintf(out, "%3d 0 lineto\n", geom->width_mm); 8012f167a42Smrg fprintf(out, "%3d %3d lineto\n", geom->width_mm, geom->height_mm); 8022f167a42Smrg fprintf(out, " 0 %3d lineto\n", geom->height_mm); 8032f167a42Smrg fprintf(out, "closepath stroke\n"); 8040e20ee16Smrg } 8052f167a42Smrg fprintf(out, "%%%%EndPageSetup\n"); 8060e20ee16Smrg return; 8070e20ee16Smrg} 8080e20ee16Smrg 8090e20ee16Smrgstatic void 8100e20ee16SmrgPSPageTrailer(FILE *out, PSState *state) 8110e20ee16Smrg{ 8122f167a42Smrg char *name; 8132f167a42Smrg XkbDescPtr xkb; 8142f167a42Smrg XkbGeometryPtr geom; 8152f167a42Smrg XkbPropertyPtr prop; 8162f167a42Smrg int p, baseline; 8172f167a42Smrg 8182f167a42Smrg xkb = state->xkb; 8192f167a42Smrg geom = state->geom; 8202f167a42Smrg if (state->args->grid > 0) { 8212f167a42Smrg fprintf(out, "%% Draw a %dmm grid\n", state->args->grid); 8222f167a42Smrg fprintf(out, "0 setlinewidth\n"); 8232f167a42Smrg fprintf(out, "0.25 setgray\n"); 8242f167a42Smrg fprintf(out, " 0 %d %d {\n", state->args->grid * 10, geom->width_mm); 8252f167a42Smrg fprintf(out, " /GX exch def\n"); 8262f167a42Smrg fprintf(out, " GX 0 moveto GX %d lineto stroke\n", geom->height_mm); 8272f167a42Smrg fprintf(out, "} for\n"); 8282f167a42Smrg fprintf(out, " 0 %d %d {\n", state->args->grid * 10, geom->height_mm); 8292f167a42Smrg fprintf(out, " /GY exch def\n"); 8302f167a42Smrg fprintf(out, " 0 GY moveto %d GY lineto stroke\n", geom->width_mm); 8312f167a42Smrg fprintf(out, "} for\n"); 8320e20ee16Smrg } 8332f167a42Smrg PSGRestore(out, state); 8342f167a42Smrg name = NULL; 8352f167a42Smrg for (p = 0, prop = geom->properties; p < geom->num_properties; p++, prop++) { 8362f167a42Smrg if ((prop->value != NULL) && (uStrCaseEqual(prop->name, "description"))) { 8372f167a42Smrg name = prop->value; 8382f167a42Smrg break; 8392f167a42Smrg } 8400e20ee16Smrg } 8412f167a42Smrg if ((!state->args->wantEPS) && 8422f167a42Smrg ((state->kbPerPage == 1) || ((state->nPages & 1) == 1) || 8432f167a42Smrg (state->nPages == state->totalKB))) { 8442f167a42Smrg if ((name == NULL) && (geom->name != None)) 8452f167a42Smrg name = XkbAtomGetString(state->dpy, geom->name); 8462f167a42Smrg 8472f167a42Smrg baseline = 16; 8482f167a42Smrg if ((name != NULL) || (state->args->label == LABEL_SYMBOLS)) { 8492f167a42Smrg PSSetColor(out, state, state->black); 8502f167a42Smrg PSSetFont(out, state, FONT_LATIN1, 14, False); 8512f167a42Smrg } 8522f167a42Smrg if (state->args->label == LABEL_SYMBOLS) { 8532f167a42Smrg char buf[40], *lbuf; 8542f167a42Smrg const char *sName = NULL; 8552f167a42Smrg Atom sAtom; 8562f167a42Smrg 8572f167a42Smrg if (state->args->nLabelGroups == 1) 8582f167a42Smrg snprintf(buf, sizeof(buf), "Group %d", 8592f167a42Smrg state->args->baseLabelGroup + 1); 8602f167a42Smrg else 8612f167a42Smrg snprintf(buf, sizeof(buf), "Groups %d-%d", 8622f167a42Smrg state->args->baseLabelGroup + 1, 8632f167a42Smrg state->args->baseLabelGroup + 8642f167a42Smrg state->args->nLabelGroups); 8652f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 8662f167a42Smrg buf); 8672f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 8682f167a42Smrg fprintf(out, " moveto\n"); 8692f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", buf); 8702f167a42Smrg baseline += 16; 8712f167a42Smrg 8722f167a42Smrg if (xkb->names != NULL) 8732f167a42Smrg sAtom = xkb->names->symbols; 8742f167a42Smrg else 8752f167a42Smrg sAtom = None; 8762f167a42Smrg if (sAtom != None) 8772f167a42Smrg sName = XkbAtomGetString(state->dpy, sAtom); 8782f167a42Smrg if (sName == NULL) 8792f167a42Smrg sName = "(unknown)"; 8802f167a42Smrg 8812f167a42Smrg if (asprintf(&lbuf, "Layout: %s", sName) == -1) { 8822f167a42Smrg uFatalError("Can't allocate memory for string\n"); 8832f167a42Smrg } 8842f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 8852f167a42Smrg lbuf); 8862f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 8872f167a42Smrg fprintf(out, " moveto\n"); 8882f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", lbuf); 8892f167a42Smrg baseline += 16; 8902f167a42Smrg free(lbuf); 8912f167a42Smrg } 8922f167a42Smrg if (name != NULL) { 8932f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 8942f167a42Smrg name); 8952f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 8962f167a42Smrg fprintf(out, " moveto\n"); 8972f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", name); 8982f167a42Smrg baseline += 16; 8992f167a42Smrg } 9002f167a42Smrg if (state->args->label == LABEL_KEYCODE) { 9012f167a42Smrg const char *sName = NULL; 9022f167a42Smrg char *lbuf; 9032f167a42Smrg Atom sAtom; 9042f167a42Smrg 9052f167a42Smrg if (xkb->names != NULL) 9062f167a42Smrg sAtom = xkb->names->keycodes; 9072f167a42Smrg else 9082f167a42Smrg sAtom = None; 9092f167a42Smrg if (sAtom != None) 9102f167a42Smrg sName = XkbAtomGetString(state->dpy, sAtom); 9112f167a42Smrg if (sName == NULL) 9122f167a42Smrg sName = "(unknown)"; 9132f167a42Smrg 9142f167a42Smrg if (asprintf(&lbuf, "Keycodes: %s", sName) == -1) { 9152f167a42Smrg uFatalError("Can't allocate memory for string\n"); 9162f167a42Smrg } 9172f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 9182f167a42Smrg lbuf); 9192f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 9202f167a42Smrg fprintf(out, " moveto\n"); 9212f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", lbuf); 9222f167a42Smrg baseline += 16; 9232f167a42Smrg free(lbuf); 9242f167a42Smrg } 9252f167a42Smrg if (state->args->copies > 1) { 9262f167a42Smrg for (p = 1; p < state->args->copies; p++) 9272f167a42Smrg fprintf(out, "copypage\n"); 9282f167a42Smrg } 9292f167a42Smrg fprintf(out, "showpage\n"); 9302f167a42Smrg fprintf(out, "restore\n"); 9312f167a42Smrg fprintf(out, "%% Done with keyboard/page %d\n", state->nPages + 1); 9320e20ee16Smrg } 9330e20ee16Smrg else { 9342f167a42Smrg if ((!state->args->wantEPS) && (state->args->label == LABEL_SYMBOLS)) { 9352f167a42Smrg char buf[40]; 9362f167a42Smrg 9372f167a42Smrg baseline = 16; 9382f167a42Smrg PSSetColor(out, state, state->black); 9392f167a42Smrg PSSetFont(out, state, FONT_LATIN1, 14, False); 9402f167a42Smrg if (state->args->nLabelGroups == 1) 9412f167a42Smrg snprintf(buf, sizeof(buf), "Group %d", 9422f167a42Smrg state->args->baseLabelGroup + 1); 9432f167a42Smrg else 9442f167a42Smrg snprintf(buf, sizeof(buf), "Groups %d-%d", 9452f167a42Smrg state->args->baseLabelGroup + 1, 9462f167a42Smrg state->args->baseLabelGroup + 9472f167a42Smrg state->args->nLabelGroups + 1); 9482f167a42Smrg fprintf(out, "kbx kbdscalewidth 0 (%s) centeroffset pop add\n", 9492f167a42Smrg buf); 9502f167a42Smrg fprintf(out, " kby kbdscaleheight add %d add\n", baseline); 9512f167a42Smrg fprintf(out, " moveto\n"); 9522f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", buf); 9532f167a42Smrg baseline += 16; 9542f167a42Smrg } 9552f167a42Smrg fprintf(out, "restore\n"); 9562f167a42Smrg fprintf(out, "%% Done with keyboard %d\n", state->nPages + 1); 9572f167a42Smrg fprintf(out, "0 devheight -1 mul translate %% next keyboard\n"); 9580e20ee16Smrg } 9590e20ee16Smrg state->nPages++; 9602f167a42Smrg state->color = state->black; 9612f167a42Smrg state->font = -1; 9620e20ee16Smrg return; 9630e20ee16Smrg} 9640e20ee16Smrg 9650e20ee16Smrgstatic void 9660e20ee16SmrgPSDoodad(FILE *out, PSState *state, XkbDoodadPtr doodad) 9670e20ee16Smrg{ 9682f167a42Smrg XkbDescPtr xkb; 9692f167a42Smrg const char *name, *dname; 9702f167a42Smrg int sz, leading; 9712f167a42Smrg 9722f167a42Smrg xkb = state->xkb; 9732f167a42Smrg if (doodad->any.name != None) 9742f167a42Smrg dname = XkbAtomGetString(xkb->dpy, doodad->any.name); 9752f167a42Smrg else 9762f167a42Smrg dname = "NoName"; 9770e20ee16Smrg switch (doodad->any.type) { 9782f167a42Smrg case XkbOutlineDoodad: 9792f167a42Smrg case XkbSolidDoodad: 9802f167a42Smrg name = XkbAtomGetString(xkb->dpy, 9812f167a42Smrg XkbShapeDoodadShape(xkb->geom, 9822f167a42Smrg &doodad->shape)->name); 9832f167a42Smrg if (state->args->wantColor) { 9842f167a42Smrg PSSetColor(out, state, doodad->shape.color_ndx); 9852f167a42Smrg if (doodad->any.type != XkbOutlineDoodad) { 9862f167a42Smrg fprintf(out, "true %d %d %d %s %% Doodad %s\n", 9872f167a42Smrg doodad->shape.angle, 9882f167a42Smrg doodad->shape.left, doodad->shape.top, name, dname); 9892f167a42Smrg PSSetColor(out, state, state->black); 9902f167a42Smrg } 9912f167a42Smrg fprintf(out, "false %d %d %d %s %% Doodad %s\n", 9922f167a42Smrg doodad->shape.angle, 9932f167a42Smrg doodad->shape.left, doodad->shape.top, name, dname); 9942f167a42Smrg } 9952f167a42Smrg else { 9962f167a42Smrg fprintf(out, "false %d %d %d %s %% Doodad %s\n", 9972f167a42Smrg doodad->shape.angle, 9982f167a42Smrg doodad->shape.left, doodad->shape.top, name, dname); 9992f167a42Smrg } 10002f167a42Smrg break; 10012f167a42Smrg case XkbTextDoodad: 10022f167a42Smrg fprintf(out, "%% Doodad %s\n", dname); 10032f167a42Smrg PSSetColor(out, state, doodad->text.color_ndx); 10042f167a42Smrg PSGSave(out, state); 10052f167a42Smrg fprintf(out, "%d %d translate\n", doodad->text.left, doodad->text.top); 10062f167a42Smrg if (doodad->text.angle != 0) 10072f167a42Smrg fprintf(out, "%s rotate\n", 10082f167a42Smrg XkbGeomFPText(doodad->text.angle, XkbMessage)); 10092f167a42Smrg sz = 14; 10102f167a42Smrg if (doodad->text.font) { 10112f167a42Smrg FontStuff stuff; 10122f167a42Smrg 10132f167a42Smrg if (CrackXLFDName(doodad->text.font, &stuff)) { 10142f167a42Smrg if (stuff.ptSize > 0) 10152f167a42Smrg sz = stuff.ptSize / 10; 10162f167a42Smrg ClearFontStuff(&stuff); 10172f167a42Smrg } 10182f167a42Smrg } 10192f167a42Smrg PSSetFont(out, state, FONT_LATIN1, sz, True); 10202f167a42Smrg leading = (sz * 12) / 10; 10212f167a42Smrg if (strchr(doodad->text.text, '\n') == NULL) { 10222f167a42Smrg fprintf(out, "0 %d pts moveto 1 -1 scale\n", (leading * 8) / 10); 10232f167a42Smrg fprintf(out, "(%s) show\n", doodad->text.text); 10242f167a42Smrg } 10252f167a42Smrg else { 10262f167a42Smrg char *tmp, *buf, *end; 10272f167a42Smrg int offset = (leading * 8 / 10); 10282f167a42Smrg 10292f167a42Smrg tmp = buf = strdup(doodad->text.text); 10302f167a42Smrg while (tmp != NULL) { 10312f167a42Smrg end = strchr(tmp, '\n'); 10322f167a42Smrg if (end != NULL) 10332f167a42Smrg *end++ = '\0'; 10342f167a42Smrg fprintf(out, "0 %d pts moveto 1 -1 scale\n", offset); 10352f167a42Smrg fprintf(out, "(%s) show 1 -1 scale\n", tmp); 10362f167a42Smrg offset += leading; 10372f167a42Smrg tmp = end; 10382f167a42Smrg } 10392f167a42Smrg free(buf); 10402f167a42Smrg } 10412f167a42Smrg PSGRestore(out, state); 10422f167a42Smrg break; 10432f167a42Smrg case XkbIndicatorDoodad: 10442f167a42Smrg name = XkbAtomGetString(xkb->dpy, 10452f167a42Smrg XkbIndicatorDoodadShape(xkb->geom, 10462f167a42Smrg &doodad->indicator)-> 10472f167a42Smrg name); 10482f167a42Smrg if (state->args->wantColor) { 10492f167a42Smrg PSSetColor(out, state, doodad->indicator.off_color_ndx); 10502f167a42Smrg fprintf(out, "true 0 %d %d %s %% Doodad %s\n", 10512f167a42Smrg doodad->indicator.left, doodad->indicator.top, name, dname); 10522f167a42Smrg PSSetColor(out, state, state->black); 10532f167a42Smrg } 10542f167a42Smrg fprintf(out, "false 0 %d %d %s %% Doodad %s\n", 10552f167a42Smrg doodad->indicator.left, doodad->indicator.top, name, dname); 10562f167a42Smrg break; 10572f167a42Smrg case XkbLogoDoodad: 10582f167a42Smrg name = XkbAtomGetString(xkb->dpy, 10592f167a42Smrg XkbLogoDoodadShape(xkb->geom, 10602f167a42Smrg &doodad->logo)->name); 10612f167a42Smrg if (state->args->wantColor) 10622f167a42Smrg PSSetColor(out, state, doodad->shape.color_ndx); 10632f167a42Smrg fprintf(out, "false %d %d %d %s %% Doodad %s\n", 10642f167a42Smrg doodad->shape.angle, 10652f167a42Smrg doodad->shape.left, doodad->shape.top, name, dname); 10662f167a42Smrg break; 10670e20ee16Smrg } 10680e20ee16Smrg return; 10690e20ee16Smrg} 10700e20ee16Smrg 10710e20ee16Smrg/***====================================================================***/ 10720e20ee16Smrg 10730e20ee16Smrgstatic Bool 10742f167a42SmrgPSKeycapsSymbol(KeySym sym, unsigned char *buf, 10752f167a42Smrg int *font_rtrn, int *sz_rtrn, PSState *state) 10760e20ee16Smrg{ 10772f167a42Smrg if (state->args->wantSymbols == NO_SYMBOLS) 10782f167a42Smrg return False; 10792f167a42Smrg 10802f167a42Smrg if (font_rtrn != NULL) 10812f167a42Smrg *font_rtrn = FONT_ISOCAPS; 10822f167a42Smrg if (sz_rtrn != NULL) 10832f167a42Smrg *sz_rtrn = SZ_LARGE; 10842f167a42Smrg buf[1] = '\0'; 10850e20ee16Smrg switch (sym) { 10862f167a42Smrg case XK_Shift_L: 10872f167a42Smrg case XK_Shift_R: 10882f167a42Smrg buf[0] = XKC_ISO_Shift; 10892f167a42Smrg return True; 10902f167a42Smrg case XK_Shift_Lock: 10912f167a42Smrg buf[0] = XKC_ISO_Shift_Lock; 10922f167a42Smrg return True; 10932f167a42Smrg case XK_ISO_Lock: 10942f167a42Smrg buf[0] = XKC_ISO_Caps_Lock; 10952f167a42Smrg return True; 10962f167a42Smrg case XK_BackSpace: 10972f167a42Smrg buf[0] = XKC_ISO_Backspace; 10982f167a42Smrg return True; 10992f167a42Smrg case XK_Return: 11002f167a42Smrg buf[0] = XKC_ISO_Return; 11012f167a42Smrg return True; 11022f167a42Smrg case XK_Up: 11032f167a42Smrg case XK_KP_Up: 11042f167a42Smrg buf[0] = XKC_ISO_Up; 11052f167a42Smrg return True; 11062f167a42Smrg case XK_Down: 11072f167a42Smrg case XK_KP_Down: 11082f167a42Smrg buf[0] = XKC_ISO_Down; 11092f167a42Smrg return True; 11102f167a42Smrg case XK_Left: 11112f167a42Smrg case XK_KP_Left: 11122f167a42Smrg buf[0] = XKC_ISO_Left; 11132f167a42Smrg return True; 11142f167a42Smrg case XK_Right: 11152f167a42Smrg case XK_KP_Right: 11162f167a42Smrg buf[0] = XKC_ISO_Right; 11172f167a42Smrg return True; 11182f167a42Smrg case XK_Tab: 11192f167a42Smrg buf[0] = XKC_ISO_Tab; 11202f167a42Smrg return True; 11212f167a42Smrg case XK_ISO_Left_Tab: 11222f167a42Smrg buf[0] = XKC_ISO_Left_Tab; 11232f167a42Smrg return True; 11240e20ee16Smrg } 11252f167a42Smrg if (state->args->wantSymbols != ALL_SYMBOLS) 11262f167a42Smrg return False; 11270e20ee16Smrg switch (sym) { 11282f167a42Smrg case XK_Caps_Lock: 11292f167a42Smrg buf[0] = XKC_ISO_Caps_Lock; 11302f167a42Smrg return True; 11312f167a42Smrg case XK_Num_Lock: 11322f167a42Smrg buf[0] = XKC_ISO_Num_Lock; 11332f167a42Smrg return True; 11342f167a42Smrg case XK_ISO_Level3_Shift: 11352f167a42Smrg buf[0] = XKC_ISO_Level3_Shift; 11362f167a42Smrg return True; 11372f167a42Smrg case XK_ISO_Level3_Lock: 11382f167a42Smrg buf[0] = XKC_ISO_Level3_Lock; 11392f167a42Smrg return True; 11402f167a42Smrg case XK_ISO_Next_Group: 11412f167a42Smrg case XK_ISO_Group_Shift: 11422f167a42Smrg buf[0] = XKC_ISO_Next_Group; 11432f167a42Smrg return True; 11442f167a42Smrg case XK_ISO_Next_Group_Lock: 11452f167a42Smrg buf[0] = XKC_ISO_Next_Group_Lock; 11462f167a42Smrg return True; 11472f167a42Smrg case XK_space: 11482f167a42Smrg buf[0] = XKC_ISO_Space; 11492f167a42Smrg return True; 11502f167a42Smrg case XK_nobreakspace: 11512f167a42Smrg buf[0] = XKC_ISO_No_Break_Space; 11522f167a42Smrg return True; 11532f167a42Smrg case XK_Insert: 11542f167a42Smrg buf[0] = XKC_ISO_Insert; 11552f167a42Smrg return True; 11562f167a42Smrg case XK_ISO_Continuous_Underline: 11572f167a42Smrg buf[0] = XKC_ISO_Continuous_Underline; 11582f167a42Smrg return True; 11592f167a42Smrg case XK_ISO_Discontinuous_Underline: 11602f167a42Smrg buf[0] = XKC_ISO_Discontinuous_Underline; 11612f167a42Smrg return True; 11622f167a42Smrg case XK_ISO_Emphasize: 11632f167a42Smrg buf[0] = XKC_ISO_Emphasize; 11642f167a42Smrg return True; 11652f167a42Smrg case XK_Multi_key: 11662f167a42Smrg buf[0] = XKC_ISO_Compose; 11672f167a42Smrg return True; 11682f167a42Smrg case XK_ISO_Center_Object: 11692f167a42Smrg buf[0] = XKC_ISO_Center_Object; 11702f167a42Smrg return True; 11712f167a42Smrg case XK_Delete: 11722f167a42Smrg buf[0] = XKC_ISO_Delete; 11732f167a42Smrg return True; 11742f167a42Smrg case XK_Clear: 11752f167a42Smrg buf[0] = XKC_ISO_Clear_Screen; 11762f167a42Smrg return True; 11772f167a42Smrg case XK_Scroll_Lock: 11782f167a42Smrg buf[0] = XKC_ISO_Scroll_Lock; 11792f167a42Smrg return True; 11802f167a42Smrg case XK_Help: 11812f167a42Smrg buf[0] = XKC_ISO_Help; 11822f167a42Smrg return True; 11832f167a42Smrg case XK_Print: 11842f167a42Smrg buf[0] = XKC_ISO_Print_Screen; 11852f167a42Smrg return True; 11862f167a42Smrg case XK_ISO_Enter: 11872f167a42Smrg buf[0] = XKC_ISO_Enter; 11882f167a42Smrg return True; 11892f167a42Smrg case XK_Alt_L: 11902f167a42Smrg case XK_Alt_R: 11912f167a42Smrg buf[0] = XKC_ISO_Alt; 11922f167a42Smrg return True; 11932f167a42Smrg case XK_Control_L: 11942f167a42Smrg case XK_Control_R: 11952f167a42Smrg buf[0] = XKC_ISO_Control; 11962f167a42Smrg return True; 11972f167a42Smrg case XK_Pause: 11982f167a42Smrg buf[0] = XKC_ISO_Pause; 11992f167a42Smrg return True; 12002f167a42Smrg case XK_Break: 12012f167a42Smrg buf[0] = XKC_ISO_Break; 12022f167a42Smrg return True; 12032f167a42Smrg case XK_Escape: 12042f167a42Smrg buf[0] = XKC_ISO_Escape; 12052f167a42Smrg return True; 12062f167a42Smrg case XK_Undo: 12072f167a42Smrg buf[0] = XKC_ISO_Undo; 12082f167a42Smrg return True; 12092f167a42Smrg case XK_ISO_Fast_Cursor_Up: 12102f167a42Smrg buf[0] = XKC_ISO_Fast_Cursor_Up; 12112f167a42Smrg return True; 12122f167a42Smrg case XK_ISO_Fast_Cursor_Down: 12132f167a42Smrg buf[0] = XKC_ISO_Fast_Cursor_Down; 12142f167a42Smrg return True; 12152f167a42Smrg case XK_ISO_Fast_Cursor_Left: 12162f167a42Smrg buf[0] = XKC_ISO_Fast_Cursor_Left; 12172f167a42Smrg return True; 12182f167a42Smrg case XK_ISO_Fast_Cursor_Right: 12192f167a42Smrg buf[0] = XKC_ISO_Fast_Cursor_Right; 12202f167a42Smrg return True; 12212f167a42Smrg case XK_Home: 12222f167a42Smrg buf[0] = XKC_ISO_Home; 12232f167a42Smrg return True; 12242f167a42Smrg case XK_End: 12252f167a42Smrg buf[0] = XKC_ISO_End; 12262f167a42Smrg return True; 12272f167a42Smrg case XK_Page_Up: 12282f167a42Smrg buf[0] = XKC_ISO_Page_Up; 12292f167a42Smrg return True; 12302f167a42Smrg case XK_Page_Down: 12312f167a42Smrg buf[0] = XKC_ISO_Page_Down; 12322f167a42Smrg return True; 12332f167a42Smrg case XK_ISO_Move_Line_Up: 12342f167a42Smrg buf[0] = XKC_ISO_Move_Line_Up; 12352f167a42Smrg return True; 12362f167a42Smrg case XK_ISO_Move_Line_Down: 12372f167a42Smrg buf[0] = XKC_ISO_Move_Line_Down; 12382f167a42Smrg return True; 12392f167a42Smrg case XK_ISO_Partial_Line_Up: 12402f167a42Smrg buf[0] = XKC_ISO_Partial_Line_Up; 12412f167a42Smrg return True; 12422f167a42Smrg case XK_ISO_Partial_Line_Down: 12432f167a42Smrg buf[0] = XKC_ISO_Partial_Line_Down; 12442f167a42Smrg return True; 12452f167a42Smrg case XK_ISO_Partial_Space_Left: 12462f167a42Smrg buf[0] = XKC_ISO_Partial_Space_Left; 12472f167a42Smrg return True; 12482f167a42Smrg case XK_ISO_Partial_Space_Right: 12492f167a42Smrg buf[0] = XKC_ISO_Partial_Space_Right; 12502f167a42Smrg return True; 12512f167a42Smrg case XK_ISO_Set_Margin_Left: 12522f167a42Smrg buf[0] = XKC_ISO_Set_Margin_Left; 12532f167a42Smrg return True; 12542f167a42Smrg case XK_ISO_Set_Margin_Right: 12552f167a42Smrg buf[0] = XKC_ISO_Set_Margin_Right; 12562f167a42Smrg return True; 12572f167a42Smrg case XK_ISO_Release_Margin_Left: 12582f167a42Smrg buf[0] = XKC_ISO_Release_Margin_Left; 12592f167a42Smrg return True; 12602f167a42Smrg case XK_ISO_Release_Margin_Right: 12612f167a42Smrg buf[0] = XKC_ISO_Release_Margin_Right; 12622f167a42Smrg return True; 12632f167a42Smrg case XK_ISO_Release_Both_Margins: 12642f167a42Smrg buf[0] = XKC_ISO_Release_Both_Margins; 12652f167a42Smrg return True; 12662f167a42Smrg case XK_ISO_Prev_Group: 12672f167a42Smrg buf[0] = XKC_ISO_Prev_Group; 12682f167a42Smrg return True; 12692f167a42Smrg case XK_ISO_Prev_Group_Lock: 12702f167a42Smrg buf[0] = XKC_ISO_Prev_Group_Lock; 12712f167a42Smrg return True; 12720e20ee16Smrg } 12730e20ee16Smrg return False; 12740e20ee16Smrg} 12750e20ee16Smrg 12760e20ee16Smrgstatic Bool 12770e20ee16SmrgPSNonLatin1Symbol(KeySym sym, unsigned char *buf, 12782f167a42Smrg int *font_rtrn, int *sz_rtrn, PSState *state) 12790e20ee16Smrg{ 12802f167a42Smrg if (state->args->wantSymbols == NO_SYMBOLS) 12812f167a42Smrg return False; 12822f167a42Smrg 12832f167a42Smrg if (font_rtrn != NULL) 12842f167a42Smrg *font_rtrn = FONT_TEXT; 12852f167a42Smrg if (sz_rtrn != NULL) 12862f167a42Smrg *sz_rtrn = SZ_LARGE; 12872f167a42Smrg buf[1] = '\0'; 12880e20ee16Smrg switch (sym) { 12892f167a42Smrg case XK_breve: 12902f167a42Smrg buf[0] = 0xC6; 12912f167a42Smrg return True; 12922f167a42Smrg case XK_abovedot: 12932f167a42Smrg buf[0] = 0xC7; 12942f167a42Smrg return True; 12952f167a42Smrg case XK_doubleacute: 12962f167a42Smrg buf[0] = 0xCD; 12972f167a42Smrg return True; 12982f167a42Smrg case XK_ogonek: 12992f167a42Smrg buf[0] = 0xCE; 13002f167a42Smrg return True; 13012f167a42Smrg case XK_caron: 13022f167a42Smrg buf[0] = 0xCF; 13032f167a42Smrg return True; 13042f167a42Smrg case XK_Lstroke: 13052f167a42Smrg buf[0] = 0xE8; 13062f167a42Smrg return True; 13072f167a42Smrg case XK_idotless: 13082f167a42Smrg buf[0] = 0xF5; 13092f167a42Smrg return True; 13102f167a42Smrg case XK_lstroke: 13112f167a42Smrg buf[0] = 0xF8; 13122f167a42Smrg return True; 13130e20ee16Smrg } 13142f167a42Smrg if (font_rtrn != NULL) 13152f167a42Smrg *font_rtrn = FONT_SYMBOL; 13162f167a42Smrg if (sz_rtrn != NULL) 13172f167a42Smrg *sz_rtrn = SZ_MEDIUM; 13182f167a42Smrg if ((sym & (~0xffUL)) == 0x700) { 13192f167a42Smrg switch (sym) { 13202f167a42Smrg /* Greek symbol */ 13212f167a42Smrg case XK_Greek_ALPHA: 13222f167a42Smrg buf[0] = 0x41; 13232f167a42Smrg return True; 13242f167a42Smrg case XK_Greek_BETA: 13252f167a42Smrg buf[0] = 0x42; 13262f167a42Smrg return True; 13272f167a42Smrg case XK_Greek_CHI: 13282f167a42Smrg buf[0] = 0x43; 13292f167a42Smrg return True; 13302f167a42Smrg case XK_Greek_DELTA: 13312f167a42Smrg buf[0] = 0x44; 13322f167a42Smrg return True; 13332f167a42Smrg case XK_Greek_EPSILON: 13342f167a42Smrg buf[0] = 0x45; 13352f167a42Smrg return True; 13362f167a42Smrg case XK_Greek_PHI: 13372f167a42Smrg buf[0] = 0x46; 13382f167a42Smrg return True; 13392f167a42Smrg case XK_Greek_GAMMA: 13402f167a42Smrg buf[0] = 0x47; 13412f167a42Smrg return True; 13422f167a42Smrg case XK_Greek_ETA: 13432f167a42Smrg buf[0] = 0x48; 13442f167a42Smrg return True; 13452f167a42Smrg case XK_Greek_IOTA: 13462f167a42Smrg buf[0] = 0x49; 13472f167a42Smrg return True; 13482f167a42Smrg case XK_Greek_KAPPA: 13492f167a42Smrg buf[0] = 0x4B; 13502f167a42Smrg return True; 13512f167a42Smrg case XK_Greek_LAMDA: 13522f167a42Smrg buf[0] = 0x4C; 13532f167a42Smrg return True; 13542f167a42Smrg case XK_Greek_MU: 13552f167a42Smrg buf[0] = 0x4D; 13562f167a42Smrg return True; 13572f167a42Smrg case XK_Greek_NU: 13582f167a42Smrg buf[0] = 0x4E; 13592f167a42Smrg return True; 13602f167a42Smrg case XK_Greek_OMICRON: 13612f167a42Smrg buf[0] = 0x4F; 13622f167a42Smrg return True; 13632f167a42Smrg case XK_Greek_PI: 13642f167a42Smrg buf[0] = 0x50; 13652f167a42Smrg return True; 13662f167a42Smrg case XK_Greek_THETA: 13672f167a42Smrg buf[0] = 0x51; 13682f167a42Smrg return True; 13692f167a42Smrg case XK_Greek_RHO: 13702f167a42Smrg buf[0] = 0x52; 13712f167a42Smrg return True; 13722f167a42Smrg case XK_Greek_SIGMA: 13732f167a42Smrg buf[0] = 0x53; 13742f167a42Smrg return True; 13752f167a42Smrg case XK_Greek_TAU: 13762f167a42Smrg buf[0] = 0x54; 13772f167a42Smrg return True; 13782f167a42Smrg case XK_Greek_UPSILON: 13792f167a42Smrg buf[0] = 0x55; 13802f167a42Smrg return True; 13812f167a42Smrg case XK_Greek_OMEGA: 13822f167a42Smrg buf[0] = 0x57; 13832f167a42Smrg return True; 13842f167a42Smrg case XK_Greek_XI: 13852f167a42Smrg buf[0] = 0x58; 13862f167a42Smrg return True; 13872f167a42Smrg case XK_Greek_PSI: 13882f167a42Smrg buf[0] = 0x59; 13892f167a42Smrg return True; 13902f167a42Smrg case XK_Greek_ZETA: 13912f167a42Smrg buf[0] = 0x5A; 13922f167a42Smrg return True; 13932f167a42Smrg 13942f167a42Smrg case XK_Greek_alpha: 13952f167a42Smrg buf[0] = 0x61; 13962f167a42Smrg return True; 13972f167a42Smrg case XK_Greek_beta: 13982f167a42Smrg buf[0] = 0x62; 13992f167a42Smrg return True; 14002f167a42Smrg case XK_Greek_chi: 14012f167a42Smrg buf[0] = 0x63; 14022f167a42Smrg return True; 14032f167a42Smrg case XK_Greek_delta: 14042f167a42Smrg buf[0] = 0x64; 14052f167a42Smrg return True; 14062f167a42Smrg case XK_Greek_epsilon: 14072f167a42Smrg buf[0] = 0x65; 14082f167a42Smrg return True; 14092f167a42Smrg case XK_Greek_phi: 14102f167a42Smrg buf[0] = 0x66; 14112f167a42Smrg return True; 14122f167a42Smrg case XK_Greek_gamma: 14132f167a42Smrg buf[0] = 0x67; 14142f167a42Smrg return True; 14152f167a42Smrg case XK_Greek_eta: 14162f167a42Smrg buf[0] = 0x68; 14172f167a42Smrg return True; 14182f167a42Smrg case XK_Greek_iota: 14192f167a42Smrg buf[0] = 0x69; 14202f167a42Smrg return True; 14212f167a42Smrg case XK_Greek_kappa: 14222f167a42Smrg buf[0] = 0x6B; 14232f167a42Smrg return True; 14242f167a42Smrg case XK_Greek_lamda: 14252f167a42Smrg buf[0] = 0x6C; 14262f167a42Smrg return True; 14272f167a42Smrg case XK_Greek_mu: 14282f167a42Smrg buf[0] = 0x6D; 14292f167a42Smrg return True; 14302f167a42Smrg case XK_Greek_nu: 14312f167a42Smrg buf[0] = 0x6E; 14322f167a42Smrg return True; 14332f167a42Smrg case XK_Greek_omicron: 14342f167a42Smrg buf[0] = 0x6F; 14352f167a42Smrg return True; 14362f167a42Smrg case XK_Greek_pi: 14372f167a42Smrg buf[0] = 0x70; 14382f167a42Smrg return True; 14392f167a42Smrg case XK_Greek_theta: 14402f167a42Smrg buf[0] = 0x71; 14412f167a42Smrg return True; 14422f167a42Smrg case XK_Greek_rho: 14432f167a42Smrg buf[0] = 0x72; 14442f167a42Smrg return True; 14452f167a42Smrg case XK_Greek_sigma: 14462f167a42Smrg buf[0] = 0x73; 14472f167a42Smrg return True; 14482f167a42Smrg case XK_Greek_tau: 14492f167a42Smrg buf[0] = 0x74; 14502f167a42Smrg return True; 14512f167a42Smrg case XK_Greek_upsilon: 14522f167a42Smrg buf[0] = 0x75; 14532f167a42Smrg return True; 14542f167a42Smrg case XK_Greek_omega: 14552f167a42Smrg buf[0] = 0x77; 14562f167a42Smrg return True; 14572f167a42Smrg case XK_Greek_xi: 14582f167a42Smrg buf[0] = 0x78; 14592f167a42Smrg return True; 14602f167a42Smrg case XK_Greek_psi: 14612f167a42Smrg buf[0] = 0x79; 14622f167a42Smrg return True; 14632f167a42Smrg case XK_Greek_zeta: 14642f167a42Smrg buf[0] = 0x7A; 14652f167a42Smrg return True; 14662f167a42Smrg } 14670e20ee16Smrg } 14680e20ee16Smrg switch (sym) { 14692f167a42Smrg case XK_leftarrow: 14702f167a42Smrg buf[0] = 0xAC; 14712f167a42Smrg return True; 14722f167a42Smrg case XK_uparrow: 14732f167a42Smrg buf[0] = 0xAD; 14742f167a42Smrg return True; 14752f167a42Smrg case XK_rightarrow: 14762f167a42Smrg buf[0] = 0xAE; 14772f167a42Smrg return True; 14782f167a42Smrg case XK_downarrow: 14792f167a42Smrg buf[0] = 0xAF; 14802f167a42Smrg return True; 14812f167a42Smrg case XK_horizconnector: 14822f167a42Smrg buf[0] = 0xBE; 14832f167a42Smrg return True; 14842f167a42Smrg case XK_trademark: 14852f167a42Smrg buf[0] = 0xE4; 14862f167a42Smrg return True; 14870e20ee16Smrg } 14880e20ee16Smrg return False; 14890e20ee16Smrg} 14900e20ee16Smrg 14910e20ee16Smrgstatic KeySym 14920e20ee16SmrgCheckSymbolAlias(KeySym sym, PSState *state) 14930e20ee16Smrg{ 14940e20ee16Smrg if (XkbKSIsKeypad(sym)) { 14952f167a42Smrg if ((sym >= XK_KP_0) && (sym <= XK_KP_9)) 14962f167a42Smrg sym = (sym - XK_KP_0) + XK_0; 14972f167a42Smrg else 14982f167a42Smrg switch (sym) { 14992f167a42Smrg case XK_KP_Space: 15002f167a42Smrg return XK_space; 15012f167a42Smrg case XK_KP_Tab: 15022f167a42Smrg return XK_Tab; 15032f167a42Smrg case XK_KP_Enter: 15042f167a42Smrg return XK_Return; 15052f167a42Smrg case XK_KP_F1: 15062f167a42Smrg return XK_F1; 15072f167a42Smrg case XK_KP_F2: 15082f167a42Smrg return XK_F2; 15092f167a42Smrg case XK_KP_F3: 15102f167a42Smrg return XK_F3; 15112f167a42Smrg case XK_KP_F4: 15122f167a42Smrg return XK_F4; 15132f167a42Smrg case XK_KP_Home: 15142f167a42Smrg return XK_Home; 15152f167a42Smrg case XK_KP_Left: 15162f167a42Smrg return XK_Left; 15172f167a42Smrg case XK_KP_Up: 15182f167a42Smrg return XK_Up; 15192f167a42Smrg case XK_KP_Right: 15202f167a42Smrg return XK_Right; 15212f167a42Smrg case XK_KP_Down: 15222f167a42Smrg return XK_Down; 15232f167a42Smrg case XK_KP_Page_Up: 15242f167a42Smrg return XK_Page_Up; 15252f167a42Smrg case XK_KP_Page_Down: 15262f167a42Smrg return XK_Page_Down; 15272f167a42Smrg case XK_KP_End: 15282f167a42Smrg return XK_End; 15292f167a42Smrg case XK_KP_Begin: 15302f167a42Smrg return XK_Begin; 15312f167a42Smrg case XK_KP_Insert: 15322f167a42Smrg return XK_Insert; 15332f167a42Smrg case XK_KP_Delete: 15342f167a42Smrg return XK_Delete; 15352f167a42Smrg case XK_KP_Equal: 15362f167a42Smrg return XK_equal; 15372f167a42Smrg case XK_KP_Multiply: 15382f167a42Smrg return XK_asterisk; 15392f167a42Smrg case XK_KP_Add: 15402f167a42Smrg return XK_plus; 15412f167a42Smrg case XK_KP_Subtract: 15422f167a42Smrg return XK_minus; 15432f167a42Smrg case XK_KP_Divide: 15442f167a42Smrg return XK_slash; 15452f167a42Smrg } 15460e20ee16Smrg } 15470e20ee16Smrg else if (XkbKSIsDeadKey(sym)) { 15482f167a42Smrg switch (sym) { 15492f167a42Smrg case XK_dead_grave: 15502f167a42Smrg sym = XK_grave; 15512f167a42Smrg break; 15522f167a42Smrg case XK_dead_acute: 15532f167a42Smrg sym = XK_acute; 15542f167a42Smrg break; 15552f167a42Smrg case XK_dead_circumflex: 15562f167a42Smrg sym = XK_asciicircum; 15572f167a42Smrg break; 15582f167a42Smrg case XK_dead_tilde: 15592f167a42Smrg sym = XK_asciitilde; 15602f167a42Smrg break; 15612f167a42Smrg case XK_dead_macron: 15622f167a42Smrg sym = XK_macron; 15632f167a42Smrg break; 15642f167a42Smrg case XK_dead_breve: 15652f167a42Smrg sym = XK_breve; 15662f167a42Smrg break; 15672f167a42Smrg case XK_dead_abovedot: 15682f167a42Smrg sym = XK_abovedot; 15692f167a42Smrg break; 15702f167a42Smrg case XK_dead_diaeresis: 15712f167a42Smrg sym = XK_diaeresis; 15722f167a42Smrg break; 15732f167a42Smrg case XK_dead_abovering: 15742f167a42Smrg sym = XK_degree; 15752f167a42Smrg break; 15762f167a42Smrg case XK_dead_doubleacute: 15772f167a42Smrg sym = XK_doubleacute; 15782f167a42Smrg break; 15792f167a42Smrg case XK_dead_caron: 15802f167a42Smrg sym = XK_caron; 15812f167a42Smrg break; 15822f167a42Smrg case XK_dead_cedilla: 15832f167a42Smrg sym = XK_cedilla; 15842f167a42Smrg break; 15852f167a42Smrg case XK_dead_ogonek: 15862f167a42Smrg sym = XK_ogonek; 15872f167a42Smrg break; 15882f167a42Smrg case XK_dead_iota: 15892f167a42Smrg sym = XK_Greek_iota; 15902f167a42Smrg break; 15912f167a42Smrg case XK_dead_voiced_sound: 15922f167a42Smrg sym = XK_voicedsound; 15932f167a42Smrg break; 15942f167a42Smrg case XK_dead_semivoiced_sound: 15952f167a42Smrg sym = XK_semivoicedsound; 15962f167a42Smrg break; 15972f167a42Smrg } 15980e20ee16Smrg } 15990e20ee16Smrg return sym; 16000e20ee16Smrg} 16010e20ee16Smrg 16020e20ee16Smrgstatic Bool 16030e20ee16SmrgFindKeysymsByName(XkbDescPtr xkb, char *name, PSState *state, KeyTop *top) 16040e20ee16Smrg{ 16052f167a42Smrg static unsigned char buf[30]; 16062f167a42Smrg int kc; 16072f167a42Smrg KeySym sym, *syms, topSyms[NLABELS]; 16082f167a42Smrg int level, group; 16092f167a42Smrg int eG, nG, gI, l, g; 16102f167a42Smrg 16112f167a42Smrg bzero(top, sizeof(KeyTop)); 16122f167a42Smrg kc = XkbFindKeycodeByName(xkb, name, True); 16132f167a42Smrg if (state->args != NULL) { 16142f167a42Smrg level = state->args->labelLevel; 16152f167a42Smrg group = state->args->baseLabelGroup; 16160e20ee16Smrg } 16172f167a42Smrg else 16182f167a42Smrg level = group = 0; 16192f167a42Smrg syms = XkbKeySymsPtr(xkb, kc); 16202f167a42Smrg eG = group; 16212f167a42Smrg nG = XkbKeyNumGroups(xkb, kc); 16222f167a42Smrg gI = XkbKeyGroupInfo(xkb, kc); 16232f167a42Smrg if ((state->args->wantDiffs) && (eG >= XkbKeyNumGroups(xkb, kc))) 16242f167a42Smrg return False; /* XXX was a return with no value */ 16252f167a42Smrg if (nG == 0) { 16262f167a42Smrg return False; 16270e20ee16Smrg } 16282f167a42Smrg else if (nG == 1) { 16292f167a42Smrg eG = 0; 16300e20ee16Smrg } 16312f167a42Smrg else if (eG >= XkbKeyNumGroups(xkb, kc)) { 16322f167a42Smrg switch (XkbOutOfRangeGroupAction(gI)) { 16332f167a42Smrg default: 16342f167a42Smrg eG %= nG; 16352f167a42Smrg break; 16362f167a42Smrg case XkbClampIntoRange: 16372f167a42Smrg eG = nG - 1; 16382f167a42Smrg break; 16392f167a42Smrg case XkbRedirectIntoRange: 16402f167a42Smrg eG = XkbOutOfRangeGroupNumber(gI); 16412f167a42Smrg if (eG >= nG) 16422f167a42Smrg eG = 0; 16432f167a42Smrg break; 16442f167a42Smrg } 16450e20ee16Smrg } 16462f167a42Smrg for (g = 0; g < state->args->nLabelGroups; g++) { 16472f167a42Smrg if ((eG + g) >= nG) 16482f167a42Smrg continue; 16492f167a42Smrg for (l = 0; l < 2; l++) { 16502f167a42Smrg int font, sz; 16512f167a42Smrg 16522f167a42Smrg if (level + l >= XkbKeyGroupWidth(xkb, kc, (eG + g))) 16532f167a42Smrg continue; 16542f167a42Smrg sym = syms[((eG + g) * XkbKeyGroupsWidth(xkb, kc)) + (level + l)]; 16552f167a42Smrg 16562f167a42Smrg if (state->args->wantSymbols != NO_SYMBOLS) 16572f167a42Smrg sym = CheckSymbolAlias(sym, state); 16582f167a42Smrg topSyms[(g * 2) + l] = sym; 16592f167a42Smrg 16602f167a42Smrg if (PSKeycapsSymbol(sym, buf, &font, &sz, state)) { 16612f167a42Smrg top->font[(g * 2) + l] = font; 16622f167a42Smrg top->size[(g * 2) + l] = sz; 16632f167a42Smrg } 16642f167a42Smrg else if (((sym & (~0xffUL)) == 0) && isprint(sym) && (!isspace(sym))) { 16652f167a42Smrg if (sym == '(') 16662f167a42Smrg snprintf((char *) buf, sizeof(buf), "\\("); 16672f167a42Smrg else if (sym == ')') 16682f167a42Smrg snprintf((char *) buf, sizeof(buf), "\\)"); 16692f167a42Smrg else if (sym == '\\') 16702f167a42Smrg snprintf((char *) buf, sizeof(buf), "\\\\"); 16712f167a42Smrg else 16722f167a42Smrg snprintf((char *) buf, sizeof(buf), "%c", (char) sym); 16732f167a42Smrg top->font[(g * 2) + l] = FONT_LATIN1; 16742f167a42Smrg top->size[(g * 2) + l] = SZ_MEDIUM; 16752f167a42Smrg switch (buf[0]) { 16762f167a42Smrg case '.': 16772f167a42Smrg case ':': 16782f167a42Smrg case ',': 16792f167a42Smrg case ';': 16802f167a42Smrg case '\'': 16812f167a42Smrg case '"': 16822f167a42Smrg case '`': 16832f167a42Smrg case '~': 16842f167a42Smrg case '^': 16852f167a42Smrg case 0250: 16862f167a42Smrg case 0270: 16872f167a42Smrg case 0267: 16882f167a42Smrg case 0260: 16892f167a42Smrg case 0252: 16902f167a42Smrg case 0272: 16912f167a42Smrg case 0271: 16922f167a42Smrg case 0262: 16932f167a42Smrg case 0263: 16942f167a42Smrg case 0264: 16952f167a42Smrg case 0255: 16962f167a42Smrg case 0254: 16972f167a42Smrg case 0257: 16982f167a42Smrg top->size[(g * 2) + l] = SZ_LARGE; 16992f167a42Smrg break; 17002f167a42Smrg } 17012f167a42Smrg } 17022f167a42Smrg else if (PSNonLatin1Symbol(sym, buf, &font, &sz, state)) { 17032f167a42Smrg top->font[(g * 2) + l] = font; 17042f167a42Smrg top->size[(g * 2) + l] = sz; 17052f167a42Smrg } 17062f167a42Smrg else { 17072f167a42Smrg char *tmp; 17082f167a42Smrg 17092f167a42Smrg tmp = XKeysymToString(sym); 17102f167a42Smrg if (tmp != NULL) 17112f167a42Smrg strcpy((char *) buf, tmp); 17122f167a42Smrg else 17132f167a42Smrg snprintf((char *) buf, sizeof(buf), "(%ld)", sym); 17142f167a42Smrg top->font[(g * 2) + l] = FONT_LATIN1; 17152f167a42Smrg if (strlen((char *) buf) < 9) 17162f167a42Smrg top->size[(g * 2) + l] = SZ_SMALL; 17172f167a42Smrg else 17182f167a42Smrg top->size[(g * 2) + l] = SZ_TINY; 17192f167a42Smrg } 17202f167a42Smrg top->present |= (1 << ((g * 2) + l)); 17212f167a42Smrg strncpy(top->label[(g * 2) + l], (char *) buf, LABEL_LEN - 1); 17222f167a42Smrg top->label[(g * 2) + l][LABEL_LEN - 1] = '\0'; 17232f167a42Smrg } 17242f167a42Smrg if (((g == 0) && (top->present & G1LX_MASK) == G1LX_MASK) || 17252f167a42Smrg ((g == 1) && (top->present & G2LX_MASK) == G2LX_MASK)) { 17262f167a42Smrg KeySym lower, upper; 17272f167a42Smrg 17282f167a42Smrg XConvertCase(topSyms[(g * 2)], &lower, &upper); 17292f167a42Smrg if ((topSyms[(g * 2)] == lower) && (topSyms[(g * 2) + 1] == upper)) { 17302f167a42Smrg top->alpha[g] = True; 17312f167a42Smrg } 17322f167a42Smrg } 17330e20ee16Smrg } 17340e20ee16Smrg return True; 17350e20ee16Smrg} 17360e20ee16Smrg 17370e20ee16Smrgstatic void 17382f167a42SmrgPSDrawLabel(FILE *out, const char *label, int x, int y, int w, int h) 17390e20ee16Smrg{ 17402f167a42Smrg fprintf(out, "%d %d (%s) centeroffset\n", w, h, label); 17412f167a42Smrg fprintf(out, "%d add exch\n", y); 17422f167a42Smrg fprintf(out, "%d add exch moveto\n", x); 17432f167a42Smrg fprintf(out, "1 -1 scale (%s) show 1 -1 scale\n", label); 17440e20ee16Smrg return; 17450e20ee16Smrg} 17460e20ee16Smrg 17470e20ee16Smrg#define TOP_ROW 0 17480e20ee16Smrg#define BOTTOM_ROW 1 17490e20ee16Smrg#define CENTER_ROW 2 17500e20ee16Smrg 17510e20ee16Smrg#define LEFT_COL 0 17520e20ee16Smrg#define RIGHT_COL 1 17530e20ee16Smrg#define CENTER_COL 2 17540e20ee16Smrg 17550e20ee16Smrgstatic void 17560e20ee16SmrgPSLabelKey(FILE *out, PSState *state, KeyTop *top, int x, int y, 17572f167a42Smrg XkbBoundsPtr bounds, int kc, int btm) 17580e20ee16Smrg{ 17592f167a42Smrg int w, h, i; 17602f167a42Smrg int row_y[3]; 17612f167a42Smrg int col_x[3]; 17622f167a42Smrg int row_h[3]; 17632f167a42Smrg int col_w[3]; 17642f167a42Smrg Bool present[NLABELS]; 17652f167a42Smrg int sym_row[NLABELS]; 17662f167a42Smrg int sym_col[NLABELS]; 17672f167a42Smrg 17682f167a42Smrg w = XkbBoundsWidth(bounds); 17692f167a42Smrg h = XkbBoundsHeight(bounds); 17702f167a42Smrg row_y[TOP_ROW] = y + bounds->y1 + (h / 10); 17712f167a42Smrg row_y[BOTTOM_ROW] = y + bounds->y1 + (h / 2) + (h / 10); 17722f167a42Smrg row_y[CENTER_ROW] = y + bounds->y1 + (h / 10); 17732f167a42Smrg row_h[TOP_ROW] = h / 2; 17742f167a42Smrg row_h[BOTTOM_ROW] = h / 2; 17752f167a42Smrg row_h[CENTER_ROW] = h; 17762f167a42Smrg 17772f167a42Smrg col_x[LEFT_COL] = x + bounds->x1; 17782f167a42Smrg col_x[RIGHT_COL] = x + bounds->x1 + w / 2; 17792f167a42Smrg col_x[CENTER_COL] = x + bounds->x1; 17802f167a42Smrg col_w[LEFT_COL] = w / 2; 17812f167a42Smrg col_w[RIGHT_COL] = w / 2; 17822f167a42Smrg col_w[CENTER_COL] = w; 17832f167a42Smrg 17842f167a42Smrg present[G1L1] = False; 17852f167a42Smrg sym_row[G1L1] = BOTTOM_ROW; 17862f167a42Smrg sym_col[G1L1] = LEFT_COL; 17872f167a42Smrg 17882f167a42Smrg present[G1L2] = False; 17892f167a42Smrg sym_row[G1L2] = TOP_ROW; 17902f167a42Smrg sym_col[G1L2] = LEFT_COL; 17912f167a42Smrg 17922f167a42Smrg present[G2L1] = False; 17932f167a42Smrg sym_row[G2L1] = BOTTOM_ROW; 17942f167a42Smrg sym_col[G2L1] = RIGHT_COL; 17952f167a42Smrg 17962f167a42Smrg present[G2L2] = False; 17972f167a42Smrg sym_row[G2L2] = TOP_ROW; 17982f167a42Smrg sym_col[G2L2] = RIGHT_COL; 17992f167a42Smrg 18002f167a42Smrg present[CENTER] = False; 18012f167a42Smrg sym_row[CENTER] = CENTER_ROW; 18022f167a42Smrg sym_col[CENTER] = CENTER_COL; 18032f167a42Smrg 18042f167a42Smrg if (top->present & CENTER_MASK) { 18052f167a42Smrg present[CENTER] = True; 18060e20ee16Smrg } 18072f167a42Smrg else 18082f167a42Smrg switch (top->present & GXLX_MASK) { 18092f167a42Smrg case G1L1_MASK: 18102f167a42Smrg present[G1L1] = True; 18112f167a42Smrg sym_row[G1L1] = CENTER_ROW; 18122f167a42Smrg sym_col[G1L1] = CENTER_COL; 18132f167a42Smrg break; 18142f167a42Smrg case G1LX_MASK: 18152f167a42Smrg present[G1L2] = True; 18162f167a42Smrg if (!top->alpha[0]) { 18172f167a42Smrg present[G1L1] = True; 18182f167a42Smrg if ((strlen(top->label[G1L1]) > 1) && 18192f167a42Smrg (top->label[G1L1][0] != '\\')) 18202f167a42Smrg sym_col[G1L1] = CENTER_COL; 18212f167a42Smrg if ((strlen(top->label[G1L2]) > 1) && 18222f167a42Smrg (top->label[G1L1][0] != '\\')) 18232f167a42Smrg sym_col[G1L2] = CENTER_COL; 18242f167a42Smrg } 18252f167a42Smrg break; 18262f167a42Smrg default: 18272f167a42Smrg if ((top->present & G1LX_MASK) == G1LX_MASK) { 18282f167a42Smrg present[G1L2] = True; 18292f167a42Smrg if (!top->alpha[0]) 18302f167a42Smrg present[G1L1] = True; 18312f167a42Smrg } 18322f167a42Smrg else if ((top->present & G1LX_MASK) == G1L1_MASK) { 18332f167a42Smrg present[G1L1] = True; 18342f167a42Smrg } 18352f167a42Smrg else if ((top->present & G1LX_MASK) == G1L2_MASK) { 18362f167a42Smrg present[G1L2] = True; 18372f167a42Smrg } 18382f167a42Smrg if ((top->present & G2LX_MASK) == G2LX_MASK) { 18392f167a42Smrg present[G2L2] = True; 18402f167a42Smrg if (!top->alpha[1]) 18412f167a42Smrg present[G2L1] = True; 18422f167a42Smrg } 18432f167a42Smrg else if ((top->present & G2LX_MASK) == G2L1_MASK) { 18442f167a42Smrg present[G2L1] = True; 18452f167a42Smrg } 18462f167a42Smrg else if ((top->present & G2LX_MASK) == G2L2_MASK) { 18472f167a42Smrg present[G2L2] = True; 18482f167a42Smrg } 18492f167a42Smrg break; 18502f167a42Smrg case 0: 18512f167a42Smrg return; 18522f167a42Smrg } 18532f167a42Smrg for (i = 0; i < NLABELS; i++) { 18542f167a42Smrg if (present[i]) { 18552f167a42Smrg int size; 18562f167a42Smrg 18572f167a42Smrg if (top->size[i] == SZ_AUTO) { 18582f167a42Smrg size_t len = strlen(top->label[i]); 18592f167a42Smrg if (len == 1) { 18602f167a42Smrg if (top->font[i] == FONT_ISOCAPS) 18612f167a42Smrg size = 18; 18622f167a42Smrg else 18632f167a42Smrg size = 14; 18642f167a42Smrg } 18652f167a42Smrg else if (len < 10) 18662f167a42Smrg size = 12; 18672f167a42Smrg else 18682f167a42Smrg size = 10; 18692f167a42Smrg } 18702f167a42Smrg else if (top->size[i] == SZ_TINY) 18712f167a42Smrg size = 10; 18722f167a42Smrg else if (top->size[i] == SZ_SMALL) 18732f167a42Smrg size = 12; 18742f167a42Smrg else if (top->size[i] == SZ_LARGE) 18752f167a42Smrg size = 18; 18762f167a42Smrg else if (top->size[i] == SZ_XLARGE) 18772f167a42Smrg size = 24; 18782f167a42Smrg else 18792f167a42Smrg size = 14; 18802f167a42Smrg PSSetFont(out, state, top->font[i], size, True); 18812f167a42Smrg PSDrawLabel(out, top->label[i], col_x[sym_col[i]], 18822f167a42Smrg row_y[sym_row[i]], col_w[sym_col[i]], 18832f167a42Smrg row_h[sym_row[i]]); 18842f167a42Smrg } 18850e20ee16Smrg } 18860e20ee16Smrg if (state->args->wantKeycodes) { 18872f167a42Smrg char keycode[10]; 18882f167a42Smrg 18892f167a42Smrg snprintf(keycode, sizeof(keycode), "%d", kc); 18902f167a42Smrg PSSetFont(out, state, FONT_LATIN1, 8, True); 18912f167a42Smrg PSDrawLabel(out, keycode, x + bounds->x1, y + btm - 5, w, 0); 18920e20ee16Smrg } 18930e20ee16Smrg return; 18940e20ee16Smrg} 18950e20ee16Smrg 18960e20ee16Smrgstatic void 18970e20ee16SmrgPSSection(FILE *out, PSState *state, XkbSectionPtr section) 18980e20ee16Smrg{ 18992f167a42Smrg int r, offset; 19002f167a42Smrg XkbRowPtr row; 19012f167a42Smrg Display *dpy; 19022f167a42Smrg XkbDescPtr xkb; 19032f167a42Smrg 19042f167a42Smrg xkb = state->xkb; 19052f167a42Smrg dpy = xkb->dpy; 19062f167a42Smrg fprintf(out, "%% Begin Section '%s'\n", (section->name != None ? 19072f167a42Smrg XkbAtomGetString(dpy, section-> name) : "NoName")); 19082f167a42Smrg PSGSave(out, state); 19092f167a42Smrg fprintf(out, "%d %d translate\n", section->left, section->top); 19102f167a42Smrg if (section->angle != 0) 19112f167a42Smrg fprintf(out, "%s rotate\n", XkbGeomFPText(section->angle, XkbMessage)); 19120e20ee16Smrg if (section->doodads) { 19132f167a42Smrg XkbDrawablePtr first, draw; 19142f167a42Smrg 19152f167a42Smrg first = draw = XkbGetOrderedDrawables(NULL, section); 19162f167a42Smrg while (draw) { 19172f167a42Smrg if (draw->type == XkbDW_Section) 19182f167a42Smrg PSSection(out, state, draw->u.section); 19192f167a42Smrg else 19202f167a42Smrg PSDoodad(out, state, draw->u.doodad); 19212f167a42Smrg draw = draw->next; 19222f167a42Smrg } 19232f167a42Smrg XkbFreeOrderedDrawables(first); 19240e20ee16Smrg } 19252f167a42Smrg for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { 19262f167a42Smrg int k; 19272f167a42Smrg XkbKeyPtr key; 19282f167a42Smrg XkbShapePtr shape; 19292f167a42Smrg 19302f167a42Smrg if (row->vertical) 19312f167a42Smrg offset = row->top; 19322f167a42Smrg else 19332f167a42Smrg offset = row->left; 19342f167a42Smrg fprintf(out, "%% Begin %s %d\n", row->vertical ? "column" : "row", 19352f167a42Smrg r + 1); 19362f167a42Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 19372f167a42Smrg shape = XkbKeyShape(xkb->geom, key); 19382f167a42Smrg offset += key->gap; 19392f167a42Smrg if (row->vertical) { 19402f167a42Smrg if (state->args->wantColor) { 19412f167a42Smrg if (key->color_ndx != state->white) { 19422f167a42Smrg PSSetColor(out, state, key->color_ndx); 19432f167a42Smrg fprintf(out, "true 0 %d %d %s %% %s\n", 19442f167a42Smrg row->left, offset, 19452f167a42Smrg XkbAtomGetString(dpy, shape->name), 19462f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 19472f167a42Smrg } 19482f167a42Smrg PSSetColor(out, state, state->black); 19492f167a42Smrg } 19502f167a42Smrg fprintf(out, "false 0 %d %d %s %% %s\n", row->left, offset, 19512f167a42Smrg XkbAtomGetString(dpy, shape->name), 19522f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 19532f167a42Smrg offset += shape->bounds.y2; 19542f167a42Smrg } 19552f167a42Smrg else { 19562f167a42Smrg if (state->args->wantColor) { 19572f167a42Smrg if (key->color_ndx != state->white) { 19582f167a42Smrg PSSetColor(out, state, key->color_ndx); 19592f167a42Smrg fprintf(out, "true 0 %d %d %s %% %s\n", offset, 19602f167a42Smrg row->top, XkbAtomGetString(dpy, shape->name), 19612f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 19622f167a42Smrg } 19632f167a42Smrg PSSetColor(out, state, state->black); 19642f167a42Smrg } 19652f167a42Smrg fprintf(out, "false 0 %d %d %s %% %s\n", offset, row->top, 19662f167a42Smrg XkbAtomGetString(dpy, shape->name), 19672f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 19682f167a42Smrg offset += shape->bounds.x2; 19692f167a42Smrg } 19702f167a42Smrg } 19710e20ee16Smrg } 19722f167a42Smrg for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { 19732f167a42Smrg int k, kc = 0; 19742f167a42Smrg XkbKeyPtr key; 19752f167a42Smrg XkbShapePtr shape; 19762f167a42Smrg XkbBoundsRec bounds; 19772f167a42Smrg 19782f167a42Smrg if (state->args->label == LABEL_NONE) 19792f167a42Smrg break; 19802f167a42Smrg if (row->vertical) 19812f167a42Smrg offset = row->top; 19822f167a42Smrg else 19832f167a42Smrg offset = row->left; 19842f167a42Smrg fprintf(out, "%% Begin %s %d labels\n", 19852f167a42Smrg row->vertical ? "column" : "row", r + 1); 19862f167a42Smrg PSSetColor(out, state, xkb->geom->label_color->pixel); 19872f167a42Smrg PSSetFont(out, state, FONT_LATIN1, 12, True); 19882f167a42Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 19892f167a42Smrg char *name, *name2, buf[30], buf2[30]; 19902f167a42Smrg int x, y; 19912f167a42Smrg KeyTop top; 19922f167a42Smrg 19932f167a42Smrg shape = XkbKeyShape(xkb->geom, key); 19942f167a42Smrg XkbComputeShapeTop(shape, &bounds); 19952f167a42Smrg offset += key->gap; 19962f167a42Smrg name = name2 = NULL; 19972f167a42Smrg if (state->args->label == LABEL_SYMBOLS) { 19982f167a42Smrg if (!FindKeysymsByName(xkb, key->name.name, state, &top)) { 19992f167a42Smrg fprintf(out, "%% No label for %s\n", 20002f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 20012f167a42Smrg } 20022f167a42Smrg } 20032f167a42Smrg else { 20042f167a42Smrg char *olKey; 20052f167a42Smrg 20062f167a42Smrg if (section->num_overlays > 0) 20072f167a42Smrg olKey = XkbFindOverlayForKey(xkb->geom, section, 20082f167a42Smrg key->name.name); 20092f167a42Smrg else 20102f167a42Smrg olKey = NULL; 20112f167a42Smrg 20122f167a42Smrg if (state->args->label == LABEL_KEYNAME) { 20132f167a42Smrg name = XkbKeyNameText(key->name.name, XkbMessage); 20142f167a42Smrg if (olKey) 20152f167a42Smrg name2 = XkbKeyNameText(olKey, XkbMessage); 20162f167a42Smrg } 20172f167a42Smrg else if (state->args->label == LABEL_KEYCODE) { 20182f167a42Smrg name = buf; 20192f167a42Smrg snprintf(name, sizeof(buf), "%d", 20202f167a42Smrg XkbFindKeycodeByName(xkb, key->name.name, True)); 20212f167a42Smrg if (olKey) { 20222f167a42Smrg name2 = buf2; 20232f167a42Smrg snprintf(name2, sizeof(buf2), "%d", 20242f167a42Smrg XkbFindKeycodeByName(xkb, olKey, True)); 20252f167a42Smrg } 20262f167a42Smrg } 20272f167a42Smrg bzero(&top, sizeof(KeyTop)); 20282f167a42Smrg if (name2 != NULL) { 20292f167a42Smrg top.present |= G1LX_MASK; 20302f167a42Smrg strncpy(top.label[G1L1], name, LABEL_LEN - 1); 20312f167a42Smrg top.label[G1L1][LABEL_LEN - 1] = '\0'; 20322f167a42Smrg strncpy(top.label[G1L2], name2, LABEL_LEN - 1); 20332f167a42Smrg top.label[G1L2][LABEL_LEN - 1] = '\0'; 20342f167a42Smrg } 20352f167a42Smrg else if (name != NULL) { 20362f167a42Smrg top.present |= CENTER_MASK; 20372f167a42Smrg strncpy(top.label[CENTER], name, LABEL_LEN - 1); 20382f167a42Smrg top.label[CENTER][LABEL_LEN - 1] = '\0'; 20392f167a42Smrg } 20402f167a42Smrg else { 20412f167a42Smrg fprintf(out, "%% No label for %s\n", 20422f167a42Smrg XkbKeyNameText(key->name.name, XkbMessage)); 20432f167a42Smrg } 20442f167a42Smrg } 20452f167a42Smrg if (row->vertical) { 20462f167a42Smrg x = row->left; 20472f167a42Smrg y = offset; 20482f167a42Smrg offset += shape->bounds.y2; 20492f167a42Smrg } 20502f167a42Smrg else { 20512f167a42Smrg x = offset; 20522f167a42Smrg y = row->top; 20532f167a42Smrg offset += shape->bounds.x2; 20542f167a42Smrg } 20552f167a42Smrg name = key->name.name; 20562f167a42Smrg fprintf(out, "%% %s\n", XkbKeyNameText(name, XkbMessage)); 20572f167a42Smrg if (state->args->wantKeycodes) 20582f167a42Smrg kc = XkbFindKeycodeByName(xkb, key->name.name, True); 20592f167a42Smrg PSLabelKey(out, state, &top, x, y, &bounds, kc, shape->bounds.y2); 20602f167a42Smrg } 20610e20ee16Smrg } 20622f167a42Smrg PSGRestore(out, state); 20630e20ee16Smrg return; 20640e20ee16Smrg} 20650e20ee16Smrg 20660e20ee16SmrgBool 20670e20ee16SmrgGeometryToPostScript(FILE *out, XkbFileInfo *pResult, XKBPrintArgs *args) 20680e20ee16Smrg{ 20692f167a42Smrg XkbDrawablePtr first, draw; 20702f167a42Smrg PSState state; 20712f167a42Smrg Bool dfltBorder; 20722f167a42Smrg int i; 20732f167a42Smrg 20742f167a42Smrg if ((!pResult) || (!pResult->xkb) || (!pResult->xkb->geom)) 20752f167a42Smrg return False; 20762f167a42Smrg state.xkb = pResult->xkb; 20772f167a42Smrg state.dpy = pResult->xkb->dpy; 20782f167a42Smrg state.geom = pResult->xkb->geom; 20792f167a42Smrg state.color = state.black = state.white = -1; 20802f167a42Smrg state.font = -1; 20812f167a42Smrg state.nPages = 0; 20822f167a42Smrg state.totalKB = 1; 20832f167a42Smrg state.kbPerPage = 1; 20842f167a42Smrg state.x1 = state.y1 = state.x2 = state.y2 = 0; 20852f167a42Smrg state.args = args; 20862f167a42Smrg 20872f167a42Smrg if ((args->label == LABEL_SYMBOLS) && (pResult->xkb->ctrls)) { 20882f167a42Smrg if (args->nTotalGroups == 0) 20892f167a42Smrg state.totalKB = 20902f167a42Smrg pResult->xkb->ctrls->num_groups / args->nLabelGroups; 20912f167a42Smrg else 20922f167a42Smrg state.totalKB = args->nTotalGroups; 20932f167a42Smrg if (state.totalKB < 1) 20942f167a42Smrg state.totalKB = 1; 20952f167a42Smrg else if (state.totalKB > 1) 20962f167a42Smrg state.kbPerPage = 2; 20970e20ee16Smrg } 20982f167a42Smrg if (args->nKBPerPage != 0) 20992f167a42Smrg state.kbPerPage = args->nKBPerPage; 21002f167a42Smrg 21012f167a42Smrg PSProlog(out, &state); 21022f167a42Smrg first = XkbGetOrderedDrawables(state.geom, NULL); 21032f167a42Smrg 21042f167a42Smrg for (draw = first, dfltBorder = True; draw != NULL; draw = draw->next) { 21052f167a42Smrg if ((draw->type != XkbDW_Section) && 21062f167a42Smrg ((draw->u.doodad->any.type == XkbOutlineDoodad) || 21072f167a42Smrg (draw->u.doodad->any.type == XkbSolidDoodad))) { 21082f167a42Smrg char *name; 21092f167a42Smrg 21102f167a42Smrg name = XkbAtomGetString(state.dpy, draw->u.doodad->any.name); 21112f167a42Smrg if ((name != NULL) && (uStrCaseEqual(name, "edges"))) { 21122f167a42Smrg dfltBorder = False; 21132f167a42Smrg break; 21142f167a42Smrg } 21152f167a42Smrg } 21160e20ee16Smrg } 21172f167a42Smrg for (i = 0; i < state.totalKB; i++) { 21182f167a42Smrg PSPageSetup(out, &state, dfltBorder); 21192f167a42Smrg for (draw = first; draw != NULL; draw = draw->next) { 21202f167a42Smrg if (draw->type == XkbDW_Section) 21212f167a42Smrg PSSection(out, &state, draw->u.section); 21222f167a42Smrg else { 21232f167a42Smrg PSDoodad(out, &state, draw->u.doodad); 21242f167a42Smrg } 21252f167a42Smrg } 21262f167a42Smrg PSPageTrailer(out, &state); 21272f167a42Smrg state.args->baseLabelGroup += state.args->nLabelGroups; 21280e20ee16Smrg } 21290e20ee16Smrg XkbFreeOrderedDrawables(first); 21302f167a42Smrg PSFileTrailer(out, &state); 21310e20ee16Smrg return True; 21320e20ee16Smrg} 2133