psgeom.c revision 3e6697d4
1/* $Xorg: psgeom.c,v 1.4 2000/08/17 19:54:50 cpqbld Exp $ */ 2/************************************************************ 3 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 4 5 Permission to use, copy, modify, and distribute this 6 software and its documentation for any purpose and without 7 fee is hereby granted, provided that the above copyright 8 notice appear in all copies and that both that copyright 9 notice and this permission notice appear in supporting 10 documentation, and that the name of Silicon Graphics not be 11 used in advertising or publicity pertaining to distribution 12 of the software without specific prior written permission. 13 Silicon Graphics makes no representation about the suitability 14 of this software for any purpose. It is provided "as is" 15 without any express or implied warranty. 16 17 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24 THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 26 ********************************************************/ 27/* $XFree86: xc/programs/xkbprint/psgeom.c,v 1.5 2001/07/25 15:05:25 dawes Exp $ */ 28 29#define XK_TECHNICAL 30#define XK_PUBLISHING 31#define XK_KATAKANA 32#include <stdio.h> 33#include <ctype.h> 34#include <X11/X.h> 35#include <X11/Xlib.h> 36#include <X11/XKBlib.h> 37#include <X11/extensions/XKBgeom.h> 38#include <X11/extensions/XKM.h> 39#include <X11/extensions/XKBfile.h> 40#include <X11/keysym.h> 41#include <X11/Xutil.h> 42 43#if defined(sgi) 44#include <malloc.h> 45#endif 46 47#define DEBUG_VAR_NOT_LOCAL 48#define DEBUG_VAR debugFlags 49#include <stdlib.h> 50 51#include "utils.h" 52#include "xkbprint.h" 53#include "isokeys.h" 54 55#define FONT_NONE -1 56#define FONT_TEXT 0 57#define FONT_LATIN1 1 58#define FONT_SYMBOL 2 59#define FONT_ISOCAPS 3 60#define FONT_MOUSECAPS 4 61 62typedef struct { 63 Display * dpy; 64 XkbDescPtr xkb; 65 XkbGeometryPtr geom; 66 int totalKB; 67 int kbPerPage; 68 int black; 69 int white; 70 int color; 71 int font; 72 int fontSize; 73 int nPages; 74 int x1,y1; 75 int x2,y2; 76 XKBPrintArgs * args; 77} PSState; 78 79#define G1L1 0 80#define G1L2 1 81#define G2L1 2 82#define G2L2 3 83#define CENTER 4 84 85#define G1L1_MASK (1<<G1L1) 86#define G1L2_MASK (1<<G1L2) 87#define G2L1_MASK (1<<G2L1) 88#define G2L2_MASK (1<<G2L2) 89#define CENTER_MASK (1<<CENTER) 90 91#define LABEL_MASK (0x1f) 92#define GXL1_MASK (G1L1_MASK|G2L1_MASK) 93#define GXL2_MASK (G1L2_MASK|G2L2_MASK) 94#define G1LX_MASK (G1L1_MASK|G1L2_MASK) 95#define G2LX_MASK (G2L1_MASK|G2L2_MASK) 96#define GXLX_MASK (0x0f) 97 98#define NLABELS 5 99#define LABEL_LEN 30 100 101#define SZ_AUTO 0 102#define SZ_TINY 1 103#define SZ_SMALL 2 104#define SZ_MEDIUM 3 105#define SZ_LARGE 4 106#define SZ_XLARGE 5 107 108typedef struct { 109 unsigned present; 110 Bool alpha[2]; 111 char label[NLABELS][LABEL_LEN]; 112 int font[NLABELS]; 113 int size[NLABELS]; 114} KeyTop; 115 116#define DFLT_LABEL_FONT "Helvetica-Narrow-Bold" 117#define DFLT_LABEL_FONT_SIZE 10 118 119/***====================================================================***/ 120 121typedef struct _PSFontDef { 122 char *name; 123 char **def; 124} PSFontDef; 125 126static PSFontDef internalFonts[] = { 127 { "IsoKeyCaps", IsoKeyCaps } 128}; 129static int nInternalFonts = (sizeof(internalFonts)/sizeof(PSFontDef)); 130 131static void 132ListInternalFonts(FILE *out, int first, int indent) 133{ 134register int i,n,nThisLine; 135 136 for (n=0;n<first;n++) { 137 putc(' ',out); 138 } 139 140 for (nThisLine=i=0;i<nInternalFonts;i++) { 141 if (nThisLine==4) { 142 fprintf(out,",\n"); 143 for (n=0;n<indent;n++) { 144 putc(' ',out); 145 } 146 nThisLine= 0; 147 } 148 if (nThisLine==0) 149 fprintf(out,"%s",internalFonts[i].name); 150 else fprintf(out,", %s",internalFonts[i].name); 151 nThisLine++; 152 } 153 if (nThisLine!=0) 154 fprintf(out,"\n"); 155 return; 156} 157 158static Bool 159PSIncludeFont(FILE *out, char *font) 160{ 161char ** pstr; 162register int i; 163 164 pstr= NULL; 165 for (i=0;(i<nInternalFonts)&&(pstr==NULL);i++) { 166 if (uStringEqual(internalFonts[i].name,font)) 167 pstr= internalFonts[i].def; 168 } 169 if (pstr!=NULL) { 170 fprintf(out,"%%%%BeginFont: %s\n",font); 171 while (*pstr!=NULL) { 172 fprintf(out,"%s\n",*pstr); 173 pstr++; 174 } 175 fprintf(out,"%%%%EndFont\n"); 176 return True; 177 } 178 return False; 179} 180 181Bool 182DumpInternalFont(FILE *out, char *fontName) 183{ 184 if (strcmp(fontName,"IsoKeyCaps")!=0) { 185 uError("No internal font named \"%s\"\n",fontName); 186 uAction("No font dumped\n"); 187 fprintf(stderr,"Current internal fonts are: "); 188 ListInternalFonts(stderr,0,8); 189 return False; 190 } 191 PSIncludeFont(out,fontName); 192 return True; 193} 194 195/***====================================================================***/ 196 197static void 198PSColorDef(FILE *out, PSState *state, XkbColorPtr color) 199{ 200int tmp; 201 202 fprintf(out,"/C%03d ",color->pixel); 203 if (uStrCaseEqual(color->spec,"black")) { 204 state->black= color->pixel; 205 fprintf(out,"{ 0 setgray } def %% %s\n",color->spec); 206 } 207 else if (uStrCaseEqual(color->spec,"white")) { 208 state->white= color->pixel; 209 fprintf(out,"{ 1 setgray } def %% %s\n",color->spec); 210 } 211 else if ((sscanf(color->spec,"grey%d",&tmp)==1)|| 212 (sscanf(color->spec,"gray%d",&tmp)==1)|| 213 (sscanf(color->spec,"Grey%d",&tmp)==1)|| 214 (sscanf(color->spec,"Gray%d",&tmp)==1)) { 215 fprintf(out,"{ %f setgray } def %% %s\n",1.0-(((float)tmp)/100.0), 216 color->spec); 217 } 218 else if ((tmp=(uStrCaseEqual(color->spec,"red")*100))|| 219 (sscanf(color->spec,"red%d",&tmp)==1)) { 220 fprintf(out,"{ %f 0 0 setrgbcolor } def %% %s\n",(((float)tmp)/100.0), 221 color->spec); 222 } 223 else if ((tmp=(uStrCaseEqual(color->spec,"green")*100))|| 224 (sscanf(color->spec,"green%d",&tmp)==1)) { 225 fprintf(out,"{ 0 %f 0 setrgbcolor } def %% %s\n",(((float)tmp)/100.0), 226 color->spec); 227 } 228 else if ((tmp=(uStrCaseEqual(color->spec,"blue")*100))|| 229 (sscanf(color->spec,"blue%d",&tmp)==1)) { 230 fprintf(out,"{ 0 0 %f setrgbcolor } def %% %s\n",(((float)tmp)/100.0), 231 color->spec); 232 } 233 else fprintf(out,"{ 0.9 setgray } def %% BOGUS! %s\n",color->spec); 234} 235 236static void 237PSSetColor(FILE *out,PSState *state,int color) 238{ 239 if ((state->args->wantColor)&&(state->color!=color)) { 240 fprintf(out,"C%03d %% set color\n",color); 241 state->color= color; 242 } 243 return; 244} 245 246static void 247PSGSave(FILE *out, PSState *state) 248{ 249 fprintf(out,"gsave\n"); 250 return; 251} 252 253static void 254PSGRestore(FILE *out, PSState *state) 255{ 256 fprintf(out,"grestore\n"); 257 state->color= -1; 258 state->font= FONT_NONE; 259 state->fontSize= -1; 260 return; 261} 262 263static void 264PSShapeDef(FILE *out, PSState *state, XkbShapePtr shape) 265{ 266int o,p; 267XkbOutlinePtr ol; 268 269 fprintf(out,"/%s {\n",XkbAtomGetString(state->dpy,shape->name)); 270 fprintf(out," gsave translate rotate /SOLID exch def\n"); 271 for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) { 272 XkbPointPtr pt; 273 if ((shape->num_outlines>1)&&(ol==shape->approx)) 274 continue; 275 pt=ol->points; 276 fprintf(out,"%% Outline %d\n",o+1); 277 if (ol->num_points==1) { 278 if (ol->corner_radius<1) { 279 fprintf(out," 0 0 moveto\n"); 280 fprintf(out," %3d 0 lineto\n",pt->x); 281 fprintf(out," %3d %3d lineto\n",pt->x,pt->y); 282 fprintf(out," 0 %3d lineto\n",pt->y); 283 fprintf(out," 0 0 lineto\n"); 284 fprintf(out," SOLID { fill } { stroke } ifelse\n"); 285 } 286 else { 287 fprintf(out," mark\n"); 288 fprintf(out," %3d 0 moveto\n",ol->corner_radius); 289 fprintf(out," %3d 0 %3d %3d %3d arcto\n",pt->x,pt->x,pt->y, 290 ol->corner_radius); 291 fprintf(out," %3d %3d 0 %3d %3d arcto\n",pt->x,pt->y,pt->y, 292 ol->corner_radius); 293 fprintf(out," 0 %3d 0 0 %3d arcto\n",pt->y, 294 ol->corner_radius); 295 fprintf(out," 0 0 %3d 0 %3d arcto\n",pt->x, 296 ol->corner_radius); 297 fprintf(out," SOLID { fill } { stroke } ifelse\n"); 298 fprintf(out," cleartomark\n"); 299 } 300 } 301 else if (ol->num_points==2) { 302 if (ol->corner_radius<1) { 303 fprintf(out," %3d %3d moveto\n",pt[0].x,pt[0].y); 304 fprintf(out," %3d %3d lineto\n",pt[1].x,pt[0].y); 305 fprintf(out," %3d %3d lineto\n",pt[1].x,pt[1].y); 306 fprintf(out," %3d %3d lineto\n",pt[0].x,pt[1].y); 307 fprintf(out," %3d %3d lineto\n",pt[0].x,pt[0].y); 308 fprintf(out," SOLID { fill } { stroke } ifelse\n"); 309 } 310 else { 311 fprintf(out," mark\n"); 312 fprintf(out," %3d %3d moveto\n",pt[0].x + ol->corner_radius,pt[0].y); 313 fprintf(out," %3d %3d %3d %3d %3d arcto\n",pt[1].x,pt[0].y, 314 pt[1].x,pt[1].y, 315 ol->corner_radius); 316 fprintf(out," %3d %3d %3d %3d %3d arcto\n",pt[1].x,pt[1].y, 317 pt[0].x,pt[1].y, 318 ol->corner_radius); 319 fprintf(out," %3d %3d %3d %3d %3d arcto\n",pt[0].x,pt[1].y, 320 pt[0].x,pt[0].y, 321 ol->corner_radius); 322 fprintf(out," %3d %3d %3d %3d %3d arcto\n",pt[0].x,pt[0].y, 323 pt[1].x,pt[0].y, 324 ol->corner_radius); 325 fprintf(out," SOLID { fill } { stroke } ifelse\n"); 326 fprintf(out," cleartomark\n"); 327 } 328 } 329 else { 330 if (ol->corner_radius<1) { 331 fprintf(out," %3d %3d moveto\n",pt->x,pt->y); 332 pt++; 333 for (p=1;p<ol->num_points;p++,pt++) { 334 fprintf(out," %3d %3d lineto\n",pt->x,pt->y); 335 } 336 if ((pt->x!=ol->points[0].x)||(pt->y!=ol->points[0].y)) 337 fprintf(out," closepath\n"); 338 fprintf(out," SOLID { fill } { stroke } ifelse\n"); 339 } 340 else { 341 XkbPointPtr last; 342 last= &pt[ol->num_points-1]; 343 if ((last->x==pt->x)&&(last->y==pt->y)) 344 last--; 345 fprintf(out," mark\n"); 346 fprintf(out," %% Determine tangent point of first corner\n"); 347 fprintf(out," %3d %3d moveto %d %d %d %d %d arcto\n", 348 last->x,last->y, 349 pt[0].x,pt[0].y,pt[1].x,pt[1].y, 350 ol->corner_radius); 351 fprintf(out," /TY exch def /TX exch def pop pop newpath\n"); 352 fprintf(out," %% Now draw the shape\n"); 353 fprintf(out," TX TY moveto\n"); 354 for (p=1;p<ol->num_points;p++) { 355 if (p<(ol->num_points-1)) last= &pt[p+1]; 356 else last= &pt[0]; 357 fprintf(out," %3d %3d %3d %3d %3d arcto\n", 358 pt[p].x,pt[p].y, 359 last->x,last->y, 360 ol->corner_radius); 361 } 362 last= &pt[ol->num_points-1]; 363 if ((last->x!=pt->x)||(last->y!=pt->y)) { 364 fprintf(out," %3d %3d %3d %3d %3d arcto\n", 365 pt[0].x,pt[0].y, 366 pt[1].x,pt[1].y, 367 ol->corner_radius); 368 } 369 fprintf(out," SOLID { fill } { stroke } ifelse\n"); 370 fprintf(out," cleartomark\n"); 371 } 372 } 373 } 374 fprintf(out," grestore\n"); 375 fprintf(out,"} def\n"); 376 return; 377} 378 379/***====================================================================***/ 380 381typedef struct { 382 char * foundry; 383 char * face; 384 char * weight; 385 char * slant; 386 char * setWidth; 387 char * variant; 388 int pixelSize; 389 int ptSize; 390 int resX; 391 int resY; 392 char * spacing; 393 int avgWidth; 394 char * encoding; 395} FontStuff; 396 397static void 398ClearFontStuff(FontStuff *stuff) 399{ 400 if (stuff && stuff->foundry) 401 uFree(stuff->foundry); 402 bzero(stuff,sizeof(FontStuff)); 403 return; 404} 405 406static Bool 407CrackXLFDName(char *name, FontStuff *stuff) 408{ 409char *tmp; 410 if ((name==NULL)||(stuff==NULL)) 411 return False; 412 if (name[0]=='-') tmp= uStringDup(&name[1]); 413 else tmp= uStringDup(name); 414 if (tmp==NULL) 415 return False; 416 stuff->foundry= tmp; 417 418 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 419 else *tmp++= '\0'; 420 stuff->face= tmp; 421 422 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 423 else *tmp++= '\0'; 424 stuff->weight= tmp; 425 426 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 427 else *tmp++= '\0'; 428 stuff->slant= tmp; 429 430 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 431 else *tmp++= '\0'; 432 stuff->setWidth= tmp; 433 434 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 435 else *tmp++= '\0'; 436 stuff->variant= tmp; 437 438 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 439 else *tmp++= '\0'; 440 if (*tmp=='*') stuff->pixelSize= 0; 441 else if (sscanf(tmp,"%i",&stuff->pixelSize)!=1) goto BAILOUT; 442 443 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 444 else *tmp++= '\0'; 445 if (*tmp=='*') stuff->ptSize= 0; 446 else if (sscanf(tmp,"%i",&stuff->ptSize)!=1) goto BAILOUT; 447 448 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 449 else *tmp++= '\0'; 450 if (*tmp=='*') stuff->resX= 0; 451 else if (sscanf(tmp,"%i",&stuff->resX)!=1) goto BAILOUT; 452 453 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 454 else *tmp++= '\0'; 455 if (*tmp=='*') stuff->resY= 0; 456 else if (sscanf(tmp,"%i",&stuff->resY)!=1) goto BAILOUT; 457 458 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 459 else *tmp++= '\0'; 460 stuff->spacing= tmp; 461 462 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 463 else *tmp++= '\0'; 464 if (*tmp=='*') stuff->avgWidth= 0; 465 else if (sscanf(tmp,"%i",&stuff->avgWidth)!=1) goto BAILOUT; 466 467 if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 468 else *tmp++= '\0'; 469 stuff->encoding= tmp; 470 return True; 471BAILOUT: 472 ClearFontStuff(stuff); 473 return False; 474} 475 476static void 477PSSetUpForLatin1(FILE *out, PSState *state) 478{ 479 fprintf(out,"save\n"); 480 fprintf(out,"/ISOLatin1Encoding where {pop save true}{false} ifelse\n"); 481 fprintf(out,"/ISOLatin1Encoding [\n"); 482 fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 483 fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 484 fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 485 fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 486 fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 487 fprintf(out," /.notdef /.notdef /space /exclam /quotedbl /numbersign\n"); 488 fprintf(out," /dollar /percent /ampersand /quoteright /parenleft\n"); 489 fprintf(out," /parenright /asterisk /plus /comma /minus /period\n"); 490 fprintf(out," /slash /zero /one /two /three /four /five /six /seven\n"); 491 fprintf(out," /eight /nine /colon /semicolon /less /equal /greater\n"); 492 fprintf(out," /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M\n"); 493 fprintf(out," /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft\n"); 494 fprintf(out," /backslash /bracketright /asciicircum /underscore\n"); 495 fprintf(out," /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m\n"); 496 fprintf(out," /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft\n"); 497 fprintf(out," /bar /braceright /asciitilde /guilsinglright /fraction\n"); 498 fprintf(out," /florin /quotesingle /quotedblleft /guilsinglleft /fi\n"); 499 fprintf(out," /fl /endash /dagger /daggerdbl /bullet /quotesinglbase\n"); 500 fprintf(out," /quotedblbase /quotedblright /ellipsis /trademark\n"); 501 fprintf(out," /perthousand /grave /scaron /circumflex /Scaron /tilde\n"); 502 fprintf(out," /breve /zcaron /dotaccent /dotlessi /Zcaron /ring\n"); 503 fprintf(out," /hungarumlaut /ogonek /caron /emdash /space /exclamdown\n"); 504 fprintf(out," /cent /sterling /currency /yen /brokenbar /section\n"); 505 fprintf(out," /dieresis /copyright /ordfeminine /guillemotleft\n"); 506 fprintf(out," /logicalnot /hyphen /registered /macron /degree\n"); 507 fprintf(out," /plusminus /twosuperior /threesuperior /acute /mu\n"); 508 fprintf(out," /paragraph /periodcentered /cedilla /onesuperior\n"); 509 fprintf(out," /ordmasculine /guillemotright /onequarter /onehalf\n"); 510 fprintf(out," /threequarters /questiondown /Agrave /Aacute\n"); 511 fprintf(out," /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n"); 512 fprintf(out," /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute\n"); 513 fprintf(out," /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute\n"); 514 fprintf(out," /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n"); 515 fprintf(out," /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n"); 516 fprintf(out," /germandbls /agrave /aacute /acircumflex /atilde\n"); 517 fprintf(out," /adieresis /aring /ae /ccedilla /egrave /eacute\n"); 518 fprintf(out," /ecircumflex /edieresis /igrave /iacute /icircumflex\n"); 519 fprintf(out," /idieresis /eth /ntilde /ograve /oacute /ocircumflex\n"); 520 fprintf(out," /otilde /odieresis /divide /oslash /ugrave /uacute\n"); 521 fprintf(out," /ucircumflex /udieresis /yacute /thorn /ydieresis\n"); 522 fprintf(out,"] def {restore} if\n"); 523 fprintf(out,"/reencodeISO-1 {\n"); 524 fprintf(out," dup length dict begin\n"); 525 fprintf(out," {1 index /FID ne {def}{pop pop} ifelse} forall\n"); 526 fprintf(out," /Encoding ISOLatin1Encoding def\n"); 527 fprintf(out," currentdict\n"); 528 fprintf(out," end\n"); 529 fprintf(out,"} def\n"); 530} 531 532static void 533PSReencodeLatin1Font(FILE *out, char *font) 534{ 535 fprintf(out,"/%s findfont reencodeISO-1\n",font); 536 fprintf(out," /%s-8859-1 exch definefont pop\n",font); 537 return; 538} 539 540static void 541PSSetUpFonts(FILE *out, char *textFont, int size) 542{ 543 fprintf(out,"/F%d { /%s findfont exch scalefont setfont } def\n", 544 FONT_TEXT,textFont); 545 fprintf(out,"/F%d { /%s-8859-1 findfont exch scalefont setfont } def\n", 546 FONT_LATIN1,textFont); 547 fprintf(out,"/F%d { /%s findfont exch scalefont setfont } def\n", 548 FONT_SYMBOL,"Symbol"); 549 fprintf(out,"/F%d { /%s findfont exch scalefont setfont } def\n", 550 FONT_ISOCAPS,"IsoKeyCaps"); 551 return; 552} 553 554static void 555PSSetFont(FILE *out, PSState *state, int font, int size, int pts) 556{ 557 if ((state->font!=font)||(state->fontSize!=size)) { 558 fprintf(out,"%d %sF%d\n",size,(pts?"pts ":""),font); 559 state->font= font; 560 state->fontSize= size; 561 } 562 return; 563} 564 565 566static void 567PSProlog(FILE *out, PSState *state) 568{ 569register int i; 570 571 if (!state->args->wantEPS) { 572 fprintf(out,"%%!PS-Adobe-2.0\n"); 573 fprintf(out,"%%%%Creator: xkbprint\n"); 574 if (state->geom->name!=None) 575 fprintf(out,"%%%%Title: %s\n", 576 XkbAtomGetString(state->dpy,state->geom->name)); 577 fprintf(out,"%%%%BoundingBox: (atend)\n"); 578 fprintf(out,"%%%%Pages: 1\n"); 579 fprintf(out,"%%%%PageOrder: Ascend\n"); 580 fprintf(out,"%%%%DocumentFonts: (atend)\n"); 581 fprintf(out,"%%%%DocumentData: Clean7Bit\n"); 582 fprintf(out,"%%%%Orientation: Landscape\n"); 583 fprintf(out,"%%%%EndComments\n"); 584 fprintf(out,"%%%%BeginProlog\n"); 585 fprintf(out,"%% Resolution is 1/10mm -- need pt sizes for fonts\n"); 586 fprintf(out,"clippath pathbbox\n"); 587 fprintf(out," /ury exch def /urx exch def\n"); 588 fprintf(out," /llx exch def /lly exch def\n"); 589 fprintf(out," newpath\n"); 590 fprintf(out,"/devwidth urx llx sub def\n"); 591 fprintf(out,"/devheight ury lly sub def\n"); 592 } 593 else { 594 int w,h; 595 int pw,ph; 596 597 w= (((state->geom->width_mm*72)/254)*11)/10; 598 h= (((state->geom->height_mm*72)/254)*11)/10; 599 if (state->kbPerPage>1) 600 h*= (state->kbPerPage+1); 601 602 if (w<=h) { 603 pw= 7.5*72; 604 ph= 10*72; 605 } 606 else { 607 pw= 10*72; 608 ph= 7.5*72; 609 } 610 while ((w>pw)||(h>ph)) { 611 w= (w*9)/10; 612 h= (h*9)/10; 613 } 614 615 fprintf(out,"%%!PS-Adobe-2.0 EPSF-2.0\n"); 616 fprintf(out,"%%%%BoundingBox: 0 0 %d %d\n",w,h); 617 fprintf(out,"%%%%Creator: xkbprint\n"); 618 if (state->geom->name!=None) 619 fprintf(out,"%%%%Title: %s\n", 620 XkbAtomGetString(state->dpy,state->geom->name)); 621 fprintf(out,"%%%%Pages: 1\n"); 622 fprintf(out,"%%%%EndComments\n"); 623 fprintf(out,"%%%%BeginProlog\n"); 624 fprintf(out,"/ury 0 def /urx 0 def\n"); 625 fprintf(out,"/llx %d def /lly %d def\n",w,h); 626 fprintf(out,"/devwidth %d def /devheight %d def\n",w,h); 627 } 628 fprintf(out,"/kbdwidth %d def\n",state->geom->width_mm); 629 fprintf(out,"/kbdheight %d def\n",state->geom->height_mm); 630 fprintf(out,"/pts { 254 mul 72 div } def\n"); 631 fprintf(out,"/mm10 { 72 mul 254 div } def\n"); 632 fprintf(out,"/landscape? {\n"); 633 fprintf(out," devheight devwidth gt {\n"); 634 fprintf(out," /pwidth devheight def /pheight devwidth def\n"); 635 fprintf(out," 0 devheight translate\n"); 636 fprintf(out," -90 rotate\n"); 637 fprintf(out," } {\n"); 638 fprintf(out," /pwidth devwidth def /pheight devheight def\n"); 639 fprintf(out," } ifelse\n"); 640 fprintf(out," 0 pheight translate\n"); 641 fprintf(out," 1 -1 scale\n"); 642 fprintf(out,"} def\n"); 643 fprintf(out,"/centeroffset {\n"); 644 fprintf(out," /S exch def\n"); 645 fprintf(out," /HEIGHT exch def\n"); 646 fprintf(out," /WIDTH exch def\n"); 647 fprintf(out," S stringwidth /SH exch def /SW exch def\n"); 648 fprintf(out," WIDTH SW sub 2 div\n"); 649 fprintf(out," HEIGHT SH sub 2 div\n"); 650 fprintf(out,"} def\n"); 651 PSSetUpForLatin1(out,state); 652 PSReencodeLatin1Font(out,DFLT_LABEL_FONT); 653 if (state->args->wantColor) { 654 XkbGeometryPtr geom= state->geom; 655 for (i=0;i<geom->num_colors;i++) { 656 PSColorDef(out,state,&geom->colors[i]); 657 } 658 if (state->black<0) { 659 XkbColorPtr color; 660 if (!(color= XkbAddGeomColor(geom,"black",geom->num_colors))) 661 uFatalError("Couldn't allocate black color!\n"); 662 PSColorDef(out,state,color); 663 } 664 if (state->white<0) { 665 XkbColorPtr color; 666 if (!(color= XkbAddGeomColor(geom,"white",geom->num_colors))) 667 uFatalError("Couldn't allocate white color!\n"); 668 PSColorDef(out,state,color); 669 } 670 } 671 for (i=0;i<state->geom->num_shapes;i++) { 672 PSShapeDef(out,state,&state->geom->shapes[i]); 673 } 674 if (state->args->label==LABEL_SYMBOLS) { 675 PSIncludeFont(out,"IsoKeyCaps"); 676 } 677 PSSetUpFonts(out,DFLT_LABEL_FONT, DFLT_LABEL_FONT_SIZE); 678 fprintf(out,"%%%%EndProlog\n"); 679 return; 680} 681 682static void 683PSFileTrailer(FILE *out, PSState *state) 684{ 685 fprintf(out,"restore\n"); 686 if (!state->args->wantEPS) 687 fprintf(out,"%%%%Trailer\n"); 688 fprintf(out,"%%%%EOF\n"); 689#ifdef NOTYET 690 fprintf(out,"%%%%BoundingBox %d %d\n"); 691 fprintf(out,"%%%%DocumentFonts: \n"); 692#endif 693 return; 694} 695 696static void 697PSPageSetup(FILE *out, PSState *state, Bool drawBorder) 698{ 699XkbGeometryPtr geom; 700 701 geom= state->geom; 702 if (state->kbPerPage==1) { 703 fprintf(out,"%%%%Page: %d %d\n",state->nPages+1,state->nPages+1); 704 fprintf(out,"%%%%BeginPageSetup\n"); 705 } 706 else if ((state->nPages&1)==0) { /* even page */ 707 int realPage; 708 realPage= state->nPages/2+1; 709 fprintf(out,"%%%%Page: %d %d\n",realPage,realPage); 710 fprintf(out,"%%%%BeginPageSetup\n"); 711 fprintf(out,"%% Keyboard %d\n",state->nPages+1); 712 if (state->nPages==0) { 713 fprintf(out,"/realwidth devwidth def\n"); 714 fprintf(out,"/realheight devheight def\n"); 715 fprintf(out,"/devheight realheight 3 div def\n"); 716 } 717 fprintf(out,"0 devheight dup 2 div add translate\n"); 718 } 719 else { 720 fprintf(out,"%% Keyboard %d\n",state->nPages+1); 721 } 722 fprintf(out,"save\n"); 723 fprintf(out,"landscape?\n"); 724 if (state->args->scaleToFit) { 725 fprintf(out,"%% Scale keyboard to fit on the page\n"); 726 fprintf(out,"/kbdscale pwidth 72 sub kbdwidth div def\n"); 727 fprintf(out,"/kbdscalewidth kbdwidth kbdscale mul def\n"); 728 fprintf(out,"/kbdscaleheight kbdheight kbdscale mul def\n"); 729 fprintf(out,"/kbx 36 def\n"); 730 fprintf(out,"/kby pheight kbdscaleheight sub 2 div def\n"); 731 PSGSave(out,state); 732 fprintf(out,"kbx kby translate\n"); 733 fprintf(out,"kbdscale kbdscale scale\n"); 734 } 735 else { 736 fprintf(out,"%% Draw keyboard full size\n"); 737 fprintf(out,"/kbdscale 1 def\n"); 738 fprintf(out,"/kbdscalewidth kbdwidth mm10 def\n"); 739 fprintf(out,"/kbdscaleheight kbdheight mm10 def\n"); 740 fprintf(out,"/kbx pwidth kbdscalewidth sub 2 div def\n"); 741 fprintf(out,"/kby pheight kbdscaleheight sub 2 div def\n"); 742 PSGSave(out,state); 743 fprintf(out,"kbx kby translate\n"); 744 fprintf(out,"72 254 div dup scale\n"); 745 } 746 if (drawBorder) { 747 if (state->args->wantColor) { 748 PSSetColor(out,state,geom->base_color->pixel); 749 fprintf(out," 0 0 moveto\n"); 750 fprintf(out,"%3d 0 lineto\n",geom->width_mm); 751 fprintf(out,"%3d %3d lineto\n",geom->width_mm,geom->height_mm); 752 fprintf(out," 0 %3d lineto\n",geom->height_mm); 753 fprintf(out,"closepath fill\n"); 754 } 755 PSSetColor(out,state,state->black); 756 fprintf(out," 0 0 moveto\n"); 757 fprintf(out,"%3d 0 lineto\n",geom->width_mm); 758 fprintf(out,"%3d %3d lineto\n",geom->width_mm,geom->height_mm); 759 fprintf(out," 0 %3d lineto\n",geom->height_mm); 760 fprintf(out,"closepath stroke\n"); 761 } 762 fprintf(out,"%%%%EndPageSetup\n"); 763 return; 764} 765 766static void 767PSPageTrailer(FILE *out, PSState *state) 768{ 769char * name; 770XkbDescPtr xkb; 771XkbGeometryPtr geom; 772XkbPropertyPtr prop; 773int p,baseline; 774 775 xkb= state->xkb; 776 geom= state->geom; 777 if (state->args->grid>0) { 778 fprintf(out,"%% Draw a %dmm grid\n",state->args->grid); 779 fprintf(out,"0 setlinewidth\n"); 780 fprintf(out,"0.25 setgray\n"); 781 fprintf(out," 0 %d %d {\n",state->args->grid*10,geom->width_mm); 782 fprintf(out," /GX exch def\n"); 783 fprintf(out," GX 0 moveto GX %d lineto stroke\n",geom->height_mm); 784 fprintf(out,"} for\n"); 785 fprintf(out," 0 %d %d {\n",state->args->grid*10,geom->height_mm); 786 fprintf(out," /GY exch def\n"); 787 fprintf(out," 0 GY moveto %d GY lineto stroke\n",geom->width_mm); 788 fprintf(out,"} for\n"); 789 } 790 PSGRestore(out,state); 791 name= NULL; 792 for (p=0,prop=geom->properties;p<geom->num_properties;p++,prop++) { 793 if ((prop->value!=NULL)&&(uStrCaseEqual(prop->name,"description"))) { 794 name= prop->value; 795 break; 796 } 797 } 798 if ((!state->args->wantEPS)&& 799 ((state->kbPerPage==1)||((state->nPages&1)==1)|| 800 (state->nPages==state->totalKB))) { 801 if ((name==NULL)&&(geom->name!=None)) 802 name= XkbAtomGetString(state->dpy,geom->name); 803 804 baseline= 16; 805 if ((name!=NULL)||(state->args->label==LABEL_SYMBOLS)) { 806 PSSetColor(out,state,state->black); 807 PSSetFont(out,state,FONT_LATIN1,14,False); 808 } 809 if (state->args->label==LABEL_SYMBOLS) { 810 char buf[40],*sName= NULL, *lbuf; 811 Atom sAtom; 812 813 if (state->args->nLabelGroups==1) 814 sprintf(buf,"Group %d",state->args->baseLabelGroup+1); 815 else sprintf(buf,"Groups %d-%d",state->args->baseLabelGroup+1, 816 state->args->baseLabelGroup+state->args->nLabelGroups); 817 fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",buf); 818 fprintf(out," kby kbdscaleheight add %d add\n",baseline); 819 fprintf(out," moveto\n"); 820 fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",buf); 821 baseline+= 16; 822 823 if (xkb->names!=NULL) sAtom= xkb->names->symbols; 824 else sAtom= None; 825 if (sAtom!=None) 826 sName= XkbAtomGetString(state->dpy,sAtom); 827 if (sName==NULL) 828 sName= "(unknown)"; 829 830 lbuf = uAlloc(10+strlen(sName)); 831 if (!lbuf) { 832 uFatalError("Can't allocate memory for string\n"); 833 } 834 sprintf(lbuf,"Layout: %s",sName); 835 fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",lbuf); 836 fprintf(out," kby kbdscaleheight add %d add\n",baseline); 837 fprintf(out," moveto\n"); 838 fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",lbuf); 839 baseline+= 16; 840 free(lbuf); 841 } 842 if (name!=NULL) { 843 fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",name); 844 fprintf(out," kby kbdscaleheight add %d add\n",baseline); 845 fprintf(out," moveto\n"); 846 fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",name); 847 baseline+= 16; 848 } 849 if (state->args->label==LABEL_KEYCODE) { 850 char *sName= NULL, *lbuf; 851 Atom sAtom; 852 853 if (xkb->names!=NULL) sAtom= xkb->names->keycodes; 854 else sAtom= None; 855 if (sAtom!=None) 856 sName= XkbAtomGetString(state->dpy,sAtom); 857 if (sName==NULL) 858 sName= "(unknown)"; 859 860 lbuf = uAlloc(12+strlen(sName)); 861 if (!lbuf) { 862 uFatalError("Can't allocate memory for string\n"); 863 } 864 sprintf(lbuf,"Keycodes: %s",sName); 865 fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",lbuf); 866 fprintf(out," kby kbdscaleheight add %d add\n",baseline); 867 fprintf(out," moveto\n"); 868 fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",lbuf); 869 baseline+= 16; 870 free(lbuf); 871 } 872 if (state->args->copies>1) { 873 for (p=1;p<state->args->copies;p++) 874 fprintf(out,"copypage\n"); 875 } 876 fprintf(out,"showpage\n"); 877 fprintf(out,"restore\n"); 878 fprintf(out,"%% Done with keyboard/page %d\n",state->nPages+1); 879 } 880 else { 881 if ((!state->args->wantEPS)&&(state->args->label==LABEL_SYMBOLS)) { 882 char buf[40]; 883 baseline= 16; 884 PSSetColor(out,state,state->black); 885 PSSetFont(out,state,FONT_LATIN1,14,False); 886 if (state->args->nLabelGroups==1) 887 sprintf(buf,"Group %d",state->args->baseLabelGroup+1); 888 else sprintf(buf,"Groups %d-%d",state->args->baseLabelGroup+1, 889 state->args->baseLabelGroup+state->args->nLabelGroups+1); 890 fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",buf); 891 fprintf(out," kby kbdscaleheight add %d add\n",baseline); 892 fprintf(out," moveto\n"); 893 fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",buf); 894 baseline+= 16; 895 } 896 fprintf(out,"restore\n"); 897 fprintf(out,"%% Done with keyboard %d\n",state->nPages+1); 898 fprintf(out,"0 devheight -1 mul translate %% next keyboard\n"); 899 } 900 state->nPages++; 901 state->color= state->black; 902 state->font= -1; 903 return; 904} 905 906static void 907PSDoodad(FILE *out, PSState *state, XkbDoodadPtr doodad) 908{ 909XkbDescPtr xkb; 910char *name,*dname; 911int sz,leading; 912 913 xkb= state->xkb; 914 if (doodad->any.name!=None) 915 dname= XkbAtomGetString(xkb->dpy,doodad->any.name); 916 else dname= "NoName"; 917 switch (doodad->any.type) { 918 case XkbOutlineDoodad: 919 case XkbSolidDoodad: 920 name= XkbAtomGetString(xkb->dpy, 921 XkbShapeDoodadShape(xkb->geom,&doodad->shape)->name); 922 if (state->args->wantColor) { 923 PSSetColor(out,state,doodad->shape.color_ndx); 924 if (doodad->any.type!=XkbOutlineDoodad) { 925 fprintf(out,"true %d %d %d %s %% Doodad %s\n", 926 doodad->shape.angle, 927 doodad->shape.left,doodad->shape.top, 928 name,dname); 929 PSSetColor(out,state,state->black); 930 } 931 fprintf(out,"false %d %d %d %s %% Doodad %s\n", 932 doodad->shape.angle, 933 doodad->shape.left,doodad->shape.top, 934 name,dname); 935 } 936 else { 937 fprintf(out,"false %d %d %d %s %% Doodad %s\n", 938 doodad->shape.angle, 939 doodad->shape.left,doodad->shape.top, 940 name,dname); 941 } 942 break; 943 case XkbTextDoodad: 944 fprintf(out,"%% Doodad %s\n",dname); 945 PSSetColor(out,state,doodad->text.color_ndx); 946 PSGSave(out,state); 947 fprintf(out,"%d %d translate\n",doodad->text.left,doodad->text.top); 948 if (doodad->text.angle!=0) 949 fprintf(out,"%s rotate\n", 950 XkbGeomFPText(doodad->text.angle,XkbMessage)); 951 sz= 14; 952 if (doodad->text.font) { 953 FontStuff stuff; 954 if (CrackXLFDName(doodad->text.font,&stuff)) { 955 if (stuff.ptSize>0) 956 sz= stuff.ptSize/10; 957 ClearFontStuff(&stuff); 958 } 959 } 960 PSSetFont(out,state,FONT_LATIN1,sz,True); 961 leading= (sz*12)/10; 962 if (strchr(doodad->text.text,'\n')==NULL) { 963 fprintf(out,"0 %d pts moveto 1 -1 scale\n",(leading*8)/10); 964 fprintf(out,"(%s) show\n",doodad->text.text); 965 } 966 else { 967 char *tmp,*buf,*end; 968 int offset= (leading*8/10); 969 tmp= buf= uStringDup(doodad->text.text); 970 while (tmp!=NULL) { 971 end= strchr(tmp,'\n'); 972 if (end!=NULL) 973 *end++= '\0'; 974 fprintf(out,"0 %d pts moveto 1 -1 scale\n",offset); 975 fprintf(out,"(%s) show 1 -1 scale\n",tmp); 976 offset+= leading; 977 tmp= end; 978 } 979 free(buf); 980 } 981 PSGRestore(out,state); 982 break; 983 case XkbIndicatorDoodad: 984 name= XkbAtomGetString(xkb->dpy, 985 XkbIndicatorDoodadShape(xkb->geom,&doodad->indicator)->name); 986 if (state->args->wantColor) { 987 PSSetColor(out,state,doodad->indicator.off_color_ndx); 988 fprintf(out,"true 0 %d %d %s %% Doodad %s\n", 989 doodad->indicator.left,doodad->indicator.top, 990 name,dname); 991 PSSetColor(out,state,state->black); 992 } 993 fprintf(out,"false 0 %d %d %s %% Doodad %s\n", 994 doodad->indicator.left,doodad->indicator.top, 995 name,dname); 996 break; 997 case XkbLogoDoodad: 998 name= XkbAtomGetString(xkb->dpy, 999 XkbLogoDoodadShape(xkb->geom,&doodad->logo)->name); 1000 if (state->args->wantColor) 1001 PSSetColor(out,state,doodad->shape.color_ndx); 1002 fprintf(out,"false %d %d %d %s %% Doodad %s\n", 1003 doodad->shape.angle, 1004 doodad->shape.left,doodad->shape.top, 1005 name,dname); 1006 break; 1007 } 1008 return; 1009} 1010 1011/***====================================================================***/ 1012 1013static Bool 1014PSKeycapsSymbol(KeySym sym, unsigned char *buf, 1015 int *font_rtrn, int *sz_rtrn, PSState *state) 1016{ 1017 if (state->args->wantSymbols==NO_SYMBOLS) 1018 return False; 1019 1020 if (font_rtrn!=NULL) 1021 *font_rtrn= FONT_ISOCAPS; 1022 if (sz_rtrn!=NULL) 1023 *sz_rtrn= SZ_LARGE; 1024 buf[1]= '\0'; 1025 switch (sym) { 1026 case XK_Shift_L: case XK_Shift_R: 1027 buf[0]= XKC_ISO_Shift; return True; 1028 case XK_Shift_Lock: 1029 buf[0]= XKC_ISO_Shift_Lock; return True; 1030 case XK_ISO_Lock: 1031 buf[0]= XKC_ISO_Caps_Lock; return True; 1032 case XK_BackSpace: 1033 buf[0]= XKC_ISO_Backspace; return True; 1034 case XK_Return: 1035 buf[0]= XKC_ISO_Return; return True; 1036 case XK_Up: case XK_KP_Up: 1037 buf[0]= XKC_ISO_Up; return True; 1038 case XK_Down: case XK_KP_Down: 1039 buf[0]= XKC_ISO_Down; return True; 1040 case XK_Left: case XK_KP_Left: 1041 buf[0]= XKC_ISO_Left; return True; 1042 case XK_Right: case XK_KP_Right: 1043 buf[0]= XKC_ISO_Right; return True; 1044 case XK_Tab: 1045 buf[0]= XKC_ISO_Tab; return True; 1046 case XK_ISO_Left_Tab: 1047 buf[0]= XKC_ISO_Left_Tab; return True; 1048 } 1049 if (state->args->wantSymbols!=ALL_SYMBOLS) 1050 return False; 1051 switch (sym) { 1052 case XK_Caps_Lock: 1053 buf[0]= XKC_ISO_Caps_Lock; return True; 1054 case XK_Num_Lock: 1055 buf[0]= XKC_ISO_Num_Lock; return True; 1056 case XK_ISO_Level3_Shift: 1057 buf[0]= XKC_ISO_Level3_Shift; return True; 1058 case XK_ISO_Level3_Lock: 1059 buf[0]= XKC_ISO_Level3_Lock; return True; 1060 case XK_ISO_Next_Group: case XK_ISO_Group_Shift: 1061 buf[0]= XKC_ISO_Next_Group; return True; 1062 case XK_ISO_Next_Group_Lock: 1063 buf[0]= XKC_ISO_Next_Group_Lock;return True; 1064 case XK_space: 1065 buf[0]= XKC_ISO_Space; return True; 1066 case XK_nobreakspace: 1067 buf[0]= XKC_ISO_No_Break_Space; return True; 1068 case XK_Insert: 1069 buf[0]= XKC_ISO_Insert; return True; 1070 case XK_ISO_Continuous_Underline: 1071 buf[0]= XKC_ISO_Continuous_Underline;return True; 1072 case XK_ISO_Discontinuous_Underline: 1073 buf[0]= XKC_ISO_Discontinuous_Underline;return True; 1074 case XK_ISO_Emphasize: 1075 buf[0]= XKC_ISO_Emphasize; return True; 1076 case XK_Multi_key: 1077 buf[0]= XKC_ISO_Compose; return True; 1078 case XK_ISO_Center_Object: 1079 buf[0]= XKC_ISO_Center_Object; return True; 1080 case XK_Delete: 1081 buf[0]= XKC_ISO_Delete; return True; 1082 case XK_Clear: 1083 buf[0]= XKC_ISO_Clear_Screen; return True; 1084 case XK_Scroll_Lock: 1085 buf[0]= XKC_ISO_Scroll_Lock; return True; 1086 case XK_Help: 1087 buf[0]= XKC_ISO_Help; return True; 1088 case XK_Print: 1089 buf[0]= XKC_ISO_Print_Screen; return True; 1090 case XK_ISO_Enter: 1091 buf[0]= XKC_ISO_Enter; return True; 1092 case XK_Alt_L: case XK_Alt_R: 1093 buf[0]= XKC_ISO_Alt; return True; 1094 case XK_Control_L: case XK_Control_R: 1095 buf[0]= XKC_ISO_Control; return True; 1096 case XK_Pause: 1097 buf[0]= XKC_ISO_Pause; return True; 1098 case XK_Break: 1099 buf[0]= XKC_ISO_Break; return True; 1100 case XK_Escape: 1101 buf[0]= XKC_ISO_Escape; return True; 1102 case XK_Undo: 1103 buf[0]= XKC_ISO_Undo; return True; 1104 case XK_ISO_Fast_Cursor_Up: 1105 buf[0]= XKC_ISO_Fast_Cursor_Up; return True; 1106 case XK_ISO_Fast_Cursor_Down: 1107 buf[0]= XKC_ISO_Fast_Cursor_Down;return True; 1108 case XK_ISO_Fast_Cursor_Left: 1109 buf[0]= XKC_ISO_Fast_Cursor_Left;return True; 1110 case XK_ISO_Fast_Cursor_Right: 1111 buf[0]= XKC_ISO_Fast_Cursor_Right;return True; 1112 case XK_Home: 1113 buf[0]= XKC_ISO_Home; return True; 1114 case XK_End: 1115 buf[0]= XKC_ISO_End; return True; 1116 case XK_Page_Up: 1117 buf[0]= XKC_ISO_Page_Up; return True; 1118 case XK_Page_Down: 1119 buf[0]= XKC_ISO_Page_Down; return True; 1120 case XK_ISO_Move_Line_Up: 1121 buf[0]= XKC_ISO_Move_Line_Up; return True; 1122 case XK_ISO_Move_Line_Down: 1123 buf[0]= XKC_ISO_Move_Line_Down; return True; 1124 case XK_ISO_Partial_Line_Up: 1125 buf[0]= XKC_ISO_Partial_Line_Up;return True; 1126 case XK_ISO_Partial_Line_Down: 1127 buf[0]= XKC_ISO_Partial_Line_Down;return True; 1128 case XK_ISO_Partial_Space_Left: 1129 buf[0]= XKC_ISO_Partial_Space_Left;return True; 1130 case XK_ISO_Partial_Space_Right: 1131 buf[0]= XKC_ISO_Partial_Space_Right;return True; 1132 case XK_ISO_Set_Margin_Left: 1133 buf[0]= XKC_ISO_Set_Margin_Left;return True; 1134 case XK_ISO_Set_Margin_Right: 1135 buf[0]= XKC_ISO_Set_Margin_Right;return True; 1136 case XK_ISO_Release_Margin_Left: 1137 buf[0]= XKC_ISO_Release_Margin_Left;return True; 1138 case XK_ISO_Release_Margin_Right: 1139 buf[0]= XKC_ISO_Release_Margin_Right;return True; 1140 case XK_ISO_Release_Both_Margins: 1141 buf[0]= XKC_ISO_Release_Both_Margins;return True; 1142 case XK_ISO_Prev_Group: 1143 buf[0]= XKC_ISO_Prev_Group; return True; 1144 case XK_ISO_Prev_Group_Lock: 1145 buf[0]= XKC_ISO_Prev_Group_Lock; return True; 1146 } 1147#ifdef NOTYET 1148 if (font_rtrn!=NULL) 1149 font_rtrn= FONT_MOUSECAPS; 1150 switch (sym) { 1151 case XK_Pointer_Up: 1152 buf[0]= XKC_Mouse_Pointer_Up; return True; 1153 case XK_Pointer_Down: 1154 buf[0]= XKC_Mouse_Pointer_Down; return True; 1155 case XK_Pointer_Left: 1156 buf[0]= XKC_Mouse_Pointer_Left; return True; 1157 case XK_Pointer_Right: 1158 buf[0]= XKC_Mouse_Pointer_Right;return True; 1159 case XK_Pointer_Button1: 1160 buf[0]= XKC_Mouse_Pointer_Button1;return True; 1161 case XK_Pointer_Button2: 1162 buf[0]= XKC_Mouse_Pointer_Button2;return True; 1163 case XK_Pointer_Button3: 1164 buf[0]= XKC_Mouse_Pointer_Button3;return True; 1165 case XK_Pointer_Button4: 1166 buf[0]= XKC_Mouse_Pointer_Button4;return True; 1167 } 1168#endif 1169 return False; 1170} 1171 1172static Bool 1173PSNonLatin1Symbol(KeySym sym, unsigned char *buf, 1174 int *font_rtrn, int *sz_rtrn, PSState *state) 1175{ 1176 if (state->args->wantSymbols==NO_SYMBOLS) 1177 return False; 1178 1179 if (font_rtrn!=NULL) 1180 *font_rtrn= FONT_TEXT; 1181 if (sz_rtrn!=NULL) 1182 *sz_rtrn= SZ_LARGE; 1183 buf[1]= '\0'; 1184 switch (sym) { 1185 case XK_breve: buf[0]= 0xC6; return True; 1186 case XK_abovedot: buf[0]= 0xC7; return True; 1187 case XK_doubleacute: buf[0]= 0xCD; return True; 1188 case XK_ogonek: buf[0]= 0xCE; return True; 1189 case XK_caron: buf[0]= 0xCF; return True; 1190 case XK_Lstroke: buf[0]= 0xE8; return True; 1191 case XK_idotless: buf[0]= 0xF5; return True; 1192 case XK_lstroke: buf[0]= 0xF8; return True; 1193 } 1194 if (font_rtrn!=NULL) 1195 *font_rtrn= FONT_SYMBOL; 1196 if (sz_rtrn!=NULL) 1197 *sz_rtrn= SZ_MEDIUM; 1198 if ((sym&(~0xff))==0x700) { 1199 switch (sym) { 1200 /* Greek symbol */ 1201 case XK_Greek_ALPHA: buf[0]= 0x41; return True; 1202 case XK_Greek_BETA: buf[0]= 0x42; return True; 1203 case XK_Greek_CHI: buf[0]= 0x43; return True; 1204 case XK_Greek_DELTA: buf[0]= 0x44; return True; 1205 case XK_Greek_EPSILON: buf[0]= 0x45; return True; 1206 case XK_Greek_PHI: buf[0]= 0x46; return True; 1207 case XK_Greek_GAMMA: buf[0]= 0x47; return True; 1208 case XK_Greek_ETA: buf[0]= 0x48; return True; 1209 case XK_Greek_IOTA: buf[0]= 0x49; return True; 1210 case XK_Greek_KAPPA: buf[0]= 0x4B; return True; 1211 case XK_Greek_LAMDA: buf[0]= 0x4C; return True; 1212 case XK_Greek_MU: buf[0]= 0x4D; return True; 1213 case XK_Greek_NU: buf[0]= 0x4E; return True; 1214 case XK_Greek_OMICRON: buf[0]= 0x4F; return True; 1215 case XK_Greek_PI: buf[0]= 0x50; return True; 1216 case XK_Greek_THETA: buf[0]= 0x51; return True; 1217 case XK_Greek_RHO: buf[0]= 0x52; return True; 1218 case XK_Greek_SIGMA: buf[0]= 0x53; return True; 1219 case XK_Greek_TAU: buf[0]= 0x54; return True; 1220 case XK_Greek_UPSILON: buf[0]= 0x55; return True; 1221 case XK_Greek_OMEGA: buf[0]= 0x57; return True; 1222 case XK_Greek_XI: buf[0]= 0x58; return True; 1223 case XK_Greek_PSI: buf[0]= 0x59; return True; 1224 case XK_Greek_ZETA: buf[0]= 0x5A; return True; 1225 1226 case XK_Greek_alpha: buf[0]= 0x61; return True; 1227 case XK_Greek_beta: buf[0]= 0x62; return True; 1228 case XK_Greek_chi: buf[0]= 0x63; return True; 1229 case XK_Greek_delta: buf[0]= 0x64; return True; 1230 case XK_Greek_epsilon: buf[0]= 0x65; return True; 1231 case XK_Greek_phi: buf[0]= 0x66; return True; 1232 case XK_Greek_gamma: buf[0]= 0x67; return True; 1233 case XK_Greek_eta: buf[0]= 0x68; return True; 1234 case XK_Greek_iota: buf[0]= 0x69; return True; 1235 case XK_Greek_kappa: buf[0]= 0x6B; return True; 1236 case XK_Greek_lamda: buf[0]= 0x6C; return True; 1237 case XK_Greek_mu: buf[0]= 0x6D; return True; 1238 case XK_Greek_nu: buf[0]= 0x6E; return True; 1239 case XK_Greek_omicron: buf[0]= 0x6F; return True; 1240 case XK_Greek_pi: buf[0]= 0x70; return True; 1241 case XK_Greek_theta: buf[0]= 0x71; return True; 1242 case XK_Greek_rho: buf[0]= 0x72; return True; 1243 case XK_Greek_sigma: buf[0]= 0x73; return True; 1244 case XK_Greek_tau: buf[0]= 0x74; return True; 1245 case XK_Greek_upsilon: buf[0]= 0x75; return True; 1246 case XK_Greek_omega: buf[0]= 0x77; return True; 1247 case XK_Greek_xi: buf[0]= 0x78; return True; 1248 case XK_Greek_psi: buf[0]= 0x79; return True; 1249 case XK_Greek_zeta: buf[0]= 0x7A; return True; 1250 } 1251 } 1252 switch (sym) { 1253 case XK_leftarrow: buf[0]= 0xAC; return True; 1254 case XK_uparrow: buf[0]= 0xAD; return True; 1255 case XK_rightarrow: buf[0]= 0xAE; return True; 1256 case XK_downarrow: buf[0]= 0xAF; return True; 1257 case XK_horizconnector: buf[0]= 0xBE; return True; 1258 case XK_trademark: buf[0]= 0xE4; return True; 1259 } 1260 return False; 1261} 1262 1263static KeySym 1264CheckSymbolAlias(KeySym sym, PSState *state) 1265{ 1266 if (XkbKSIsKeypad(sym)) { 1267 if ((sym>=XK_KP_0)&&(sym<=XK_KP_9)) 1268 sym= (sym-XK_KP_0)+XK_0; 1269 else switch (sym) { 1270 case XK_KP_Space: return XK_space; 1271 case XK_KP_Tab: return XK_Tab; 1272 case XK_KP_Enter: return XK_Return; 1273 case XK_KP_F1: return XK_F1; 1274 case XK_KP_F2: return XK_F2; 1275 case XK_KP_F3: return XK_F3; 1276 case XK_KP_F4: return XK_F4; 1277 case XK_KP_Home: return XK_Home; 1278 case XK_KP_Left: return XK_Left; 1279 case XK_KP_Up: return XK_Up; 1280 case XK_KP_Right: return XK_Right; 1281 case XK_KP_Down: return XK_Down; 1282 case XK_KP_Page_Up: return XK_Page_Up; 1283 case XK_KP_Page_Down: return XK_Page_Down; 1284 case XK_KP_End: return XK_End; 1285 case XK_KP_Begin: return XK_Begin; 1286 case XK_KP_Insert: return XK_Insert; 1287 case XK_KP_Delete: return XK_Delete; 1288 case XK_KP_Equal: return XK_equal; 1289 case XK_KP_Multiply: return XK_asterisk; 1290 case XK_KP_Add: return XK_plus; 1291 case XK_KP_Subtract: return XK_minus; 1292 case XK_KP_Divide: return XK_slash; 1293 } 1294 } 1295 else if (XkbKSIsDeadKey(sym)) { 1296 switch (sym) { 1297 case XK_dead_grave: sym= XK_grave; break; 1298 case XK_dead_acute: sym= XK_acute; break; 1299 case XK_dead_circumflex: sym= XK_asciicircum; break; 1300 case XK_dead_tilde: sym= XK_asciitilde; break; 1301 case XK_dead_macron: sym= XK_macron; break; 1302 case XK_dead_breve: sym= XK_breve; break; 1303 case XK_dead_abovedot: sym= XK_abovedot; break; 1304 case XK_dead_diaeresis: sym= XK_diaeresis; break; 1305 case XK_dead_abovering: sym= XK_degree; break; 1306 case XK_dead_doubleacute: sym= XK_doubleacute; break; 1307 case XK_dead_caron: sym= XK_caron; break; 1308 case XK_dead_cedilla: sym= XK_cedilla; break; 1309 case XK_dead_ogonek: sym= XK_ogonek; break; 1310 case XK_dead_iota: sym= XK_Greek_iota; break; 1311 case XK_dead_voiced_sound: 1312 sym= XK_voicedsound; 1313 break; 1314 case XK_dead_semivoiced_sound: 1315 sym= XK_semivoicedsound; 1316 break; 1317 } 1318 } 1319 return sym; 1320} 1321 1322static Bool 1323FindKeysymsByName(XkbDescPtr xkb, char *name, PSState *state, KeyTop *top) 1324{ 1325static unsigned char buf[30]; 1326int kc; 1327KeySym sym,*syms,topSyms[NLABELS]; 1328int level,group; 1329int eG,nG,gI,l,g; 1330 1331 bzero(top,sizeof(KeyTop)); 1332 kc= XkbFindKeycodeByName(xkb,name,True); 1333 if (state->args!=NULL) { 1334 level= state->args->labelLevel; 1335 group= state->args->baseLabelGroup; 1336 } 1337 else level= group= 0; 1338 syms= XkbKeySymsPtr(xkb,kc); 1339 eG= group; 1340 nG= XkbKeyNumGroups(xkb,kc); 1341 gI= XkbKeyGroupInfo(xkb,kc); 1342 if ((state->args->wantDiffs)&&(eG>=XkbKeyNumGroups(xkb,kc))) 1343 return False; /* XXX was a return with no value */ 1344 if (nG==0) { 1345 return False; 1346 } 1347 else if (nG==1) { 1348 eG= 0; 1349 } 1350 else if (eG>=XkbKeyNumGroups(xkb,kc)) { 1351 switch (XkbOutOfRangeGroupAction(gI)) { 1352 default: 1353 eG%= nG; 1354 break; 1355 case XkbClampIntoRange: 1356 eG= nG-1; 1357 break; 1358 case XkbRedirectIntoRange: 1359 eG= XkbOutOfRangeGroupNumber(gI); 1360 if (eG>=nG) 1361 eG= 0; 1362 break; 1363 } 1364 } 1365 for (g=0;g<state->args->nLabelGroups;g++) { 1366 if ((eG+g)>=nG) 1367 continue; 1368 for (l=0;l<2;l++) { 1369 int font,sz; 1370 if (level+l>=XkbKeyGroupWidth(xkb,kc,(eG+g))) 1371 continue; 1372 sym= syms[((eG+g)*XkbKeyGroupsWidth(xkb,kc))+(level+l)]; 1373 1374 if (state->args->wantSymbols!=NO_SYMBOLS) 1375 sym= CheckSymbolAlias(sym,state); 1376 topSyms[(g*2)+l]= sym; 1377 1378 if (PSKeycapsSymbol(sym,buf,&font,&sz,state)) { 1379 top->font[(g*2)+l]= font; 1380 top->size[(g*2)+l]= sz; 1381 } 1382 else if (((sym&(~0xff))==0)&&isprint(sym)&&(!isspace(sym))) { 1383 if (sym=='(') sprintf((char *)buf,"\\("); 1384 else if (sym==')') sprintf((char *)buf,"\\)"); 1385 else if (sym=='\\') sprintf((char *)buf,"\\\\"); 1386 else sprintf((char *)buf,"%c",(char)sym); 1387 top->font[(g*2)+l]= FONT_LATIN1; 1388 top->size[(g*2)+l]= SZ_MEDIUM; 1389 switch (buf[0]) { 1390 case '.': case ':': case ',': case ';': 1391 case '\'': case '"': case '`': case '~': 1392 case '^': case 0250: case 0270: case 0267: 1393 case 0260: case 0252: case 0272: case 0271: 1394 case 0262: case 0263: case 0264: case 0255: 1395 case 0254: case 0257: 1396 top->size[(g*2)+l]= SZ_LARGE; 1397 break; 1398 } 1399 } 1400 else if (PSNonLatin1Symbol(sym,buf,&font,&sz,state)) { 1401 top->font[(g*2)+l]= font; 1402 top->size[(g*2)+l]= sz; 1403 } 1404 else { 1405 char *tmp; 1406 tmp= XKeysymToString(sym); 1407 if (tmp!=NULL) strcpy((char *)buf,tmp); 1408 else sprintf((char *)buf,"(%ld)",sym); 1409 top->font[(g*2)+l]= FONT_LATIN1; 1410 if (strlen((char *)buf)<9) 1411 top->size[(g*2)+l]= SZ_SMALL; 1412 else top->size[(g*2)+l]= SZ_TINY; 1413 } 1414 top->present|= (1<<((g*2)+l)); 1415 strncpy(top->label[(g*2)+l],(char *)buf,LABEL_LEN-1); 1416 top->label[(g*2)+l][LABEL_LEN-1]= '\0'; 1417 } 1418 if (((g==0)&&(top->present&G1LX_MASK)==G1LX_MASK)|| 1419 ((g==1)&&(top->present&G2LX_MASK)==G2LX_MASK)) { 1420 KeySym lower,upper; 1421 XConvertCase(topSyms[(g*2)],&lower,&upper); 1422 if ((topSyms[(g*2)]==lower)&&(topSyms[(g*2)+1]==upper)) { 1423 top->alpha[g]= True; 1424 } 1425 } 1426 } 1427 return True; 1428} 1429 1430static void 1431PSDrawLabel(FILE *out, char *label, int x, int y, int w, int h) 1432{ 1433 fprintf(out,"%d %d (%s) centeroffset\n",w,h,label); 1434 fprintf(out,"%d add exch\n",y); 1435 fprintf(out,"%d add exch moveto\n",x); 1436 fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",label); 1437 return; 1438} 1439 1440#define TOP_ROW 0 1441#define BOTTOM_ROW 1 1442#define CENTER_ROW 2 1443 1444#define LEFT_COL 0 1445#define RIGHT_COL 1 1446#define CENTER_COL 2 1447 1448static void 1449PSLabelKey(FILE *out, PSState *state, KeyTop *top, int x, int y, 1450 XkbBoundsPtr bounds, int kc, int btm) 1451{ 1452char keycode[10]; 1453int w,h,i; 1454int row_y[3]; 1455int col_x[3]; 1456int row_h[3]; 1457int col_w[3]; 1458Bool present[NLABELS]; 1459int sym_row[NLABELS]; 1460int sym_col[NLABELS]; 1461 1462 w= XkbBoundsWidth(bounds); 1463 h= XkbBoundsHeight(bounds); 1464 row_y[TOP_ROW]= y+bounds->y1+(h/10); 1465 row_y[BOTTOM_ROW]= y+bounds->y1+(h/2)+(h/10); 1466 row_y[CENTER_ROW]= y+bounds->y1+(h/10); 1467 row_h[TOP_ROW]= h/2; 1468 row_h[BOTTOM_ROW]= h/2; 1469 row_h[CENTER_ROW]= h; 1470 1471 col_x[LEFT_COL]= x+bounds->x1; 1472 col_x[RIGHT_COL]= x+bounds->x1+w/2; 1473 col_x[CENTER_COL]= x+bounds->x1; 1474 col_w[LEFT_COL]= w/2; 1475 col_w[RIGHT_COL]= w/2; 1476 col_w[CENTER_COL]= w; 1477 1478 present[G1L1]= False; 1479 sym_row[G1L1]= BOTTOM_ROW; 1480 sym_col[G1L1]= LEFT_COL; 1481 1482 present[G1L2]= False; 1483 sym_row[G1L2]= TOP_ROW; 1484 sym_col[G1L2]= LEFT_COL; 1485 1486 present[G2L1]= False; 1487 sym_row[G2L1]= BOTTOM_ROW; 1488 sym_col[G2L1]= RIGHT_COL; 1489 1490 present[G2L2]= False; 1491 sym_row[G2L2]= TOP_ROW; 1492 sym_col[G2L2]= RIGHT_COL; 1493 1494 present[CENTER]= False; 1495 sym_row[CENTER]= CENTER_ROW; 1496 sym_col[CENTER]= CENTER_COL; 1497 1498 if (top->present&CENTER_MASK) { 1499 present[CENTER]= True; 1500 } 1501 else switch (top->present&GXLX_MASK) { 1502 case G1L1_MASK: 1503 present[G1L1]= True; 1504 sym_row[G1L1]= CENTER_ROW; 1505 sym_col[G1L1]= CENTER_COL; 1506 break; 1507 case G1LX_MASK: 1508 present[G1L2]= True; 1509 if (!top->alpha[0]) { 1510 present[G1L1]= True; 1511 if ((strlen(top->label[G1L1])>1)&&(top->label[G1L1][0]!='\\')) 1512 sym_col[G1L1]= CENTER_COL; 1513 if ((strlen(top->label[G1L2])>1)&&(top->label[G1L1][0]!='\\')) 1514 sym_col[G1L2]= CENTER_COL; 1515 } 1516 break; 1517 default: 1518 if ((top->present&G1LX_MASK)==G1LX_MASK) { 1519 present[G1L2]= True; 1520 if (!top->alpha[0]) 1521 present[G1L1]= True; 1522 } 1523 else if ((top->present&G1LX_MASK)==G1L1_MASK) { 1524 present[G1L1]= True; 1525 } 1526 else if ((top->present&G1LX_MASK)==G1L2_MASK) { 1527 present[G1L2]= True; 1528 } 1529 if ((top->present&G2LX_MASK)==G2LX_MASK) { 1530 present[G2L2]= True; 1531 if (!top->alpha[1]) 1532 present[G2L1]= True; 1533 } 1534 else if ((top->present&G2LX_MASK)==G2L1_MASK) { 1535 present[G2L1]= True; 1536 } 1537 else if ((top->present&G2LX_MASK)==G2L2_MASK) { 1538 present[G2L2]= True; 1539 } 1540 break; 1541 case 0: 1542 return; 1543 } 1544 for (i=0;i<NLABELS;i++) { 1545 if (present[i]) { 1546 int len,size; 1547 if (top->size[i]==SZ_AUTO) { 1548 len= strlen(top->label[i]); 1549 if (len==1) { 1550 if (top->font[i]==FONT_ISOCAPS) 1551 size= 18; 1552 else size= 14; 1553 } 1554 else if (len<10) size= 12; 1555 else size= 10; 1556 } 1557 else if (top->size[i]==SZ_TINY) 1558 size= 10; 1559 else if (top->size[i]==SZ_SMALL) 1560 size= 12; 1561 else if (top->size[i]==SZ_LARGE) 1562 size= 18; 1563 else if (top->size[i]==SZ_XLARGE) 1564 size= 24; 1565 else size= 14; 1566 PSSetFont(out,state,top->font[i],size,True); 1567 PSDrawLabel(out,top->label[i],col_x[sym_col[i]],row_y[sym_row[i]], 1568 col_w[sym_col[i]],row_h[sym_row[i]]); 1569 } 1570 } 1571 if (state->args->wantKeycodes) { 1572 sprintf(keycode,"%d",kc); 1573 PSSetFont(out,state,FONT_LATIN1,8,True); 1574 PSDrawLabel(out,keycode,x+bounds->x1,y+btm-5,w,0); 1575 } 1576 return; 1577} 1578 1579static void 1580PSSection(FILE *out, PSState *state, XkbSectionPtr section) 1581{ 1582int r,offset; 1583XkbRowPtr row; 1584Display * dpy; 1585XkbDescPtr xkb; 1586 1587 xkb= state->xkb; 1588 dpy= xkb->dpy; 1589 fprintf(out,"%% Begin Section '%s'\n",(section->name!=None? 1590 XkbAtomGetString(dpy,section->name): 1591 "NoName")); 1592 PSGSave(out,state); 1593 fprintf(out,"%d %d translate\n",section->left,section->top); 1594 if (section->angle!=0) 1595 fprintf(out,"%s rotate\n",XkbGeomFPText(section->angle,XkbMessage)); 1596 if (section->doodads) { 1597 XkbDrawablePtr first,draw; 1598 first= draw= XkbGetOrderedDrawables(NULL,section); 1599 while (draw) { 1600 if (draw->type==XkbDW_Section) 1601 PSSection(out,state,draw->u.section); 1602 else PSDoodad(out,state,draw->u.doodad); 1603 draw= draw->next; 1604 } 1605 XkbFreeOrderedDrawables(first); 1606 } 1607 for (r=0,row=section->rows;r<section->num_rows;r++,row++) { 1608 int k; 1609 XkbKeyPtr key; 1610 XkbShapePtr shape; 1611 if (row->vertical) offset= row->top; 1612 else offset= row->left; 1613 fprintf(out,"%% Begin %s %d\n",row->vertical?"column":"row",r+1); 1614 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 1615 shape= XkbKeyShape(xkb->geom,key); 1616 offset+= key->gap; 1617 if (row->vertical) { 1618 if (state->args->wantColor) { 1619 if (key->color_ndx!=state->white) { 1620 PSSetColor(out,state,key->color_ndx); 1621 fprintf(out,"true 0 %d %d %s %% %s\n", 1622 row->left,offset, 1623 XkbAtomGetString(dpy,shape->name), 1624 XkbKeyNameText(key->name.name,XkbMessage)); 1625 } 1626 PSSetColor(out,state,state->black); 1627 } 1628 fprintf(out,"false 0 %d %d %s %% %s\n",row->left,offset, 1629 XkbAtomGetString(dpy,shape->name), 1630 XkbKeyNameText(key->name.name,XkbMessage)); 1631 offset+= shape->bounds.y2; 1632 } 1633 else { 1634 if (state->args->wantColor) { 1635 if (key->color_ndx!=state->white) { 1636 PSSetColor(out,state,key->color_ndx); 1637 fprintf(out,"true 0 %d %d %s %% %s\n",offset,row->top, 1638 XkbAtomGetString(dpy,shape->name), 1639 XkbKeyNameText(key->name.name,XkbMessage)); 1640 } 1641 PSSetColor(out,state,state->black); 1642 } 1643 fprintf(out,"false 0 %d %d %s %% %s\n",offset,row->top, 1644 XkbAtomGetString(dpy,shape->name), 1645 XkbKeyNameText(key->name.name,XkbMessage)); 1646 offset+= shape->bounds.x2; 1647 } 1648 } 1649 } 1650 for (r=0,row=section->rows;r<section->num_rows;r++,row++) { 1651 int k,kc=0; 1652 XkbKeyPtr key; 1653 XkbShapePtr shape; 1654 XkbBoundsRec bounds; 1655 if (state->args->label==LABEL_NONE) 1656 break; 1657 if (row->vertical) offset= row->top; 1658 else offset= row->left; 1659 fprintf(out,"%% Begin %s %d labels\n",row->vertical?"column":"row",r+1); 1660 PSSetColor(out,state,xkb->geom->label_color->pixel); 1661 PSSetFont(out,state,FONT_LATIN1,12,True); 1662 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 1663 char * name,*name2,buf[30],buf2[30]; 1664 int x,y; 1665 KeyTop top; 1666 1667 shape= XkbKeyShape(xkb->geom,key); 1668 XkbComputeShapeTop(shape,&bounds); 1669 offset+= key->gap; 1670 name= name2= NULL; 1671 if (state->args->label==LABEL_SYMBOLS) { 1672 if (!FindKeysymsByName(xkb,key->name.name,state,&top)) { 1673 fprintf(out,"%% No label for %s\n", 1674 XkbKeyNameText(key->name.name,XkbMessage)); 1675 } 1676 } 1677 else { 1678 char *olKey; 1679 1680 if (section->num_overlays>0) 1681 olKey= XkbFindOverlayForKey(xkb->geom,section, 1682 key->name.name); 1683 else olKey= NULL; 1684 1685 if (state->args->label==LABEL_KEYNAME) { 1686 name= XkbKeyNameText(key->name.name,XkbMessage); 1687 if (olKey) 1688 name2= XkbKeyNameText(olKey,XkbMessage); 1689 } 1690 else if (state->args->label==LABEL_KEYCODE) { 1691 name= buf; 1692 sprintf(name,"%d",XkbFindKeycodeByName(xkb,key->name.name, 1693 True)); 1694 if (olKey) { 1695 name2= buf2; 1696 sprintf(name,"%d",XkbFindKeycodeByName(xkb,olKey,True)); 1697 } 1698 } 1699 bzero(&top,sizeof(KeyTop)); 1700 if (name2!=NULL) { 1701 top.present|= G1LX_MASK; 1702 strncpy(top.label[G1L1],name,LABEL_LEN-1); 1703 top.label[G1L1][LABEL_LEN-1]= '\0'; 1704 strncpy(top.label[G1L2],name2,LABEL_LEN-1); 1705 top.label[G1L2][LABEL_LEN-1]= '\0'; 1706 } 1707 else if (name!=NULL) { 1708 top.present|= CENTER_MASK; 1709 strncpy(top.label[CENTER],name,LABEL_LEN-1); 1710 top.label[CENTER][LABEL_LEN-1]= '\0'; 1711 } 1712 else { 1713 fprintf(out,"%% No label for %s\n", 1714 XkbKeyNameText(key->name.name,XkbMessage)); 1715 } 1716 } 1717 if (row->vertical) { 1718 x= row->left; 1719 y= offset; 1720 offset+= shape->bounds.y2; 1721 } 1722 else { 1723 x= offset; 1724 y= row->top; 1725 offset+= shape->bounds.x2; 1726 } 1727 name= key->name.name; 1728 fprintf(out,"%% %s\n",XkbKeyNameText(name,XkbMessage)); 1729 if (state->args->wantKeycodes) 1730 kc= XkbFindKeycodeByName(xkb,key->name.name,True); 1731 PSLabelKey(out,state,&top,x,y,&bounds,kc,shape->bounds.y2); 1732 } 1733 } 1734 PSGRestore(out,state); 1735 return; 1736} 1737 1738Bool 1739GeometryToPostScript(FILE *out, XkbFileInfo *pResult, XKBPrintArgs *args) 1740{ 1741XkbDrawablePtr first,draw; 1742PSState state; 1743Bool dfltBorder; 1744int i; 1745 1746 if ((!pResult)||(!pResult->xkb)||(!pResult->xkb->geom)) 1747 return False; 1748 state.xkb= pResult->xkb; 1749 state.dpy= pResult->xkb->dpy; 1750 state.geom= pResult->xkb->geom; 1751 state.color= state.black= state.white= -1; 1752 state.font= -1; 1753 state.nPages= 0; 1754 state.totalKB= 1; 1755 state.kbPerPage= 1; 1756 state.x1= state.y1= state.x2= state.y2= 0; 1757 state.args= args; 1758 1759 if ((args->label==LABEL_SYMBOLS)&&(pResult->xkb->ctrls)) { 1760 if (args->nTotalGroups==0) 1761 state.totalKB= pResult->xkb->ctrls->num_groups/args->nLabelGroups; 1762 else state.totalKB= args->nTotalGroups; 1763 if (state.totalKB<1) 1764 state.totalKB= 1; 1765 else if (state.totalKB>1) 1766 state.kbPerPage= 2; 1767 } 1768 if (args->nKBPerPage!=0) 1769 state.kbPerPage= args->nKBPerPage; 1770 1771 PSProlog(out,&state); 1772 first= XkbGetOrderedDrawables(state.geom,NULL); 1773 1774 for (draw=first,dfltBorder=True;draw!=NULL;draw=draw->next) { 1775 if ((draw->type!=XkbDW_Section)&& 1776 ((draw->u.doodad->any.type==XkbOutlineDoodad)|| 1777 (draw->u.doodad->any.type==XkbSolidDoodad))) { 1778 char *name; 1779 name= XkbAtomGetString(state.dpy,draw->u.doodad->any.name); 1780 if ((name!=NULL)&&(uStrCaseEqual(name,"edges"))) { 1781 dfltBorder= False; 1782 break; 1783 } 1784 } 1785 } 1786 for (i=0;i<state.totalKB;i++) { 1787 PSPageSetup(out,&state,dfltBorder); 1788 for (draw=first;draw!=NULL;draw=draw->next) { 1789 if (draw->type==XkbDW_Section) 1790 PSSection(out,&state,draw->u.section); 1791 else { 1792 PSDoodad(out,&state,draw->u.doodad); 1793 } 1794 } 1795 PSPageTrailer(out,&state); 1796 state.args->baseLabelGroup+= state.args->nLabelGroups; 1797 } 1798 XkbFreeOrderedDrawables(first); 1799 PSFileTrailer(out,&state); 1800 return True; 1801} 1802