1 #include <tk.h>
2 #include <X11/Xlib.h>
3 #include <X11/keysym.h>
4 #include <xcircuit.h>
5 
6 #include <tk.h>
7 #include <tkPlatDecls.h>
8 
9 #include <X11/cursorfont.h>
10 
11 extern Tcl_Interp *xcinterp;
12 extern XCWindowData *areawin;
13 extern char* TkKeysymToString(KeySym ks);
14 
unimplemented(const char * str)15 static void unimplemented(const char *str)
16 {
17 	printf(">>>>>>>>> Unimplemented: %s\n", str);
18 }
19 
20 typedef struct font_item {
21 	Tk_Font tkfont;
22 	Font fid;
23 	struct font_item *next;
24 };
25 static struct font_item *font_map = NULL;
26 
add_tkfont(Tk_Font tkfont,Font fid)27 static void add_tkfont(Tk_Font tkfont, Font fid)
28 {
29 	struct font_item *item = (struct font_item*)malloc(sizeof(struct font_item));
30 
31 	item->next = font_map;
32 	font_map = item;
33 	item->tkfont = tkfont;
34 	item->fid = fid;
35 }
36 
get_tkfont(Font fid)37 static Tk_Font get_tkfont(Font fid)
38 {
39 	struct font_item *item = font_map;
40 
41 	while (item != NULL) {
42 		if (item->fid == fid)
43 			return item->tkfont;
44 		item = item->next;
45 	}
46 	fprintf(stderr, "Font not found: ID=%d\n", fid);
47 	return (Tk_Font)NULL;
48 }
49 
50 #ifndef STATIC_BUILD
XDrawPoint(Display * dpy,Drawable d,GC gc,int x,int y)51 int XDrawPoint(Display *dpy, Drawable d, GC gc, int x, int y)
52 {
53 	HDC hdc;
54 	HWND hwnd;
55 
56 	hwnd = Tk_GetHWND(d);
57 	if (IsWindow(hwnd)) {
58 		hdc = GetDC(hwnd);
59 		SetPixelV(hdc, x, y, gc->foreground);
60 		ReleaseDC(hwnd, hdc);
61 		hdc = NULL;
62 	} else {
63 		/* This is pretty slow when called a lot
64 		hdc = CreateCompatibleDC(NULL);
65 		SelectObject(hdc, hwnd);
66 		SetPixelV(hdc, x, y, gc->foreground);
67 		DeleteDC(hdc);
68 		*/
69 	}
70 	return 1;
71 }
72 #endif
73 
XClearArea(Display * dpy,Window w,int x,int y,unsigned int width,unsigned int height,Bool exposures)74 int XClearArea(Display *dpy, Window w, int x, int y, unsigned int width, unsigned int height, Bool exposures)
75 {
76 	HWND hnd;
77 	RECT r;
78 	HDC hdc;
79 	int oldROP;
80 
81 	hnd = Tk_GetHWND(w);
82 	hdc = GetDC(hnd);
83 	oldROP = SetROP2(hdc, R2_COPYPEN);
84 	GetClientRect(hnd, &r);
85 	if (width != 0 || height != 0) {
86 		r.left = x;
87 		r.top = y;
88 		r.right = x+width;
89 		r.bottom = y+height;
90 		FillRect(hdc, &r, (HBRUSH)(COLOR_WINDOW+1));
91 	}
92 	SetROP2(hdc, oldROP);
93 	ReleaseDC(hnd, hdc);
94 	return 1;
95 }
96 
XCreatePixmap(Display * dpy,Drawable d,unsigned int width,unsigned int height,unsigned int depth)97 Pixmap XCreatePixmap(Display *dpy, Drawable d, unsigned int width, unsigned int height, unsigned int depth)
98 {
99 	return Tk_GetPixmap(dpy, d, width, height, depth);
100 }
101 
XLookupString(XKeyEvent * event,char * buf,int buflen,KeySym * keysym,XComposeStatus * status)102 int XLookupString(XKeyEvent *event, char *buf, int buflen, KeySym *keysym, XComposeStatus *status)
103 {
104 #if 0
105 	printf("code : %04x\n", event->keycode);
106 	printf("state: %04x\n", event->state);
107 #endif
108 	switch (event->keycode) {
109 	  case VK_NUMPAD0:
110 	  case VK_NUMPAD1:
111 	  case VK_NUMPAD2:
112 	  case VK_NUMPAD3:
113 	  case VK_NUMPAD4:
114 	  case VK_NUMPAD5:
115 	  case VK_NUMPAD6:
116 	  case VK_NUMPAD7:
117 	  case VK_NUMPAD8:
118 	  case VK_NUMPAD9:
119 		  *keysym = XK_KP_0 + (event->keycode - VK_NUMPAD0);
120 		  event->state |= ShiftMask;
121 		  break;
122 	  default:
123 		  *keysym = XKeycodeToKeysym(NULL, event->keycode, event->state);
124 		  break;
125 	}
126 	return 1;
127 }
128 
XCheckWindowEvent(Display * dpy,Window w,long event_mask,XEvent * event)129 Bool XCheckWindowEvent(Display *dpy, Window w, long event_mask, XEvent *event)
130 {
131 	unimplemented("XCheckWindowEvent");
132 	return False;
133 }
134 
XTextWidth(XFontStruct * font,char * string,int len)135 int XTextWidth(XFontStruct *font, char *string, int len)
136 {
137 	Tk_Font tkfont = get_tkfont(font->fid);
138 	return Tk_TextWidth(tkfont, string, len);
139 }
140 
XDrawString(Display * dpy,Drawable d,GC gc,int x,int y,char * string,int len)141 int XDrawString(Display *dpy, Drawable d, GC gc, int x, int y, char *string, int len)
142 {
143 	Tk_Font tkfont = get_tkfont(gc->font);
144 	Tk_DrawChars(dpy, d, gc, tkfont, string, len, x, y);
145 	return 1;
146 }
147 
XFreePixmap(Display * dpy,Pixmap pix)148 int XFreePixmap(Display *dpy, Pixmap pix)
149 {
150 	Tk_FreePixmap(dpy, pix);
151 	return 1;
152 }
153 
154 #ifndef STATIC_BUILD
XPutImage(Display * dpy,Drawable d,GC gc,XImage * img,int src_x,int src_y,int dest_x,int dest_y,unsigned int width,unsigned int height)155 int XPutImage(Display *dpy, Drawable d, GC gc, XImage *img, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)
156 {
157 	// unimplemented("XPutImage");
158 
159 	TkPutImage(NULL, 0, dpy, d, gc, img, src_x, src_y, dest_x, dest_y,
160 			width, height);
161 	return 1;
162 }
163 #endif
164 
165 // The following two functions may be defined as macros. . .
166 
167 #ifndef XSync
XSync(Display * dpy,Bool discard)168 int XSync(Display *dpy, Bool discard)
169 {
170 	unimplemented("XSync");
171 	return 1;
172 }
173 #endif
174 
175 #ifndef XFlush
XFlush(Display * dpy)176 int XFlush(Display *dpy)
177 {
178 	unimplemented("XFlush");
179 	return 1;
180 }
181 #endif
182 
183 #ifndef STATIC_BUILD
XCreateFontCursor(Display * dpy,unsigned int shape)184 Cursor XCreateFontCursor(Display *dpy, unsigned int shape)
185 {
186 	Tk_Window win = Tk_MainWindow(xcinterp);
187 
188 	switch (shape) {
189 		case XC_xterm: return (Cursor)Tk_GetCursor(xcinterp, win, "xterm");
190 		case XC_watch: return (Cursor)Tk_GetCursor(xcinterp, win, "watch");
191 		default: return (Cursor)NULL;
192 	}
193 }
194 #endif
195 
XDefineCursor_TkW32(Display * dpy,Window w,Cursor c)196 void XDefineCursor_TkW32(Display *dpy, Window w, Cursor c)
197 {
198 	Tk_DefineCursor(Tk_IdToWindow(dpy, w), (Tk_Cursor)c);
199 }
200 
reverse_byte(u_char c)201 static u_char reverse_byte(u_char c)
202 {
203 	u_char rc = 0;
204 	int i;
205 
206 	for (i=(sizeof(char)*8-1); i>=0; i--, c>>=1)
207 		rc |= (c&0x01) << i;
208 	return rc;
209 }
210 
compute_cursor_src_mask(u_char * src,u_char * mask)211 static void compute_cursor_src_mask(u_char *src, u_char *mask)
212 {
213 	u_char pixsrc = *src, pixmask = *mask;
214 	*src = ~(reverse_byte(pixmask));
215 	*mask = reverse_byte(~pixsrc & pixmask);
216 }
217 
218 typedef struct tkw32cursor {
219 	struct tkcursor {
220 		Tk_Cursor cursor;
221 		Display *display;
222 		int resourceCount;
223 		int objRefCount;
224 		Tcl_HashTable *otherTable;
225 		Tcl_HashEntry *hashPtr;
226 		Tcl_HashEntry *idHashPtr;
227 		struct tkcursor *nextPtr;
228 	} info;
229 	HCURSOR winCursor;
230 	int system;
231 } w32cursor;
232 
233 static
Tk_GetCursorFromData_TkW32(Tcl_Interp * interp,Tk_Window w,u_char * src,u_char * mask,int width,int height,int xhot,int yhot,Tk_Uid fg,Tk_Uid bg)234 Cursor Tk_GetCursorFromData_TkW32(Tcl_Interp *interp, Tk_Window w, u_char *src, u_char *mask, int width, int height, int xhot, int yhot, Tk_Uid fg, Tk_Uid bg)
235 {
236 	w32cursor *wcursor;
237 
238 	wcursor = (w32cursor*)ckalloc(sizeof(w32cursor));
239 	wcursor->info.cursor = (Tk_Cursor)wcursor;
240 	wcursor->winCursor = NULL;
241 	wcursor->system = 0;
242 
243 	wcursor->winCursor = CreateCursor(Tk_GetHINSTANCE(), xhot, yhot, width, height, src, mask);
244 	if (wcursor->winCursor == NULL) {
245 		ckfree((char*)wcursor);
246 		return (Cursor)NULL;
247 	}
248 
249 	return (Cursor)wcursor;
250 }
251 
CreateW32Cursor(Tcl_Interp * interp,Tk_Window w,u_char * src,u_char * mask,int width,int height,int xhot,int yhot,Tk_Uid fg,Tk_Uid bg)252 Cursor CreateW32Cursor(Tcl_Interp *interp, Tk_Window w, u_char *src, u_char *mask, int width, int height, int xhot, int yhot, Tk_Uid fg, Tk_Uid bg)
253 {
254 	u_char *new_src, *new_mask;
255 	int nb = (width-1)/(8*sizeof(char))+1;
256 	int nb2 = (GetSystemMetrics(SM_CXCURSOR)-1)/(8*sizeof(char))+1, height2 = GetSystemMetrics(SM_CYCURSOR);
257 	int i, j, idx1 = 0, idx2 = 0;
258 	Cursor cursor;
259 
260 	new_src = (u_char*)malloc(sizeof(char)*nb2*height2);
261 	new_mask = (u_char*)malloc(sizeof(char)*nb2*height2);
262 
263 	for (j=0; j<height; j++) {
264 		for (i=0; i<nb; i++, idx1++, idx2++) {
265 			new_src[idx2] = src[idx1];
266 			new_mask[idx2] = mask[idx1];
267 			compute_cursor_src_mask(&new_src[idx2], &new_mask[idx2]);
268 			/*printf("%02x ", new_src[idx2]);*/
269 		}
270 		for (i=0; i<(nb2-nb); i++, idx2++) {
271 			new_src[idx2] = 0xff;
272 			new_mask[idx2] = 0x00;
273 			/*printf("%02x ", new_src[idx2]);*/
274 		}
275 		/*printf("\n");*/
276 	}
277 	for (j=0; j<(height2-height); j++) {
278 		for (i=0; i<nb2; i++, idx2++) {
279 			new_src[idx2] = 0xff;
280 			new_mask[idx2] = 0x00;
281 			/*printf("%02x ", new_src[idx2]);*/
282 		}
283 		/*printf("\n");*/
284 	}
285 	/*printf("\n");*/
286 
287 	cursor = Tk_GetCursorFromData_TkW32(interp, w, new_src, new_mask, nb2*8, height2, xhot, yhot, fg, bg);
288 
289 	free(new_src);
290 	free(new_mask);
291 
292 	return cursor;
293 }
294 
XRecolorCursor(Display * dpy,Cursor cursor,XColor * foreground,XColor * background)295 int XRecolorCursor(Display *dpy, Cursor cursor, XColor *foreground, XColor *background)
296 {
297 	unimplemented("XRecolorCursor");
298 	return 1;
299 }
300 
XAllocNamedColor(Display * dpy,Colormap cm,char * cname,XColor * screen_return,XColor * exact_return)301 Status XAllocNamedColor(Display *dpy, Colormap cm, char* cname, XColor *screen_return, XColor *exact_return)
302 {
303 	XColor *c = Tk_GetColor(xcinterp, (areawin ? areawin->area : NULL), cname);
304 
305 	if (c != NULL) {
306 		screen_return->pixel = c->pixel;
307 		exact_return->pixel = c->pixel;
308 		return True;
309 	}
310 	return False;
311 }
312 
XLookupColor_TkW32(Display * dpy,Colormap cmap,const char * name,XColor * cvcolor,XColor * cvexact)313 Status XLookupColor_TkW32(Display *dpy, Colormap cmap, const char *name, XColor *cvcolor, XColor *cvexact)
314 {
315 	if (XParseColor(dpy, cmap, name, cvcolor)) {
316 		return True;
317 	}
318 	else {
319 		return False;
320 	}
321 }
322 
XQueryColors_TkW32(Display * dpy,Colormap cmap,XColor * colors,int ncolors)323 int XQueryColors_TkW32(Display *dpy, Colormap cmap, XColor *colors, int ncolors)
324 {
325 	int i;
326 
327 	for (i=0; i<ncolors; i++) {
328 		int pixel = colors[i].pixel;
329 		colors[i].red = ((pixel&0x000000ff)<<8)|(pixel&0x000000ff);
330 		colors[i].green = (pixel&0x0000ff00)|((pixel&0x0000ff00)>>8);
331 		colors[i].blue = ((pixel&0x00ff0000)>>8)|((pixel&0x00ff0000)>>16);
332 	}
333 
334 	return 1;
335 }
336 
XQueryPointer_TkW32(Display * dpy,Window w,Window * root_return,Window * child_return,int * root_x,int * root_y,int * win_x,int * win_y,unsigned int * mask)337 Bool XQueryPointer_TkW32(Display *dpy, Window w, Window *root_return, Window *child_return,
338 		int *root_x, int *root_y, int *win_x, int *win_y, unsigned int *mask)
339 {
340 	POINT p;
341 
342 	GetCursorPos(&p);
343 	*root_x = p.x;
344 	*root_y = p.y;
345 	ScreenToClient(Tk_GetHWND(w), &p);
346 	*win_x = p.x;
347 	*win_y = p.y;
348 	*mask = 0;
349 
350 	return True;
351 }
352 
XCopyColormapAndFree(Display * dpy,Colormap cmap)353 Colormap XCopyColormapAndFree(Display *dpy, Colormap cmap)
354 {
355 	unimplemented("XCopyColormapAndFree");
356 	return cmap;
357 }
358 
XDisplayString(Display * dpy)359 char* XDisplayString(Display *dpy)
360 {
361 	/*printf("XDisplayString\n");*/
362 	return "localhost:0.0\n";
363 }
364 
365 
XKeysymToString_TkW32(KeySym ks)366 char* XKeysymToString_TkW32(KeySym ks)
367 {
368 	return TkKeysymToString(ks);
369 }
370 
XLoadQueryFont(Display * dpy,char * fontname)371 XFontStruct* XLoadQueryFont(Display *dpy, char *fontname)
372 {
373 	Tk_Font tkfont;
374 	Tk_FontMetrics tkfm;
375 	XFontStruct *fs;
376 
377 	tkfont = Tk_GetFont(xcinterp, Tk_MainWindow(xcinterp), fontname);
378 	if (tkfont != NULL)
379 	{
380 		fs = (XFontStruct*)malloc(sizeof(XFontStruct));
381 		fs->fid = Tk_FontId(tkfont);
382 		Tk_GetFontMetrics(tkfont, &tkfm);
383 		fs->ascent = tkfm.ascent;
384 		fs->descent = tkfm.descent;
385 		add_tkfont(tkfont, fs->fid);
386 		return fs;
387 	}
388 	else
389 		return NULL;
390 }
391 
opendir(const char * name)392 DIR* opendir(const char *name)
393 {
394 	DIR *d = (DIR*)malloc(sizeof(DIR));
395 	static char buffer[MAX_PATH];
396 
397 	strncpy(buffer, name, MAX_PATH);
398 	strncat(buffer, "\\*", MAX_PATH);
399 	d->hnd = FindFirstFile(buffer, &(d->fd));
400 	if (d->hnd == INVALID_HANDLE_VALUE)
401 		return NULL;
402 	d->dirty = 1;
403 	return d;
404 }
405 
closedir(DIR * d)406 void closedir(DIR *d)
407 {
408 	free(d);
409 }
410 
readdir(DIR * d)411 struct direct* readdir(DIR *d)
412 {
413 	if (!d->dirty)
414 	{
415 		if (!FindNextFile(d->hnd, &(d->fd)))
416 			return NULL;
417 	}
418 	d->d.d_name = d->fd.cFileName;
419 	d->dirty = 0;
420 	return &(d->d);
421 }
422