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