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 #ifndef __tkgate_h
19 #define __tkgate_h
20 
21 #define TKGATE_EDITOR	1	/* This is the editor */
22 #define TOUCH_XGATE_ED	0	/* Consider TkGate.ed to be undoable */
23 
24 #include "config.h"
25 
26 #ifndef _GNU_SOURCE
27 #define _GNU_SOURCE
28 #endif
29 
30 #include <ctype.h>
31 #include <errno.h>
32 #include <limits.h>
33 #include <stdarg.h>
34 #if HAVE_STRING_H
35 #include <string.h>
36 #endif
37 #include <time.h>
38 #if HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41 
42 #if HAVE_SYS_TYPES_H
43 #include <sys/types.h>
44 #endif
45 #if HAVE_SYS_STAT_H
46 #include <sys/stat.h>
47 #endif
48 #if HAVE_SYS_PARAM_H
49 #include <sys/param.h>
50 #endif
51 
52 #include <X11/Xlib.h>
53 #include <X11/Xresource.h>
54 #include <X11/cursorfont.h>
55 
56 #if HAVE_ICONV_H
57 #include <iconv.h>
58 #endif
59 
60 #include "tcl.h"
61 #include "tk.h"
62 #include "fonts.h"
63 #include "zoom.h"
64 #include "tkgate_config.h"
65 #include "tkgate_misc.h"
66 #include "hash.h"
67 #include "list.h"
68 #include "misc.h"
69 #include "text.h"
70 #include "ycmalloc.h"
71 #include "expr.h"
72 #include "delay.h"
73 #include "icon.h"
74 #include "module.h"
75 #include "net.h"
76 #include "wires.h"
77 #include "elements.h"
78 #include "modsym.h"
79 #include "simulate.h"
80 #include "breakpoint.h"
81 #include "script.h"
82 #include "error.h"
83 #include "vparser.h"
84 #include "scope.h"
85 #include "gates.h"
86 #include "generic.h"
87 #include "functions.h"
88 #include "message.h"
89 #include "object.h"
90 #include "cpath.h"
91 #include "igenerate.h"
92 #include "verilog.h"
93 #include "editstate.h"
94 #include "circuit.h"
95 #include "primitives.h"
96 #include "gate_painter.h"
97 
98 #if TCL_MAJOR_VERSION != 8
99 #error This program has not been tested with versions of tcl/tk other than 8.*
100 #endif
101 
102 /*
103  * Versions of tcl/tk from 8.4 change some uses of 'char*' to 'const char*'.  Tkgate
104  * now assumes 'const char*' is always used so if we are using an earlier version of
105  * tcl/tk we need to cast them back to 'char*' to prevent errors/warnings.
106  */
107 #if TCL_MINOR_VERSION <= 3
108 typedef int New_Tcl_CmdProc(ClientData d,Tcl_Interp *tcl,int argc,const char *argv[]);
109 #define Tcl_CreateCommand(t,c,f,d,x) Tcl_CreateCommand(t,c,(Tcl_CmdProc*)(f),d,x)
110 #define Tk_ConfigureWidget(t, w, cs, argc, argv, gw, flags) Tk_ConfigureWidget(t, w, cs, argc, (char**)(argv), gw, flags)
111 #define Tk_CreateWindowFromPath(tcl, root, name, top) Tk_CreateWindowFromPath(tcl, root, (char*)(name), (char*)(top))
112 #define Tcl_SetVar(tcl, var , val, flags) Tcl_SetVar(tcl, (char*)(var) , (char*)(val), flags)
113 #define Tcl_Merge(argc, argv) Tcl_Merge(argc, (char**) (argv))
114 #define Tcl_SplitList(tcl, list, argcP, argvP) Tcl_SplitList(tcl, list, argcP, (char***) (argvP))
115 #else
116 typedef Tcl_CmdProc New_Tcl_CmdProc;
117 #endif
118 
119 /*
120  * Coordinate conversion macros.  The 'ctow' macros convert from circuit
121  * to window coordinates while the 'wtoc' mactos convert from window
122  * to circuit coordinates.
123  */
124 #define ctow_x(x) ((x) + TkGate.circuit->org_x)
125 #define ctow_y(y) ((y) + TkGate.circuit->org_y)
126 #define wtoc_x(x) ((x) - TkGate.circuit->org_x)
127 #define wtoc_y(y) ((y) - TkGate.circuit->org_y)
128 
129 /*
130  * Modified flags to indicate what is changeing
131  */
132 #define MF_MODULE	0x1		/* Changes that affect the module list or heirarchy */
133 #define MF_NET		0x2		/* Changes to the nets */
134 #define MF_INTERFACE	0x4		/* Changes to a module interface */
135 #define MF_GATE		0x8		/* Changes to gates or gate properties */
136 #define MF_NOMODULE	0xfffe		/* Set all modified flags except module change */
137 #define MF_ALL		0xffff		/* Set all modified flags */
138 #define MF_SYNCONLY	0x10000		/* Synchronize interface only */
139 #define MF_BEGINSPEC	0x20000		/* Begin modifications in a special module */
140 #define MF_ENDSPEC	0x40000		/* End modifications in a special module */
141 #define MF_FORCE	0x80000		/* Force non-special even if between BEGINSPEC/ENDSPEC  */
142 
143 #define CE_ISO8859_1	"iso8859-1"
144 #define CE_ISO8859_2	"iso8859-2"
145 #define CE_UTF8		"utf-8"
146 #define CE_EUC_JP	"euc-jp"
147 
148 /*
149  * Search mode flags
150  */
151 #define SF_NETS		0x1		/* Search net names */
152 #define SF_GATES	0x2		/* Search gate names */
153 #define SF_TEXT		0x4		/* Search comment text */
154 #define SF_IGNORECASE	0x100		/* Ignore case in comparison */
155 
156 /*
157  * Search qualifiers
158  */
159 #define SQ_CONTAINS	0		/* Search for things containing target */
160 #define SQ_BEGINS	1		/* Search for things beginning with target */
161 #define SQ_ENDS		2		/* Search for things ending with target */
162 #define SQ_MATCHES	3		/* Search for things that exactly match */
163 
164 /*
165  * Interface editing sub-modes
166  */
167 #define INTFMODE_NONE		0	/* We are not in interface mode */
168 #define INTFMODE_ALL		1	/* We are on the module list interface mode */
169 #define INTFMODE_SINGLE		2	/* We are in the single module interface mode */
170 
171 /*
172  * Describes an encoder object used to translate strings from one code to another.
173  */
174 struct encoder_str {
175   const char	*fromCode;
176   const char	*toCode;
177   int		isJapanese;
178 #if HAVE_ICONV_H
179   iconv_t	ico;
180 #endif
181 };
182 
183 /*
184  * Describes a locale and all its encoding methods
185  */
186 struct locale_str {
187   const char	*l_code;		/* Locale code (e.g., en, ja, de, etc.) */
188   const char	*l_name;		/* Name of the locale (e.g., English, Japanese, German) */
189   const char	*l_messages;		/* Path of messages file */
190 
191   const char	*l_encFont;		/* Font family to use (e.g., iso8859-1) */
192   const char	*l_encDisplay;		/* Encoding for display */
193   const char	*l_encMessages;		/* Encoding of messages file */
194   const char	*l_encVerilog;		/* Encoding of verilog save files */
195   const char	*l_encPostscript;	/* Encoding for postscript files */
196 };
197 
198 /*
199  *  TkGate major modes
200  */
201 typedef enum { MM_EDIT, 		/* Circuit editing mode */
202 	       MM_SIMULATE, 		/* Circuit simulation mode */
203 	       MM_ANALYZE		/* Critical path analysis mode */
204 }  MajorMode;
205 
206 /*
207  * Data structure used for building the "Make" menu.
208  */
209 typedef struct  {
210   char		*mname;		/* Actual name of the menu */
211   int		count;		/* Number of entries on page */
212   GKeyMenuEnt	**kme;		/* List of entries on page */
213 } BuildMenuRoot;
214 
215 /*
216  * Top-level data structure for "Make" menus
217  */
218 typedef struct {
219   SHash		*rmap;
220   BuildMenuRoot	*roots[MAKEENTRYMAX];
221   int numRoot;
222 }  MakeMenuData;
223 
224 /*****************************************************************************
225  *
226  * This data structure is used to represent the main editing canvas.
227  *
228  *****************************************************************************/
229 struct TkgGatWin_str {
230   Tk_Window	win;		/* Main TK window */
231   Display	*d;		/* Pointer to X11 display structure */
232   Tcl_Interp	*tcl;		/* The Tcl interpteter */
233   int		width, height;	/* Size of main window */
234   XColor	*bgColor;	/* Background border color of main window */
235   XColor	*fgColor;	/* Foreground border color of main window */
236   GC		gc;		/* Graphics context */
237   TkGateParams	*parms;		/* TkGate main object */
238   char		*xscroll;	/* Command for x scrolling */
239   char		*yscroll;	/* Command for y scrolling */
240   char		*takefocus;	/* Should we take focus */
241 };
242 
243 struct EditData_str {
244   MajorMode major_mode;		/* The current major mode */
245   int saved_mode;		/* Saved minor edito mode for button 2 quick moving */
246 
247   int mark_vis;			/* Is the mark visible? */
248   int mark_posted;		/* The mark has been posted (should be visible) */
249   int mark_x, mark_y;		/* Position of mark */
250 
251   int rx,ry;			/* Point of current mouse activity (raw coordinates) */
252 
253   int tx,ty;			/* Point of current mouse activity (circuit coordinates) */
254   int lx,ly;			/* Point of last mouse activity (circuit coordinates) */
255   int sx,sy;			/* Point of saved mouse activity (circuit coordinates) */
256 
257   int scr_x,scr_y;		/* Scrolling origin point */
258 
259   /*
260    * Used for hand scroll
261    */
262   struct {
263     int orgSave_x,orgSave_y;	/* Saved origin point */
264     int setSave_x,setSave_y;	/* Saved button press point */
265   } handScroll;
266 
267   int min_x,max_x;		/* Min and max x-coordinates of current module */
268   int min_y,max_y;		/* Min and max y-coordinates of current module */
269 };
270 
271 /*****************************************************************************
272  *
273  * State information for idle events.  Idle events are events that are executed
274  * when the interface is "idle".  This allows the redraw rate to be throttled
275  * based on available processing power as opposed to redraws after each mouse
276  * movement.
277  *
278  *****************************************************************************/
279 typedef struct {
280   int pending;			/*   idle event pending */
281   int redraw;			/*   redraw requested */
282   int scroll_area;		/*   scroll change in viewable area requested */
283   int scroll_new_x;		/*   x-coordinate for new origin */
284   int scroll_new_y;		/*   y-coordinate for new origin */
285   int scope_redraw;		/*   redraw scope window */
286   int trace_redraw;		/*   redraw a trace in scope window */
287 } IdleEv;
288 
289 /*****************************************************************************
290  *
291  * State information for popup menus.
292  *
293  *****************************************************************************/
294 typedef struct {
295   int		isSet;		/*    Non-zero if we are doing a popup */
296   GCElement	*g;		/*    selected gate */
297   GWire		*w;		/*    selected wire */
298   GWireNode	*n;		/*    selected wire node */
299   GNet		*net;		/*    Selected net */
300   int		x,y;		/*    position of pointer */
301   int		wx,wy;		/*    untranslated position of pointer */
302 } PopState;
303 
304 /*****************************************************************************
305  *
306  * This data structure represents the global state of the tkgate application.
307  * There is only one object of this type defined as the global variable "TkGate".
308  *
309  *****************************************************************************/
310 struct TkGateParams_str {
311   Tcl_Interp	*tcl;		/* The TCL intepreter */
312   Display	*D;		/* X Display */
313   Screen	*S;		/* Default screen of display */
314   Window	W;		/* Editing window */
315   Window	ScopeW;		/* Scope Window */
316   Window	root;		/* Root window */
317   Colormap	CM;		/* The color map */
318   XrmDatabase	rdb;		/* The resource database */
319   int		bitorder;	/* Order of bits in image data */
320   int           byteorder;      /* Order of bytes in image data */
321 
322   GatePainter	*painterW;	/* editing window painter */
323   GatePainterContext *commentContext;
324 
325   GatePainter	*painterScopeW;	/* scope window painter */
326 
327   TkgGateWin	*gw;		/* Tcl/Tk view of main window. */
328 
329   char *homedir;		/* Directory for all tkgate files */
330 
331   XFontStruct	**textXF;	/* Normal text */
332   XFontStruct	**textbXF;	/* Bold text */
333   XFontStruct	**stextXF;	/* Small text */
334   XFontStruct	**stextbXF;	/* Small bold text */
335   XFontStruct	**ktextXF;	/* Kanji font */
336 
337   GC instGC;			/* GC for built-in instances (variable font) */
338   GC moduleGC;			/* GC for modules (variable font)  */
339   GC modportGC;			/* GC for module ports  (variable font) */
340   GC frameGC;			/* Dashed line GC for frames  (variable font) */
341   //GC commentGC;			/* GC for comments (variable font) */
342   GC imageGC;			/* GC for images */
343   GC hyperlinkGC;		/* GC for hyperlink comments (variable font) */
344   GC wireGC;			/* GC for wire drawing */
345   GC busGC;			/* GC for multi-bit wire drawing */
346   GC selWireGC;			/* GC for selected wire drawing */
347   GC selBusGC;			/* GC for selected multi-bit wire drawing */
348   GC toolGC;			/* GC for TkGate tools, etc. */
349   GC cpathGC;			/* GC for critical path */
350   GC kanjiGC;			/* GC for kanji (comments only) */
351 
352   GC copyGC;			/* Basic GC for copying areas, etc. */
353 
354   GC scopeGridGC;		/* Scope GC for grid lines, etc. */
355   GC scopeOneGC;		/* Scope GC for non-zero signal values */
356   GC scopeZeroGC;		/* Scope GC for 0 signal values */
357   GC scopeFloatGC;		/* Scope GC for z,l,h signal values */
358   GC scopeUnknownGC;		/* Scope GC for x signal values */
359   GC scopeClearGC;		/* Scope GC for clearing signal values */
360   GC scopeXHairGC;		/* Scope GC for crosshair. */
361   GC scopeSelectGC;		/* Scope GC for scope selection. */
362 
363   GC bitGC;			/* special 1-bit GC */
364 
365   int inst_pixel;		/* Pixel value for instances */
366   int ledoff_pixel;		/* Pixel value for off leds */
367   int ledon_pixel;		/* Pixel value for on leds */
368   int ledunknown_pixel;		/* Pixel value for led with unknown input */
369   GateColor comment_color;	/* Color for comment regular text */
370   GateColor hyperlink_color;	/* Color for hyperlinks */
371 
372   IdleEv idle_ev;		/* Idle event flags */
373   PopState popstate;		/* Popup menu state */
374 
375   SHash *libraries;		/* Libraries loaded into tkgate */
376 
377   int cpath_flashState;		/* State for flashing cpath */
378   int cpath_len;		/* Length of current critical path */
379   char **cpath_pelems;		/* The current critcal path */
380 
381   int width,height;		/* Size of edit window */
382   unsigned state;		/* Mouse button state mask */
383   unsigned button;		/* Mouse button that was pressed */
384 
385   EditData	*ed;		/* Basic editor data */
386   Circuit	*circuit;	/* Top-level circuit data */
387   ErrorList	*errl;		/* Error list manager data */
388 
389   int ErrorMarkTimeout;		/* Status flag for drawing the error "X" marker. */
390 
391   unsigned	sync_flags;	/* Flags indicating what tcl elements need synchronizing  */
392 
393   /*
394    * Encoding and font handling
395    */
396   Locale	*locale;		/* Locale that we are running under */
397   SHash		*localeTable;		/* Locales that are available */
398   SHash		*localeNameTable;	/* Locales by full name */
399   int		japaneseMode;		/* Are we in Japanese mode? */
400 
401   char *errorLogFile;
402   char *siteName;
403   char *defaultTech;
404   char *browserCommand;
405   char *emailCommand;
406   int regionUpdate;
407   int smoothScroll;
408   int changedp;
409   int startrekp;
410   int baderp;
411   int batp;
412   int batc;
413   int flashCPath;
414   int saveTraces;
415   int sortTraces;
416   int extendBars;
417   int showSwitchNets;
418 };
419 
420 typedef struct{
421   char	 		*command;
422   New_Tcl_CmdProc	*func;
423 } Tkg_Command;
424 
425 void init_cursors(void);
426 void init_localeSet(void);
427 void init_mainWindow(Tcl_Interp *tcl);
428 void init_tclProcs(Tcl_Interp *tcl);
429 
430 void Comment_addLine(GCElement *g,const char *text);
431 void Comment_flushLines(GCElement *g);
432 void FlagScrolling(void);
433 void HandScroll_drop(EditState *es);
434 void HandScroll_move(EditState *es);
435 void HandScroll_set(EditState *es);
436 void SwitchDip_getCompositeName(GCElement *g,char *compositeName);
437 void getFontName(char *fullName,fontfamily_t ff,fontprop_t fp,fontsize_t fs,int zoom);
438 void guessPortName(char *buf,GCElement *g,int orient,int dir,int nbits);
439 
440 int Tkg_GetColor(const char *name);
441 
442 void configureMainWindow(Tcl_Interp *);
443 void message(int,const char*,...);
444 
445 int checkValidName(const char *name,SHash *H);
446 void pickValidName(char *buf,const char *name,const char *base,SHash *H);
447 
448 void logError(int code,const char *fname,int lnum,const char *s,...);
449 
450 void GCellSpec_writeBeginModule(FILE *f,GCellSpec *gcs);
451 void GCellSpec_writeEndModule(FILE *f,GCellSpec *gcs);
452 
453 unsigned transition_type(int from,int to);
454 
455 Encoder *getEncoder(const char *toCode,const char *fromCode);
456 size_t recodeText(Encoder *encoder, char *toString,int len, const char *fromString);
457 char *recodeTextP(Encoder *encoder, const char *fromString);
458 int isJapaneseDisplay(Encoder*);
459 
460 void icon_init();
461 void SetUpCursors();
462 void MouseoverCursor(int cursorType);
463 void MakeHashTables();
464 
465 int DoTcl(const char*,...);
466 int DoTclL(const char*,...);
467 int DoTclV(const char*,int,const char**);
468 void InitTclProcs(Tcl_Interp *tcl);
469 
470 void mark_draw();
471 void mark_flush();
472 void mark_hide();
473 void mark_redraw();
474 void mark_post();
475 void mark_unpost();
476 
477 void net_editProps(GNet *n,int x,int y);
478 
479 /*
480  * Convert value to a string.
481  */
482 #define STR(X) #X
483 
484 /*****************************************************************************
485  * Hold-overs from ancient wm window manager code.
486  *****************************************************************************/
487 void wm_GetDimensions(int *X,int *Y);
488 void wm_SetCursor(int id);
489 
490 /*
491  * Manage changes within tkgate
492  */
493 void SetModified(unsigned flags);		/* Flags are from the MF_ group */
494 void ClearModified();
495 void UpdateModifiedIndicator();
496 void FlagRedraw();
497 void SynchronizeInterface();
498 
499 void SetBatCursor();
500 void ClearErrorMark();
501 void DrawErrorPositionMark();
502 void ReqScopeRedisplay();
503 
504 void TkGate_clearSelection();
505 void TkGate_setOrigin(int x,int y);
506 
507 int required_bits(int n);
508 void badermessage(const char *m);
509 int posongate(GWire *w,GCElement *g,int *p,int *n);
510 int findwirepos(GWire *w,GWire *l);
511 int GetPadPosition(GCElement *g,const char *name);
512 void panicSave(int);
513 FILE *openInPath(const char*);
514 int badaddr(void *S);
515 
516 void Tkg_changeColor(GC gc,int func,int pixel);
517 
518 int fontheight(XFontStruct *F);
519 
520 void line(int x1,int y1,int x2,int y2);
521 void box(int x,int y,int w,int h);
522 void mk_gate(int x,int y,GGateInfo *gi,int rot,int selected);
523 
524 char *filterParen(char *buf,const char *s);
525 
526 int dce_DrawString(GC gc,int x,int y,int p,const char *s);
527 int RelPosDrawString(GatePainter*,XFontStruct *F,GC gc,int x,int y,const char *S,int p);
528 int PosDrawString(GatePainter*,XFontStruct *F,GC gc,int x,int y,const char *S,int p);
529 void GKDrawString(GatePainter *,GC gc,int x,int y,const char *s,int l);
530 int GKTextWidth(XFontStruct *F,const char *S,int l);
531 void DrawTextCursor(Window W,int x,int y);
532 
533 void cpath_show(int n,const char *netNames[]);
534 void cpath_initNetDelayTable();
535 void cpath_flushNetDelayTable();
536 void cpath_registerNetDelay(const char *,int,int);
537 void cpath_registerNetAlias(const char *,const char*);
538 int  cpath_getNetDelay(const char *,int*,int*);
539 void cpath_showNetDelay(GNet *n);
540 
541 void scrollbar_update();
542 void scrollbar_bbx_update();
543 
544 char *msgLookup(const char*);
545 
546 void dohyperlink(const char*);
547 
548 void makeMakeMenu(const char *m);
549 
550 MajorMode tkgate_currentMode();
551 void tkgate_setMajorMode(MajorMode mm);
552 
553 void init_gates();
554 
555 int verify_circuit();
556 
557 void setEditCursor(int mode);
558 
559 void TkGate_init(Tcl_Interp*);
560 void TkGate_initDelay();
561 void SetErrorPosition(int,int);
562 
563 void gateCleanUp();
564 
565 void initJapanese();
566 void setGCcolors();
567 void makeMakeShortcuts();
568 
569 double traceLinesPerPage(const char *orient,const char *paper);
570 int tracePageCountEst(const char *orient,const char *paper,int scale,int start,int end);
571 
572 void scopeButtonPress(int x,int y,int px,int py,int n,int state);
573 void scopeButtonMotion(int x,int y,int px,int py,int n,int state);
574 void scopeButtonRelease(int x,int y,int px,int py,int n,int state);
575 
576 void hdl_load(GModuleDef *M);
577 int hdl_checkSave(const char *name);
578 int hdl_save(const char *name);
579 int hdl_close(void);
580 void hdl_saveCursor(const char*,int,int);
581 int hdl_getCursor(int*,int*);
582 int hdl_replaceName(GModuleDef *M,const char *new_name);
583 
584 void undoSignals();
585 
586 void Concat_updateAutos(GModuleDef *M,int doDraw);
587 
588 void getLocaleSet();
589 void localization_Setup(Tcl_Interp *tcl);
590 
591 extern TkGateParams TkGate;
592 
593 extern int KANJIFONT_WIDTH;
594 
595 extern Icon *INVERTER;
596 extern Icon *Mark;
597 extern Icon *SIZEHASH;
598 extern Icon *REPCOUNTMARK;
599 
600 extern int ycLineNumber;
601 extern const char *ycFileName;
602 
603 extern SHash *message_table;
604 
605 extern char tkgate_homedir[STRMAX];
606 extern char *tkgate_exampledir;
607 extern char *tkgate_tutorialdir;
608 extern MakeMenuData *makeMenuData;
609 
610 extern VersionDef VERSIONS[];
611 extern int numVersions;
612 
613 extern int debugContinuousVerify;
614 extern int debugSimInterface;
615 
616 extern NHash *GateIdxHash;
617 
618 extern int debugmode;
619 
620 extern int hdl_isactive;
621 
622 #endif
623