2 #define _WIN32_WINNT 0x0500
10 #include "colordefs.h"
13 #include "prototypes.h"
16 #include "xcwin32-colors.h"
19 #define MK_XBUTTON1 32
20 #define MK_XBUTTON2 64
24 #define W32DEBUG(x) printf##x
29 extern XCWindowData
*areawin
;
30 extern Globaldata xobjs
;
31 extern char _STR2
[250];
32 extern Pixmap STIPPLE
[STIPPLES
]; /* Polygon fill-style stipple patterns */
33 static char STIPDATA
[STIPPLES
][4] = {
43 extern xcWidget top
, message2
, message3
;
44 extern ApplicationData appdata
;
45 extern int number_colors
;
46 extern colorindex
*colorlist
;
47 extern menustruct TopButtons
[];
48 extern short maxbuttons
;
49 extern xcWidget menuwidgets
[MaxMenuWidgets
];
51 extern toolbarstruct ToolBar
[];
52 extern short toolbuttons
;
53 extern Pixmap dbuf
, helppix
;
54 extern Dimension helpwidth
, helpheight
;
58 extern propstruct okstruct
[MAXPROPS
], fpokstruct
;
60 static HWND corner
= NULL
, statusBar
= NULL
;
61 static Widget toolBar
= NULL
;
62 static int statusBarWidth
[2] = { 100, -1 };
67 LRESULT CALLBACK XcStaticProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
68 LRESULT CALLBACK XcEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
69 LRESULT CALLBACK XcButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
70 LRESULT CALLBACK XcToggleProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
71 LRESULT CALLBACK XcPopupProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
74 INT_PTR CALLBACK
OutputDlgProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
75 void updatename(xcWidget button
, xcWidgetList callstruct
, caddr_t calldata
);
76 void linkset(xcWidget button
, propstruct
*callstruct
, caddr_t calldata
);
77 extern int COM_initialize();
78 extern int COM_terminate();
81 #define WIN_MENUITEM 1
84 #define WIN_TOOLITEM 4
86 #define IS_WIDGET(w) (w->type == WIN_WIDGET)
87 #define IS_MENU(w) (w->type == WIN_MENU)
88 #define IS_MENUITEM(w) (w->type == WIN_MENUITEM)
89 #define IS_STATUS(w) (w->type == WIN_STATUS)
90 #define IS_TOOLITEM(w) (w->type == WIN_TOOLITEM)
92 #define TOWIDGET(w) ((Widget)w)
93 #define TOMENU(w) ((Menu)w)
94 #define TOMENUITEM(w) ((MenuItem)w)
95 #define TOSTATUS(w) ((StatusItem)w)
96 #define TOTOOLITEM(w) ((ToolItem)w)
98 #define STATUSBAR_ID 10000
99 #define TOOLBAR_ID 10001
101 typedef struct __WinCallback
{
105 struct __WinCallback
*next
;
107 typedef WinCallback WinEventHandler
;
113 WinCallback
*callbacks
;
114 WinEventHandler
*handlers
;
120 #define HAS_HANDLER(win,themask) (win->handler_mask & themask)
121 #define WM_BITBLT (WM_USER+1)
128 struct __WinMenuItem
{
130 struct __WinMenu
*parentMenu
;
131 struct __WinMenu
*popup
;
135 WinCallback
*callbacks
;
140 struct __WinStatusItem
{
146 struct __WinToolItem
{
148 struct __WinWidget
*toolbar
;
151 WinCallback
*callbacks
;
154 typedef struct __WinMenu
* Menu
;
155 typedef struct __WinMenuItem
* MenuItem
;
156 typedef struct __WinStatusItem
* StatusItem
;
157 typedef struct __WinToolItem
* ToolItem
;
159 void execute_callback(int action
, Widget w
, void *calldata
)
168 cb
= ((MenuItem
)w
)->callbacks
;
171 cb
= ((ToolItem
)w
)->callbacks
;
177 if (cb
->action
== action
) {
178 (*cb
->proc
)(w
, cb
->data
, calldata
);
184 void execute_handler(int mask
, Widget w
, void *calldata
)
186 WinCallback
*h
= w
->handlers
;
187 if (!HAS_HANDLER(w
,mask
))
190 if (h
->action
& mask
)
191 (*h
->proc
)(w
, h
->data
, calldata
);
196 void update_event_mask(Widget win
)
198 WinEventHandler
*h
= win
->handlers
;
199 win
->handler_mask
= 0;
200 for (; h
!= NULL
; h
=h
->next
)
201 win
->handler_mask
|= h
->action
;
204 Widget
get_widget(HWND win
)
207 int nbytes = GetClassLong(win, GCL_CBWNDEXTRA);
208 if (nbytes >= sizeof(Widget))
209 return (Widget)GetWindowLong(win, nbytes-sizeof(Widget));
213 return (Widget
)GetWindowLong(win
, GWL_USERDATA
);
216 static void get_value(Widget w
, Arg
*a
)
222 if (w
->type
== WIN_STATUS
) {
223 StatusItem item
= (StatusItem
)w
;
224 if (item
->position
< 1)
225 *(int*)(a
->data
) = statusBarWidth
[item
->position
];
227 GetClientRect(w
->handle
, &rect
);
228 *(int*)(a
->data
) = rect
.right
- rect
.left
- statusBarWidth
[0];
231 if (GetClientRect(w
->handle
, &rect
))
232 *(int*)(a
->data
) = rect
.right
- rect
.left
;
236 if (GetClientRect(w
->handle
, &rect
))
237 *(int*)(a
->data
) = rect
.bottom
- rect
.top
;
241 if (w
->type
== WIN_MENUITEM
) {
242 *(int*)(a
->data
) = ((MenuItem
)w
)->menudata
;
248 W32DEBUG(("Unsupported get value: %d\n", a
->type
));
253 static void set_value(Widget w
, Arg
*a
)
259 SendMessage(TOSTATUS(w
)->handle
, SB_SETTEXT
, TOSTATUS(w
)->position
, (LPARAM
)(char*)a
->data
);
262 SetWindowText(w
->handle
, (char*)a
->data
);
271 CheckMenuItem(TOMENUITEM(w
)->parentMenu
->handle
, TOMENUITEM(w
)->position
,
272 MF_BYPOSITION
|(a
->data
== NULL
? MF_UNCHECKED
: MF_CHECKED
));
282 MENUITEMINFO mi_info
;
283 ZeroMemory(&mi_info
, sizeof(mi_info
));
284 mi_info
.cbSize
= sizeof(mi_info
);
285 mi_info
.fMask
= MIIM_STRING
;
286 mi_info
.dwTypeData
= a
->data
;
287 SetMenuItemInfo(TOMENUITEM(w
)->parentMenu
->handle
, TOMENUITEM(w
)->position
, MF_BYPOSITION
, &mi_info
);
291 SetWindowText(w
->handle
, (char*)a
->data
);
300 SendMessage(w
->handle
, WM_SETFONT
, (WPARAM
)((XFontStruct
*)a
->data
)->fid
, MAKELONG(TRUE
, 0));
309 SendMessage(w
->handle
, BM_SETCHECK
, ((int)a
->data
== True
? BST_CHECKED
: BST_UNCHECKED
), 0);
318 if ((int)a
->data
== RATSNESTCOLOR
) {
319 W32DEBUG(("Check button: %s\n", ((ToolItem
)w
)->name
));
320 SendMessage(TOTOOLITEM(w
)->toolbar
->handle
, TB_CHECKBUTTON
, TOTOOLITEM(w
)->ID
, MAKELONG(TRUE
, 0));
323 W32DEBUG(("Uncheck button: %s\n", ((ToolItem
)w
)->name
));
324 SendMessage(TOTOOLITEM(w
)->toolbar
->handle
, TB_CHECKBUTTON
, TOTOOLITEM(w
)->ID
, MAKELONG(FALSE
, 0));
333 W32DEBUG(("Unsupported set value: %d\n", a
->type
));
339 void WinGetValues(Widget w
, Arg
*args
, int n
)
345 get_value(w
, args
+i
);
348 void WinSetValues(Widget w
, Arg
*args
, int n
)
354 set_value(w
, args
+i
);
357 HBITMAP
WinCreatePixmap(HWND w
, int width
, int height
)
363 hBitmap
= CreateCompatibleBitmap(hdc
, width
, height
);
368 Widget
WinParent(Widget child
)
371 switch (child
->type
) {
373 return (Widget
)get_widget(GetParent(child
->handle
));
375 return (Widget
)((MenuItem
)child
)->parentMenu
;
377 return (Widget
)((ToolItem
)child
)->toolbar
;
382 void WinFreePixmap(Pixmap pix
)
387 void WinDestroyImage(XImage
*img
)
389 if (img
->handle
!= NULL
)
390 DeleteObject(img
->handle
);
395 XImage
* WinCreateImage(int width
, int height
)
397 HWND h
= GetDesktopWindow();
399 XImage
*img
= (XImage
*)malloc(sizeof(XImage
));
401 img
->bits_per_pixel
= GetDeviceCaps(hdc
, BITSPIXEL
);
402 img
->bytes_per_line
= width
* img
->bits_per_pixel
/ 8;
404 img
->height
= height
;
411 int WinGetPixel(XImage
*img
, int x
, int y
)
414 if (img
->bits_per_pixel
!= 32) {
415 W32DEBUG(("WinGetPixel only supported on 32bpp\n"));
418 src
= img
->data
+ (y
* img
->bytes_per_line
) + (x
* img
->bits_per_pixel
) / 8;
419 return RGB(src
[0], src
[1], src
[2]);
422 void WinPutPixel(XImage
*img
, int x
, int y
, Pixel pix
)
425 if (img
->bits_per_pixel
!= 32) {
426 W32DEBUG(("WinPutPixel only supported on 32bpp\n"));
429 src
= img
->data
+ (y
* img
->bytes_per_line
) + (x
* img
->bits_per_pixel
) / 8;
430 src
[0] = GetRValue(pix
);
431 src
[1] = GetGValue(pix
);
432 src
[2] = GetBValue(pix
);
435 DIR* opendir(const char *name
)
437 DIR *d
= (DIR*)malloc(sizeof(DIR));
438 static char buffer
[MAX_PATH
];
440 strncpy(buffer
, name
, MAX_PATH
);
441 strncat(buffer
, "\\*", MAX_PATH
);
442 d
->hnd
= FindFirstFile(buffer
, &(d
->fd
));
443 if (d
->hnd
== INVALID_HANDLE_VALUE
)
449 void closedir(DIR *d
)
454 struct direct
* readdir(DIR *d
)
458 if (!FindNextFile(d
->hnd
, &(d
->fd
)))
461 d
->d
.d_name
= d
->fd
.cFileName
;
466 int WinDesktopWidth(void)
469 GetWindowRect(GetDesktopWindow(), &r
);
470 return r
.right
-r
.left
;
473 int WinDesktopHeight(void)
476 GetWindowRect(GetDesktopWindow(), &r
);
477 return r
.bottom
-r
.top
;
480 void WinSetCursor(HWND win
, HCURSOR cursor
)
482 SetClassLong(win
, GCL_HCURSOR
, (LONG
)cursor
);
485 HDC cached_hdc
= NULL
;
486 HWND cached_win
= NULL
;
488 static HPEN
create_pen(GC gc
)
492 if (gc
->line_style
!= LineSolid
&& gc
->line_dash_len
> 0 && gc
->line_dash
!= NULL
) {
493 DWORD
*dashes
= NULL
;
498 logBrush
.lbStyle
= BS_SOLID
;
499 logBrush
.lbColor
= gc
->foreground
;
500 logBrush
.lbHatch
= 0;
502 style
|= PS_GEOMETRIC
| PS_USERSTYLE
| gc
->line_cap
| gc
->line_join
;
503 dashes
= (DWORD
*)malloc(sizeof(DWORD
)*gc
->line_dash_len
);
504 for (i
=0; i
<gc
->line_dash_len
; i
++)
505 dashes
[i
] = gc
->line_dash
[i
];
506 hPen
= ExtCreatePen(PS_GEOMETRIC
| PS_USERSTYLE
| gc
->line_cap
| gc
->line_join
,
507 gc
->line_width
, &logBrush
, gc
->line_dash_len
, dashes
);
510 hPen
= CreatePen(PS_SOLID
, gc
->line_width
, gc
->foreground
);
516 static HBRUSH
create_brush(GC gc
)
519 logBrush
.lbStyle
= (gc
->fill_style
== FillSolid
? BS_SOLID
: BS_PATTERN
);
520 logBrush
.lbColor
= gc
->foreground
;
521 logBrush
.lbHatch
= (LONG
)(gc
->fill_style
!= FillSolid
? gc
->fill_stipple
: NULL
);
522 return CreateBrushIndirect(&logBrush
);
525 static HDC
get_hdc(HWND win
, GC gc
)
529 Widget winwidget
= (Widget
)get_widget(win
);
530 if (winwidget
== NULL
|| winwidget
->buffer
== NULL
)
533 hdc
= winwidget
->bufhdc
;
534 } else if (win
== cached_win
&& cached_hdc
!= NULL
) {
537 hdc
= CreateCompatibleDC(NULL
);
538 SelectObject(hdc
, win
);
539 if (cached_hdc
!= NULL
)
540 DeleteDC(cached_hdc
);
545 SetROP2(hdc
, gc
->function
);
546 SetBkColor(hdc
, gc
->background
);
547 SetTextColor(hdc
, gc
->foreground
);
548 SetBkMode(hdc
, TRANSPARENT
);
549 SelectObject(hdc
, create_pen(gc
));
550 SelectObject(hdc
, create_brush(gc
));
551 SelectObject(hdc
, gc
->font
);
556 static release_hdc(HWND win
, HDC hdc
)
558 DeleteObject(SelectObject(hdc
, GetStockObject(BLACK_PEN
)));
559 DeleteObject(SelectObject(hdc
, GetStockObject(NULL_BRUSH
)));
561 Widget winwidget
= (Widget
)get_widget(win
);
562 if (winwidget
== NULL
|| winwidget
->buffer
== NULL
)
565 PostMessage(win
, WM_BITBLT
, 0, 0);
572 void WinDrawLine(HWND win
, GC gc
, int x1
, int y1
, int x2
, int y2
)
574 HDC hdc
= get_hdc(win
, gc
);
575 MoveToEx(hdc
, x1
, y1
, NULL
);
577 release_hdc(win
, hdc
);
580 void WinFillPolygon(HWND win
, GC gc
, XPoint
* pathlist
, int number
)
582 LPPOINT pts
= (LPPOINT
)malloc(sizeof(POINT
)*number
);
583 HDC hdc
= get_hdc(win
, gc
);
584 RECT rect
= { 0x0000ffff, 0x0000ffff, -0x0000ffff, -0x0000ffff };
587 DeleteObject(SelectObject(hdc
, CreatePen(PS_NULL
, 0, 0)));
589 for (i
=0; i
<number
; i
++) {
590 pts
[i
].x
= pathlist
[i
].x
;
591 pts
[i
].y
= pathlist
[i
].y
;
592 rect
.left
= min(rect
.left
, pts
[i
].x
);
593 rect
.top
= min(rect
.top
, pts
[i
].y
);
594 rect
.right
= max(rect
.right
, pts
[i
].x
);
595 rect
.bottom
= max(rect
.bottom
, pts
[i
].y
);
597 if (gc
->fill_style
== FillStippled
) {
598 int width
= rect
.right
-rect
.left
, height
= rect
.bottom
-rect
.top
;
599 HDC tmphdc
= CreateCompatibleDC(hdc
);
600 HBITMAP tmpbmp
= CreateCompatibleBitmap(hdc
, width
, height
);
601 HBRUSH tmpbrush
= CreateSolidBrush(gc
->foreground
);
603 SelectObject(tmphdc
, tmpbmp
);
604 SelectObject(tmphdc
, tmpbrush
);
605 SetROP2(tmphdc
, gc
->function
);
606 BitBlt(tmphdc
, 0, 0, width
, height
, hdc
, rect
.left
, rect
.top
, SRCCOPY
);
607 for (i
=0; i
<number
; i
++) {
608 pts
[i
].x
-= rect
.left
;
609 pts
[i
].y
-= rect
.top
;
611 Polygon(tmphdc
, pts
, number
);
612 BitBlt(hdc
, rect
.left
, rect
.top
, width
, height
, tmphdc
, 0, 0, 0x00AC0744);
615 DeleteObject(tmpbmp
);
616 DeleteObject(tmpbrush
);
618 Polygon(hdc
, pts
, number
);
621 release_hdc(win
, hdc
);
625 void WinDrawArc(HWND win
, GC gc
, int x
, int y
, int width
, int height
, int angle
, int span
)
627 HDC hdc
= get_hdc(win
, gc
);
628 if (span
!= (360*64)) {
629 W32DEBUG(("Unimplemented\n"));
631 Ellipse(hdc
, x
, y
, width
, height
);
632 release_hdc(win
, hdc
);
635 void WinClearArea(HWND win
, int x
, int y
, int w
, int h
)
637 HDC hdc
= get_hdc(win
, NULL
);
643 FillRect(hdc
, &r
, (HBRUSH
)(COLOR_WINDOW
+1));
644 release_hdc(win
, hdc
);
647 void WinFillRectangle(HWND win
, GC gc
, int x
, int y
, int w
, int h
)
649 HDC hdc
= get_hdc(win
, gc
);
655 FillRect(hdc
, &r
, (HBRUSH
)GetCurrentObject(hdc
, OBJ_BRUSH
));
656 release_hdc(win
, hdc
);
659 void WinSetFunction(GC gc
, int op
)
664 void WinSetForeground(GC gc
, int color
)
666 gc
->foreground
= color
;
669 void WinSetBackground(GC gc
, int rgb
)
671 gc
->background
= rgb
;
674 void WinCopyArea(Pixmap pix
, HWND win
, GC gc
, int x
, int y
, int width
, int height
, int offx
, int offy
)
676 HDC pixhdc
= get_hdc((HWND
)pix
, gc
), hdc
= get_hdc(win
, gc
);
677 BitBlt(hdc
, offx
, offy
, width
, height
, pixhdc
, x
, y
, SRCCOPY
);
678 release_hdc((HWND
)pix
, pixhdc
);
679 release_hdc(win
, hdc
);
682 void WinDrawPoint(HWND win
, GC gc
, int x
, int y
)
684 HDC hdc
= get_hdc(win
, gc
);
685 SetPixelV(hdc
, x
, y
, gc
->foreground
);
686 release_hdc(win
, hdc
);
689 void WinSetLineAttributes(GC gc
, int width
, int style
, int capstyle
, int joinstyle
)
691 gc
->line_style
= style
;
692 gc
->line_width
= width
;
693 gc
->line_cap
= capstyle
;
694 gc
->line_join
= joinstyle
;
697 void WinWarpPointer(HWND w
, int x
, int y
)
703 ClientToScreen(w
, &pt
);
704 SetCursorPos(pt
.x
, pt
.y
);
707 void WinDrawLines(HWND win
, GC gc
, XPoint
* pathlist
, int number
)
709 LPPOINT pts
= (LPPOINT
)malloc(sizeof(POINT
)*number
);
710 HDC hdc
= get_hdc(win
, gc
);
713 for (i
=0; i
<number
; i
++) {
714 pts
[i
].x
= pathlist
[i
].x
;
715 pts
[i
].y
= pathlist
[i
].y
;
717 Polyline(hdc
, pts
, number
);
718 release_hdc(win
, hdc
);
722 void WinQueryPointer(HWND win
, int *x
, int *y
)
726 if (GetCursorPos(&pt
)) {
727 ScreenToClient(win
, &pt
);
733 void WinDrawRectangle(HWND win
, GC gc
, int x
, int y
, int width
, int height
)
735 HDC hdc
= get_hdc(win
, gc
);
736 Rectangle(hdc
, x
, y
, x
+width
, y
+height
);
737 release_hdc(win
, hdc
);
740 GC
WinCreateGC(HWND win
, int mask
, XGCValues
*values
)
742 GC gc
= (GC
)malloc(sizeof(struct __GC
));
744 gc
->foreground
= RGB(0, 0, 0);
745 gc
->background
= RGB(255, 255, 255);
746 gc
->function
= R2_COPYPEN
;
748 gc
->graphics_exposures
= False
;
749 gc
->fill_style
= BS_SOLID
;
750 gc
->fill_stipple
= NULL
;
752 gc
->line_style
= PS_SOLID
;
753 gc
->line_cap
= PS_ENDCAP_ROUND
;
754 gc
->line_join
= PS_JOIN_BEVEL
;
755 gc
->line_dash_len
= 0;
756 gc
->line_dash
= NULL
;
759 if (mask
& GCForeground
)
760 gc
->foreground
= values
->foreground
;
761 if (mask
& GCBackground
)
762 gc
->background
= values
->background
;
764 gc
->font
= values
->font
;
765 if (mask
& GCFunction
)
766 gc
->function
= values
->function
;
767 if (mask
& GCGraphicsExposures
)
768 gc
->graphics_exposures
= values
->graphics_exposures
;
773 void WinFreeGC(GC gc
)
778 void WinSetDashes(GC gc
, int offset
, char *dash
, int n
)
782 gc
->line_dash
= NULL
;
783 gc
->line_dash_len
= 0;
785 if (n
> 0 && dash
!= NULL
) {
786 gc
->line_dash
= (char*)malloc(sizeof(char)*n
);
787 memcpy(gc
->line_dash
, dash
+offset
, n
);
788 gc
->line_dash_len
= n
;
792 void WinSetFillStyle(GC gc
, int style
)
794 gc
->fill_style
= style
;
797 void WinSetStipple(GC gc
, Pixmap pattern
)
799 gc
->fill_stipple
= pattern
;
802 HCURSOR
WinCreateStandardCursor(char *cur
)
804 return LoadCursor(NULL
, cur
);
807 void WinDrawString(HWND win
, GC gc
, int x
, int y
, const char *str
, int len
)
809 HDC hdc
= get_hdc(win
, gc
);
814 GetTextExtentPoint32(hdc, str, len, &sz);
819 TextOut(hdc, r.left, r.top, str, len);
821 SetTextAlign(hdc
, TA_LEFT
|TA_BASELINE
);
822 TextOut(hdc
, x
, y
, str
, len
);
823 release_hdc(win
, hdc
);
826 int WinTextWidth(XFontStruct
*fn
, char *s
, int len
)
828 HWND w
= GetDesktopWindow();
832 SelectObject(hdc
, fn
->fid
);
833 GetTextExtentPoint32(hdc
, s
, len
, &sz
);
839 void WinTextExtents(XFontStruct
*fn
, char *str
, int len
, int *width
, int *height
)
841 HWND w
= GetDesktopWindow();
845 SelectObject(hdc
, fn
->fid
);
846 GetTextExtentPoint32(hdc
, str
, len
, &sz
);
853 #define DUPBITS(x) (((x)<<8)|(x))
855 void WinQueryColors(XColor
*colors
, int n
)
859 for (i
=0; i
<n
; i
++) {
860 colors
[i
].red
= DUPBITS(GetRValue(colors
[i
].pixel
));
861 colors
[i
].green
= DUPBITS(GetGValue(colors
[i
].pixel
));
862 colors
[i
].blue
= DUPBITS(GetBValue(colors
[i
].pixel
));
866 void WinAppMainLoop(void)
871 DrawMenuBar(top
->handle
);
872 ShowWindow(top
->handle
, SW_SHOWNORMAL
);
873 while ((bRet
= GetMessage(&msg
, NULL
, 0, 0)) != 0) {
875 W32DEBUG(("Loop error\n"));
878 if (GetAncestor(msg
.hwnd
, GA_ROOT
) != topwin
) {
879 TranslateMessage(&msg
);
881 DispatchMessage(&msg
);
890 void WinPutImage(HWND win
, GC gc
, XImage
*img
, int srcx
, int srcy
, int destx
, int desty
, int width
, int height
)
894 if (img
->handle
== NULL
) {
895 W32DEBUG(("Invalid image handle\n"));
899 pixhdc
= get_hdc((HWND
)img
->handle
, gc
);
900 hdc
= get_hdc(win
, gc
);
901 if (gc
->clipMask
== NULL
)
902 BitBlt(hdc
, destx
, desty
, width
, height
, pixhdc
, srcx
, srcy
, SRCCOPY
);
904 MaskBlt(hdc
, destx
, desty
, width
, height
, pixhdc
, srcx
, srcy
, gc
->clipMask
, 0, 0, SRCCOPY
);
905 release_hdc((HWND
)img
->handle
, pixhdc
);
906 release_hdc(win
, hdc
);
909 void WinSetClipMask(GC gc
, Pixmap pix
)
914 typedef struct __win32_timer
{ int ID
; void(*proc
)(); void *data
; struct __win32_timer
*next
; } win32_timer
;
915 static win32_timer
*timers
= NULL
;
917 VOID CALLBACK
WinTimerProc(HWND hwnd
, UINT umsg
, UINT id
, DWORD dwtime
)
919 win32_timer
*t
= timers
, *prev
= NULL
;
921 for (; t
!=NULL
&& t
->ID
!= id
; prev
=t
, t
=t
->next
);
923 W32DEBUG(("Timer %d not found\n", id
));
929 prev
->next
= t
->next
;
930 KillTimer(NULL
, t
->ID
);
931 (*t
->proc
)(t
->data
, &(t
->ID
));
935 int WinAddTimeOut(int delay
, void(*proc
)(), void *data
)
937 win32_timer
* t
= (win32_timer
*)malloc(sizeof(win32_timer
));
941 t
->ID
= SetTimer(NULL
, 0, delay
, WinTimerProc
);
953 void WinRemoveTimeOut(int id
)
955 win32_timer
*t
= timers
, *prev
= NULL
;
957 for (; t
!=NULL
&& t
->ID
!= id
; prev
=t
, t
=t
->next
);
964 prev
->next
= t
->next
;
965 KillTimer(NULL
, t
->ID
);
969 void WinTranslateCoords(Widget win
, short x
, short y
, short *rx
, short *ry
)
975 ClientToScreen(win
->handle
, &pt
);
985 BOOL CALLBACK
InputDlgProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
993 SetDlgItemText(hwnd
, IDC_EDIT1
, ((InputDlgData
*)lParam
)->current
);
994 SetDlgItemText(hwnd
, IDC_INFOTEXT
, ((InputDlgData
*)lParam
)->request
);
995 GetWindowRect(GetParent(hwnd
), &r1
);
996 GetWindowRect(hwnd
, &r2
);
997 w1
= r1
.right
-r1
.left
;
998 w2
= r2
.right
-r2
.left
;
999 h1
= r1
.bottom
-r1
.top
;
1000 h2
= r2
.bottom
-r2
.top
;
1001 SetWindowPos(hwnd
, HWND_TOP
, r1
.left
+(w1
-w2
)/2, r1
.top
+(h1
-h2
)/2, 0, 0, SWP_NOSIZE
);
1002 SendMessage(GetDlgItem(hwnd
, IDC_EDIT1
), EM_SETSEL
, 0, -1);
1003 SetFocus(GetDlgItem(hwnd
, IDC_EDIT1
));
1007 if (HIWORD(wParam
) == BN_CLICKED
)
1008 switch (LOWORD(wParam
)) {
1010 GetDlgItemText(hwnd
, IDC_EDIT1
, _STR2
, sizeof(_STR2
));
1022 #define HELP_MARGIN 10
1024 BOOL CALLBACK
HelpDlgProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1029 RECT br
, r
, cr
, pr
, pcr
;
1032 GetWindowRect(hwnd
, &r
);
1033 GetClientRect(hwnd
, &cr
);
1034 GetClientRect(GetDlgItem(hwnd
, IDOK
), &br
);
1035 GetWindowRect(GetDlgItem(hwnd
, IDC_HELPPIX
), &pr
);
1036 GetClientRect(GetDlgItem(hwnd
, IDC_HELPPIX
), &pcr
);
1037 sbwidth
= (pr
.right
-pr
.left
)-(pcr
.right
-pcr
.left
);
1038 SetWindowPos(hwnd
, HWND_TOP
, 0, 0, sbwidth
+helpwidth
+2*HELP_MARGIN
+(r
.right
-r
.left
)-(cr
.right
-cr
.left
),
1039 r
.bottom
-r
.top
, SWP_NOMOVE
);
1040 GetClientRect(hwnd
, &cr
);
1041 SetWindowPos(GetDlgItem(hwnd
, IDC_HELPPIX
), HWND_TOP
, HELP_MARGIN
, HELP_MARGIN
, helpwidth
+sbwidth
,
1042 (cr
.bottom
-cr
.top
)-(br
.bottom
-br
.top
)-3*HELP_MARGIN
, 0);
1043 SetWindowPos(GetDlgItem(hwnd
, IDOK
), HWND_TOP
,
1044 HELP_MARGIN
+((cr
.right
-cr
.left
)-(br
.right
-br
.left
))/2, cr
.bottom
-HELP_MARGIN
-(br
.bottom
-br
.top
),
1045 br
.right
-br
.left
, br
.bottom
-br
.top
, 0);
1046 SetFocus(GetDlgItem(hwnd
, IDC_HELPPIX
));
1050 if (HIWORD(wParam
) == BN_CLICKED
)
1051 switch (LOWORD(wParam
)) {
1064 void popupprompt(Widget button
, char *request
, char *current
, void (*function
)(), buttonsave
*datastruct
, const char *filter
)
1066 if (current
!= NULL
&& filter
== NULL
) {
1069 data
.request
= request
;
1070 data
.current
= current
;
1071 if (DialogBoxParam(GetModuleHandle(NULL
), MAKEINTRESOURCE(IDD_INPUTDIALOG
), areawin
->window
, InputDlgProc
, (LPARAM
)&data
))
1072 (*function
)(button
, (datastruct
!= NULL
? datastruct
->dataptr
: NULL
));
1073 } else if (filter
!= NULL
) {
1075 char filename
[1024] = {0};
1076 char filterspec
[1024] = {0};
1078 ZeroMemory(&ofn
, sizeof(ofn
));
1079 ofn
.lStructSize
= sizeof(ofn
);
1080 ofn
.hwndOwner
= areawin
->window
;
1082 _snprintf(filterspec
, 1024, "Enable Filter (*%s)%c*%s%cDisable Filter (*.*)%c*.*%c%c%c",
1083 filter
, 0, filter
, 0, 0, 0, 0, 0);
1084 ofn
.lpstrFilter
= filterspec
;
1086 ofn
.lpstrFilter
= "All Files (*.*)\000*.*\000\000\000";
1087 ofn
.lpstrFile
= filename
;
1088 ofn
.nMaxFile
= 1024;
1089 if (GetOpenFileName(&ofn
)) {
1091 strcpy(_STR2
, ofn
.lpstrFile
);
1092 for (c
=_STR2
; *c
; c
++)
1093 if (*c
== '\\') *c
= '/';
1094 (*function
)(button
, datastruct
->dataptr
);
1097 if (MessageBox(areawin
->window
, request
, "XCircuit", MB_YESNO
|MB_ICONQUESTION
) == IDYES
)
1098 (*function
)(button
, datastruct
->dataptr
);
1101 if (datastruct
!= NULL
) free(datastruct
);
1104 static void get_vkey_name(int key
, char *str
, int len
)
1106 UINT scan
= MapVirtualKey(key
, 0);
1107 scan
= (scan
&0xff)<<16;
1122 memcpy(str
, "CLEAR", 5);
1127 GetKeyNameText(scan
, str
, len
);
1130 char *WinKeyToString(int key
)
1132 static char buffer
[1024];
1134 memset(buffer
, 0, 1024);
1135 if (key
>= XK_a
&& key
<= XK_z
)
1136 buffer
[0] = (char)key
;
1137 else if (key
>= XK_A
&& key
<= XK_Z
)
1138 buffer
[0] = (char)key
;
1143 strcpy(buffer
, "Keypad_");
1147 get_vkey_name(key
&0x00ff, buffer
+offset
, 1024-offset
);
1149 buffer
[offset
] = key
&0x00ff;
1155 int WinStringToKey(const char *str
)
1160 for (key
=1; key
<256; key
++) {
1161 memset(buf
, 0, 256);
1162 get_vkey_name(key
, buf
, 256);
1163 if (strcmp(str
, buf
) == 0)
1169 static Widget WndFound
;
1171 BOOL CALLBACK
WndLookupProc(HWND hwnd
, LPARAM lParam
)
1173 Widget w
= (Widget
)get_widget(hwnd
);
1175 if (w
!= NULL
&& strcmp((char*)lParam
, w
->name
) == 0) {
1177 W32DEBUG(("widget name: '%s'\n", w
->name
));
1180 W32DEBUG(("widget name: '%s' (%p)\n", (w
? w
->name
: (char*)w
)));
1184 const char* WinName(Widget w
)
1190 return TOMENUITEM(w
)->name
;
1192 return TOTOOLITEM(w
)->name
;
1198 Widget
WinNameToWindow(Widget parent
, const char *name
)
1200 W32DEBUG(("Looking for '%s' in %p\n", name
, parent
));
1203 switch (parent
->type
) {
1205 if (parent
== toolBar
) {
1207 int nbuttons
= SendMessage(toolBar
->handle
, TB_BUTTONCOUNT
, 0, 0), i
;
1208 for (i
=0; i
<nbuttons
; i
++) {
1209 ZeroMemory(&tb
, sizeof(tb
));
1210 SendMessage(toolBar
->handle
, TB_GETBUTTON
, i
, (LPARAM
)&tb
);
1211 if (tb
.dwData
!= 0) {
1212 ToolItem item
= (ToolItem
)tb
.dwData
;
1213 if (item
->name
&& strcmp(item
->name
, name
) == 0) {
1214 WndFound
= (Widget
)item
;
1220 EnumChildWindows(parent
->handle
, WndLookupProc
, (LPARAM
)name
);
1223 if (TOMENUITEM(parent
)->popup
!= NULL
)
1224 parent
= (Widget
)TOMENUITEM(parent
)->popup
;
1229 int i
, n
= GetMenuItemCount((HMENU
)parent
->handle
);
1230 MENUITEMINFO mi_info
;
1232 ZeroMemory(&mi_info
, sizeof(mi_info
));
1233 mi_info
.cbSize
= sizeof(mi_info
);
1234 mi_info
.fMask
= MIIM_DATA
;
1235 for (i
=0; i
<n
; i
++) {
1236 mi_info
.dwItemData
= (LONG
)NULL
;
1237 if (GetMenuItemInfo((HMENU
)parent
->handle
, i
, MF_BYPOSITION
, &mi_info
)
1238 && mi_info
.dwItemData
&& ((MenuItem
)mi_info
.dwItemData
)->name
1239 && strcmp(((MenuItem
)mi_info
.dwItemData
)->name
, name
) == 0) {
1240 WndFound
= (Widget
)mi_info
.dwItemData
;
1250 void outputpopup(Widget button
, caddr_t clientdata
, caddr_t calldata
)
1252 if (is_page(topobject
) == -1) {
1253 Wprintf("Can only save a top-level page!");
1256 DialogBox(GetModuleHandle(NULL
), MAKEINTRESOURCE(IDD_OUTPUTDLG
), top
->handle
, OutputDlgProc
);
1264 static u_char
reverse_byte(u_char c
)
1269 for (i
=(sizeof(char)*8-1); i
>=0; i
--, c
>>=1)
1270 rc
|= (c
&0x01) << i
;
1274 static void compute_cursor_src_mask(u_char
*src
, u_char
*mask
)
1276 u_char pixsrc
= *src
, pixmask
= *mask
;
1277 *src
= ~(reverse_byte(pixmask
));
1278 *mask
= reverse_byte((u_char
)((~pixsrc
&0xff)&pixmask
));
1281 static HBITMAP
create_stipple(char *stipdata
)
1287 for (i
=0; i
<4; i
++) {
1288 data
[2*i
] = 0xff & ~reverse_byte(stipdata
[i
]);
1290 hBitmap
= CreateBitmap(4, 4, 1, 1, data
);
1294 HBITMAP
WinCreateBitmapFromData(HWND w
, char *data
, int width
, int height
)
1296 if (width
== 4 && height
== 4) {
1297 return create_stipple(data
);
1299 cursor_bits
*cbits
= (cursor_bits
*)malloc(sizeof(cursor_bits
));
1301 cbits
->width
= width
;
1302 cbits
->height
= height
;
1303 return (HBITMAP
)cbits
;
1307 HCURSOR
WinCreateCursor(HBITMAP _src
, HBITMAP _mask
, int xhot
, int yhot
)
1309 HCURSOR hCursor
= NULL
;
1310 u_char
*src
= ((cursor_bits
*)_src
)->bits
, *mask
= ((cursor_bits
*)_mask
)->bits
;
1311 u_char
*new_src
, *new_mask
;
1312 int width
= ((cursor_bits
*)_src
)->width
, height
= ((cursor_bits
*)_src
)->height
;
1313 int nb
= (width
-1)/(8*sizeof(char))+1;
1314 int nb2
= (GetSystemMetrics(SM_CXCURSOR
)-1)/(8*sizeof(char))+1, height2
= GetSystemMetrics(SM_CYCURSOR
);
1315 int i
, j
, idx1
= 0, idx2
= 0;
1317 new_src
= (u_char
*)malloc(sizeof(char)*nb2
*height2
);
1318 new_mask
= (u_char
*)malloc(sizeof(char)*nb2
*height2
);
1320 for (j
=0; j
<height
; j
++) {
1321 for (i
=0; i
<nb
; i
++, idx1
++, idx2
++) {
1322 new_src
[idx2
] = src
[idx1
];
1323 new_mask
[idx2
] = mask
[idx1
];
1324 compute_cursor_src_mask(&new_src
[idx2
], &new_mask
[idx2
]);
1326 for (i
=0; i
<(nb2
-nb
); i
++, idx2
++) {
1327 new_src
[idx2
] = 0xff;
1328 new_mask
[idx2
] = 0x00;
1331 for (j
=0; j
<(height2
-height
); j
++) {
1332 for (i
=0; i
<nb2
; i
++, idx2
++) {
1333 new_src
[idx2
] = 0xff;
1334 new_mask
[idx2
] = 0x00;
1338 hCursor
= CreateCursor(GetModuleHandle(NULL
), xhot
, yhot
, nb2
*8, height2
, new_src
, new_mask
);
1348 static Widget
create_widget(HWND handle
, char *name
)
1350 Widget w
= (Widget
)malloc(sizeof(struct __WinWidget
));
1352 ZeroMemory(w
, sizeof(struct __WinWidget
));
1353 w
->type
= WIN_WIDGET
;
1355 w
->name
= strdup(name
);
1356 if (strcmp(name
, "Area") == 0) {
1358 GetWindowRect(handle
, &r
);
1359 w
->buffer
= WinCreatePixmap(handle
, r
.right
-r
.left
, r
.bottom
-r
.top
);
1360 w
->bufhdc
= CreateCompatibleDC(NULL
);
1361 SelectObject(w
->bufhdc
, w
->buffer
);
1363 SetWindowLong(handle
, GWL_USERDATA
, (LONG
)w
);
1367 static void destroy_widget(HWND handle
)
1369 Widget w
= (Widget
)get_widget(handle
);
1370 WinCallback
*cb
= w
->callbacks
, *free_cb
;
1371 WinEventHandler
*eh
= w
->handlers
, *free_eh
;
1374 while (cb
!= NULL
) {
1379 while (eh
!= NULL
) {
1384 if (w
->wndproc
!= NULL
)
1385 SetWindowLong(handle
, GWL_WNDPROC
, (LONG
)w
->wndproc
);
1389 LRESULT CALLBACK
XcTopWindowProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1393 quitcheck(NULL
, NULL
, NULL
);
1399 for (w
=xobjs
.windowlist
; w
!=NULL
; w
=w
->next
)
1400 if (GetAncestor(w
->window
, GA_ROOT
) == hwnd
)
1402 if (w
!= NULL
&& areawin
!= w
) {
1404 top
= get_widget(GetAncestor(areawin
->window
, GA_ROOT
));
1405 topwin
= top
->handle
;
1406 toolBar
= get_widget(GetDlgItem(topwin
, TOOLBAR_ID
));
1407 statusBar
= GetDlgItem(topwin
, STATUSBAR_ID
);
1409 MENUITEMINFO mi_info
;
1410 HMENU hMenu
= GetMenu(hwnd
);
1413 ZeroMemory(&mi_info
, sizeof(mi_info
));
1414 mi_info
.cbSize
= sizeof(mi_info
);
1415 for (i
=0; i
<MaxMenuWidgets
; i
++) {
1416 mi_info
.fMask
= MIIM_DATA
;
1417 mi_info
.dwItemData
= (LONG
)NULL
;
1418 if (GetMenuItemInfo(hMenu
, 100+i
, FALSE
, &mi_info
))
1419 menuwidgets
[i
] = (Widget
)mi_info
.dwItemData
;
1421 printf("menu not found: %d\n", i
);
1425 SetFocus(areawin
->window
);
1430 int width
= LOWORD(lParam
), th
, sh
, height
= HIWORD(lParam
), nbrows
= 1;
1434 SetWindowPos(toolBar
->handle
, HWND_TOP
, 0, 0, width
, 25, 0);
1436 sz
= SendMessage(toolBar
->handle
, TB_GETBUTTONSIZE
, 0, 0);
1437 nbrows
= SendMessage(toolBar
->handle
, TB_GETROWS
, 0, 0);
1438 th
= nbrows
*HIWORD(sz
)+6;
1439 GetWindowRect(statusBar
, &sr
);
1440 sh
= sr
.bottom
-sr
.top
;
1442 SetWindowPos(areawin
->area
->handle
, HWND_TOP
, SBARSIZE
, th
, width
-SBARSIZE
, height
-sh
-th
-SBARSIZE
, 0);
1443 SetWindowPos(areawin
->scrollbarh
->handle
, HWND_TOP
, SBARSIZE
, height
-sh
-SBARSIZE
, width
-SBARSIZE
, SBARSIZE
, 0);
1444 SetWindowPos(areawin
->scrollbarv
->handle
, HWND_TOP
, 0, th
, SBARSIZE
, height
-sh
-th
-SBARSIZE
, 0);
1445 SetWindowPos(corner
, HWND_TOP
, 0, height
-sh
-SBARSIZE
, 0, 0, SWP_NOSIZE
);
1446 SetWindowPos(statusBar
, HWND_TOP
, 0, height
-sh
, width
, sh
, 0);
1447 InvalidateRect(statusBar
, NULL
, FALSE
);
1448 SetWindowPos(toolBar
->handle
, HWND_TOP
, 0, 0, width
, th
, 0);
1449 InvalidateRect(toolBar
->handle
, NULL
, FALSE
);
1451 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
1452 case WM_MENUCOMMAND
:
1454 MENUITEMINFO mi_info
;
1457 ZeroMemory(&mi_info
, sizeof(mi_info
));
1458 mi_info
.cbSize
= sizeof(mi_info
);
1459 mi_info
.fMask
= MIIM_DATA
;
1460 GetMenuItemInfo((HMENU
)lParam
, wParam
, MF_BYPOSITION
, &mi_info
);
1462 if ((item
= (MenuItem
)mi_info
.dwItemData
) != NULL
&& item
->callbacks
!= NULL
) {
1463 W32DEBUG(("Calling callback\n"));
1464 execute_callback(XtNselect
, (Widget
)item
, NULL
);
1469 if ((HWND
)lParam
== toolBar
->handle
) {
1472 ZeroMemory(&tbi
, sizeof(tbi
));
1473 tbi
.cbSize
= sizeof(tbi
);
1474 tbi
.dwMask
= TBIF_LPARAM
;
1475 if (SendMessage(toolBar
->handle
, TB_GETBUTTONINFO
, LOWORD(wParam
), (LPARAM
)&tbi
) != -1) {
1476 ToolItem item
= (ToolItem
)tbi
.lParam
;
1477 W32DEBUG(("Tool button: %s\n", item
->name
));
1478 execute_callback(XtNselect
, (Widget
)item
, NULL
);
1483 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
1487 void button_event(Widget win
, int type
, int button
, short x
, short y
)
1494 event
.button
= (button
& MK_LBUTTON
? Button1
: 0) |
1495 (button
& MK_RBUTTON
? Button3
: 0) |
1496 (button
& MK_MBUTTON
? Button2
: 0) |
1497 (button
& MK_XBUTTON1
? Button4
: 0) |
1498 (button
& MK_XBUTTON2
? Button5
: 0);
1499 event
.state
= (GetKeyState(VK_CONTROL
) & 0x8000 ? ControlMask
: 0) |
1500 (GetKeyState(VK_SHIFT
) & 0x8000 ? ShiftMask
: 0) |
1501 (GetKeyState(VK_MENU
) & 0x8000 ? Mod1Mask
: 0);
1503 if (win
== areawin
->scrollbarh
|| win
== areawin
->scrollbarv
)
1504 if (type
== ButtonPress
)
1505 SetCapture(win
->handle
);
1506 else if (type
== ButtonRelease
)
1511 execute_callback(XtNselect
, win
, &event
);
1514 execute_callback(XtNrelease
, win
, &event
);
1517 if (event
.button
&& HAS_HANDLER(win
, ButtonMotionMask
))
1518 execute_handler(ButtonMotionMask
, win
, &event
);
1519 if ((event
.button
& Button1Mask
) && HAS_HANDLER(win
, Button1MotionMask
))
1520 execute_handler(Button1MotionMask
, win
, &event
);
1521 if ((event
.button
& Button2Mask
) && HAS_HANDLER(win
, Button2MotionMask
))
1522 execute_handler(Button2MotionMask
, win
, &event
);
1523 if (HAS_HANDLER(win
, PointerMotionMask
))
1524 execute_handler(PointerMotionMask
, win
, &event
);
1529 void key_event(Widget win
, int type
, int key
, int scan
)
1532 static BYTE keys
[256];
1537 ScreenToClient(win
->handle
, &pt
);
1544 GetKeyboardState(keys
);
1545 if (keys
[VK_CONTROL
] & 0x80) { event
.state
|= ControlMask
; keys
[VK_CONTROL
] &= ~0x80; }
1546 if (keys
[VK_MENU
] & 0x80) { event
.state
|= Mod1Mask
; keys
[VK_MENU
] &= ~0x80; }
1547 keys
[VK_NUMLOCK
] &= 0x01;
1548 if (ToAscii(key
, scan
, keys
, &c
, 0) == 1 && c
>= ' ' && c
<= '~') {
1549 W32DEBUG(("char: %c (%08x)\n", c
, c
));
1550 event
.keycode
= 0xff & c
;
1553 if (scan
& 0x1000000) event
.keycode
|= KPMOD
;
1558 if ((VkKeyScan(c
)&0xff) != key
)
1559 event
.keycode
|= KPMOD
;
1565 if (keys
[VK_SHIFT
] & 0x80) event
.state
|= ShiftMask
;
1566 event
.keycode
|= VKMOD
;
1569 if (scan
& 0x1000000) event
.keycode
|= KPMOD
;
1570 else event
.keycode
|= VKMOD
;
1581 if (!(scan
& 0x1000000)) event
.keycode
|= KPMOD
;
1582 else event
.keycode
|= VKMOD
;
1585 if (scan
== 0x004c0001 || scan
== 0xc04c0001) event
.keycode
|= KPMOD
;
1588 event
.keycode
|= VKMOD
;
1591 event
.keycode
|= key
;
1592 W32DEBUG(("non char: %d\n", event
.keycode
));
1597 execute_callback(XtNkeyDown
, win
, &event
);
1600 execute_callback(XtNkeyUp
, win
, &event
);
1605 LRESULT CALLBACK
XcWidgetProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1607 Widget win
= (Widget
)get_widget(hwnd
);
1611 destroy_widget(hwnd
);
1616 GetUpdateRect(hwnd
, &r
, FALSE
);
1618 execute_callback(XtNexpose
, win
, NULL
);
1619 ValidateRect(hwnd
, &r
);
1623 InvalidateRect(hwnd
, NULL
, FALSE
);
1625 execute_callback(XtNresize
, win
, NULL
);
1626 if (win
->buffer
!= NULL
) {
1627 WinFreePixmap(win
->buffer
);
1628 win
->buffer
= WinCreatePixmap(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
1629 SelectObject(win
->bufhdc
, win
->buffer
);
1634 W32DEBUG(("WM_CHAR: %08x %08x\n", wParam
, lParam
));
1637 if (wParam
== VK_MENU
|| (wParam
== VK_F4
&& GetKeyState(VK_MENU
) && 0x8000))
1638 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
1640 W32DEBUG(("WM_KEYDOWN: %08x %08x %08x\n", wParam
, lParam
, MapVirtualKey((0x00ff0000&lParam
)>>16, 1)));
1641 key_event(win
, KeyPress
, MapVirtualKey((0x00ff0000&lParam
)>>16, 1), lParam
);
1644 if (wParam
== VK_MENU
)
1645 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
1647 W32DEBUG(("WM_KEYUP: %08x %08x\n", wParam
, lParam
));
1648 key_event(win
, KeyRelease
, MapVirtualKey((0x00ff0000&lParam
)>>16, 1), lParam
);
1651 button_event(win
, MotionNotify
, wParam
, LOWORD(lParam
), HIWORD(lParam
));
1653 case WM_RBUTTONDOWN
:
1654 case WM_MBUTTONDOWN
:
1655 case WM_LBUTTONDOWN
:
1656 button_event(win
, ButtonPress
, wParam
, LOWORD(lParam
), HIWORD(lParam
));
1659 button_event(win
, ButtonRelease
, MK_RBUTTON
, LOWORD(lParam
), HIWORD(lParam
));
1662 button_event(win
, ButtonRelease
, MK_MBUTTON
, LOWORD(lParam
), HIWORD(lParam
));
1665 button_event(win
, ButtonRelease
, MK_LBUTTON
, LOWORD(lParam
), HIWORD(lParam
));
1669 SHORT delta
= HIWORD(wParam
);
1670 panbutton((delta
> 0 ? 3 : 4), 0, 0, 0.05);
1671 refresh(NULL
, NULL
, NULL
);
1675 switch (LOWORD(wParam
)) {
1677 panbutton(1, 0, 0, 0.03);
1680 panbutton(2, 0, 0, 0.03);
1683 refresh(NULL
, NULL
, NULL
);
1686 if (msg
== WM_BITBLT
&& win
!= NULL
&& win
->buffer
!= NULL
) {
1687 HDC winhdc
= GetDC(hwnd
);
1691 while (PeekMessage(&pmsg
, hwnd
, WM_BITBLT
, WM_BITBLT
, PM_REMOVE
));
1692 GetWindowRect(hwnd
, &r
);
1693 BitBlt(winhdc
, 0, 0, r
.right
-r
.left
, r
.bottom
-r
.top
, win
->bufhdc
, 0, 0, SRCCOPY
);
1694 ReleaseDC(hwnd
, winhdc
);
1697 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
1701 LRESULT CALLBACK
XcHelppixProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1705 return DLGC_WANTARROWS
;
1707 if (helppix
== NULL
)
1715 si
.cbSize
= sizeof(SCROLLINFO
);
1718 si
.nMax
= (helpheight
-HIWORD(lParam
)+400-1);
1721 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
1730 hdc
= BeginPaint(hwnd
, &ps
);
1731 pixhdc
= get_hdc(helppix
, hgc
);
1732 GetClientRect(hwnd
, &r
);
1733 BitBlt(hdc
, 0, 0, r
.right
-r
.left
, r
.bottom
-r
.top
, pixhdc
, 0, helptop
, SRCCOPY
);
1734 release_hdc(helppix
, pixhdc
);
1735 EndPaint(hwnd
, &ps
);
1744 si
.cbSize
= sizeof(si
);
1746 GetScrollInfo(hwnd
, SB_VERT
, &si
);
1747 switch (LOWORD(wParam
)) {
1749 si
.nPos
-= si
.nPage
;
1752 si
.nPos
+= si
.nPage
;
1761 si
.nPos
= si
.nTrackPos
;
1765 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
1766 GetScrollInfo(hwnd
, SB_VERT
, &si
);
1768 InvalidateRect(hwnd
, NULL
, FALSE
);
1774 SendMessage(hwnd
, WM_VSCROLL
, MAKELONG(SB_PAGEDOWN
, 0), 0);
1777 SendMessage(hwnd
, WM_VSCROLL
, MAKELONG(SB_PAGEUP
, 0), 0);
1780 SendMessage(hwnd
, WM_VSCROLL
, MAKELONG(SB_LINEDOWN
, 0), 0);
1783 SendMessage(hwnd
, WM_VSCROLL
, MAKELONG(SB_LINEUP
, 0), 0);
1788 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
1792 static XFontStruct
* create_font_struct(HFONT hFont
)
1795 XFontStruct
*fs
= NULL
;
1796 HDC hdc
= GetDC(NULL
);
1798 SelectObject(hdc
, hFont
);
1799 if (GetTextMetrics(hdc
, &tm
)) {
1800 fs
= (XFontStruct
*)malloc(sizeof(XFontStruct
));
1801 fs
->ascent
= tm
.tmAscent
;
1802 fs
->descent
= tm
.tmDescent
;
1805 W32DEBUG(("Failed to create font structure\n"));
1807 ReleaseDC(NULL
, hdc
);
1812 static menuID
= 100;
1814 static Menu
create_win_menu(HMENU menu
)
1816 Menu wmenu
= (Menu
)malloc(sizeof(struct __WinMenu
));
1819 wmenu
->type
= WIN_MENU
;
1820 wmenu
->handle
= menu
;
1821 minfo
.cbSize
= sizeof(MENUINFO
);
1822 minfo
.fMask
= MIM_MENUDATA
| MIM_STYLE
;
1823 minfo
.dwStyle
= MNS_NOTIFYBYPOS
;
1824 minfo
.dwMenuData
= (DWORD
)wmenu
;
1825 SetMenuInfo(menu
, &minfo
);
1830 static MenuItem
insert_win_menuitem(Menu menu
, MENUITEMINFO
* mi_info
, menustruct
*ms
, int pos
)
1832 MenuItem item
= (MenuItem
)malloc(sizeof(struct __WinMenuItem
));
1834 ZeroMemory(item
, sizeof(struct __WinMenuItem
));
1835 item
->type
= WIN_MENUITEM
;
1836 item
->parentMenu
= menu
;
1837 if (mi_info
->fMask
& MIIM_SUBMENU
&& mi_info
->hSubMenu
!= NULL
) {
1838 MENUINFO popup_info
;
1839 ZeroMemory(&popup_info
, sizeof(popup_info
));
1840 popup_info
.cbSize
= sizeof(popup_info
);
1841 popup_info
.fMask
= MIM_MENUDATA
;
1842 if (GetMenuInfo(mi_info
->hSubMenu
, &popup_info
))
1843 item
->popup
= (Menu
)popup_info
.dwMenuData
;
1845 else if (mi_info
->fMask
& MIIM_ID
) {
1846 item
->ID
= mi_info
->wID
;
1847 menuwidgets
[mi_info
->wID
-100] = (Widget
)item
;
1848 } else if (!(mi_info
->fMask
& MIIM_FTYPE
&& mi_info
->fType
== MFT_SEPARATOR
)){
1851 if (ms
->func
!= NULL
&& ms
->func
!= DoNothing
)
1852 WinAddCallback((Widget
)item
, XtNselect
, ms
->func
, ms
->passeddata
);
1853 item
->name
= strdup(ms
->name
);
1856 pos
= GetMenuItemCount(menu
->handle
);
1857 item
->position
= pos
;
1858 item
->menudata
= mi_info
->dwItemData
;
1859 mi_info
->fMask
|= MIIM_DATA
;
1860 mi_info
->dwItemData
= (DWORD
)item
;
1861 InsertMenuItem(menu
->handle
, item
->position
, MF_BYPOSITION
, mi_info
);
1862 for (pos
++; pos
<GetMenuItemCount(menu
->handle
); pos
++) {
1864 ZeroMemory(&info
, sizeof(info
));
1865 info
.cbSize
= sizeof(info
);
1866 info
.fMask
= MIIM_DATA
;
1867 GetMenuItemInfo(menu
->handle
, pos
, MF_BYPOSITION
, &info
);
1868 TOMENUITEM(info
.dwItemData
)->position
= pos
;
1874 #define MENUICON_WIDTH GetSystemMetrics(SM_CXMENUCHECK)
1875 #define MENUICON_HEIGHT GetSystemMetrics(SM_CYMENUCHECK)
1877 #define MENUICON_WIDTH 12
1878 #define MENUICON_HEIGHT 12
1881 static HBITMAP
create_color_icon(int color
, int width
, int height
)
1883 HDC hdc
= GetDC(NULL
);
1884 HBITMAP hBitmap
= CreateCompatibleBitmap(hdc
, width
, height
);
1885 HBRUSH hBrush
= CreateSolidBrush(color
);
1888 ReleaseDC(NULL
, hdc
);
1891 hdc
= CreateCompatibleDC(NULL
);
1892 SelectObject(hdc
, hBitmap
);
1893 FillRect(hdc
, &r
, hBrush
);
1894 DeleteObject(hBrush
);
1900 static HBITMAP
create_stipple_icon(int stipdata
, int width
, int height
)
1902 HDC hdc
= GetDC(NULL
);
1903 HBITMAP hBitmap
= CreateCompatibleBitmap(hdc
, width
, height
);
1904 HBRUSH hBrush
= CreatePatternBrush(STIPPLE
[stipdata
]);
1907 ReleaseDC(NULL
, hdc
);
1910 hdc
= CreateCompatibleDC(NULL
);
1911 SelectObject(hdc
, hBitmap
);
1912 FillRect(hdc
, &r
, hBrush
);
1913 DeleteObject(hBrush
);
1919 static char* color_string(int c
)
1921 static char buf
[256];
1922 char *cname
= WinColorName(c
);
1925 _snprintf(buf
, 256, " %s", cname
);
1927 _snprintf(buf
, 256, " %3d, %3d, %3d", GetRValue(c
), GetGValue(c
), GetBValue(c
));
1931 static void makesubmenu(Menu menu
, menustruct
*items
, int n
);
1932 static void make_color_submenu(Menu menu
, menustruct
*items
, int n
)
1935 makesubmenu(menu
, items
, n
);
1938 MENUITEMINFO mi_info
;
1941 makesubmenu(menu
, items
, 3);
1943 for (i
=0; i
<number_colors
; i
++) {
1944 int color
= colorlist
[i
].color
.pixel
;
1945 HBITMAP hBitmap
= create_color_icon(color
, MENUICON_WIDTH
, MENUICON_HEIGHT
);
1946 ZeroMemory(&mi_info
, sizeof(mi_info
));
1947 mi_info
.cbSize
= sizeof(mi_info
);
1948 mi_info
.fMask
= MIIM_BITMAP
| MIIM_STRING
;
1949 mi_info
.hbmpItem
= hBitmap
;
1950 mi_info
.dwTypeData
= color_string(color
);
1951 mi_info
.dwItemData
= color
;
1953 item
= insert_win_menuitem(menu
, &mi_info
, NULL
, -1);
1954 item
->name
= strdup(mi_info
.dwTypeData
);
1955 WinAddCallback((Widget
)item
, XtNselect
, (XtCallbackProc
)setcolor
, NULL
);
1961 static void makesubmenu(Menu menu
, menustruct
*items
, int n
)
1964 MENUITEMINFO mi_info
;
1968 for (i
=0; i
<n
; i
++) {
1969 ZeroMemory(&mi_info
, sizeof(mi_info
));
1970 mi_info
.cbSize
= sizeof(mi_info
);
1971 if (items
[i
].submenu
== NULL
) {
1972 if (items
[i
].name
[0] == ' ') {
1973 mi_info
.fMask
= MIIM_FTYPE
;
1974 mi_info
.fType
= MFT_SEPARATOR
;
1976 else if (items
[i
].name
[0] == '_') {
1977 int color
= WinNamedColor(items
[i
].name
+1);
1978 HBITMAP hBitmap
= create_color_icon(color
, MENUICON_WIDTH
, MENUICON_HEIGHT
);
1979 mi_info
.fMask
= MIIM_BITMAP
| MIIM_STRING
| MIIM_ID
;
1980 mi_info
.wID
= menuID
++;
1981 mi_info
.hbmpItem
= hBitmap
;
1982 mi_info
.dwTypeData
= color_string(color
);
1983 mi_info
.dwItemData
= color
;
1985 } else if (items
[i
].name
[0] == ':') {
1987 if ((int)items
[i
].passeddata
== (OPAQUE
| FILLED
| FILLSOLID
))
1988 hBitmap
= create_color_icon(RGB(0, 0, 0), MENUICON_WIDTH
, MENUICON_HEIGHT
);
1990 hBitmap
= create_stipple_icon(((int)items
[i
].passeddata
& FILLSOLID
)>>5, MENUICON_WIDTH
, MENUICON_HEIGHT
);
1991 mi_info
.fMask
= MIIM_BITMAP
| MIIM_STRING
| MIIM_ID
;
1992 mi_info
.wID
= menuID
++;
1993 mi_info
.hbmpItem
= hBitmap
;
1994 mi_info
.dwTypeData
= items
[i
].name
;
1995 mi_info
.dwItemData
= (DWORD
)items
[i
].passeddata
;
1997 mi_info
.fMask
= MIIM_STRING
| MIIM_ID
;
1998 mi_info
.wID
= menuID
++;
1999 mi_info
.dwTypeData
= items
[i
].name
;
2002 Menu popup
= create_win_menu(CreatePopupMenu());
2003 if (strncmp(items
[i
].name
, "Color", 5) == 0)
2004 make_color_submenu(popup
, items
[i
].submenu
, items
[i
].size
);
2006 makesubmenu(popup
, items
[i
].submenu
, items
[i
].size
);
2007 mi_info
.fMask
= MIIM_SUBMENU
| MIIM_STRING
;
2008 mi_info
.hSubMenu
= popup
->handle
;
2009 mi_info
.dwTypeData
= items
[i
].name
;
2011 mitem
= insert_win_menuitem(menu
, &mi_info
, &items
[i
], -1);
2012 if (is_color
!= -1 && dpy
== NULL
)
2013 addtocolorlist((Widget
)mitem
, is_color
);
2017 static HMENU
create_menus()
2020 MENUITEMINFO mi_info
;
2024 menu
= create_win_menu(CreateMenu());
2025 for (i
=0; i
<maxbuttons
; i
++) {
2026 ZeroMemory(&mi_info
, sizeof(mi_info
));
2027 mi_info
.cbSize
= sizeof(mi_info
);
2028 if (TopButtons
[i
].submenu
== NULL
) {
2029 mi_info
.fMask
= MIIM_STRING
| MIIM_ID
;
2030 mi_info
.wID
= menuID
++;
2031 mi_info
.dwTypeData
= TopButtons
[i
].name
;
2033 Menu popup
= create_win_menu(CreatePopupMenu());
2034 makesubmenu(popup
, TopButtons
[i
].submenu
, TopButtons
[i
].size
);
2035 mi_info
.fMask
= MIIM_SUBMENU
| MIIM_STRING
;
2036 mi_info
.hSubMenu
= popup
->handle
;
2037 mi_info
.dwTypeData
= TopButtons
[i
].name
;
2039 insert_win_menuitem(menu
, &mi_info
, &TopButtons
[i
], -1);
2042 return menu
->handle
;
2045 static void create_statusbar()
2049 StatusItem msg2
, msg3
;
2052 GetTextExtentPoint32(hdc
, "Editing: filename (Page 1)", 26, &sz
);
2053 statusBarWidth
[0] = sz
.cx
;
2054 ReleaseDC(NULL
, hdc
);
2056 statusBar
= CreateWindow(STATUSCLASSNAME
, "", WS_CHILD
|WS_VISIBLE
|SBARS_SIZEGRIP
,
2057 0, 0, 100, 100, top
->handle
, (HMENU
)STATUSBAR_ID
, NULL
, NULL
);
2058 SendMessage(statusBar
, SB_SETPARTS
, 2, (LPARAM
)statusBarWidth
);
2059 SendMessage(statusBar
, SB_SETTEXT
, 0, (LPARAM
)"Editing: Page 1");
2060 SendMessage(statusBar
, SB_SETTEXT
, 1, (LPARAM
)"Don't Panic");
2062 msg2
= (StatusItem
)malloc(sizeof(struct __WinStatusItem
));
2063 msg2
->handle
= statusBar
;
2064 msg2
->type
= WIN_STATUS
;
2066 message2
= (Widget
)msg2
;
2068 msg3
= (StatusItem
)malloc(sizeof(struct __WinStatusItem
));
2069 msg3
->handle
= statusBar
;
2070 msg3
->type
= WIN_STATUS
;
2072 message3
= (Widget
)msg3
;
2075 typedef struct { int c
; RGBQUAD color
; } xpm_color
;
2077 static HBITMAP
create_bitmap_from_xpm(char **xpm
)
2079 int width
, height
, ncolors
, nchar
;
2082 HBITMAP hBitmap
= NULL
;
2087 if (sscanf(xpm
[0], "%d %d %d %d", &width
, &height
, &ncolors
, &nchar
) != 4)
2090 W32DEBUG(("(XPM) Unsupported number of char per data\n"));
2093 colors
= (xpm_color
*)malloc(sizeof(xpm_color
)*ncolors
);
2094 for (i
=0; i
<ncolors
; i
++) {
2095 char *str
= xpm
[i
+1];
2097 colors
[i
].c
= str
[0]; str
++;
2098 for (; *str
!='c'; str
++); str
+=2;
2101 strncpy(snum
, str
, 4); snum
[4] = 0; str
+=4;
2102 colors
[i
].color
.rgbRed
= 0xff&(strtol(snum
, NULL
, 16)>>8);
2103 strncpy(snum
, str
, 4); snum
[4] = 0; str
+=4;
2104 colors
[i
].color
.rgbGreen
= 0xff&(strtol(snum
, NULL
, 16)>>8);
2105 strncpy(snum
, str
, 4); snum
[4] = 0; str
+=4;
2106 colors
[i
].color
.rgbBlue
= 0xff&(strtol(snum
, NULL
, 16)>>8);
2108 COLORREF cr
= WinNamedColor(str
);
2109 colors
[i
].color
.rgbRed
= GetRValue(cr
);
2110 colors
[i
].color
.rgbGreen
= GetGValue(cr
);
2111 colors
[i
].color
.rgbBlue
= GetBValue(cr
);
2115 data
= (BYTE
*)malloc(sizeof(BYTE
)*width
*height
);
2116 for (j
=k
=0; j
<height
; j
++) {
2117 for (i
=0; i
<width
; i
++, k
++) {
2118 char pix
= xpm
[j
+ncolors
+1][i
];
2120 for (idx
=0; idx
<ncolors
; idx
++)
2121 if (pix
== colors
[idx
].c
) break;
2126 bmi
= (BITMAPINFO
*)malloc(sizeof(BITMAPINFO
)+(ncolors
-1)*sizeof(RGBQUAD
));
2127 ZeroMemory(bmi
, sizeof(BITMAPINFO
));
2128 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
2129 bmi
->bmiHeader
.biWidth
= width
;
2130 bmi
->bmiHeader
.biHeight
= -height
;
2131 bmi
->bmiHeader
.biPlanes
= 1;
2132 bmi
->bmiHeader
.biBitCount
= 8;
2133 bmi
->bmiHeader
.biCompression
= BI_RGB
;
2134 bmi
->bmiHeader
.biClrUsed
= ncolors
;
2135 for (i
=0; i
<ncolors
; i
++)
2136 memcpy(bmi
->bmiColors
+i
, &colors
[i
].color
, sizeof(RGBQUAD
));
2138 hBitmap
= CreateDIBitmap(hdc
, &bmi
->bmiHeader
, CBM_INIT
, data
, bmi
, DIB_RGB_COLORS
);
2140 ReleaseDC(NULL
, hdc
);
2147 static void create_toolbar()
2153 toolBar
= create_widget(CreateWindow(TOOLBARCLASSNAME
, NULL
, WS_CHILD
|WS_VISIBLE
|TBSTYLE_FLAT
|TBSTYLE_WRAPABLE
, 0, 0, 0, 0,
2154 top
->handle
, (HMENU
)TOOLBAR_ID
, NULL
, NULL
), "ToolBar");
2155 SendMessage(toolBar
->handle
, TB_BUTTONSTRUCTSIZE
, sizeof(TBBUTTON
), 0);
2156 SendMessage(toolBar
->handle
, TB_SETBITMAPSIZE
, 0, MAKELONG(20, 20));
2158 buttons
= (TBBUTTON
*)malloc(sizeof(TBBUTTON
) * toolbuttons
);
2159 for (i
=0; i
<toolbuttons
; i
++) {
2162 buttons
[i
].iBitmap
= i
;
2163 buttons
[i
].idCommand
= menuID
++;
2164 buttons
[i
].fsState
= TBSTATE_ENABLED
;
2165 buttons
[i
].fsStyle
= TBSTYLE_BUTTON
;
2166 buttons
[i
].iString
= 0;
2167 bitmap
.hInst
= NULL
;
2168 bitmap
.nID
= (INT_PTR
)create_bitmap_from_xpm(ToolBar
[i
].icon_data
);
2169 SendMessage(toolBar
->handle
, TB_ADDBITMAP
, 1, (LPARAM
)&bitmap
);
2171 item
= (ToolItem
)malloc(sizeof(struct __WinToolItem
));
2172 ZeroMemory(item
, sizeof(struct __WinToolItem
));
2173 item
->type
= WIN_TOOLITEM
;
2174 item
->toolbar
= toolBar
;
2175 item
->ID
= buttons
[i
].idCommand
;
2176 item
->name
= strdup(ToolBar
[i
].name
);
2177 buttons
[i
].dwData
= (DWORD
)item
;
2179 menuwidgets
[item
->ID
-100] = (Widget
)item
;
2180 XtAddCallback((Widget
)item
, XtNselect
, (XtCallbackProc
)ToolBar
[i
].func
, ToolBar
[i
].passeddata
);
2183 if (ToolBar[i].func == changetool ||
2184 ToolBar[i].func == exec_or_changetool)
2185 buttons[i].fsStyle |= TBSTYLE_CHECK;
2188 SendMessage(toolBar
->handle
, TB_ADDBUTTONS
, toolbuttons
, (LPARAM
)buttons
);
2192 static void register_win32_classes()
2196 /* Top-level window */
2197 ZeroMemory(&wndClass
, sizeof(wndClass
));
2198 wndClass
.lpfnWndProc
= XcTopWindowProc
;
2199 wndClass
.lpszClassName
= "XcTopLevel";
2200 wndClass
.hIcon
= LoadIcon(GetModuleHandle(NULL
), "xcircuit");
2201 RegisterClass(&wndClass
);
2204 ZeroMemory(&wndClass
, sizeof(wndClass
));
2205 wndClass
.lpfnWndProc
= XcWidgetProc
;
2206 wndClass
.lpszClassName
= "XcWidget";
2207 wndClass
.cbWndExtra
= sizeof(void*);
2208 RegisterClass(&wndClass
);
2211 ZeroMemory(&wndClass
, sizeof(wndClass
));
2212 wndClass
.lpfnWndProc
= XcWidgetProc
;
2213 wndClass
.lpszClassName
= "XcScrollBar";
2214 wndClass
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
2215 wndClass
.cbWndExtra
= sizeof(void*);
2216 RegisterClass(&wndClass
);
2219 ZeroMemory(&wndClass
, sizeof(wndClass
));
2220 wndClass
.lpfnWndProc
= XcHelppixProc
;
2221 wndClass
.lpszClassName
= "XcHelp";
2222 RegisterClass(&wndClass
);
2226 ZeroMemory(&wndClass, sizeof(wndClass));
2227 wndClass.lpfnWndProc = XcPopupProc;
2228 wndClass.lpszClassName = "XcPopup";
2229 wndClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
2230 wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
2231 RegisterClass(&wndClass);
2235 XCWindowData
* GUI_init(int argc
, char *argv
[])
2240 RECT clientRect
= { 0, 0, 0, 0 };
2241 XCWindowData
*newwin
;
2243 #if 0 && defined(USE_WIN32_COM)
2244 for (i
=0; i
<argc
; i
++)
2245 if (strcmp(argv
[i
], "-register") == 0)
2247 else if (strcmp(argv
[i
], "-unregister") == 0)
2252 register_win32_classes();
2254 appdata
.globalcolor
= WinNamedColor("Orange2");
2255 appdata
.localcolor
= WinNamedColor("Red");
2256 appdata
.infocolor
= WinNamedColor("SeaGreen");
2257 appdata
.ratsnestcolor
= WinNamedColor("Tan4");
2258 appdata
.bboxpix
= WinNamedColor("greenyellow");
2259 appdata
.fixedbboxpix
= WinNamedColor("Pink");
2260 appdata
.clipcolor
= WinNamedColor("powderblue");
2261 appdata
.fg
= WinNamedColor("Black");
2262 appdata
.bg
= WinNamedColor("White");
2263 appdata
.gridpix
= WinNamedColor("Gray95");
2264 appdata
.snappix
= WinNamedColor("Red");
2265 appdata
.selectpix
= WinNamedColor("Gold3");
2266 appdata
.querypix
= WinNamedColor("Turquoise");
2267 appdata
.filterpix
= WinNamedColor("SteelBlue3");
2268 appdata
.axespix
= WinNamedColor("Antique White");
2269 appdata
.buttonpix
= WinNamedColor("Gray85");
2270 appdata
.auxpix
= WinNamedColor("Green3");
2271 appdata
.barpix
= WinNamedColor("Tan");
2272 appdata
.parampix
= WinNamedColor("Plum3");
2273 appdata
.fg2
= WinNamedColor("White");
2274 appdata
.bg2
= WinNamedColor("DarkSlateGray");
2275 appdata
.gridpix2
= WinNamedColor("Gray40");
2276 appdata
.snappix2
= WinNamedColor("Red");
2277 appdata
.selectpix2
= WinNamedColor("Gold");
2278 appdata
.querypix2
= WinNamedColor("Turquoise");
2279 appdata
.filterpix2
= WinNamedColor("SteelBlue1");
2280 appdata
.axespix2
= WinNamedColor("NavajoWhite4");
2281 appdata
.buttonpix2
= WinNamedColor("Gray50");
2282 appdata
.auxpix2
= WinNamedColor("Green");
2283 appdata
.barpix2
= WinNamedColor("Tan");
2284 appdata
.parampix2
= WinNamedColor("Plum3");
2285 appdata
.width
= 950;
2286 appdata
.height
= 760;
2287 appdata
.timeout
= 10;
2288 appdata
.xcfont
= create_font_struct(GetStockObject(DEFAULT_GUI_FONT
));
2289 appdata
.helpfont
= create_font_struct(GetStockObject(DEFAULT_GUI_FONT
));
2290 appdata
.filefont
= create_font_struct(GetStockObject(DEFAULT_GUI_FONT
));
2291 appdata
.textfont
= create_font_struct(GetStockObject(DEFAULT_GUI_FONT
));
2292 appdata
.titlefont
= create_font_struct(GetStockObject(DEFAULT_GUI_FONT
));
2294 for (i
=0; i
<STIPPLES
; i
++) {
2295 STIPPLE
[i
] = WinCreateBitmapFromData(NULL
, STIPDATA
[i
], 4, 4);
2298 number_colors
= NUMBER_OF_COLORS
;
2299 colorlist
= (colorindex
*)malloc(NUMBER_OF_COLORS
* sizeof(colorindex
));
2302 clientRect
.right
= appdata
.width
+SBARSIZE
;
2303 clientRect
.bottom
= appdata
.height
+SBARSIZE
;
2304 AdjustWindowRect(&clientRect
, WS_TILEDWINDOW
, TRUE
);
2305 OffsetRect(&clientRect
, -clientRect
.left
, -clientRect
.top
);
2307 top
= create_widget(CreateWindow("XcTopLevel", "XCircuit", WS_TILEDWINDOW
, CW_USEDEFAULT
, CW_USEDEFAULT
, clientRect
.right
, clientRect
.bottom
,
2308 NULL
, create_menus(), NULL
, NULL
), "XCircuit");
2309 topwin
= top
->handle
;
2311 dpy
= XtDisplay(top
);
2312 newwin
= create_new_window();
2314 newwin
->scrollbarv
= create_widget(CreateWindow("XcScrollBar", "SBV", WS_VISIBLE
|WS_CHILD
,
2315 0, 0, SBARSIZE
, appdata
.height
-SBARSIZE
, top
->handle
, 0, NULL
, NULL
), "SBV");
2316 newwin
->scrollbarh
= create_widget(CreateWindow("XcScrollBar", "SBH", WS_VISIBLE
|WS_CHILD
,
2317 SBARSIZE
, appdata
.height
-SBARSIZE
, appdata
.width
-SBARSIZE
, SBARSIZE
, top
->handle
, 0, NULL
, NULL
), "SBH");
2318 newwin
->area
= create_widget(CreateWindow("XcWidget", "Area", WS_VISIBLE
|WS_CHILD
,
2319 SBARSIZE
, 0, appdata
.width
, appdata
.height
, top
->handle
, 0, NULL
, NULL
), "Area");
2320 newwin
->window
= newwin
->area
->handle
;
2321 corner
= CreateWindow("BUTTON", "", WS_CHILD
|WS_VISIBLE
|BS_PUSHBUTTON
|BS_FLAT
, 0, appdata
.height
-SBARSIZE
, SBARSIZE
, SBARSIZE
, top
->handle
, NULL
, NULL
, NULL
);
2326 XtAddCallback(newwin
->area
, XtNexpose
, (XtCallbackProc
)drawarea
, NULL
);
2327 XtAddCallback(newwin
->area
, XtNresize
, (XtCallbackProc
)resizearea
, NULL
);
2329 XtAddCallback(newwin
->area
, XtNselect
, (XtCallbackProc
)buttonhandler
, NULL
);
2330 XtAddCallback(newwin
->area
, XtNrelease
, (XtCallbackProc
)buttonhandler
, NULL
);
2331 XtAddCallback(newwin
->area
, XtNkeyDown
, (XtCallbackProc
)keyhandler
, NULL
);
2332 XtAddCallback(newwin
->area
, XtNkeyUp
, (XtCallbackProc
)keyhandler
, NULL
);
2334 XtAddEventHandler(newwin
->area
, Button1MotionMask
| Button2MotionMask
,
2335 False
, (XtEventHandler
)xlib_drag
, NULL
);
2337 XtAddEventHandler(newwin
->scrollbarh
, ButtonMotionMask
, False
,
2338 (XtEventHandler
)panhbar
, NULL
);
2339 XtAddEventHandler(newwin
->scrollbarv
, ButtonMotionMask
, False
,
2340 (XtEventHandler
)panvbar
, NULL
);
2342 XtAddCallback(newwin
->scrollbarh
, XtNrelease
, (XtCallbackProc
)endhbar
, NULL
);
2343 XtAddCallback(newwin
->scrollbarv
, XtNrelease
, (XtCallbackProc
)endvbar
, NULL
);
2345 XtAddCallback(newwin
->scrollbarh
, XtNexpose
, (XtCallbackProc
)drawhbar
, NULL
);
2346 XtAddCallback(newwin
->scrollbarv
, XtNexpose
, (XtCallbackProc
)drawvbar
, NULL
);
2347 XtAddCallback(newwin
->scrollbarh
, XtNresize
, (XtCallbackProc
)drawhbar
, NULL
);
2348 XtAddCallback(newwin
->scrollbarv
, XtNresize
, (XtCallbackProc
)drawvbar
, NULL
);
2350 values
.foreground
= RGB(0, 0, 0);
2351 values
.background
= RGB(255, 255, 255);
2352 values
.font
= appdata
.xcfont
->fid
;
2354 newwin
->gc
= XCreateGC(dpy
, newwin
->window
,
2355 GCForeground
| GCBackground
| GCFont
, &values
);
2357 XtSetArg(wargs
[0], XtNwidth
, &newwin
->width
);
2358 XtSetArg(wargs
[1], XtNheight
, &newwin
->height
);
2359 XtGetValues(newwin
->area
, wargs
, 2);
2361 SendMessage(((ToolItem
)WireToolButton
)->toolbar
->handle
, TB_CHECKBUTTON
, ((ToolItem
)WireToolButton
)->ID
, MAKELONG(TRUE
, 0));
2363 #ifdef USE_WIN32_COM
2364 if (!COM_initialize())
2365 printf("Failed to initialize COM interface\n");
2371 void WinAddEventHandler(Widget win
, int event
, void(*proc
)(), void *data
)
2373 WinEventHandler
*h
= win
->handlers
;
2375 if (win
->type
!= WIN_WIDGET
) {
2376 W32DEBUG(("Can't add event handler to non widget\n"));
2381 if (h
->proc
== proc
&& h
->data
== data
) {
2389 h
= (WinEventHandler
*)malloc(sizeof(WinEventHandler
));
2393 h
->next
= win
->handlers
;
2397 update_event_mask(win
);
2400 void WinRemoveEventHandler(Widget win
, int event
, void(*proc
)(), void *data
)
2402 WinEventHandler
*h
, *prev
= NULL
;
2404 if (win
->type
!= WIN_WIDGET
) {
2405 W32DEBUG(("Can't remove event handler from non widget\n"));
2411 if ((h
->action
& event
) && h
->proc
== proc
&& h
->data
== data
) {
2412 h
->action
&= ~event
;
2413 if (h
->action
== 0) {
2414 WinEventHandler
*old_h
= h
;
2416 win
->handlers
= h
= h
->next
;
2418 prev
->next
= h
= h
->next
;
2425 update_event_mask(win
);
2428 void WinAddCallback(Widget win
, int event
, void(*proc
)(), void *data
)
2430 WinCallback
*cb
, **root
, *prev
= NULL
;
2435 switch (win
->type
) {
2437 if (TOMENUITEM(win
)->popup
!= NULL
) {
2438 Wprintf("Trying to add a callback to a popup menu");
2441 root
= &((MenuItem
)win
)->callbacks
;
2444 root
= &((ToolItem
)win
)->callbacks
;
2447 root
= &win
->callbacks
;
2457 cb
= (WinCallback
*)malloc(sizeof(WinCallback
));
2469 int WinFindCallback(Widget win
, int event
, void(**proc
)(), void **data
)
2476 switch (win
->type
) {
2478 cb
= TOMENUITEM(win
)->callbacks
;
2481 cb
= TOTOOLITEM(win
)->callbacks
;
2484 cb
= win
->callbacks
;
2489 if (cb
->action
== event
) {
2490 if (proc
== NULL
|| *proc
== NULL
|| *proc
== cb
->proc
) {
2491 if (proc
!= NULL
) *proc
= cb
->proc
;
2492 if (data
!= NULL
) *data
= cb
->data
;
2502 void WinRemoveCallback(Widget win
, int event
, void(*proc
)(), void *data
)
2505 WinCallback
*prev
= NULL
, **root
;
2510 switch (win
->type
) {
2512 cb
= ((MenuItem
)win
)->callbacks
;
2513 root
= &((MenuItem
)win
)->callbacks
;
2516 cb
= ((ToolItem
)win
)->callbacks
;
2517 root
= &((ToolItem
)win
)->callbacks
;
2520 cb
= win
->callbacks
;
2521 root
= &win
->callbacks
;
2524 while (cb
!= NULL
) {
2525 if (cb
->action
== event
&& (proc
== NULL
|| (cb
->proc
== proc
&& cb
->data
== data
))) {
2526 WinCallback
*old_cb
= cb
;
2528 *root
= cb
= cb
->next
;
2530 prev
->next
= cb
= cb
->next
;
2539 void WinRemoveAllCallbacks(Widget win
, int event
)
2544 WinRemoveCallback(win
, event
, NULL
, NULL
);
2547 static Arg
* look_arg(Arg
*args
, int type
, int n
)
2551 if (args
[i
].type
== type
)
2556 static void get_window_location(Arg
*args
, int n
, POINT
*pt
, SIZE
*sz
)
2560 switch (args
[i
].type
) {
2561 case XtNx
: if (pt
) pt
->x
= (int)args
[i
].data
; break;
2562 case XtNy
: if (pt
) pt
->y
= (int)args
[i
].data
; break;
2563 case XtNwidth
: if (sz
) sz
->cx
= (int)args
[i
].data
; break;
2564 case XtNheight
: if (sz
) sz
->cy
= (int)args
[i
].data
; break;
2568 Widget
WinCreateWidget(const char *name
, int cls
, Widget parent
, Arg
*args
, int n
, int show
)
2574 case XwcascadeWidgetClass
:
2576 MENUITEMINFO mi_info
;
2578 Menu popup
= create_win_menu(CreatePopupMenu());
2582 ZeroMemory(&mi_info
, sizeof(mi_info
));
2583 mi_info
.cbSize
= sizeof(mi_info
);
2584 mi_info
.fMask
= MIIM_SUBMENU
| MIIM_STRING
;
2585 mi_info
.hSubMenu
= popup
->handle
;
2586 mi_info
.dwTypeData
= (char*)name
;
2587 if (IS_MENUITEM(parent
))
2588 parent
= (Widget
)TOMENUITEM(parent
)->popup
;
2589 if ((a
= look_arg(args
, XtNattachTo
, n
)) != NULL
) {
2590 Widget after
= WinNameToWindow(parent
, (char*)a
->data
);
2592 pos
= TOMENUITEM(after
)->position
+ 1;
2594 item
= insert_win_menuitem((Menu
)parent
, &mi_info
, NULL
, pos
);
2595 item
->name
= strdup(name
);
2596 DrawMenuBar(topwin
);
2597 return (Widget
)item
;
2599 case XwmenubuttonWidgetClass
:
2601 MENUITEMINFO mi_info
;
2606 ZeroMemory(&mi_info
, sizeof(mi_info
));
2607 mi_info
.cbSize
= sizeof(mi_info
);
2608 if ((a
=look_arg(args
, XtNrectColor
, n
)) != NULL
) {
2609 HBITMAP hBitmap
= create_color_icon((int)a
->data
, MENUICON_WIDTH
, MENUICON_HEIGHT
);
2610 mi_info
.fMask
= MIIM_BITMAP
| MIIM_STRING
/*| MIIM_FTYPE*/;
2611 /*mi_info.fType = MFT_OWNERDRAW*/;
2612 mi_info
.hbmpItem
= hBitmap
;
2613 mi_info
.dwTypeData
= color_string((int)a
->data
);
2614 mi_info
.dwItemData
= (int)a
->data
;
2616 mi_info
.fMask
= MIIM_STRING
;
2617 mi_info
.dwTypeData
= (char*)name
;
2619 if (IS_MENUITEM(parent
))
2620 parent
= (Widget
)TOMENUITEM(parent
)->popup
;
2621 if ((a
= look_arg(args
, XtNattachTo
, n
)) != NULL
) {
2622 Widget after
= WinNameToWindow(parent
, (char*)a
->data
);
2624 pos
= TOMENUITEM(after
)->position
+ 1;
2626 item
= insert_win_menuitem((Menu
)parent
, &mi_info
, NULL
, pos
);
2627 item
->name
= strdup(name
);
2628 DrawMenuBar(topwin
);
2629 return (Widget
)item
;
2633 case XwstaticTextWidgetClass:
2635 POINT pt = {CW_USEDEFAULT, CW_USEDEFAULT};
2637 get_window_location(args, n, &pt, NULL);
2638 win = create_widget(CreateWindow("STATIC", "", WS_CHILD|WS_VISIBLE, pt.x, pt.y,
2639 CW_USEDEFAULT, CW_USEDEFAULT, parent->handle, NULL, NULL, NULL), (char*)name);
2640 win->wndproc = (WNDPROC)SetWindowLong(win->handle, GWL_WNDPROC, (LONG)XcStaticProc);
2641 WinSetValues(win, args, n);
2644 case XwtextEditWidgetClass:
2646 POINT pt = {CW_USEDEFAULT, CW_USEDEFAULT};
2647 SIZE sz = {CW_USEDEFAULT, CW_USEDEFAULT};
2649 get_window_location(args, n, &pt, &sz);
2650 win = create_widget(CreateWindow("EDIT", "", WS_BORDER|WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|WS_TABSTOP, pt.x, pt.y, sz.cx, sz.cy,
2651 parent->handle, NULL, NULL, NULL), (char*)name);
2652 //win->wndproc = (WNDPROC)SetWindowLong(win->handle, GWL_WNDPROC, (LONG)XcEditProc);
2655 case XwpushButtonWidgetClass:
2656 case XwmenuButtonWidgetClass:
2658 POINT pt = {CW_USEDEFAULT, CW_USEDEFAULT};
2660 get_window_location(args, n, &pt, NULL);
2661 win = create_widget(CreateWindow("BUTTON", name, BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE, pt.x, pt.y,
2662 CW_USEDEFAULT, CW_USEDEFAULT, parent->handle, NULL, NULL, NULL), (char*)name);
2663 win->wndproc = (WNDPROC)SetWindowLong(win->handle, GWL_WNDPROC, (LONG)XcButtonProc);
2664 WinSetValues(win, args, n);
2667 case XwtoggleWidgetClass:
2669 POINT pt = {CW_USEDEFAULT, CW_USEDEFAULT};
2671 get_window_location(args, n, &pt, NULL);
2672 win = create_widget(CreateWindow("BUTTON", name, BS_CHECKBOX|WS_CHILD|WS_VISIBLE, pt.x, pt.y,
2673 CW_USEDEFAULT, CW_USEDEFAULT, parent->handle, NULL, NULL, NULL), (char*)name);
2674 win->wndproc = (WNDPROC)SetWindowLong(win->handle, GWL_WNDPROC, (LONG)XcToggleProc);
2675 WinSetValues(win, args, n);
2678 case XwbulletinWidgetClass:
2683 W32DEBUG(("Should create widget: %02x, %s\n", cls
, name
));
2689 ShowWindow(win
->handle
, SW_SHOW
);
2691 ShowWindow(win
->handle
, SW_HIDE
);
2696 Widget
WinCreatePopup(const char *name
, Arg
*args
, int n
)
2700 hwnd
= CreateWindow("XcPopup", name
, WS_TILEDWINDOW
, CW_USEDEFAULT
, CW_USEDEFAULT
,
2701 300, 200, NULL
, NULL
, NULL
, NULL
);
2702 return create_widget(hwnd
, (char*)name
);
2705 void WinPopup(Widget popup
)
2707 ShowWindow(popup
->handle
, SW_SHOWNORMAL
);
2710 char* WinGetText(Widget win
)
2712 static char buffer
[1024];
2714 GetWindowText(win
->handle
, buffer
, 1024);
2718 void WinClearText(Widget win
)
2720 SetWindowText(win
->handle
, "");
2723 int WinNamedColor(const char *cname
)
2727 for (i
=0; X11Colors
[i
].name
; i
++) {
2728 if (_stricmp(X11Colors
[i
].name
, cname
) == 0)
2729 return RGB(X11Colors
[i
].red
, X11Colors
[i
].green
, X11Colors
[i
].blue
);
2731 W32DEBUG(("Unknown color: %s\n", cname
));
2735 int WinLookupColor(const char *cname
, XColor
*color
)
2737 int cval
= WinNamedColor(cname
);
2741 color
->pixel
= cval
;
2742 WinQueryColors(color
, 1);
2747 char *WinColorName(int c
)
2749 int red
= GetRValue(c
), green
= GetGValue(c
), blue
= GetBValue(c
);
2752 for (i
=0; X11Colors
[i
].name
; i
++)
2753 if (red
== X11Colors
[i
].red
&& green
== X11Colors
[i
].green
&& blue
== X11Colors
[i
].blue
)
2754 return X11Colors
[i
].name
;
2758 HWND
WinWindow(Widget w
)
2760 return (w
? w
->handle
: NULL
);
2763 void WinManageChild(Widget w
)
2766 ShowWindow(w
->handle
, SW_SHOW
);
2769 void WinUnmanageChild(Widget w
)
2772 ShowWindow(w
->handle
, SW_HIDE
);
2775 void WinDebug(char *c
)
2777 W32DEBUG(("%s", c
));
2780 void WinLookupString(XKeyEvent
*event
, KeySym
*key
)
2782 XKeyEvent
*kevent
= (XKeyEvent
*)event
;
2783 int vk
= kevent
->keycode
& 0xff;
2788 W32DEBUG(("Translating key event: %d\n", vk
));
2789 *key
= kevent
->keycode
;
2793 void WinPostPopup(Widget _menu
, Widget _button
, int dx
, int dy
)
2795 Menu menu
= (Menu
)_menu
;
2796 ToolItem button
= (ToolItem
)_button
;
2797 RECT bRect
= { 0, 0, 0, 0 };
2800 SendMessage(button
->toolbar
->handle
, TB_GETRECT
, button
->ID
, (LPARAM
)&bRect
);
2802 pt
.y
= bRect
.bottom
;
2803 ClientToScreen(button
->toolbar
->handle
, &pt
);
2804 SendMessage(button
->toolbar
->handle
, TB_CHECKBUTTON
, button
->ID
, MAKELONG(TRUE
, 0));
2805 TrackPopupMenu(menu
->handle
, TPM_LEFTALIGN
|TPM_TOPALIGN
, pt
.x
, pt
.y
, 0, top
->handle
, NULL
);
2806 SendMessage(button
->toolbar
->handle
, TB_CHECKBUTTON
, button
->ID
, MAKELONG(FALSE
, 0));
2809 void overdrawpixmap(Widget button
)
2811 MenuItem mitem
= (MenuItem
)button
;
2812 ToolItem titem
= NULL
;
2815 if (button
== NULL
) return;
2816 idx
= mitem
->toolbar_idx
;
2818 if (mitem
->parentMenu
== ((MenuItem
)ColorInheritColorButton
)->parentMenu
)
2819 titem
= (ToolItem
)ColorsToolButton
;
2820 else if (mitem
->parentMenu
== ((MenuItem
)FillBlackButton
)->parentMenu
)
2821 titem
= (ToolItem
)FillsToolButton
;
2826 if (mitem
== (MenuItem
)ColorInheritColorButton
) {
2827 idx
= ((ToolItem
)ColorsToolButton
)->ID
-((ToolItem
)PanToolButton
)->ID
;
2828 } else if (mitem
== (MenuItem
)FillWhiteButton
) {
2829 idx
= ((ToolItem
)FillsToolButton
)->ID
-((ToolItem
)PanToolButton
)->ID
;
2831 HBITMAP hBitmap
= NULL
;
2833 if (titem
== (ToolItem
)ColorsToolButton
)
2834 hBitmap
= create_color_icon(mitem
->menudata
, 20, 20);
2836 if (mitem
->menudata
== (OPAQUE
| FILLED
| FILLSOLID
))
2837 hBitmap
= create_color_icon(RGB(0, 0, 0), 20, 20);
2838 else if (mitem
!= (MenuItem
)FillOpaqueButton
&& mitem
!= (MenuItem
)FillTransparentButton
)
2839 hBitmap
= create_stipple_icon((mitem
->menudata
& FILLSOLID
) >> 5, 20, 20);
2841 if (hBitmap
!= NULL
) {
2843 tb
.nID
= (INT_PTR
)hBitmap
;
2844 idx
= mitem
->toolbar_idx
= SendMessage(titem
->toolbar
->handle
, TB_ADDBITMAP
, 1, (LPARAM
)&tb
);
2849 W32DEBUG(("%s: %d\n", titem
->name
, idx
));
2851 SendMessage(titem
->toolbar
->handle
, TB_CHANGEBITMAP
, titem
->ID
, MAKELPARAM(idx
, 0));
2855 void starthelp(xcWidget button
, caddr_t clientdata
, caddr_t calldata
)
2857 DialogBoxParam(GetModuleHandle(NULL
), MAKEINTRESOURCE(IDD_HELPDLG
), areawin
->window
, HelpDlgProc
, (LPARAM
)NULL
);
2861 static void get_text_size(HWND hwnd, HFONT hfont, SIZE *sz)
2863 HDC hdc = GetDC(hwnd);
2867 SelectObject(hdc, hfont);
2868 n = GetWindowText(hwnd, str, 64);
2869 GetTextExtentPoint32(hdc, str, n, sz);
2870 ReleaseDC(hwnd, hdc);
2873 LRESULT CALLBACK XcStaticProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2875 Widget w = (Widget)GetWindowLong(hwnd, GWL_USERDATA);
2881 get_text_size(hwnd, (HFONT)wParam, &sz);
2882 SetWindowPos(hwnd, HWND_TOP, 0, 0, sz.cx, sz.cy, SWP_NOMOVE);
2887 return CallWindowProc(w->wndproc, hwnd, msg, wParam, lParam);
2890 LRESULT CALLBACK XcEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2892 Widget w = (Widget)GetWindowLong(hwnd, GWL_USERDATA);
2896 if (wParam == VK_RETURN) {
2897 execute_callback(XtNexecute, w, NULL);
2903 return CallWindowProc(w->wndproc, hwnd, msg, wParam, lParam);
2906 LRESULT CALLBACK XcButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2908 Widget w = (Widget)GetWindowLong(hwnd, GWL_USERDATA);
2914 get_text_size(hwnd, (HFONT)wParam, &sz);
2915 printf("%d %d\n", sz.cx, sz.cy);
2916 SetWindowPos(hwnd, HWND_TOP, 0, 0, sz.cx+20, sz.cy+10, SWP_NOMOVE);
2921 LRESULT result = CallWindowProc(w->wndproc, hwnd, msg, wParam, lParam);
2923 get_text_size(hwnd, (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0), &sz);
2924 SetWindowPos(hwnd, HWND_TOP, 0, 0, sz.cx+20, sz.cy+10, SWP_NOMOVE);
2927 case WM_LBUTTONDOWN:
2928 execute_callback(XtNselect, w, NULL);
2932 return CallWindowProc(w->wndproc, hwnd, msg, wParam, lParam);
2935 LRESULT CALLBACK XcToggleProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2937 Widget w = (Widget)GetWindowLong(hwnd, GWL_USERDATA);
2943 get_text_size(hwnd, (HFONT)wParam, &sz);
2944 SetWindowPos(hwnd, HWND_TOP, 0, 0, sz.cx+20, sz.cy+10, SWP_NOMOVE);
2949 LRESULT result = CallWindowProc(w->wndproc, hwnd, msg, wParam, lParam);
2950 if (SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED)
2951 execute_callback(XtNselect, w, NULL);
2953 execute_callback(XtNrelease, w, NULL);
2958 return CallWindowProc(w->wndproc, hwnd, msg, wParam, lParam);
2961 LRESULT CALLBACK XcPopupProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2963 return DefDlgProc(hwnd, msg, wParam, lParam);
2967 static void change_char(char *str
, char cfrom
, char cto
)
2975 LRESULT CALLBACK
OutputDlgEditProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2977 Widget win
= get_widget (hwnd
);
2982 MSG
*message
= (MSG
*)lParam
;
2983 if (message
->message
== WM_KEYDOWN
&& message
->wParam
== VK_RETURN
)
2984 return DLGC_WANTMESSAGE
;
2990 execute_callback(XtNexecute
, win
, NULL
);
2995 return CallWindowProc(win
->wndproc
, hwnd
, msg
, wParam
, lParam
);
2998 LRESULT CALLBACK
OutputDlgProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
3000 Widget popup
= get_widget(hwnd
);
3010 void (*function
[MAXPROPS
])() = { setfilename
, setpagelabel
, setfloat
, setscalex
, setscaley
, setorient
, setpmode
};
3011 void (*update
[MAXPROPS
])() = { updatename
, NULL
, updatetext
, updatetext
, updatetext
, updatetext
, NULL
};
3012 char statics
[MAXPROPS
][50], edit
[MAXPROPS
][75], request
[150];
3013 void *data
[MAXPROPS
];
3014 struct {int edit
; int apply
; int label
;} ID
[MAXPROPS
] = {
3015 { IDC_FILENAME
, IDC_APPLY1
, IDC_STATIC1
},
3016 { IDC_PAGELABEL
, IDC_APPLY2
, IDC_STATIC2
},
3017 { IDC_SCALE
, IDC_APPLY3
, IDC_STATIC3
},
3018 { IDC_WIDTH
, IDC_APPLY4
, IDC_STATIC4
},
3019 { IDC_HEIGHT
, IDC_APPLY5
, IDC_STATIC5
},
3020 { IDC_ORIENTATION
, -1, IDC_STATIC6
},
3021 { IDC_MODE
, -1, IDC_STATIC7
} };
3022 struct stat statbuf
;
3024 GetWindowRect(GetParent(hwnd
), &pr
);
3025 GetWindowRect(hwnd
, &r
);
3026 SetWindowPos(hwnd
, HWND_TOP
, pr
.left
+((pr
.right
-pr
.left
)-(r
.right
-r
.left
))/2,
3027 pr
.top
+((pr
.bottom
-pr
.top
)-(r
.bottom
-r
.top
))/2, 0, 0, SWP_NOSIZE
);
3029 SendDlgItemMessage(hwnd
, IDC_ORIENTATION
, CB_ADDSTRING
, 0, (LPARAM
)"Landscape");
3030 SendDlgItemMessage(hwnd
, IDC_ORIENTATION
, CB_ADDSTRING
, 0, (LPARAM
)"Portrait");
3031 SendDlgItemMessage(hwnd
, IDC_MODE
, CB_ADDSTRING
, 0, (LPARAM
)"Embedded (EPS)");
3032 SendDlgItemMessage(hwnd
, IDC_MODE
, CB_ADDSTRING
, 0, (LPARAM
)"Full page");
3034 curpage
= xobjs
.pagelist
[areawin
->page
];
3035 entertext
= (Widget
*)malloc(sizeof(Widget
)*MAXPROPS
);
3036 memset(okstruct
, 0, sizeof(propstruct
)*MAXPROPS
);
3038 sprintf(edit
[0], "%s", curpage
->filename
);
3039 sprintf(edit
[1], "%s", topobject
->name
);
3040 calcbbox(areawin
->topinstance
);
3041 if (curpage
->pmode
& 2) autoscale(areawin
->page
);
3042 writescalevalues(edit
[2], edit
[3], edit
[4]);
3043 sprintf(edit
[5], "%s", (curpage
->orient
== 0) ? "Portrait" : "Landscape");
3044 sprintf(edit
[6], "%s", (curpage
->pmode
& 1) ? "Full page" : "Embedded (EPS)");
3045 data
[0] = &(curpage
->filename
);
3046 data
[1] = topobject
->name
;
3047 data
[2] = data
[3] = data
[4] = &(curpage
->outscale
);
3048 data
[5] = &(curpage
->orient
);
3049 data
[6] = &(curpage
->pmode
);
3051 popup
= create_widget(hwnd
, "outputpopup");
3052 popup
->bufhdc
= (HDC
)entertext
;
3053 create_widget(GetDlgItem(hwnd
, IDOK
), "Write File");
3054 create_widget(GetDlgItem(hwnd
, IDCANCEL
), "Close");
3056 sprintf(request
, "PostScript output properties (Page %d):", areawin
->page
+ 1);
3057 sprintf(statics
[0], "Filename:");
3058 sprintf(statics
[1], "Page label:");
3059 sprintf(statics
[2], "Scale:");
3060 if (curpage
->coordstyle
== CM
) {
3061 sprintf(statics
[3], "X Size (cm):");
3062 sprintf(statics
[4], "Y Size (cm):");
3064 sprintf(statics
[3], "X Size (in):");
3065 sprintf(statics
[4], "Y Size (in):");
3067 sprintf(statics
[5], "Orientation:");
3068 sprintf(statics
[6], "Mode:");
3069 SetDlgItemText(hwnd
, IDC_PSINFO
, request
);
3071 strcpy(request
, edit
[0]);
3072 if (strstr(request
, ".") == NULL
)
3073 strcat(request
, ".ps");
3074 if (stat(request
, &statbuf
) == 0) {
3075 SetWindowText(GetDlgItem(hwnd
, IDOK
), "Overwrite File");
3076 Wprintf(" Warning: File exists");
3078 if (errno
== ENOTDIR
)
3079 Wprintf("Error: Incorrect pathname");
3080 else if (errno
== EACCES
)
3081 Wprintf("Error: Path not readable");
3086 for (i
=0; i
<MAXPROPS
; i
++) {
3087 SetDlgItemText(hwnd
, ID
[i
].label
, statics
[i
]);
3089 okstruct
[i
].textw
= entertext
[i
] = create_widget(GetDlgItem(hwnd
, ID
[i
].edit
), "Edit");
3090 okstruct
[i
].buttonw
= create_widget(GetDlgItem(hwnd
, ID
[i
].apply
), "Apply");
3091 okstruct
[i
].setvalue
= function
[i
];
3092 okstruct
[i
].dataptr
= data
[i
];
3093 SetWindowText(okstruct
[i
].textw
->handle
, edit
[i
]);
3095 WinAddCallback(okstruct
[i
].buttonw
, XtNselect
, getproptext
, &okstruct
[i
]);
3096 WinAddCallback(okstruct
[i
].textw
, XtNexecute
, getproptext
, &okstruct
[i
]);
3097 if (update
[i
] != NULL
) {
3098 WinAddCallback(okstruct
[i
].buttonw
, XtNselect
, update
[i
], entertext
);
3099 WinAddCallback(okstruct
[i
].textw
, XtNexecute
, update
[i
], entertext
);
3102 okstruct
[i
].textw
->wndproc
= (WNDPROC
)SetWindowLong(okstruct
[i
].textw
->handle
,
3103 GWL_WNDPROC
, (LONG
)OutputDlgEditProc
);
3105 entertext
[i
] = create_widget(GetDlgItem(hwnd
, ID
[i
].edit
), "Toggle");
3106 SendMessage(entertext
[i
]->handle
, CB_SELECTSTRING
, -1, (LPARAM
)edit
[i
]);
3107 WinAddCallback(entertext
[i
], XtNselect
, function
[i
], data
[i
]);
3108 if (update
[i
] != NULL
)
3109 WinAddCallback(entertext
[i
], XtNselect
, update
[i
], entertext
);
3113 sprintf(request
, "%d Pages", pagelinks(areawin
->page
));
3114 win
= create_widget(GetDlgItem(hwnd
, IDC_PAGENUM
), "LToggle");
3115 SetWindowText(win
->handle
, request
);
3116 CheckDlgButton(hwnd
, IDC_PAGENUM
, BST_CHECKED
);
3117 WinAddCallback(win
, XtNrelease
, linkset
, &okstruct
[0]);
3119 win
= create_widget(GetDlgItem(hwnd
, IDC_AUTOFIT
), "Auto-fit");
3120 SendMessage(win
->handle
, BM_SETCHECK
, (curpage
->pmode
& 2 ? BST_CHECKED
: BST_UNCHECKED
), 0);
3121 WinAddCallback(win
, XtNselect
, autoset
, entertext
);
3122 WinAddCallback(win
, XtNrelease
, autostop
, NULL
);
3124 if (curpage
->coordstyle
== CM
) {
3125 sprintf(request
, "%3.2f x %3.2f cm",
3126 (float)curpage
->pagesize
.x
/ IN_CM_CONVERT
,
3127 (float)curpage
->pagesize
.y
/ IN_CM_CONVERT
);
3129 sprintf(request
, "%3.2f x %3.2f in",
3130 (float)curpage
->pagesize
.x
/ 72.0,
3131 (float)curpage
->pagesize
.y
/ 72.0);
3133 fpokstruct
.textw
= create_widget(GetDlgItem(hwnd
, IDC_FPEDIT
), "fpedit");
3134 SetWindowText(fpokstruct
.textw
->handle
, request
);
3135 fpokstruct
.buttonw
= create_widget(GetDlgItem(hwnd
, IDC_APPLY6
), "fpokay");
3136 fpokstruct
.setvalue
= setpagesize
;
3137 fpokstruct
.dataptr
= &(curpage
->pagesize
);
3138 WinAddCallback(fpokstruct
.buttonw
, XtNselect
, getproptext
, &fpokstruct
);
3139 WinAddCallback(fpokstruct
.buttonw
, XtNselect
, updatetext
, entertext
);
3140 WinAddCallback(fpokstruct
.textw
, XtNexecute
, getproptext
, &fpokstruct
);
3141 WinAddCallback(fpokstruct
.textw
, XtNexecute
, updatetext
, entertext
);
3143 WinAddCallback(get_widget(GetDlgItem(hwnd
, IDOK
)), XtNselect
, setfile
, entertext
[0]);
3145 if (curpage
->pmode
> 0) {
3146 XtManageChild(get_widget(GetDlgItem(hwnd
, IDC_AUTOFIT
)));
3147 XtManageChild(fpokstruct
.textw
);
3148 XtManageChild(fpokstruct
.buttonw
);
3151 if (pagelinks(areawin
->page
) > 1)
3152 XtManageChild(get_widget(GetDlgItem(hwnd
, IDC_PAGENUM
)));
3154 SetFocus(entertext
[0]->handle
);
3159 free((Widget
*)popup
->bufhdc
);
3160 destroy_widget(hwnd
);
3162 int ID
[] = { IDOK
, IDCANCEL
, IDC_APPLY1
, IDC_FILENAME
, IDC_APPLY2
, IDC_PAGELABEL
,
3163 IDC_APPLY3
, IDC_SCALE
, IDC_APPLY4
, IDC_WIDTH
, IDC_APPLY5
, IDC_HEIGHT
,
3164 IDC_PAGENUM
, IDC_AUTOFIT
, IDC_FPEDIT
, -1 };
3167 for (i
=0; ID
[i
]!=-1; i
++)
3168 destroy_widget(GetDlgItem(hwnd
, ID
[i
]));
3172 switch (LOWORD(wParam
)) {
3174 if (HIWORD(wParam
) == BN_CLICKED
) {
3175 execute_callback(XtNselect
, get_widget((HWND
)lParam
), NULL
);
3180 if (HIWORD(wParam
) == BN_CLICKED
)
3188 ZeroMemory(&ofn
, sizeof(ofn
));
3189 ofn
.lStructSize
= sizeof(ofn
);
3190 ofn
.hwndOwner
= hwnd
;
3191 ofn
.lpstrFile
= _STR2
;
3193 ofn
.lpstrFilter
= "XCircuit Files (*.ps;*.eps)\000*.ps;*.eps\000All Files (*.*)\000*.*\000\000\000";
3194 GetDlgItemText(hwnd
, IDC_FILENAME
, _STR2
, 250);
3195 change_char(_STR2
, '/', '\\');
3196 if (strstr(_STR2
, ".") == NULL
)
3197 strncat(_STR2
, ".ps", 250);
3198 if (GetSaveFileName(&ofn
)) {
3199 change_char(_STR2
, '\\', '/');
3200 len
= strlen(_STR2
);
3201 if (len
>= 3 && strncmp(_STR2
+len
-3, ".ps", 3) == 0)
3202 _STR2
[len
-3] = '\0';
3203 SetDlgItemText(hwnd
, IDC_FILENAME
, _STR2
);
3204 SendDlgItemMessage(hwnd
, IDC_APPLY1
, BM_CLICK
, 0, 0);
3214 if (HIWORD(wParam
) == BN_CLICKED
)
3215 execute_callback(XtNselect
, get_widget((HWND
)lParam
), NULL
);
3219 if (HIWORD(wParam
) == BN_CLICKED
) {
3220 if (SendMessage((HWND
)lParam
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
3221 execute_callback(XtNselect
, get_widget((HWND
)lParam
), NULL
);
3223 execute_callback(XtNrelease
, get_widget((HWND
)lParam
), NULL
);
3227 if (HIWORD(wParam
) == CBN_SELENDOK
)
3228 execute_callback(XtNselect
, get_widget((HWND
)lParam
), NULL
);
3239 extern int main(int argc
, char **argv
);
3241 int WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR cmdLine
, int cmdShow
)
3247 wargv
= CommandLineToArgvW(GetCommandLineW(), &argc
);
3248 argv
= (char**)malloc(sizeof(char*)*argc
);
3249 for (i
=0; i
<argc
; i
++) {
3250 int len
= wcslen(wargv
[i
]);
3251 argv
[i
] = (char*)malloc(sizeof(char)*2*(len
+1));
3252 wcstombs(argv
[i
], wargv
[i
], 2*(len
+1));
3253 if (argv
[i
][0] != '-')
3254 change_char(argv
[i
], '\\', '/');
3258 return main(argc
, argv
);
3261 const char* WinBuiltinsDir()
3263 static char buffer
[MAX_PATH
] = {0};
3265 if (buffer
[0] == 0) {
3267 GetModuleFileName(NULL
, buffer
, MAX_PATH
);
3268 c
= strrchr(buffer
, '\\');
3270 c
= strrchr(buffer
, '/');
3273 change_char(buffer
, '\\', '/');
3279 static Widget
find_menu_from_name(Menu menu
, const char *name
)
3282 MENUITEMINFO mi_info
;
3284 Widget found
= NULL
;
3286 count
= GetMenuItemCount((HMENU
)menu
->handle
);
3287 ZeroMemory(&mi_info
, sizeof(mi_info
));
3288 mi_info
.cbSize
= sizeof(mi_info
);
3289 mi_info
.fMask
= MIIM_DATA
;
3290 for (i
=0; found
== NULL
&& i
<count
; i
++) {
3291 mi_info
.dwItemData
= (LONG
)NULL
;
3292 if (GetMenuItemInfo((HMENU
)menu
->handle
, i
, MF_BYPOSITION
, &mi_info
) &&
3293 (item
= (MenuItem
)mi_info
.dwItemData
) != NULL
) {
3294 if (item
->name
&& strcmp(item
->name
, name
) == 0)
3295 found
= (Widget
)item
;
3296 else if (item
->popup
!= NULL
)
3297 found
= find_menu_from_name(item
->popup
, name
);
3303 Widget
WinGetMenu(const char *name
)
3307 ZeroMemory(&minfo
, sizeof(minfo
));
3308 minfo
.cbSize
= sizeof(minfo
);
3309 minfo
.fMask
= MIM_MENUDATA
;
3310 if (GetMenuInfo(GetMenu(topwin
), &minfo
)) {
3311 Menu menu
= (Menu
)minfo
.dwMenuData
;
3312 if (name
== NULL
|| *name
== '\0')
3313 return (Widget
)menu
;
3315 return find_menu_from_name(menu
, name
);
3320 int WinIsPopupMenu(Widget w
)
3323 (IS_MENUITEM(w
) && TOMENUITEM(w
)->popup
!= NULL
))
3328 void exec_script_command(void *button
, void *data
)
3330 #ifdef USE_WIN32_COM
3337 popupprompt(NULL
, "Enter command to execute:", "", exec_script_command
, NULL
, NULL
);
3340 #ifdef USE_WIN32_COM
3342 void win32_comscript()
3344 COM_runscript(_STR2
);
3347 void win32_comdotnet()
3349 COM_load_dotnet(_STR2
);
3354 void win32_new_window(Widget w
, void *clientData
, void *callData
)
3356 XCWindowData
*newwin
= GUI_init(0, NULL
);
3358 newwin
->page
= areawin
->page
;
3359 newwin
->vscale
= areawin
->vscale
;
3360 newwin
->pcorner
= areawin
->pcorner
;
3361 newwin
->topinstance
= areawin
->topinstance
;
3364 ShowWindow(top
->handle
, SW_SHOW
);