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