1 /****************************************************************************
2     Copyright (C) 1987-2015 by Jeffery P. Hansen
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 
18     Last edit by hansen on Tue Jan 20 14:47:22 2009
19 ****************************************************************************/
20 #include <stdlib.h>
21 #include "tkgate.h"
22 #include <X11/Xutil.h>
23 
24 #define DEBUG_ICON 0
25 
26 static SHash *icon_pixmaps = 0;			/* Table of pixmaps used for gate icons */
27 static NHash *zoomed_pixmaps = 0;		/* Table of zoomed versions of icon_pixmaps */
28 
init_iconTables(void)29 void init_iconTables(void)
30 {
31   icon_pixmaps = new_SHash_noob();
32   zoomed_pixmaps = new_NHash_noob();
33 }
34 
Pixmap_initZoomSet(Pixmap p,int w,int h)35 void Pixmap_initZoomSet(Pixmap p,int w,int h)
36 {
37   int i;
38   PixmapZoomSet *zset;
39 
40   zset = (PixmapZoomSet*)malloc(sizeof(PixmapZoomSet));
41   for (i = 0;i < ZOOM_MAX+1;i++)
42     zset->p[i] = 0;
43   zset->p[1] = p;
44   zset->width = w;
45   zset->height = h;
46   NHash_insert(zoomed_pixmaps,p,zset);
47 }
48 
Pixmap_deleteZoomSet(Pixmap p)49 void Pixmap_deleteZoomSet(Pixmap p)
50 {
51   PixmapZoomSet *zset;
52   int i;
53 
54   zset = (PixmapZoomSet*)NHash_find(zoomed_pixmaps,p);
55   if (!zset) return;
56 
57   NHash_remove(zoomed_pixmaps,p);
58 
59   for (i = 0;i < ZOOM_MAX+1;i++)
60     if (zset->p[i]) {
61       printf("XFreePixmap(%x)\n",(unsigned)zset->p[i]);
62       XFreePixmap(TkGate.D,zset->p[i]);
63     }
64   free(zset);
65 }
66 
Pixmap_register(char * name,unsigned char data[],unsigned w,unsigned h)67 Pixmap Pixmap_register(char *name,unsigned char data[],unsigned w,unsigned h)
68 {
69   Pixmap *P;
70 
71   if (!TkGate.tcl) return None;
72 
73   if (SHash_find(icon_pixmaps,name))
74     return None;
75 
76   P = (Pixmap*) malloc(sizeof(Pixmap));
77   *P = XCreatePixmapFromBitmapData(TkGate.D,TkGate.root,(char*)data,w,h,1,0,1);
78   SHash_insert(icon_pixmaps,name,P);
79   Pixmap_initZoomSet(*P,w,h);
80 
81   return *P;
82 }
83 
Pixmap_registerFromFileWithParms(char * name,char * file,int * pw,int * ph,int * px,int * py)84 Pixmap Pixmap_registerFromFileWithParms(char *name,char *file,int *pw,int *ph,int *px,int *py)
85 {
86   static const char *base_dir = 0;
87   Pixmap *P;
88   unsigned w,h;
89   int x,y;
90   char buf[STRMAX];
91 
92   if (!TkGate.tcl) return None;
93 
94 
95   if (!base_dir) {
96     base_dir = Tcl_GetVar(TkGate.tcl,"bd",TCL_GLOBAL_ONLY);
97     if (!base_dir) base_dir = "images";
98   }
99 
100   sprintf(buf,"%s/%s",base_dir,file);
101 
102   if (SHash_find(icon_pixmaps,name))
103     return None;
104 
105   P = (Pixmap*) malloc(sizeof(Pixmap));
106 
107   if (XReadBitmapFile(TkGate.D,TkGate.root,buf,&w,&h,P,&x,&y) != BitmapSuccess) {
108     fprintf(stderr,"Failed to find required bitmap '%s'\n",buf);
109     exit(1);
110     return None;
111   }
112 
113   SHash_insert(icon_pixmaps,name,P);
114   Pixmap_initZoomSet(*P,w,h);
115 
116   if (pw) *pw = w;
117   if (ph) *ph = h;
118   if (px) *px = x;
119   if (py) *py = y;
120 
121   return *P;
122 }
123 
Pixmap_registerFromFile(char * name,char * file)124 Pixmap Pixmap_registerFromFile(char *name,char *file)
125 {
126   return Pixmap_registerFromFileWithParms(name,file,0,0,0,0);
127 }
128 
Pixmap_find(char * name)129 Pixmap Pixmap_find(char *name)
130 {
131   Pixmap *P = (Pixmap*) SHash_find(icon_pixmaps,name);
132 
133   if (!P) return None;
134 
135   return *P;
136 }
137 
138 /*
139  * Create a copy of pixmap p magnified by scale factor zp
140  */
Pixmap_createZoomPixmap(Pixmap p,int w,int h,int zp)141 Pixmap Pixmap_createZoomPixmap(Pixmap p,int w,int h,int zp)
142 {
143   XImage *SI = XGetImage(TkGate.D,p,0,0,w,h,0x1,XYPixmap);
144   Pixmap DP = XCreatePixmap(TkGate.D,TkGate.root,zp*w,zp*h,1);
145   XImage *DI = XGetImage(TkGate.D,DP,0,0,zp*w,zp*h,0x1,XYPixmap);
146   int x,y;
147 
148   for (x = 0;x < w;x++) {
149     for (y = 0;y < h;y++) {
150       int v = XGetPixel(SI,x,y);
151       int a,b;
152 
153       for (a = 0;a < zp;a++)
154 	for (b = 0;b < zp;b++)
155 	  XPutPixel(DI,x*zp+a,y*zp+b,v);
156     }
157   }
158 
159   XPutImage(TkGate.D,DP,TkGate.bitGC,DI,0,0,0,0,zp*w,zp*h);
160 
161   XDestroyImage(DI);
162   XDestroyImage(SI);
163 
164   return DP;
165 }
166 
167 /*
168  * Find and/or create zoomed pixmap
169  */
Pixmap_zoom(Pixmap p,int z)170 Pixmap Pixmap_zoom(Pixmap p,int z)
171 {
172   PixmapZoomSet *zset;
173   if (z == 1) return p;
174 
175   zset = (PixmapZoomSet*)NHash_find(zoomed_pixmaps,p);
176   if (!zset) return None;
177   if (!zset->p[z]) {
178     zset->p[z] = Pixmap_createZoomPixmap(p,zset->width,zset->height,z);
179   }
180 
181   return zset->p[z];
182 }
183 
new_Icon(Pixmap P,int x,int y,int w,int h,int ox,int oy)184 Icon *new_Icon(Pixmap P,int x,int y,int w,int h,int ox,int oy)
185 {
186   Icon *I = (Icon*) malloc(sizeof(Icon));
187 
188   I->pm = P;
189   I->x = x;
190   I->y = y;
191   I->width = w;
192   I->height = h;
193   I->ox = ox;
194   I->oy = oy;
195 
196 #if DEBUG_ICON
197   printf("create icon [%p p=(%d,%d) %dx%d o=(%d,%d) ]\n",
198 	 I->pm,I->x,I->y,I->width,I->height,I->ox,I->oy);
199 #endif
200   return I;
201 }
202 
new_IconID(Pixmap P,iconDimensions * id,int yoffset)203 Icon *new_IconID(Pixmap P,iconDimensions *id,int yoffset)
204 {
205   return new_Icon(P,id->x,id->y+yoffset,id->w,id->h,id->ox,id->oy);
206 }
207 
Icon_draw(Display * D,Window W,GC gc,int x,int y,Icon * I)208 void Icon_draw(Display *D,Window W,GC gc,int x,int y,Icon *I)
209 {
210 #if DEBUG_ICON
211   printf("draw icon [%p p=(%d,%d) %dx%d o=(%d,%d) ] @(%d, %d) \n",
212 	 I->pm,I->x,I->y,I->width,I->height,I->ox,I->oy,x,y);
213 #endif
214   ZCopyPlane(D,I->pm,W,gc,I->x,I->y,I->width,I->height,x-I->ox,y-I->oy,0x1);
215 }
216 
217