1 /*
2
3 *****************************************************************************
4 * Author: *
5 * ------ *
6 * Anton Kokalj Email: Tone.Kokalj@ijs.si *
7 * Department of Physical and Organic Chemistry Phone: x 386 1 477 3523 *
8 * Jozef Stefan Institute Fax: x 386 1 477 3811 *
9 * Jamova 39, SI-1000 Ljubljana *
10 * SLOVENIA *
11 * *
12 * Source: $XCRYSDEN_TOPDIR/C/xcFont.c
13 * ------ *
14 * Copyright (c) 1996-2003 by Anton Kokalj *
15 *****************************************************************************
16
17 TODO:
18
19 4. make a routine for mapping TkFont -> XLFD and finding correct
20 normal/bold/medium/oblique/italic/roman
21 */
22
23 #ifndef WIN32
24 # define TOGL_X11
25 # define X11
26 #else
27 # define WIN32_LEAN_AND_MEAN
28 # include <windows.h>
29 # undef WIN32_LEAN_AND_MEAN
30 # include <winnt.h>
31 #endif
32
33 #include <togl.h>
34 #include <assert.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <tcl.h>
39 #include <tk.h>
40 #ifdef WIN32
41 # include <tkPlatDecls.h>
42 #endif
43
44 #ifndef WIN32
45 # include <X11/Xutil.h>
46 #endif
47
48 #include "struct.h"
49 #include "xcGLparam.h"
50 #include "memory.h"
51 #include "xcfunc.h"
52
53 #define XC_FONT_TKYES_XNO 999
54
55 extern GLuint fontOffset;
56 extern RasterFontSize rf;
57 AtomicLabel globalAtomLabel = {
58 0, 0, 0,
59 {1.0, 1.0, 1.0},
60 {0.0, 0.0, 0.0},
61 XC_YES, (char*)NULL, (Tk_Font)NULL
62 };
63 AtomicLabel *atomLabel = (AtomicLabel*)NULL;
64 short *do_not_display_atomlabel = (short*)NULL; /* apply to all kind
65 of labels default
66 and custom */
67
68 struct xcToglFont {
69 char *font;
70 Tk_Font tkfont;
71 GLuint base;
72 int height;
73 int width;
74 struct xcToglFont *prev;
75 };
76 static struct xcToglFont *xcFont, *xcFontPtr = (struct xcToglFont*) NULL;
77
78 typedef struct {
79 char *font;
80 char *string;
81 Tk_Font tkfont;
82 int height;
83 int width;
84 } FontType;
85
86
87 /* xcFont.c */
88 int XC_SetFontCb(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]);
89 int XC_SetAtomLabelCb(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]);
90 int XC_ClearAtomLabelCb(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]);
91 int XC_QueryFontCb(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]);
92 void xcFont_PrintString(const char *s);
93 void xcTkFontFreeAll(void);
94 GLuint Togl_LoadBitmapFontOld(const Togl *togl, const char *fontname);
95 void Togl_UnloadBitmapFontOld(const Togl *togl, GLuint fontbase);
96
97 static void _clearAtomLabel(int atomID);
98 static int _setFontColor(Tcl_Interp *interp, int argc, int bright_ind, const char *bright_argv, int dark_ind, const char *dark_argv, AtomicLabel *alabel);
99 static void xcFont_addNew(struct xcToglFont *f, struct Togl *togl, FontType this);
100 static struct xcToglFont *xcFont_find(char *font);
101 static int _assignFont(int font_found, struct Togl *togl, const char *fontString, FontType thisFont);
102
103
104 /* ------------------------------------------------------------------------
105 *
106 * xc_setfont $togl XLFD_fontname|tkfontname ?bright-fontcolor? ?dark-fontcolor?
107 *
108 * Format of bright-fontcolor & dark-fontcolor is RGB, where the
109 * components are within [0-1].
110 * ------------------------------------------------------------------------ */
111
112 int
XC_SetFontCb(ClientData clientData,Tcl_Interp * interp,int argc,const char * argv[])113 XC_SetFontCb(ClientData clientData, Tcl_Interp *interp,
114 int argc, const char *argv[])
115 {
116 Togl *togl;
117 FontType thisFont;
118 int result, font_found = 0;
119
120 if ( Togl_GetToglFromName(interp, argv[1], &togl) == TCL_ERROR ) {
121 char rss[1024];
122 snprintf(rss, sizeof(rss),
123 "couldn't find %s togl widget", argv[3]);
124 Tcl_SetResult(interp, rss, TCL_VOLATILE);
125 return TCL_ERROR;
126 }
127
128 if (argc < 3 || argc > 5) {
129 char rss[1024];
130 snprintf(rss, sizeof(rss), "wrong number of arguments, should be xc_setfont togl togl_font ?bright-fontcolor? ?dark-fontcolor?");
131 Tcl_SetResult(interp, rss, TCL_VOLATILE);
132 return TCL_ERROR;
133 }
134
135 /* assign the font color first */
136
137 if ( _setFontColor(interp, argc, 3, argv[3], 4, argv[4], &globalAtomLabel) == TCL_ERROR ) {
138 return TCL_ERROR;
139 }
140
141 /* now parse the font-name */
142
143 if (strlen(argv[2]) > 0) {
144 /*
145 int i;
146 for (i=0; i < NFONTS; i++) {
147 if ( strcmp (argv[2], fontType[i].string) == 0 ) {
148 thisFont.font = fontType[i].font;
149 thisFont.height = fontType[i].height;
150 thisFont.width = fontType[i].width;
151 font_found = 1;
152 break;
153 }
154 }
155 */
156
157 result = _assignFont(font_found, togl, argv[2], thisFont);
158 /*fprintf(stderr,"_assignFont = %d\n", result);*/
159 if ( result == TCL_ERROR ) {
160 char rss[1024];
161 snprintf(rss, sizeof(rss), "couldn't load font %s", argv[2]);
162 Tcl_SetResult(interp, rss, TCL_VOLATILE);
163 return TCL_ERROR;
164 } else if ( result == XC_FONT_TKYES_XNO ) {
165 return TCL_OK;
166 } else {
167 /* xcFont should exists by now */
168 if ( !xcFont->base ) {
169 char rss[1024];
170 snprintf(rss, sizeof(rss), "couldn't load font %s", argv[2]);
171 Tcl_SetResult(interp, rss, TCL_VOLATILE);
172 return TCL_ERROR;
173 }
174 }
175
176 /* the font setting was successful, update the globalAtomLabel */
177 globalAtomLabel.base = xcFont->base;
178 globalAtomLabel.tkfont = xcFont->tkfont;
179 globalAtomLabel.height = xcFont->height;
180 globalAtomLabel.width = xcFont->width;
181 globalAtomLabel.do_display = XC_YES;
182
183 /*
184 fprintf(stderr, "FONT-INFO:: (xcFontPtr=%d)\n", xcFontPtr);
185 fprintf(stderr, " base=%d\n tkfont=%d\n h=%d, w=%d\n",
186 xcFont->base, &xcFont->tkfont, xcFont->height, xcFont->width);
187 */
188 }
189
190 Togl_PostRedisplay (togl);
191 return TCL_OK;
192 }
193
194
195 /* ------------------------------------------------------------------------
196
197 xc_setatomlabel togl atomID labelString ?XLFD_fontname? ?bright-fontcolor? ?dark-fontcolor?
198
199 dark-fontcolor == color for ballstick+spacefill for lighting-Off display modes
200 bright-fontcolor == color for the rest of display modes
201
202 ------------------------------------------------------------------------ */
203
204 int
XC_SetAtomLabelCb(ClientData clientData,Tcl_Interp * interp,int argc,const char * argv[])205 XC_SetAtomLabelCb(ClientData clientData, Tcl_Interp *interp,
206 int argc, const char *argv[])
207 {
208 Togl *togl;
209 FontType thisFont;
210 int atomID;
211
212 if ( Togl_GetToglFromName(interp, argv[1], &togl) == TCL_ERROR ) {
213 char rss[1024];
214 snprintf(rss, sizeof(rss),
215 "couldn't find %s togl widget", argv[3]);
216 Tcl_SetResult(interp, rss, TCL_VOLATILE);
217 return TCL_ERROR;
218 }
219
220 if (argc < 4 || argc > 7) {
221 char rss[1024];
222 snprintf(rss, sizeof(rss), "wrong number of arguments, must be xc_setatomlabel togl atomID labelString ?font? ?fontColor1? ?fontColor2?");
223 Tcl_SetResult(interp, rss, TCL_VOLATILE);
224 return TCL_ERROR;
225 }
226
227 if (Tcl_GetInt(interp, argv[2], &atomID) == TCL_ERROR) {
228 char rss[1024];
229 snprintf(rss, sizeof(rss), "wanted integer but got %s", argv[2]);
230 Tcl_SetResult(interp, rss, TCL_VOLATILE);
231 return TCL_ERROR;
232 }
233 if ( atomID < 1 || atomID > natoms ) {
234 char rss[1024];
235 snprintf(rss, sizeof(rss), "atomID %d out of range, should be within [1,%d]", atomID, natoms);
236 Tcl_SetResult(interp, rss, TCL_VOLATILE);
237 return TCL_ERROR;
238 }
239
240 /* copy the atom label */
241 atomLabel[atomID].label = (char*) xcRealloc ( atomLabel[atomID].label, sizeof(char)*((size_t) strlen(argv[3])+1) );
242 strcpy(atomLabel[atomID].label, argv[3]);
243
244 if ( argc >= 5 && strlen(argv[4]) > 0 ) {
245 int result;
246
247 result = _assignFont(0, togl, argv[4], thisFont);
248 /*fprintf(stderr,"_assignFont = %d\n", result);*/
249 if ( result == TCL_ERROR || !xcFont->base) {
250 char rss[1024];
251 snprintf(rss, sizeof(rss), "couldn't load font %s", argv[2]);
252 Tcl_SetResult(interp, rss, TCL_VOLATILE);
253 return TCL_ERROR;
254 } else if ( result == XC_FONT_TKYES_XNO ) {
255 return TCL_OK;
256 }
257
258 /* now assign the font */
259
260 /* fprintf(stderr,"1-base:: %d\n", xcFont->base); */
261
262 atomLabel[atomID].base = xcFont->base;
263 atomLabel[atomID].tkfont = xcFont->tkfont;
264 atomLabel[atomID].height = xcFont->height;
265 atomLabel[atomID].width = xcFont->width;
266 } else if (!xcFontPtr) {
267 /* default font */
268
269 /* fprintf(stderr,"2-base:: %d\n", fontOffset); */
270
271 atomLabel[atomID].base = fontOffset;
272 atomLabel[atomID].tkfont = (Tk_Font)NULL;
273 atomLabel[atomID].height = rf.height;
274 atomLabel[atomID].width = rf.wid;
275 } else {
276 /* assign the last font loaded global font */
277
278 /* fprintf(stderr,"3-base:: %d\n", xcFontPtr->base); */
279
280 atomLabel[atomID].base = xcFontPtr->base;
281 atomLabel[atomID].tkfont = xcFontPtr->tkfont;
282 atomLabel[atomID].height = xcFontPtr->height;
283 atomLabel[atomID].width = xcFontPtr->width;
284 }
285 atomLabel[atomID].do_display = XC_YES;
286
287 /* assign the font color */
288
289 if ( _setFontColor(interp, argc, 5, argv[5], 6, argv[6], atomLabel + atomID) == TCL_ERROR ) {
290 return TCL_ERROR;
291 }
292
293 Togl_PostRedisplay (togl);
294 return TCL_OK;
295 }
296
297
298
299 /* ------------------------------------------------------------------------
300
301 xc_clearatomlabel togl atomID ?atomID? ...
302
303 or
304
305 xc_clearatomlabel togl all
306
307 ------------------------------------------------------------------------ */
308
309 int
XC_ClearAtomLabelCb(ClientData clientData,Tcl_Interp * interp,int argc,const char * argv[])310 XC_ClearAtomLabelCb(ClientData clientData, Tcl_Interp *interp,
311 int argc, const char *argv[])
312 {
313 Togl *togl;
314 int i;
315
316 if ( Togl_GetToglFromName(interp, argv[1], &togl) == TCL_ERROR ) {
317 char rss[1024];
318 snprintf(rss, sizeof(rss),
319 "couldn't find %s togl widget", argv[3]);
320 Tcl_SetResult(interp, rss, TCL_VOLATILE);
321 return TCL_ERROR;
322 }
323
324 if (argc < 3 ) {
325 char rss[1024];
326 snprintf(rss, sizeof(rss), "Usage:\n xc_clearatomlabels togl atomID ?atomID? ...\n or \n togl xc_cleanatomlabels all");
327 Tcl_SetResult(interp, rss, TCL_VOLATILE);
328 return TCL_ERROR;
329 }
330
331 if ( strcmp(argv[2], "all") == 0 ) {
332 /* the "xc_cleanatomlabels all form" */
333 for (i=1; i<=natoms; i++) _clearAtomLabel(i);
334 }
335
336 else {
337 int atomID;
338 for (i=2; i<argc; i++) {
339 if (Tcl_GetInt(interp, argv[i], &atomID) == TCL_ERROR) {
340 char rss[1024];
341 snprintf(rss, sizeof(rss), "wanted integer but got %s", argv[i]);
342 Tcl_SetResult(interp, rss, TCL_VOLATILE);
343 return TCL_ERROR;
344 }
345 if ( atomID < 1 || atomID > natoms ) {
346 char rss[1024];
347 snprintf(rss, sizeof(rss), "atom index %d out of range, should be between [0,%d]",
348 atomID, natoms);
349 Tcl_SetResult(interp, rss, TCL_VOLATILE);
350 return TCL_ERROR;
351 }
352 _clearAtomLabel(atomID);
353 }
354 }
355
356 Togl_PostRedisplay (togl);
357 return TCL_OK;
358 }
359
_clearAtomLabel(int atomID)360 static void _clearAtomLabel(int atomID) {
361 atomLabel[atomID].base = 0;
362 atomLabel[atomID].do_display = XC_NO;
363 xcFree(atomLabel[atomID].label);
364 atomLabel[atomID].label = (char*)NULL;
365 }
366
367
368
369
370 /* ------------------------------------------------------------------------
371 *
372 * $togl xc_queryfont togl XLFD_fontname
373 *
374 * Format of bright-fontcolor & dark-fontcolor is RGB, where the
375 * components are within [0-1].
376 * ------------------------------------------------------------------------ */
377
378 int
XC_QueryFontCb(ClientData clientData,Tcl_Interp * interp,int argc,const char * argv[])379 XC_QueryFontCb(ClientData clientData, Tcl_Interp *interp,
380 int argc, const char *argv[])
381 {
382 Togl *togl;
383 FontType thisFont;
384 int result, font_found = 0;
385
386 if ( Togl_GetToglFromName(interp, argv[1], &togl) == TCL_ERROR ) {
387 char rss[1024];
388 snprintf(rss, sizeof(rss),
389 "couldn't find %s togl widget", argv[3]);
390 Tcl_SetResult(interp, rss, TCL_VOLATILE);
391 return TCL_ERROR;
392 }
393
394 if (argc != 3) {
395 char rss[1024];
396 snprintf(rss, sizeof(rss), "wrong number of arguments, should be xc_queryfont togl XLFD_fontname");
397 Tcl_SetResult(interp, rss, TCL_VOLATILE);
398 return TCL_ERROR;
399 }
400
401 result = _assignFont(font_found, togl, argv[2], thisFont);
402
403 /* fprintf(stderr,"_assignFont = %d\n", result); */
404
405 if ( result == XC_FONT_TKYES_XNO ) {
406 return TCL_OK;
407 } else if ( result == TCL_ERROR ) {
408 char *result = Tcl_Alloc (sizeof(char) * 3);
409 sprintf(result, "-1");
410 Tcl_SetResult(interp, result, TCL_DYNAMIC);
411 } else {
412 /* xcFont should exists by now */
413 if ( xcFont->base ) {
414 char *result = Tcl_Alloc (sizeof(char) * 3);
415 sprintf(result, "+1");
416 Tcl_SetResult(interp, result, TCL_DYNAMIC);
417 } else {
418 char *result = Tcl_Alloc (sizeof(char) * 3);
419 sprintf(result, "-1");
420 Tcl_SetResult(interp, result, TCL_DYNAMIC);
421 }
422 }
423 return TCL_OK;
424 }
425
426
427
xcFont_PrintString(const char * s)428 void xcFont_PrintString (const char *s) {
429 glCallLists( strlen(s), GL_UNSIGNED_BYTE, s );
430 }
431
432
433
xcTkFontFreeAll(void)434 void xcTkFontFreeAll(void) {
435 struct xcToglFont *f = xcFontPtr;
436 while (f) {
437 if (f->tkfont) Tk_FreeFont (f->tkfont);
438 f = f->prev;
439 }
440 }
441
442
443
_setFontColor(Tcl_Interp * interp,int argc,int bright_ind,const char * bright_argv,int dark_ind,const char * dark_argv,AtomicLabel * alabel)444 static int _setFontColor(Tcl_Interp *interp, int argc,
445 int bright_ind, const char *bright_argv,
446 int dark_ind, const char *dark_argv, AtomicLabel *alabel) {
447 GetGlParam bright, dark;
448
449 if ( argc > bright_ind && strlen(bright_argv) > 0 ) {
450 if ( ! xcSplitList( XC_GET_RGB, interp, &bright_argv, &bright ) ) {
451 char rss[1024];
452 snprintf(rss, sizeof(rss), "error parsing bright font color, should be {red green blue}, but got %s", bright_argv);
453 Tcl_SetResult(interp, rss, TCL_VOLATILE);
454 return TCL_ERROR;
455 }
456 COPY_V(3, alabel->bright_color, bright.vec);
457 }
458
459 if ( argc > dark_ind && strlen(dark_argv) > 0 ) {
460 if ( ! xcSplitList( XC_GET_RGB, interp, &dark_argv, &dark ) ) {
461 char rss[1024];
462 snprintf(rss, sizeof(rss), "error parsing dark font color, should be {red green blue}, but got %s", dark_argv);
463 Tcl_SetResult(interp, rss, TCL_VOLATILE);
464 return TCL_ERROR;
465 }
466 COPY_V(3, alabel->dark_color, dark.vec);
467 }
468
469 return TCL_OK;
470 }
471
472
xcFont_addNew(struct xcToglFont * f,struct Togl * togl,FontType this)473 static void xcFont_addNew(struct xcToglFont *f, struct Togl *togl, FontType this) {
474 f->font = this.font;
475 f->base = Togl_LoadBitmapFontOld (togl, this.font);
476 /*fprintf(stderr, "f->base==%d\n", f->base);*/
477 f->tkfont = this.tkfont;
478 f->height = this.height;
479 f->width = this.width;
480 f->prev = xcFontPtr;
481
482 xcFontPtr = f;
483 }
484
485
xcFont_find(char * font)486 static struct xcToglFont *xcFont_find(char *font) {
487 struct xcToglFont *f = xcFontPtr;
488 while (f) {
489 /*fprintf(stderr, "f: %s %s\n", font, f->font);*/
490 if (strcmp(font,f->font) == 0) return f;
491 f = f->prev;
492 }
493 return (struct xcToglFont*) NULL;
494 }
495
496
497
498 #ifdef WIN32
499
500 /*
501 * The following structure represents Windows' implementation of a font.
502 */
503
504 typedef struct {
505 Tk_Font font; /* Stuff used by generic font package. Must
506 * be first in structure. */
507 HFONT hFont; /* Windows information about font. */
508 HWND hwnd; /* Toplevel window of application that owns
509 * this font, used for getting HDC. */
510 int widths[256]; /* Widths of first 256 chars in this font. */
511 } WinFont;
512
513 #include "togl_struct.h"
514 #endif /* WIN32 */
515
516
517 static int
_assignFont(int font_found,struct Togl * togl,const char * fontString,FontType thisFont)518 _assignFont(int font_found, struct Togl *togl, const char *fontString, FontType thisFont)
519 {
520 struct xcToglFont *_font;
521
522 #ifndef WIN32
523 /* X11 */
524 XFontStruct *fontinfo;
525 #else
526 /* WIN32 */
527 WinFont *winfont;
528 TEXTMETRIC tm;
529 #endif
530
531 if (!font_found) {
532 Tcl_Interp *interp = Togl_Interp(togl);
533 /*
534 use the Tk-wrapper to prevent segmentation-fault of XLoadQueryFont
535 when font-name is invalid
536 */
537 Tk_Font tkfont;
538
539 tkfont = Tk_GetFont(interp, Togl_TkWin(togl), fontString);
540 /*fprintf(stderr,"*** _assignFont: tkfont == %d\n", tkfont);*/
541 if (!tkfont) {
542 return TCL_ERROR;
543 }
544 /*_font = Tk_NameOfFont (tkfont);*/
545 #ifndef WIN32
546 /* X11 */
547 fontinfo = (XFontStruct *) XLoadQueryFont( Tk_Display(Togl_TkWin(togl)), fontString );
548 if (!fontinfo) {
549 char *result = Tcl_Alloc (sizeof(char) * 3);
550 sprintf(result, "-1");
551 Tk_FreeFont (tkfont);
552 Tcl_SetResult(interp, result, TCL_DYNAMIC);
553 return XC_FONT_TKYES_XNO;
554 }
555
556 thisFont.height = fontinfo->max_bounds.ascent - fontinfo->max_bounds.descent;
557 thisFont.width = fontinfo->max_bounds.rbearing - fontinfo->max_bounds.lbearing;
558 #else
559 /* WIN32 */
560
561 /*HFONT oldFont;*/
562 /*oldFont = SelectObject(togl->tglGLHdc, winfont->hFont);*/
563
564 winfont = (WinFont*) tkfont;
565 if (!winfont) {
566 return 0;
567 }
568
569 SelectObject(togl->tglGLHdc, winfont->hFont);
570 GetTextMetrics(togl->tglGLHdc, &tm);
571 /*fontString = Tk_NameOfFont(tkfont);
572 fprintf(stderr,"FONT-STRING: %s\n", fontString);*/
573 thisFont.height = tm.tmHeight - tm.tmInternalLeading;
574 thisFont.width = tm.tmAveCharWidth;
575 #endif
576
577 thisFont.font = (char*) xcMalloc(sizeof(char) * (strlen(fontString)+1));
578 strcpy(thisFont.font, fontString);
579 thisFont.tkfont = tkfont;
580 }
581
582 /* now find if the font was already loaded */
583
584 _font = xcFont_find(thisFont.font);
585 /*fprintf(stderr,"Font12: %d , %s\n", _font, thisFont.font); fflush(stderr);*/
586
587 if ( !_font ) {
588 /* the font was not yet loaded */
589 xcFont = (struct xcToglFont *) xcMalloc ( sizeof (struct xcToglFont) );
590 xcFont_addNew (xcFont, togl, thisFont);
591 } else {
592 /* the font was already loaded */
593 xcFont = _font;
594 }
595 return TCL_OK;
596 }
597
598
599
600
601 /* ------------------------------------------------------------------------ */
602
603
604
605
606 /*
607 The Togl_LoadBitmapFont() of Togl2.0 is bad as it seg-faults. Hence
608 we will use the routine from Togl-1.7 which works and rename it to
609 Togl_LoadBitmapFontOld. But to this end we need the definition of
610 the struct Togl.
611 */
612 #include "GL/glx.h"
613
614 struct Togl_PackageGlobals
615 {
616 Tk_OptionTable optionTable; /* Used to parse options */
617 Togl *toglHead; /* Head of linked list of all Togl widgets */
618 int nextContextTag; /* Used to assign similar context tags */
619 };
620 typedef struct Togl_PackageGlobals Togl_PackageGlobals;
621
622 struct Togl
623 {
624 Togl *Next; /* next in linked list */
625
626 #if defined(TOGL_WGL)
627 HDC tglGLHdc; /* Device context of device that OpenGL calls
628 * will be drawn on */
629 HGLRC tglGLHglrc; /* OpenGL rendering context to be made current */
630 int CiColormapSize; /* (Maximum) size of colormap in color index
631 * mode */
632 # ifdef STEREO_I_H
633 StereoI *pStereoI;
634 # endif
635 #elif defined(TOGL_X11)
636 GLXContext GlCtx; /* Normal planes GLX context */
637 #elif defined(TOGL_AGL)
638 AGLContext aglCtx;
639 #endif
640 int contextTag; /* all contexts with same tag share display
641 * lists */
642
643 XVisualInfo *VisInfo; /* Visual info of the current */
644
645 Display *display; /* X's token for the window's display. */
646 Tk_Window TkWin; /* Tk window structure */
647 Tcl_Interp *Interp; /* Tcl interpreter */
648 Tcl_Command widgetCmd; /* Token for togl's widget command */
649 Togl_PackageGlobals *tpg; /* Used to access globals */
650 #ifndef NO_TK_CURSOR
651 Tk_Cursor Cursor; /* The widget's cursor */
652 #endif
653 int Width, Height; /* Dimensions of window */
654 int SetGrid; /* positive is grid size for window manager */
655 int TimerInterval; /* Time interval for timer in milliseconds */
656 Tcl_TimerToken timerHandler; /* Token for togl's timer handler */
657 Bool RgbaFlag; /* configuration flags (ala GLX parameters) */
658 int RgbaRed;
659 int RgbaGreen;
660 int RgbaBlue;
661 Bool DoubleFlag;
662 Bool DepthFlag;
663 int DepthSize;
664 Bool AccumFlag;
665 int AccumRed;
666 int AccumGreen;
667 int AccumBlue;
668 int AccumAlpha;
669 Bool AlphaFlag;
670 int AlphaSize;
671 Bool StencilFlag;
672 int StencilSize;
673 Bool PrivateCmapFlag;
674 Bool OverlayFlag;
675 int Stereo;
676 double EyeSeparation;
677 double Convergence;
678 int AuxNumber;
679 Bool Indirect;
680 int PixelFormat;
681 int SwapInterval;
682 const char *ShareList; /* name (ident) of Togl to share dlists with */
683 const char *ShareContext; /* name (ident) to share OpenGL context with */
684
685 const char *Ident; /* User's identification string */
686 ClientData Client_Data; /* Pointer to user data */
687
688 Bool UpdatePending; /* Should normal planes be redrawn? */
689
690 Tcl_Obj *CreateProc; /* Callback when widget is realized */
691 Tcl_Obj *DisplayProc; /* Callback when widget is redrawn */
692 Tcl_Obj *ReshapeProc; /* Callback when window size changes */
693 Tcl_Obj *DestroyProc; /* Callback when widget is destroyed */
694 Tcl_Obj *TimerProc; /* Callback when widget is idle */
695
696 /* Overlay stuff */
697 #if defined(TOGL_X11)
698 GLXContext OverlayCtx; /* Overlay planes OpenGL context */
699 #elif defined(TOGL_WGL)
700 HGLRC tglGLOverlayHglrc;
701 #endif
702
703 Window OverlayWindow; /* The overlay window, or 0 */
704 Tcl_Obj *OverlayDisplayProc; /* Overlay redraw proc */
705 Bool OverlayUpdatePending; /* Should overlay be redrawn? */
706 Colormap OverlayCmap; /* colormap for overlay is created */
707 int OverlayTransparentPixel; /* transparent pixel */
708 Bool OverlayIsMapped;
709
710 GLfloat *EpsRedMap; /* Index2RGB Maps for Color index modes */
711 GLfloat *EpsGreenMap;
712 GLfloat *EpsBlueMap;
713 GLint EpsMapSize; /* = Number of indices in our Togl */
714 int currentStereoBuffer;
715 #ifdef HAVE_AUTOSTEREO
716 int as_initialized; /* for autostereo package */
717 ASHandle ash; /* for autostereo package */
718 #endif
719 int badWindow; /* true when Togl_CreateWindow fails */
720 };
721
722 # if defined(TOGL_WGL)
723 # include "tkWinInt.h"
724 # include "tkFont.h"
725
726 /*
727 * The following structure represents Windows' implementation of a font.
728 */
729
730 typedef struct WinFont
731 {
732 TkFont font; /* Stuff used by generic font package. Must be
733 * first in structure. */
734 HFONT hFont; /* Windows information about font. */
735 HWND hwnd; /* Toplevel window of application that owns
736 * this font, used for getting HDC. */
737 int widths[256]; /* Widths of first 256 chars in this font. */
738 } WinFont;
739 # endif /* TOGL_WGL */
740
741
742 # define MAX_FONTS 1000
743 static GLuint ListBase[MAX_FONTS];
744 static GLuint ListCount[MAX_FONTS];
745
746 /*
747 * "Standard" fonts which can be specified to Togl_LoadBitmapFontOld()
748 */
749 #undef TOGL_BITMAP_8_BY_13
750 #undef TOGL_BITMAP_9_BY_15
751 #undef TOGL_BITMAP_TIMES_ROMAN_10
752 #undef TOGL_BITMAP_TIMES_ROMAN_24
753 #undef TOGL_BITMAP_HELVETICA_10
754 #undef TOGL_BITMAP_HELVETICA_12
755 #undef TOGL_BITMAP_HELVETICA_18
756 #define TOGL_BITMAP_8_BY_13 ((char *) 1)
757 #define TOGL_BITMAP_9_BY_15 ((char *) 2)
758 #define TOGL_BITMAP_TIMES_ROMAN_10 ((char *) 3)
759 #define TOGL_BITMAP_TIMES_ROMAN_24 ((char *) 4)
760 #define TOGL_BITMAP_HELVETICA_10 ((char *) 5)
761 #define TOGL_BITMAP_HELVETICA_12 ((char *) 6)
762 #define TOGL_BITMAP_HELVETICA_18 ((char *) 7)
763 #define DEFAULT_FONTNAME "fixed"
764
765 /*
766 * Load the named bitmap font as a sequence of bitmaps in a display list.
767 * fontname may be one of the predefined fonts like TOGL_BITMAP_8_BY_13
768 * or an X font name, or a Windows font name, etc.
769 */
770 GLuint
Togl_LoadBitmapFontOld(const Togl * togl,const char * fontname)771 Togl_LoadBitmapFontOld(const Togl *togl, const char *fontname)
772 {
773 static Bool FirstTime = True;
774
775 # if defined(TOGL_X11)
776 XFontStruct *fontinfo;
777 # elif defined(TOGL_WGL)
778 WinFont *winfont;
779 HFONT oldFont;
780 TEXTMETRIC tm;
781 # endif
782 /* TOGL_X11 */
783 int first, last, count;
784 GLuint fontbase;
785 const char *name;
786
787 /* Initialize the ListBase and ListCount arrays */
788 if (FirstTime) {
789 int i;
790
791 for (i = 0; i < MAX_FONTS; i++) {
792 ListBase[i] = ListCount[i] = 0;
793 }
794 FirstTime = False;
795 }
796
797 /*
798 * This method of selecting X fonts according to a TOGL_ font name
799 * is a kludge. To be fixed when I find time...
800 */
801 if (fontname == TOGL_BITMAP_8_BY_13) {
802 name = "8x13";
803 } else if (fontname == TOGL_BITMAP_9_BY_15) {
804 name = "9x15";
805 } else if (fontname == TOGL_BITMAP_TIMES_ROMAN_10) {
806 name = "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1";
807 } else if (fontname == TOGL_BITMAP_TIMES_ROMAN_24) {
808 name = "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1";
809 } else if (fontname == TOGL_BITMAP_HELVETICA_10) {
810 name = "-adobe-helvetica-medium-r-normal--10-100-75-75-p-57-iso8859-1";
811 } else if (fontname == TOGL_BITMAP_HELVETICA_12) {
812 name = "-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1";
813 } else if (fontname == TOGL_BITMAP_HELVETICA_18) {
814 name = "-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1";
815 } else if (!fontname) {
816 name = DEFAULT_FONTNAME;
817 } else {
818 name = (const char *) fontname;
819 }
820
821 assert(name);
822
823 # if defined(TOGL_X11)
824 fontinfo = (XFontStruct *) XLoadQueryFont(Tk_Display(togl->TkWin), name);
825 if (!fontinfo) {
826 return 0;
827 }
828 first = fontinfo->min_char_or_byte2;
829 last = fontinfo->max_char_or_byte2;
830 # elif defined(TOGL_WGL)
831 winfont = (WinFont *) Tk_GetFont(togl->Interp, togl->TkWin, name);
832 if (!winfont) {
833 return 0;
834 }
835 oldFont = SelectObject(togl->tglGLHdc, winfont->hFont);
836 GetTextMetrics(togl->tglGLHdc, &tm);
837 first = tm.tmFirstChar;
838 last = tm.tmLastChar;
839 # elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL)
840 first = 10; /* don't know how to determine font range on
841 * Mac... */
842 last = 127;
843 # endif
844 /* TOGL_X11 */
845
846 count = last - first + 1;
847 fontbase = glGenLists((GLuint) (last + 1));
848 if (fontbase == 0) {
849 # ifdef TOGL_WGL
850 SelectObject(togl->tglGLHdc, oldFont);
851 Tk_FreeFont((Tk_Font) winfont);
852 # endif
853 /* TOGL_WGL */
854 return 0;
855 }
856 # if defined(TOGL_WGL)
857 wglUseFontBitmaps(togl->tglGLHdc, first, count, (int) fontbase + first);
858 SelectObject(togl->tglGLHdc, oldFont);
859 Tk_FreeFont((Tk_Font) winfont);
860 # elif defined(TOGL_X11)
861 glXUseXFont(fontinfo->fid, first, count, (int) fontbase + first);
862 # elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL)
863 aglUseFont(togl->aglCtx, 1, 0, 14, /* for now, only app font, regular
864 * 14-point */
865 10, 118, fontbase + first);
866 # endif
867
868 /* Record the list base and number of display lists for
869 * Togl_UnloadBitmapFont(). */
870 {
871 int i;
872
873 for (i = 0; i < MAX_FONTS; i++) {
874 if (ListBase[i] == 0) {
875 ListBase[i] = fontbase;
876 ListCount[i] = last + 1;
877 break;
878 }
879 }
880 }
881
882 return fontbase;
883 }
884
885
886
887 /*
888 * Release the display lists which were generated by Togl_LoadBitmapFontOld().
889 */
890 void
Togl_UnloadBitmapFontOld(const Togl * togl,GLuint fontbase)891 Togl_UnloadBitmapFontOld(const Togl *togl, GLuint fontbase)
892 {
893 int i;
894
895 (void) togl;
896 for (i = 0; i < MAX_FONTS; i++) {
897 if (ListBase[i] == fontbase) {
898 glDeleteLists(ListBase[i], ListCount[i]);
899 ListBase[i] = ListCount[i] = 0;
900 return;
901 }
902 }
903 }
904
905
906