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 Sat Sep 26 14:30:18 2009
19 ****************************************************************************/
20 
21 #include "tkgate.h"
22 #include "print.h"
23 
24 #define LED_IN 0
25 
26 #define MAXDIGITS	12
27 
28 #define LT_BASIC	0
29 #define LT_BAR		1
30 #define LT_HEX		2
31 #define LT_DEC		3
32 #define LT_SEG		4
33 
34 static iconDimensions led_iconDims[] = {
35   {0,  0,  13, 14, 6, 7},
36   {14, 0,  14, 13, 7, 6},
37   {15, 14, 13, 14, 6, 6},
38   {0,  15, 14, 13, 6, 6},
39 };
40 static int led_iconBoldOffset = 29;
41 
42 GCElement *Led_Make(EditState **,GModuleDef *,int,int,int,int,const char *,int,const char**,int);
43 void Led_GetExtents(GCElement *g,TargetDev_e,int *minx,int *miny,int *maxx,int *maxy,int *bd);
44 void Led_Draw(GCElement *g,int md);
45 void Led_VerSave(FILE*,GCElement*);
46 void Led_SetProp(GCElement*,const char*,const void*);
47 int Led_EditProps(GCElement *g,int isLoadDialog);
48 void Led_PSWrite(GPrint *P,GModLayout*,GCElement *g);
49 GCElement *Led_Copy(GModuleDef *M,GCElement *g,int x,int y,unsigned flags);
50 
51 GPadLoc led_in_loc[] = {		/* Control line */
52  {0,7,0,7,D_DOWN},
53  {7,0,7,0,D_RIGHT},
54  {0,-7,0,-7,D_UP},
55  {-7,0,-7,0,D_LEFT}};
56 
57 static char *psLed[] = {
58   "%",
59   "% An LED (bit)",
60   "%",
61   "/psled_bit {",
62   "  startgate",
63   "  -5 -7 moveto",
64   "  5 -7 lineto",
65   "  5 0 lineto",
66   "  0 0 5 0 180 arc",
67   "  closepath",
68   "  gsave .8 setgray fill grestore",
69   "  stroke",
70   "  grestore",
71   "} bind def",
72   "%",
73   "% Single bar graph segment",
74   "%",
75   "/psled_barseg {",
76   "  gsave",
77   "  3 -13 translate",
78   "  3 10 pbox ",
79   "  gsave .8 setgray fill grestore",
80   "  stroke",
81   "  grestore",
82   "} def",
83   "%",
84   "% An LED (bar graph)",
85   "%",
86   "/psled_bar {",
87   "  startgate",
88   "  neg 0 0 4 2 roll box",
89   "  1 1 3 -1 roll { psled_barseg 5 0 translate } for",
90   "  grestore",
91   "} bind def",
92   "%",
93   "% Single 7-segment digit",
94   "%",
95   "/psled_7segdig {",
96   "  gsave",
97   "  2 setlinewidth",
98   "  0 -27 translate",
99   "  5 0 17 0 line",
100   "  5 11 17 11 line",
101   "  5 22 17 22 line",
102   "",
103   "  4 1 4 10 line",
104   "  18 1 18 10 line",
105   "  4 12 4 21 line",
106   "  18 12 18 21 line",
107   "  grestore",
108   "} def",
109   "%",
110   "% An LED (7 segment)",
111   "%",
112   "/psled_7seg {",
113   "  startgate",
114   "  neg 0 0 4 2 roll box",
115   "  1 1 3 -1 roll { psled_7segdig 20 0 translate } for",
116   "  grestore",
117   "} bind def",
118   0
119 };
120 
121 GGateInfo gate_led_info = {
122   GC_LED,
123   "LED",
124   "led",0x0,
125   "psled",psLed,
126   -1,0,
127 
128  { {"l",	{"gm.io",0},		{"gm.io.led",0,"led",100},	"gat_make LED -type basic"},
129    {"L 1",	{0,0},			{0,0,0,0},			"gat_make LED -type bar -bits 1"},
130    {"L 2",	{0,0},			{0,0,0,0},			"gat_make LED -type bar -bits 2"},
131    {"L 3",	{0,0},			{0,0,0,0},			"gat_make LED -type bar -bits 3"},
132    {"L 4",	{0,0},			{0,0,0,0},			"gat_make LED -type bar -bits 4"},
133    {"L 5",	{0,0},			{0,0,0,0},			"gat_make LED -type bar -bits 5"},
134    {"L 6",	{0,0},			{0,0,0,0},			"gat_make LED -type bar -bits 6"},
135    {"L 7",	{0,0},			{0,0,0,0},			"gat_make LED -type bar -bits 7"},
136    {"L 8",	{"gm.io",0},		{"gm.io.ledbar",0,"led",200},	"gat_make LED -type bar -bits 8"},
137    {"L 9",	{0,0},			{0,0,0,0},			"gat_make LED -type bar -bits 9"},
138    {"L h",	{"gm.io",0},		{"gm.io.ledhex",0,"led",300},	"gat_make LED -type hex -bits 8"},
139    {"L d",	{"gm.io",0},		{"gm.io.leddec",0,"led",400},	"gat_make LED -type dec -bits 8"},
140    {"L s",	{"gm.io",0},		{"gm.io.ledseg",0,"led",500},	"gat_make LED -type seg -bits 7"},
141    {0}},
142 
143   led_iconDims,
144 
145   1,{{"I",IN,1,1,led_in_loc,0}},
146   {{0,-12,CT},{-12,3,RJ},{0,18,CT},{12,3,LJ}},
147   {1,1,0,0,0},
148 
149   {0},
150 
151   Led_Make,
152   Nop_WriteCellDef,
153   Generic_Init,
154   Generic_Delete,
155   Led_GetExtents,
156   Generic_HitDistance,
157   Led_Draw,
158   Generic_Move,
159   Led_Copy,
160   Generic_AddInput,
161   Err_AddOutput,
162   Err_AddInOut,
163   Generic_Rotate,
164   Err_RemovePort,
165   Err_ChangePin,
166   Nop_SimInitFunc,
167   Nop_SimHitFunc,
168   Led_PSWrite,
169   Led_EditProps,
170   Led_VerSave,
171   Led_SetProp
172 };
173 
174 
175 Icon *inled_icon[8];	/* Special icons for 'light' part of led. */
176 Icon *seg_icon[7];	/* Icons for 7-segment display */
177 
Led_Make(EditState ** es,GModuleDef * env,int GType,int x,int y,int r,const char * Name,int noWires,const char ** options,int nOptions)178 GCElement *Led_Make(EditState **es,GModuleDef *env,int GType,
179 			int x,int y,int r,const char *Name,int noWires,const char **options,int nOptions)
180 {
181   GCElement *g = Generic_Make(es,env,GType,x,y,r,Name,noWires,options,nOptions);
182   const char *LType,*NBits;
183   int n;
184 
185   ob_touch(g);
186 
187   g->u.led.ltype = LT_BASIC;
188   g->u.led.value = 0;
189   g->u.led.valid = ~0;
190   n = 1;
191 
192   LType = seekOption("-type",options,nOptions);
193   NBits = seekOption("-bits",options,nOptions);
194 
195   if (LType) {
196     if (strcmp(LType,"basic") == 0)
197       g->u.led.ltype = LT_BASIC;
198     else if (strcmp(LType,"hex") == 0)
199       g->u.led.ltype = LT_HEX;
200     else if (strcmp(LType,"dec") == 0)
201       g->u.led.ltype = LT_DEC;
202     else if (strcmp(LType,"bar") == 0)
203       g->u.led.ltype = LT_BAR;
204     else if (strcmp(LType,"seg") == 0)
205       g->u.led.ltype = LT_SEG;
206   }
207 
208   if (NBits) {
209     sscanf(NBits,"%d",&n);
210     if (n < 1) n = 1;
211     if (n > 32) n = 32;
212   }
213 
214   if (!noWires)
215     net_setSize(g->wires[LED_IN]->net,n);
216 
217   return g;
218 }
219 
220 /*
221  * Returns number of decimal digits required to display an n-bit number.
222  */
decDigits(unsigned n)223 static unsigned decDigits(unsigned n)
224 {
225 
226   unsigned m;
227 
228   if (n < 32)
229     m = (1 << n) - 1;
230   else
231     m = 0xffffffff;
232 
233   n = 0;
234   while (m > 0) {
235     m /= 10;
236     n++;
237   }
238   if (!n) n = 1;
239 
240   return n;
241 }
242 
243 /*
244  * Returns number of 7-seg digits.
245  */
numDigits(GCElement * g)246 static unsigned numDigits(GCElement *g)
247 {
248   unsigned n = g->wires[LED_IN]->net->n_nbits;
249 
250   switch (g->u.led.ltype) {
251   case LT_HEX :
252   default :
253     n = (n+3)/4;
254     break;
255   case LT_SEG :
256     n = (n+6)/7;
257     break;
258   case LT_DEC :
259     n = decDigits(n);
260     break;
261   }
262 
263   return n;
264 }
265 
266 /*
267  *    _1
268  *  2| |3
269  *    -4
270  *  5| |6
271  *    _7
272  */
getLedSegments(GCElement * g,unsigned * seg_value,unsigned * seg_valid,unsigned * n)273 static void getLedSegments(GCElement *g,unsigned *seg_value,unsigned *seg_valid,unsigned *n)
274 {
275 #define S(n) (1 << (n-1))
276   static unsigned seg_data[] = {
277     S(1)|S(2)|S(3)|S(5)|S(6)|S(7),		/* 0 */
278     S(3)|S(6),					/* 1 */
279     S(1)|S(3)|S(4)|S(5)|S(7),			/* 2 */
280     S(1)|S(3)|S(4)|S(6)|S(7),			/* 3 */
281     S(2)|S(4)|S(3)|S(6),			/* 4 */
282     S(1)|S(2)|S(4)|S(6)|S(7),			/* 5 */
283     S(1)|S(2)|S(4)|S(5)|S(6)|S(7),		/* 6 */
284     S(1)|S(3)|S(6),				/* 7 */
285     S(1)|S(2)|S(3)|S(4)|S(5)|S(6)|S(7),		/* 8 */
286     S(1)|S(2)|S(3)|S(4)|S(6),			/* 9 */
287     S(1)|S(2)|S(3)|S(4)|S(5)|S(6),		/* A */
288     S(2)|S(4)|S(5)|S(6)|S(7),			/* b */
289     S(1)|S(2)|S(5)|S(7),			/* C */
290     S(3)|S(4)|S(5)|S(6)|S(7),			/* d */
291     S(1)|S(2)|S(4)|S(5)|S(7),			/* E */
292     S(1)|S(2)|S(4)|S(5),			/* F */
293   };
294 #undef S
295   int nb = g->wires[LED_IN]->net->n_nbits;
296   unsigned valid = g->u.led.valid;
297   unsigned value = g->u.led.value;
298   int i;
299 
300   /*
301    * 0 extend if necessary
302    */
303   if (nb < 32) {
304     value &= (1<<nb)-1;
305     valid |= ~((1<< nb)-1);
306   }
307 
308   *n = numDigits(g);
309 
310   i = *n - 1;
311   switch (g->u.led.ltype) {
312   case LT_HEX :
313   default :
314     for (i = *n-1;i >= 0;i--) {
315       unsigned a = value & 0xf;
316       unsigned b = valid & 0xf;
317 
318       if (b == 0xf) {
319 	seg_value[i] = seg_data[a];
320 	seg_valid[i] = 0x7f;
321       } else {
322 	seg_value[i] = 0;
323 	seg_valid[i] = 0;
324       }
325 
326       valid >>= 4;
327       value >>= 4;
328     }
329     break;
330   case LT_SEG :
331     for (i = *n-1;i >= 0;i--) {
332       unsigned a = value & 0x7f;
333       unsigned b = valid & 0x7f;
334 
335       seg_value[i] = a;
336       seg_valid[i] = b;
337 
338       valid >>= 7;
339       value >>= 7;
340     }
341     break;
342   case LT_DEC :
343     if (valid == 0xffffffff) {
344       for (i = *n-1;i >= 0;i--) {
345 	unsigned a = value % 10;
346 
347 	seg_value[i] = seg_data[a];
348 	seg_valid[i] = 0x7f;
349 
350 	value /= 10;
351       }
352     } else {
353       for (i = *n-1;i >= 0;i--) {
354 	seg_value[i] = 0;
355 	seg_valid[i] = 0;
356       }
357     }
358     break;
359   }
360 }
361 
Led_GetExtents(GCElement * g,TargetDev_e target,int * minx,int * miny,int * maxx,int * maxy,int * bd)362 void Led_GetExtents(GCElement *g,TargetDev_e target,int *minx,int *miny,int *maxx,int *maxy,int *bd)
363 {
364   switch (g->u.led.ltype) {
365   case LT_BASIC :
366   default :
367     Generic_GetExtents(g,target,minx,miny,maxx,maxy,bd);
368     break;
369   case LT_BAR :
370     {
371       int x = 0,y = 0,w,h,n;
372 
373       n = g->wires[LED_IN]->net->n_nbits;
374       h = 15;
375       w = 3 + 5*n;
376 
377       switch (g->orient) {
378       case D_RIGHT :
379 	x = g->xpos - w/2;
380 	y = g->ypos - 9;
381 	break;
382       case D_UP :
383 	x = g->xpos - w + 6;
384 	y = g->ypos - 7 ;
385 	break;
386       case D_LEFT :
387 	x = g->xpos - w/2;
388 	y = g->ypos - 6;
389 	break;
390       case D_DOWN :
391 	x = g->xpos - 6 ;
392 	y = g->ypos - 7;
393 	break;
394       }
395 
396       if (bd) *bd = 10;
397       if (minx) *minx = x;
398       if (miny) *miny = y;
399       if (maxx) *maxx = x + w;
400       if (maxy) *maxy = y + h;
401       break;
402     }
403   case LT_HEX :
404   case LT_SEG :
405   case LT_DEC :
406     {
407       int x = 0,y = 0,w,h;
408       unsigned n;
409 
410       n = numDigits(g);
411       h = 31;
412       w = 3 + 20*n;
413 
414       switch (g->orient) {
415       case D_RIGHT :
416 	x = g->xpos - w/2;
417 	y = g->ypos - h + 6;
418 	break;
419       case D_UP :
420 	x = g->xpos - w + 6;
421 	y = g->ypos - h/2 ;
422 	break;
423       case D_LEFT :
424 	x = g->xpos - w/2;
425 	y = g->ypos - 6;
426 	break;
427       case D_DOWN :
428 	x = g->xpos - 6;
429 	y = g->ypos - h/2;
430 	break;
431       }
432 
433       if (bd) *bd = 10;
434       if (minx) *minx = x;
435       if (miny) *miny = y;
436       if (maxx) *maxx = x + w;
437       if (maxy) *maxy = y + h;
438       break;
439     }
440 
441   }
442 }
443 
led_drawname(GCElement * g,char * ename,int ax,int ay,int w,int h)444 void led_drawname(GCElement *g,char *ename,int ax,int ay,int w,int h)
445 {
446   int x,y;
447 
448   if (g->selected)
449     XSetFont(TkGate.D,TkGate.instGC,TkGate.textbXF[TkGate.circuit->zoom_factor]->fid);
450   else
451     XSetFont(TkGate.D,TkGate.instGC,TkGate.textXF[TkGate.circuit->zoom_factor]->fid);
452 
453   x = ax+w/2;
454 
455   if (g->orient == 2) {
456     if (g->u.led.ltype != LT_BAR)
457       y = ay+h+22;
458     else
459       y = ay+h+12;
460   } else
461     y = ay-5;
462 
463   dce_DrawString(TkGate.instGC,x,y,CT,ename);
464 }
465 
led_PSdrawname(GPrint * P,GCElement * g,char * ename,int ax,int ay,int w,int h)466 void led_PSdrawname(GPrint *P,GCElement *g,char *ename,int ax,int ay,int w,int h)
467 {
468   int x,y;
469   HtmlFont font[1];
470   GateFont gateFont = {FF_HELVETICA,FP_ROMAN};
471 
472   if (g->selected)
473     XSetFont(TkGate.D,TkGate.instGC,TkGate.textbXF[TkGate.circuit->zoom_factor]->fid);
474   else
475     XSetFont(TkGate.D,TkGate.instGC,TkGate.textXF[TkGate.circuit->zoom_factor]->fid);
476 
477   x = ax+w/2;
478 
479   if (g->orient == 2) {
480     if (g->u.led.ltype != LT_BAR)
481       y = ay+h+22;
482     else
483       y = ay+h+12;
484   } else
485     y = ay-5;
486 
487   PSDrawText(P,HtmlFont_init(font,gateFont,8),
488 	     x,y,ename,BetweenLeftAndRight|AtBaseline);
489 }
490 
Led_Draw_basic(GCElement * g,int md)491 static void Led_Draw_basic(GCElement *g,int md)
492 {
493   int idx;
494 
495   Generic_Draw(g,md);
496 
497   if (!(g->u.led.valid & 0x1)) {
498     Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledunknown_pixel);
499   } else if (g->u.led.value) {
500     Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledon_pixel);
501   } else {
502     Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledoff_pixel);
503   }
504 
505   idx = g->orient;
506   if (g->selected) idx += 4;
507   Icon_draw(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(g->xpos),ctow_y(g->ypos),inled_icon[idx]);
508 
509   Tkg_changeColor(TkGate.instGC, GXxor, TkGate.inst_pixel);
510 }
511 
Led_Draw_bar(GCElement * g,int md)512 static void Led_Draw_bar(GCElement *g,int md)
513 {
514   int i,n,x,y,x2,y2,w,h,dx;
515 
516   n = g->wires[LED_IN]->net->n_nbits;
517 
518   Led_GetExtents(g,TD_X11,&x,&y,&x2,&y2,0);
519   w = x2-x;
520   h = y2-y;
521 
522   if (g->show_name && g->ename)
523     led_drawname(g,g->ename,x,y,w,h);
524 
525   ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x),ctow_y(y),w,h);
526   if (g->selected)
527     ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x)+1,ctow_y(y)+1,w-2,h-2);
528 
529   x += 3;
530   y += 3;
531 
532   /*
533    * Draw all of the unknown bits
534    */
535   Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledunknown_pixel);
536   dx = 0;
537   for (i = 0;i < n;i++) {
538     if (!(g->u.led.valid & (1 << (n-i-1)))) {
539       ZFillRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx),ctow_y(y),3,10);
540     }
541     dx += 5;
542   }
543 
544   /*
545    * Draw all of the on bits
546    */
547   Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledon_pixel);
548   dx = 0;
549   for (i = 0;i < n;i++) {
550     if ((g->u.led.valid & (1 << (n-i-1)) && (g->u.led.value & (1 << (n-i-1))))) {
551       ZFillRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx),ctow_y(y),3,10);
552     }
553     dx += 5;
554   }
555 
556   /*
557    * Draw all of the off bits
558    */
559   Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledoff_pixel);
560   dx = 0;
561   for (i = 0;i < n;i++) {
562     if ((g->u.led.valid & (1 << (n-i-1)) && !(g->u.led.value & (1 << (n-i-1))))) {
563       ZFillRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx),ctow_y(y),3,10);
564     }
565     dx += 5;
566   }
567 
568   Tkg_changeColor(TkGate.instGC, GXxor, TkGate.inst_pixel);
569   gate_drawWires(g,md);
570 }
571 
572 
Led_Draw_7segs(GCElement * g,int md)573 void Led_Draw_7segs(GCElement *g,int md)
574 {
575   int i,j,x,y,x2,y2,w,h,dx;
576   unsigned seg_value[MAXDIGITS];
577   unsigned seg_valid[MAXDIGITS];
578   unsigned n;
579   char *seg_type = 0;
580 
581   Led_GetExtents(g,TD_X11,&x,&y,&x2,&y2,0);
582   w = x2-x;
583   h = y2-y;
584 
585   if (g->show_name && g->ename)
586     led_drawname(g,g->ename,x,y,w,h);
587 
588   getLedSegments(g,seg_value,seg_valid,&n);
589 
590   ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x),ctow_y(y),w,h);
591   if (g->selected)
592     ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+1),ctow_y(y+1),w-2,h-2);
593 
594   dx = 0;
595   for (i = 0;i < n;i++, dx += 20)
596     ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx+3),ctow_y(y+3),17,25);
597 
598 
599   /*
600     Draw the type indicator for 7-seg LEDs
601   */
602   switch (g->u.led.ltype) {
603   case LT_HEX :
604     seg_type = "16";
605     break;
606   case LT_SEG :
607     seg_type = "D";
608     break;
609   case LT_DEC :
610     seg_type = "10";
611     break;
612   }
613 
614   if (seg_type) {
615     if (g->selected)
616       XSetFont(TkGate.D,TkGate.instGC,TkGate.stextbXF[TkGate.circuit->zoom_factor]->fid);
617     else
618       XSetFont(TkGate.D,TkGate.instGC,TkGate.stextXF[TkGate.circuit->zoom_factor]->fid);
619     dce_DrawString(TkGate.instGC,x+w/2+5,y+40,LJ,seg_type);
620   }
621 
622   dx = 0;
623   Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledunknown_pixel);
624   for (i = 0;i < n;i++, dx += 20) {
625     for (j = 0;j < 7;j++) {
626       if (!(seg_valid[i] & (1<<j)))
627 	Icon_draw(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx+5),ctow_y(y+5),seg_icon[j]);
628     }
629   }
630 
631   dx = 0;
632   Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledon_pixel);
633   for (i = 0;i < n;i++, dx += 20) {
634     for (j = 0;j < 7;j++) {
635       if ((seg_valid[i] & (1<<j)) && (seg_value[i] & (1<<j)))
636 	Icon_draw(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx+5),ctow_y(y+5),seg_icon[j]);
637     }
638   }
639 
640   dx = 0;
641   Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledoff_pixel);
642   for (i = 0;i < n;i++, dx += 20) {
643     for (j = 0;j < 7;j++) {
644       if ((seg_valid[i] & (1<<j)) && !(seg_value[i] & (1<<j)))
645 	Icon_draw(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx+5),ctow_y(y+5),seg_icon[j]);
646     }
647   }
648 
649   Tkg_changeColor(TkGate.instGC, GXxor, TkGate.inst_pixel);
650   gate_drawWires(g,md);
651 }
652 
653 
Led_Draw(GCElement * g,int md)654 void Led_Draw(GCElement *g,int md)
655 {
656   if (tkgate_currentMode() != MM_SIMULATE) {
657     g->u.led.valid = 0xffffffff;
658     g->u.led.value = 0;
659   }
660 
661   switch (g->u.led.ltype) {
662   case LT_BASIC :
663     Led_Draw_basic(g,md);
664     break;
665   case LT_BAR :
666     Led_Draw_bar(g,md);
667     break;
668   default :
669     Led_Draw_7segs(g,md);
670     break;
671   }
672 }
673 
Led_Copy(GModuleDef * M,GCElement * g,int x,int y,unsigned flags)674 GCElement *Led_Copy(GModuleDef *M,GCElement *g,int x,int y,unsigned flags)
675 {
676   GCElement *ng;
677 
678   ng = Generic_Copy(M,g,x,y,flags);
679   ob_touch(ng);
680 
681   ng->u.led.ltype = g->u.led.ltype;
682   ng->u.led.value = g->u.led.value;
683   ng->u.led.valid = g->u.led.value;
684 
685   return ng;
686 }
687 
688 
Led_VerSave(FILE * f,GCElement * g)689 void Led_VerSave(FILE *f,GCElement *g)
690 {
691   fprintf(f,"  //: %s %s (%s)"
692 	  ,g->typeinfo->name
693 	  ,g->ename
694 	  ,g->wires[0]->net->n_signame);
695   VerilogBasicGateComment(f,g,0);
696   fprintf(f," /type:%d",g->u.led.ltype);
697   fprintf(f,"\n");
698 
699 #if 0
700   VerilogBasicGateCall(f,g);
701   VerilogBasicGateParmList(f,g);
702   VerilogBasicGateComment(f,g,1);
703   fprintf(f," /type:%d",g->u.led.ltype);
704   fprintf(f,"\n");
705 #endif
706 }
707 
Led_EditProps(GCElement * g,int isLoadDialog)708 int Led_EditProps(GCElement *g,int isLoadDialog)
709 {
710   Tcl_Interp *tcl = TkGate.tcl;
711 
712   Generic_EditProps(g,isLoadDialog);
713   if (isLoadDialog) {
714     DoTcl("set ::edgat_ledType %d",g->u.led.ltype);
715   } else {
716     const char *p;
717 
718     if ((p = Tcl_GetVar(tcl,"edgat_ledType",TCL_GLOBAL_ONLY))) {
719       ob_touch(g);
720       sscanf(p,"%d",&g->u.led.ltype);
721     }
722   }
723   return 0;
724 }
725 
Led_SetProp(GCElement * g,const char * prop,const void * value)726 void Led_SetProp(GCElement *g,const char *prop,const void *value)
727 {
728   if (strcmp(prop,"/type") == 0) {
729     int n = *((int*)value);
730     ob_touch(g);
731     g->u.led.ltype = n;
732   }
733 }
734 
Led_PSWrite(GPrint * P,GModLayout * L,GCElement * g)735 void Led_PSWrite(GPrint *P,GModLayout *L,GCElement *g)
736 {
737   int n;
738   int x,y,x2,y2,w,h;
739   HtmlFont font[1];
740   GateFont gateFont = {FF_HELVETICA,FP_ROMAN};
741 
742   Led_GetExtents(g,TD_PRINT,&x,&y,&x2,&y2,0);
743   w = x2-x;
744   h = y2-y;
745 
746   switch (g->u.led.ltype) {
747   case LT_BASIC :
748   default :
749     Generic_PSLabels(P,g);
750     fprintf(P->p_f,"%d %d %d psled_bit\n",g->xpos,g->ypos,-g->orient*90);
751     break;
752   case LT_BAR :
753     if (g->show_name && g->ename)
754       led_PSdrawname(P,g,g->ename,x,y,w,h);
755 
756     n = g->wires[LED_IN]->net->n_nbits;
757     fprintf(P->p_f,"%d %d %d %d %d 0 psled_bar\n",n,w,h,x,y);
758     break;
759   case LT_HEX :
760   case LT_SEG :
761   case LT_DEC :
762     if (g->show_name && g->ename)
763       led_PSdrawname(P,g,g->ename,x,y,w,h);
764     n = numDigits(g);
765     fprintf(P->p_f,"%d %d %d %d %d 0 psled_7seg\n",n,w,h,x,y);
766     break;
767   }
768 
769   switch (g->u.led.ltype) {
770   case LT_HEX :
771     PSDrawText(P,HtmlFont_init(font,gateFont,8),x+w/2+3,y+30,"16",AtLeft|AtTop);
772     break;
773   case LT_SEG :
774     PSDrawText(P,HtmlFont_init(font,gateFont,8),x+w/2+3,y+30,"D",AtLeft|AtTop);
775     break;
776   case LT_DEC :
777     PSDrawText(P,HtmlFont_init(font,gateFont,8),x+w/2+3,y+30,"10",AtLeft|AtTop);
778     break;
779   }
780 }
781 
782 
init_led()783 void init_led()
784 {
785   Pixmap P;
786   int i;
787   char buf1[STRMAX],buf2[STRMAX];
788   iconDimensions *id = led_iconDims;
789 
790   P = Pixmap_registerFromFile("led","led.b");
791   gateinfo_iconInit(&gate_led_info,P,led_iconDims,led_iconBoldOffset);
792   RegisterGate(&gate_led_info);
793 
794   for (i = 0;i < 7;i++) {
795     sprintf(buf1,"ledseg%d",i+1);
796     sprintf(buf2,"ledseg%d.b",i+1);
797     P = Pixmap_registerFromFile(buf1,buf2);
798     seg_icon[i] = new_Icon(P,0,0,13,21,0,0);
799   }
800 
801   /*
802    * Load special pixmap for leds.
803    */
804   P = Pixmap_registerFromFile("ledinside","ledinside.b");
805   for (i = 0;i < 4;i++) {
806     inled_icon[i] = new_Icon(P,id[i].x,id[i].y,id[i].w,id[i].h,id[i].ox,id[i].oy);
807     inled_icon[i+4] = new_Icon(P,id[i].x,id[i].y+led_iconBoldOffset,id[i].w,id[i].h,id[i].ox,id[i].oy);
808   }
809 
810 }
811