Check-in [35d71c4ec8]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:add Peter Spjuth's Win32 WM_TOUCH support to tk plus other changes
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 35d71c4ec8577a68f4feb3689dc25823b6ec7b55
User & Date: chw 2016-09-05 19:23:00.718
Context
2016-09-06
21:36
fix for ticket [9c8e7490ad] check-in: b530e1ef53 user: chw tags: trunk
2016-09-05
19:23
add Peter Spjuth's Win32 WM_TOUCH support to tk plus other changes check-in: 35d71c4ec8 user: chw tags: trunk
18:00
add tcl upstream changes check-in: 3ef2f5b270 user: chw tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Added jni/sdl2tk/library/demos/wintouch.tcl.






























































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# Example usage of the touch interface

if 0 {
    The current interface is as follows.

    All configuration is done via:
    wm touch <win> ?options?

    Some gestures are on by default. It seems like all but rotate.
    To get raw touch events, they must be turned on.

    To control gestures:
    -all : Turn on all gestures
    -pressandtap <bool> : Turn on or off PressAndTap gesture
    -rotate <bool> : Turn on or off Rotate gesture
    -twofingertap <bool> : Turn on or off TwoFingerTap gesture
    -zoom <bool> : Turn on or off Zoom gesture
    -pan <bool> : Turn on or off Pan gestures
    -pansfh <bool> : Turn on or off Pan single finger horizontal gesture
    -pansfv <bool> : Turn on or off Pan single finger vertical gesture
    -pangutter <bool> : Turn on or off Pan gutter mode
    -paninertia <bool> : Turn on or off Pan inertial mode
    See GESTURECONFIG in win API for pan flags.

    To get raw touch events:
    If any of the flags -touch, -fine or -wantpalm is given,
    the window is registered to receive raw touch event.
    It will no longer receive any gesture events.
    The flags -fine/-wantpalm corresponds to the Windows API
    RegisterTouchWindow.

    Events are received as virtual events.
    These events support at least base %W %x %y %X %Y fields.
    All extra information is given in a dictionary in the %d field.
    <<FingerDown>> <<FingerUp>> <<FingerMotion>> : Raw touch events
    <<PinchToZoom>> : Zoom gesture
    <<Gesture>>     : Other gestures

    Any boolean field in the dictionary is either present with
    the value 1 or not present. Below they are written without a value.

    Touch fields:
    event = touch : Identify event as a touch. (i.e. not a gesture)
    id <val> : Id to know what events belong to the same touch.
    flags <val> : Raw flags value, in case future flags are provided.
    down : Start of touch
    move : Touch is moving
    up   : End of touch
    primary : First touch in a multi touch. Primary touch might also cause
              button events.
    inrange/nocoalesce/palm : See TOUCHINPUT in Windows API.

    Gesture fields:
    event = gesture : Identify event as a gesture.
    flags <val> : Raw flags value, in case future flags are provided.
    begin : Start of gesture
    end : End of gesture
    inertia : Gesture has triggered inertia

    Note that begin and end can both be set, e.g. in two finger tap.

    gesture <type> : Where type is one of:
      zoom : Zoom gesture. %x/y is between fingers
      pan  : Pan gesture. %x/y is between fingers
      rotate : Rotate gesture. %x/y is between fingers
      twofingertap : Two finger tap gesture. %x/y is between fingers
      pressandtap : Press and tap gesture. %x/y is first finger
    
    distance <i> : For zoom/pan/twofingertap: Distance between fingers.
    angle <r> : For rotate: Rotation angle in radians.
    deltax <i> : For pressandtap: Locates second finger. Valid with begin.
    deltay <i> : For pressandtap: Locates second finger. Valid with begin.
    inertiax <i> : For pan: Inertia vector. Valid with inertia flag.
    inertiay <i> : For pan: Inertia vector. Valid with inertia flag.

}

namespace import tcl::mathop::*

proc rndCol {} {
    set lst {orange yellow green cyan blue purple violet pink}
    set i [expr {int(rand()*[llength $lst])}]
    return [lindex $lst $i]
}

proc Circle {w x y r args} {
    $w create oval [- $x $r] [- $y $r] [+ $x $r] [+ $y $r] \
	-fill "" -outline black -width 2 {*}$args
}

proc Touch1 {W d x y X Y} {
    puts stderr "Touch1: $W $x $y $X $Y"
    puts stderr "Touch1: $d"

    set id [dict get $d id]

    set move [dict exists $d move]
    set down [dict exists $d down]
    set up   [dict exists $d up]
    set primary [dict exists $d primary]

    if {![info exists ::t($id,id)]} {
	set ::t($id,id) [$W create oval $x $y $x $y]
	if {$primary} {
	    $W itemconfigure $::t($id,id) -fill red
	} else {
	    $W itemconfigure $::t($id,id) -fill [rndCol]
	}
    }
    if {$up} {
	$W delete $::t($id,id)
	array unset ::t $id,*
	return
    }

    # Filter unnecessary movement
    if {$move && $x == $::t($id,x) && $y == $::t($id,y)} {
	return
    }
    set r [expr {[winfo screenwidth .] / 50}]
    set ::t($id,x) $x
    set ::t($id,y) $y
    $W coords $::t($id,id) [- $x $r] [- $y $r] [+ $x $r] [+ $y $r]
}

proc Log {W d} {
    # Make a little log of messages for now
    if {[lindex $::messages 9] ne $d} {
	lappend ::messages $d
	set ::messages [lrange $::messages end-9 end]
    }
    set txt [join $::messages \n]
    $W itemconfigure gesture -text $txt
    $W raise gesture
}

proc Touch2 {W d x y X Y} {
    if {[dict get $d event] ne "gesture"} return

    puts stderr "Touch2: $W $x $y $X $Y"
    puts stderr "Touch2: $d"

    switch [dict get $d gesture] {
        twofingertap {
            $W delete twofingertap
            set r [expr {[dict get $d distance] / 2}]
            Circle $W $x $y $r -fill yellow -tags twofingertap
        }
        pressandtap {
            if {[dict exists $d begin]} {
                # Only the begin message has delta set
                $W delete pressandtap
                set x1 [expr {$x + [dict get $d deltax]}]
                set y1 [expr {$y + [dict get $d deltay]}]
                $W create line $x $y $x1 $y1 -width 5 -fill red \
                        -tags pressandtap
            }
            if {[dict exists $d end]} {
                # Make end visible by changing colour
                $W itemconfigure pressandtap -fill purple
            }
        }
        zoom {
            $W delete zoom
            set r [expr {[dict get $d distance] / 2}]
            Circle $W $x $y $r -fill blue -tags zoom
        }
        pan {
            $W delete pan
            set dist [dict get $d distance]
            if {$dist == 0} {
                # Must be one finger?
                set r 40
                set col red
            } else {
                set r [expr {$dist / 2}]
                set col green
            }
            Circle $W $x $y $r -fill $col -tags pan
        }
        rotate {
            $W delete rotate
            set a [expr {180.0*[dict get $d angle]/3.141592 - 20}]
            set r [expr {$::size/4}]
            $W create arc [- $x $r] [- $y $r] [+ $x $r] [+ $y $r] \
                    -fill orange -outline black -width 2 -tags rotate \
                    -start $a -extent 40
        }
    }
    Log $W $d
}

console show
set ::sizew [expr {[winfo screenwidth .] * 0.45}]
set ::sizeh [expr {[winfo screenheight .] * 0.45}]
if {$::sizeh < $::sizew} {
    set ::size [expr round($::sizeh)]
} else {
    set ::size [expr round($::sizew)]
}
canvas .c1 -width $::size -height $::size -bd 3 -relief solid
canvas .c2 -width $::size -height $::size -bd 3 -relief solid
canvas .c3 -width $::size -height $::size -bd 3 -relief solid
.c1 create text [expr {$::size /2}] [expr {$::size /2}] -text Touch
lappend ::messages "Gesture"
.c2 create text [expr {$::size / 2}] [expr {$::size / 2}] -text GestureAll -tags gesture
.c3 create text [expr {$::size / 2}] [expr {$::size / 2}] -text Gesture -tags gesture

grid .c1 -   -sticky news
grid .c2 .c3 -sticky news
grid columnconfigure . all -weight 1
grid rowconfigure . all -weight 1
wm touch .c1 -touch
wm touch .c2 -all
wm touch .c3 -pan 1 -pansfv 0 -pansfh 0 -pangutter 0 -paninertia 0
bind .c1 <<FingerDown>> "Touch1 %W %d %x %y %X %Y"
bind .c1 <<FingerUp>> "Touch1 %W %d %x %y %X %Y"
bind .c1 <<FingerMotion>> "Touch1 %W %d %x %y %X %Y"
bind .c2 <<Gesture>> "Touch2 %W %d %x %y %X %Y"
bind .c2 <<PinchToZoom>> "Touch2 %W %d %x %y %X %Y"
bind .c3 <<Gesture>> "Touch2 %W %d %x %y %X %Y"
bind .c3 <<PinchToZoom>> "Touch2 %W %d %x %y %X %Y"

jni/sdl2tk/unix/configure.in became a regular file.
Changes to jni/sdl2tk/win/tkWinInt.h.
201
202
203
204
205
206
207





208
209
210
211
212
213
214
MODULE_SCOPE int		TkpWmGetState(TkWindow *winPtr);

/*
 * Common routines used in Windows implementation
 */
MODULE_SCOPE Tcl_Obj *	        TkWin32ErrorObj(HRESULT hrError);







/*
 * The following functions are not present in old versions of Windows
 * API headers but are used in the Tk source to ensure 64bit
 * compatibility.
 */








>
>
>
>
>







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
MODULE_SCOPE int		TkpWmGetState(TkWindow *winPtr);

/*
 * Common routines used in Windows implementation
 */
MODULE_SCOPE Tcl_Obj *	        TkWin32ErrorObj(HRESULT hrError);

/*
 * Touch/gesture event support
 */
MODULE_SCOPE int		TkWinGenerateTouchEvent(HWND hwnd, WPARAM wParam, LPARAM lParam);
MODULE_SCOPE int		TkWinGenerateGestureEvent(HWND hwnd, WPARAM wParam, LPARAM lParam);

/*
 * The following functions are not present in old versions of Windows
 * API headers but are used in the Tk source to ensure 64bit
 * compatibility.
 */

Changes to jni/sdl2tk/win/tkWinKey.c.
331
332
333
334
335
336
337





338
339
340
341
342
343


344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
    if (keycode > MAX_KEYCODE) {
	return NoSymbol;
    }
    switch (keycode) {
	/*
	 * Windows only gives us an undifferentiated VK_CONTROL code (for
	 * example) when either Control key is pressed. To distinguish between





	 * left and right, we have to query the state of one of the two to
	 * determine which was actually pressed. So if the keycode indicates
	 * Control, Shift, or Menu (the key that everybody else calls Alt), do
	 * this extra test. If the right-side key was pressed, return the
	 * appropriate keycode. Otherwise, we fall through and rely on the
	 * keymap table to hold the correct keysym value.


	 */

    case VK_CONTROL:
	if (GetKeyState(VK_RCONTROL) & 0x80) {
	    return XK_Control_R;
	}
	break;
    case VK_SHIFT:
	if (GetKeyState(VK_RSHIFT) & 0x80) {
	    return XK_Shift_R;
	}
	break;
    case VK_MENU:
	if (GetKeyState(VK_RMENU) & 0x80) {
	    return XK_Alt_R;
	}
	break;
    }
    return keymap[keycode];
}

/*
 *----------------------------------------------------------------------







>
>
>
>
>
|
|
<
|
|
|
>
>



|
|
|







|
|
|







331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
    if (keycode > MAX_KEYCODE) {
	return NoSymbol;
    }
    switch (keycode) {
	/*
	 * Windows only gives us an undifferentiated VK_CONTROL code (for
	 * example) when either Control key is pressed. To distinguish between
	 * left and right, we use the Extended flag. Indeed, the right Control
	 * and Alt (aka Menu) keys are such extended keys (which their left
	 * counterparts are not).
	 * Regarding the shift case, Windows does not set the Extended flag for
	 * the neither the left nor the right shift key. As a consequence another
	 * way to distinguish between the two keys is to query the state of one
	 * of the two to determine which was actually pressed. So if the keycode

	 * indicates Shift, do this extra test. If the right-side key was
	 * pressed, return the appropriate keycode. Otherwise, we fall through
	 * and rely on the keymap table to hold the correct keysym value.
	 * Note: this little trick only works for KeyPress, not for KeyRelease,
	 * for reasons stated in bug [2945130]
	 */

    case VK_CONTROL:
        if (state & EXTENDED_MASK) {
            return XK_Control_R;
        }
	break;
    case VK_SHIFT:
	if (GetKeyState(VK_RSHIFT) & 0x80) {
	    return XK_Shift_R;
	}
	break;
    case VK_MENU:
        if (state & EXTENDED_MASK) {
            return XK_Alt_R;
        }
	break;
    }
    return keymap[keycode];
}

/*
 *----------------------------------------------------------------------
Changes to jni/sdl2tk/win/tkWinWm.c.
393
394
395
396
397
398
399
















































400
401
402
403
404
405
406
 */

static int initialized;		/* Flag indicating whether module has been
				 * initialized. */

TCL_DECLARE_MUTEX(winWmMutex)

















































/*
 * Forward declarations for functions defined in this file:
 */

static int		ActivateWindow(Tcl_Event *evPtr, int flags);
static void		ConfigureTopLevel(WINDOWPOS *pos);
static void		GenerateConfigureNotify(TkWindow *winPtr);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
 */

static int initialized;		/* Flag indicating whether module has been
				 * initialized. */

TCL_DECLARE_MUTEX(winWmMutex)

#if (_WIN32_WINNT >= 0x0601)

/*
 * Helpers for touch event to fill in its dictionary.
 */

#define ADD_DICT_STR(d, s, v)						\
    Tcl_DictObjPut(NULL, d, Tcl_NewStringObj(s, -1), Tcl_NewStringObj(v, -1))
#define ADD_DICT_INT(d, s, v)						\
    Tcl_DictObjPut(NULL, d, Tcl_NewStringObj(s, -1), Tcl_NewIntObj(v))
#define ADD_DICT_WIDE(d, s, v) \
    Tcl_DictObjPut(NULL, d, Tcl_NewStringObj(s, -1), Tcl_NewWideIntObj(v))
#define ADD_DICT_DOUB(d, s, v) \
    Tcl_DictObjPut(NULL, d, Tcl_NewStringObj(s, -1), Tcl_NewDoubleObj(v))

/*
 * Touch/gesture event Windows APIs.
 */

typedef WINBOOL (WINAPI CloseTouchInputHandleProc)(HANDLE);
typedef WINBOOL (WINAPI GetTouchInputInfoProc)(HANDLE, UINT, PTOUCHINPUT, int);
typedef WINBOOL (WINAPI RegisterTouchWindowProc)(HWND, ULONG);
typedef WINBOOL (WINAPI UnregisterTouchWindowProc)(HWND);
typedef WINBOOL (WINAPI GetGestureInfoProc)(HGESTUREINFO, PGESTUREINFO);
typedef WINBOOL (WINAPI SetGestureConfigProc)(HWND, DWORD, UINT,
				PGESTURECONFIG, UINT);

static CloseTouchInputHandleProc	*pCloseTouchInputHandle;
static GetTouchInputInfoProc		*pGetTouchInputInfo;
static RegisterTouchWindowProc		*pRegisterTouchWindow;
static UnregisterTouchWindowProc	*pUnregisterTouchWindow;
static GetGestureInfoProc		*pGetGestureInfo;
static SetGestureConfigProc		*pSetGestureConfig;

#ifndef TWF_FINETOUCH
#define TWF_FINETOUCH 1
#endif

#ifndef TWF_WANTPALM
#define TWF_WANTPALM 2 
#endif

#ifndef TOUCH_COORD_TO_PIXEL
#define TOUCH_COORD_TO_PIXEL(c) ((c) / 100)
#endif

#endif

/*
 * Forward declarations for functions defined in this file:
 */

static int		ActivateWindow(Tcl_Event *evPtr, int flags);
static void		ConfigureTopLevel(WINDOWPOS *pos);
static void		GenerateConfigureNotify(TkWindow *winPtr);
533
534
535
536
537
538
539



540
541
542
543
544
545
546
			    Tcl_Obj *const objv[]);
static int		WmStateCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTitleCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);



static int		WmTransientCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);







>
>
>







581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
			    Tcl_Obj *const objv[]);
static int		WmStateCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTitleCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTouchCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTransientCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);
898
899
900
901
902
903
904





















905
906
907
908
909
910
911
		tsdPtr->iconPtr = titlebaricon;
	    }
	    class.hCursor = LoadCursor(NULL, IDC_ARROW);

	    if (!RegisterClass(&class)) {
		Tcl_Panic("Unable to register TkTopLevel class");
	    }





















	}
	Tcl_MutexUnlock(&winWmMutex);
    }
    return TCL_OK;
}

/*







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
		tsdPtr->iconPtr = titlebaricon;
	    }
	    class.hCursor = LoadCursor(NULL, IDC_ARROW);

	    if (!RegisterClass(&class)) {
		Tcl_Panic("Unable to register TkTopLevel class");
	    }
#if (_WIN32_WINNT >= 0x0601)
	    {
		HANDLE lib = LoadLibrary(TEXT("user32.dll"));

		if (lib != NULL) {
		    pCloseTouchInputHandle = (CloseTouchInputHandleProc *)
			GetProcAddress(lib, "CloseTouchInputHandle");
		    pGetTouchInputInfo = (GetTouchInputInfoProc *)
			GetProcAddress(lib, "GetTouchInputInfo");
		    pRegisterTouchWindow = (RegisterTouchWindowProc *)
			GetProcAddress(lib, "RegisterTouchWindow");
		    pUnregisterTouchWindow = (UnregisterTouchWindowProc *)
			GetProcAddress(lib, "UnregisterTouchWindow");
		    pGetGestureInfo = (GetGestureInfoProc *)
			GetProcAddress(lib, "GetGestureInfo");
		    pSetGestureConfig = (SetGestureConfigProc *)
			GetProcAddress(lib, "SetGestureConfig");
		}
		FreeLibrary(lib);
	    }
#endif
	}
	Tcl_MutexUnlock(&winWmMutex);
    }
    return TCL_OK;
}

/*
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget", "frame",
	"geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname",
	"iconphoto", "iconposition",
	"iconwindow", "manage", "maxsize", "minsize", "overrideredirect",
	"positionfrom", "protocol", "resizable", "sizefrom",
	"stackorder", "state", "title", "transient",
	"withdraw", NULL
    };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME,
	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION,
	WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE,
	WMOPT_OVERRIDEREDIRECT,
	WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
	WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
	WMOPT_WITHDRAW
    };
    int index;
    size_t length;
    const char *argv1;
    TkWindow *winPtr, **winPtrPtr = &winPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;







|












|







2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget", "frame",
	"geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname",
	"iconphoto", "iconposition",
	"iconwindow", "manage", "maxsize", "minsize", "overrideredirect",
	"positionfrom", "protocol", "resizable", "sizefrom",
	"stackorder", "state", "title", "touch", "transient",
	"withdraw", NULL
    };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME,
	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION,
	WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE,
	WMOPT_OVERRIDEREDIRECT,
	WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
	WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TOUCH, WMOPT_TRANSIENT,
	WMOPT_WITHDRAW
    };
    int index;
    size_t length;
    const char *argv1;
    TkWindow *winPtr, **winPtrPtr = &winPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) winPtrPtr)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    if (!Tk_IsTopLevel(winPtr) && (index != WMOPT_MANAGE)
	    && (index != WMOPT_FORGET)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" isn't a top-level window", winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName,
		NULL);
	return TCL_ERROR;
    }








|







2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) winPtrPtr)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    if (!Tk_IsTopLevel(winPtr) && (index != WMOPT_MANAGE)
	    && (index != WMOPT_TOUCH) && (index != WMOPT_FORGET)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" isn't a top-level window", winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName,
		NULL);
	return TCL_ERROR;
    }

2917
2918
2919
2920
2921
2922
2923


2924
2925
2926
2927
2928
2929
2930
	return WmSizefromCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_STACKORDER:
	return WmStackorderCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_STATE:
	return WmStateCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_TITLE:
	return WmTitleCmd(tkwin, winPtr, interp, objc, objv);


    case WMOPT_TRANSIENT:
	return WmTransientCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_WITHDRAW:
	return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv);
    }

    /* This should not happen */







>
>







2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
	return WmSizefromCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_STACKORDER:
	return WmStackorderCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_STATE:
	return WmStateCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_TITLE:
	return WmTitleCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_TOUCH:
	return WmTouchCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_TRANSIENT:
	return WmTransientCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_WITHDRAW:
	return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv);
    }

    /* This should not happen */
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687

    if (Tk_IsTopLevel(frameWin)) {
	Tk_UnmapWindow(frameWin);
	winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr);
	RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window));

        /*
         * Make sure wm no longer manages this window
         */
        Tk_ManageGeometry(frameWin, NULL, NULL);

	TkWmDeadWindow(winPtr);
	/* flags (above) must be cleared before calling */
	/* TkMapTopFrame (below) */
	TkMapTopFrame(frameWin);
    } else {
	/* Already not managed by wm - ignore it */







|
|
|
|







3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761

    if (Tk_IsTopLevel(frameWin)) {
	Tk_UnmapWindow(frameWin);
	winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr);
	RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window));

	/*
	 * Make sure wm no longer manages this window
	 */
	Tk_ManageGeometry(frameWin, NULL, NULL);

	TkWmDeadWindow(winPtr);
	/* flags (above) must be cleared before calling */
	/* TkMapTopFrame (below) */
	TkMapTopFrame(frameWin);
    } else {
	/* Already not managed by wm - ignore it */
5495
5496
5497
5498
5499
5500
5501

















































































































































































































5502
5503
5504
5505
5506
5507
5508
	    Tcl_WinUtfToTChar(wmPtr->title, -1, &titleString);
	    SetWindowText(wrapper, (LPCTSTR) Tcl_DStringValue(&titleString));
	    Tcl_DStringFree(&titleString);
	}
    }
    return TCL_OK;
}


















































































































































































































/*
 *----------------------------------------------------------------------
 *
 * WmTransientCmd --
 *
 *	This function is invoked to process the "wm transient" Tcl command.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
	    Tcl_WinUtfToTChar(wmPtr->title, -1, &titleString);
	    SetWindowText(wrapper, (LPCTSTR) Tcl_DStringValue(&titleString));
	    Tcl_DStringFree(&titleString);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmTouchCmd --
 *
 *	This function is invoked to process the "wm touch" Tcl command. See
 *	the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmTouchCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
#if (_WIN32_WINNT >= 0x0601)
    Window win;
    HWND hwnd;
    int i, index, gCnt = 0, value;
    ULONG flags = 0;
    int touch = 0, panFlag;
    GESTURECONFIG gcPan = { 0, 0, 0 };
    GESTURECONFIG gc[16];
    static const char *const optionStrings[] = {
	"-all", "-fine", "-pan", "-pangutter", "-paninertia",
	"-pansfh", "-pansfv", "-pressandtap", "-rotate",
	"-touch", "-twofingertap", "-wantpalm", "-zoom",
	"-notouch", "-none", NULL
    };
    enum options {
	TOUCH_ALL, TOUCH_FINE, TOUCH_PAN, TOUCH_PANGUTTER, TOUCH_PANINERTIA,
	TOUCH_PANSFH, TOUCH_PANSFV, TOUCH_PRESSANDTAP, TOUCH_ROTATE,
	TOUCH_TOUCH, TOUCH_TWOFINGERTAP, TOUCH_WANTPALM, TOUCH_ZOOM,
	TOUCH_NOTOUCH, TOUCH_NONE,
    };

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	return TCL_ERROR;
    }
    ZeroMemory(&gc, sizeof(gc));
    for (i = 3; i < objc; i++) {
	if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0,
				&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch ((enum options) index) {
	case TOUCH_ALL:
	    gc[gCnt++].dwWant = GC_ALLGESTURES;
	    break;
	case TOUCH_NONE:
	    gc[gCnt++].dwBlock = GC_ALLGESTURES;
	    break;
	case TOUCH_FINE:
	    flags |= TWF_FINETOUCH;
	    touch = 1;
	    break;
	case TOUCH_PAN:
	    panFlag = GC_PAN;
	    goto pan;
	case TOUCH_PANGUTTER:
	    panFlag = GC_PAN_WITH_GUTTER;
	    goto pan;
	case TOUCH_PANINERTIA:
	    panFlag = GC_PAN_WITH_INERTIA;
	    goto pan;
	case TOUCH_PANSFH:
	    panFlag = GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
	    goto pan;
	case TOUCH_PANSFV:
	    panFlag = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
	pan:
	    if (++i >= objc) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"missing value", -1));
		return TCL_ERROR;
	    }
	    if (Tcl_GetBooleanFromObj(interp, objv[i], &value) != TCL_OK) {
		return TCL_ERROR;
	    }
	    gcPan.dwID = GID_PAN;
	    if (value) {
		gcPan.dwWant |= panFlag;
	    } else {
		gcPan.dwBlock |= panFlag;
	    }
	    break;
	case TOUCH_PRESSANDTAP:
	    if (++i >= objc) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"missing pressandtap", -1));
		return TCL_ERROR;
	    }
	    if (Tcl_GetBooleanFromObj(interp, objv[i], &value) != TCL_OK) {
		return TCL_ERROR;
	    }
	    gc[gCnt].dwID = GID_PRESSANDTAP;
	    if (value) {
		gc[gCnt++].dwWant = GC_PRESSANDTAP;
	    } else {
		gc[gCnt++].dwBlock = GC_PRESSANDTAP;
	    }
	    break;
	case TOUCH_ROTATE:
	    if (++i >= objc) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"missing rotate", -1));
		return TCL_ERROR;
	    }
	    if (Tcl_GetBooleanFromObj(interp, objv[i], &value) != TCL_OK) {
		return TCL_ERROR;
	    }
	    gc[gCnt].dwID = GID_ROTATE;
	    if (value) {
		gc[gCnt++].dwWant = GC_ROTATE;
	    } else {
		gc[gCnt++].dwBlock = GC_ROTATE;
	    }
	    break;
	case TOUCH_TOUCH:
	    touch = 1;
	    break;
	case TOUCH_TWOFINGERTAP:
	    if (++i >= objc) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"missing pressandtap", -1));
		return TCL_ERROR;
	    }
	    if (Tcl_GetBooleanFromObj(interp, objv[i], &value) != TCL_OK) {
		return TCL_ERROR;
	    }
	    gc[gCnt].dwID = GID_TWOFINGERTAP;
	    if (value) {
		gc[gCnt++].dwWant = GC_TWOFINGERTAP;
	    } else {
		gc[gCnt++].dwBlock = GC_TWOFINGERTAP;
	    }
	    break;
	case TOUCH_WANTPALM:
	    flags |= TWF_WANTPALM;
	    touch = 1;
	    break;
	case TOUCH_ZOOM:
	    if (++i >= objc) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"missing zoom", -1));
		return TCL_ERROR;
	    }
	    if (Tcl_GetBooleanFromObj(interp, objv[i], &value) != TCL_OK) {
		return TCL_ERROR;
	    }
	    gc[gCnt].dwID = GID_ZOOM;
	    if (value) {
		gc[gCnt++].dwWant = GC_ZOOM;
	    } else {
		gc[gCnt++].dwBlock = GC_ZOOM;
	    }
	    break;
	case TOUCH_NOTOUCH:
	    touch = -1;
	    break;
	}
	if (gCnt >= sizeof (gc) / sizeof (gc[0]) - 1) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"touch config overflow", -1));
	    return TCL_ERROR;
	}
    }

    if (gcPan.dwID != 0) {
	gc[gCnt++] = gcPan;
    }

    win = Tk_WindowId((Tk_Window) winPtr);
    if (win == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
	win = Tk_WindowId((Tk_Window) winPtr);
    }

    hwnd = Tk_GetHWND(win);

    if (touch > 0) {
	if (pRegisterTouchWindow != NULL) {
	    pRegisterTouchWindow(hwnd, flags);
	}
    } else if (touch < 0) {
	if (pUnregisterTouchWindow != NULL) {
	    pUnregisterTouchWindow(hwnd);
	}
    }
    if (gCnt > 0) {
	if (pSetGestureConfig != NULL) {
	    pSetGestureConfig(hwnd, 0, gCnt, gc, sizeof(GESTURECONFIG));
	}
    }
#endif
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmTransientCmd --
 *
 *	This function is invoked to process the "wm transient" Tcl command.
8674
8675
8676
8677
8678
8679
8680












































































































































































































































































8681
8682
8683
8684
8685
8686
8687
8688

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	RemapWindows(childPtr,
		winPtr->window ? Tk_GetHWND(winPtr->window) : NULL);
    }
}













































































































































































































































































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	RemapWindows(childPtr,
		winPtr->window ? Tk_GetHWND(winPtr->window) : NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * InitTouchEvent --
 *
 *	This function initialises an event structure with the base
 *	fields used in a TouchEvent.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#if (_WIN32_WINNT >= 0x0601)
static void
InitTouchEvent(XEvent *event, HWND hwnd, int rootx, int rooty)
{
    POINT sInput, cInput;
    Tk_Window tkwin;
    TkWindow *winPtr;

    sInput.x = rootx;
    sInput.y = rooty;
    cInput = sInput;
    ScreenToClient(hwnd, &cInput);

    tkwin = Tk_HWNDToWindow(hwnd);
    winPtr = (TkWindow *)tkwin;
    memset(event, 0, sizeof(*event));
    event->xany.type = VirtualEvent;
    event->xany.serial =
	LastKnownRequestProcessed(winPtr->display);
    event->xany.send_event = False;
    event->xany.window = Tk_WindowId(tkwin);
    event->xany.display = winPtr->display;
    event->xkey.root =
	RootWindow(winPtr->display,winPtr->screenNum);
    event->xkey.x_root = sInput.x;
    event->xkey.y_root = sInput.y;
    event->xkey.x = cInput.x;
    event->xkey.y = cInput.y;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkWinGenerateTouchEvent --
 *
 *	This function generate touch events when a WM_TOUCH event has
 *      been received.
 *
 * Results:
 *	Returns 1 if the event was handled, else 0.
 *
 * Side effects:
 *	May queue one or more X events.
 *
 *----------------------------------------------------------------------
 */

int
TkWinGenerateTouchEvent(
    HWND hwnd,
    WPARAM wParam,
    LPARAM lParam)
{
#if (_WIN32_WINNT >= 0x0601)
    BOOL bHandled = FALSE;
    UINT cInputs = LOWORD(wParam);
    PTOUCHINPUT pInputs = ckalloc(sizeof(TOUCHINPUT)*cInputs);
    union {XEvent general; XVirtualEvent virtual;} event;
    Tcl_Obj *dictPtr;

    if (pGetTouchInputInfo == NULL) {
	return 0;
    }
    if (pInputs != NULL) {
	if (pGetTouchInputInfo((HANDLE)lParam,
			       cInputs,
			       pInputs,
			       sizeof(TOUCHINPUT))) {
	    UINT i;

	    for (i = 0; i < cInputs; i++) {
		TOUCHINPUT ti = pInputs[i];
		InitTouchEvent(&event.general, hwnd,
			       TOUCH_COORD_TO_PIXEL(ti.x),
			       TOUCH_COORD_TO_PIXEL(ti.y));
		/*
		 * Which info needs to be passed to the event, and how should
		 * is be passed ?
		 * Put it into a dict and pass it through %d
		 */
		dictPtr = Tcl_NewDictObj();
		Tcl_IncrRefCount(dictPtr);
		/* Identify as a touch event */
		ADD_DICT_STR(dictPtr, "event", "touch");
		/* Touch ID */
		ADD_DICT_INT(dictPtr, "id", ti.dwID);
		/* Raw flags value */
		ADD_DICT_INT(dictPtr, "flags", ti.dwFlags);
		/* Decode known flags */
		if (ti.dwFlags & TOUCHEVENTF_MOVE) {
		    ADD_DICT_INT(dictPtr, "move", 1);
		    event.virtual.name = Tk_GetUid("FingerMotion");
		}
		if (ti.dwFlags & TOUCHEVENTF_DOWN) {
		    ADD_DICT_INT(dictPtr, "down", 1);
		    event.virtual.name = Tk_GetUid("FingerDown");
		}
		if (ti.dwFlags & TOUCHEVENTF_UP) {
		    ADD_DICT_INT(dictPtr, "up", 1);
		    event.virtual.name = Tk_GetUid("FingerUp");
		}
		if (ti.dwFlags & TOUCHEVENTF_INRANGE) {
		    ADD_DICT_INT(dictPtr, "inrange", 1);
		}
		if (ti.dwFlags & TOUCHEVENTF_PRIMARY) {
		    ADD_DICT_INT(dictPtr, "primary", 1);
		}
		if (ti.dwFlags & TOUCHEVENTF_NOCOALESCE) {
		    ADD_DICT_INT(dictPtr, "nocoalesce", 1);
		}
		if (ti.dwFlags & TOUCHEVENTF_PALM) {
		    ADD_DICT_INT(dictPtr, "palm", 1);
		}
		event.virtual.user_data = dictPtr;
		Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
	    }
	    bHandled = TRUE;
	}
	ckfree(pInputs);
    }
    if (bHandled) {
	pCloseTouchInputHandle((HANDLE)lParam);
	return 1;
    }
#endif
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinGenerateGestureEvent --
 *
 *	This function generate touch events when a WM_GESTURE event has
 *      been received.
 *
 * Results:
 *	Returns 1 if the event was handled, else 0.
 *
 * Side effects:
 *	May queue an X event.
 *
 *----------------------------------------------------------------------
 */

int
TkWinGenerateGestureEvent(
    HWND hwnd,
    WPARAM wParam,
    LPARAM lParam)
{
#if (_WIN32_WINNT >= 0x0601)
    GESTUREINFO gi;
    union {XEvent general; XVirtualEvent virtual;} event;
    Tcl_Obj *dictPtr;
    POINT sLoc, delta;
    POINTS pts;
    UINT LInt, HInt;

    if (pGetGestureInfo == NULL) {
	return 0;
    }

    ZeroMemory(&gi, sizeof(GESTUREINFO));
    gi.cbSize = sizeof(GESTUREINFO);

    if (!pGetGestureInfo((HGESTUREINFO)lParam, &gi)) {
	return 0;
    }

    /* Is it something we want to handle? */
    switch (gi.dwID) {
    case GID_BEGIN:
    case GID_END:
	/* These should not be handled */
	return 0;
    case GID_ZOOM:
    case GID_PAN:
    case GID_ROTATE:
    case GID_TWOFINGERTAP:
    case GID_PRESSANDTAP:
	break;
    default:
	/* A gesture was not recognized */
	return 0;
    }

    POINTSTOPOINT(sLoc, gi.ptsLocation);

    InitTouchEvent(&event.general, hwnd, sLoc.x, sLoc.y);
    event.virtual.name = Tk_GetUid("Gesture");
    dictPtr = Tcl_NewDictObj();
    Tcl_IncrRefCount(dictPtr);
    /* Identify as a gesture event */
    ADD_DICT_STR(dictPtr, "event", "gesture");
    /* Raw flags value */
    ADD_DICT_INT(dictPtr, "flags", gi.dwFlags);
    /* Decode known flags */
    if (gi.dwFlags & GF_BEGIN) {
	ADD_DICT_INT(dictPtr, "begin", 1);
    }
    if (gi.dwFlags & GF_INERTIA) {
	ADD_DICT_INT(dictPtr, "inertia", 1);
    }
    if (gi.dwFlags & GF_END) {
	ADD_DICT_INT(dictPtr, "end", 1);
    }

    LInt = (UINT) (gi.ullArguments & 0xFFFFFFFF);
    HInt = (UINT) (gi.ullArguments >> 32);
    switch (gi.dwID) {
    case GID_ZOOM:
	ADD_DICT_STR(dictPtr, "gesture", "zoom");
	ADD_DICT_WIDE(dictPtr, "distance", gi.ullArguments);
	event.virtual.name = Tk_GetUid("PinchToZoom");
	break;
    case GID_PAN:
	ADD_DICT_STR(dictPtr, "gesture", "pan");
	ADD_DICT_WIDE(dictPtr, "distance", LInt);
	if (gi.dwFlags & GF_INERTIA) {
	    pts = MAKEPOINTS(HInt);
	    ADD_DICT_INT(dictPtr, "inertiax", pts.x);
	    ADD_DICT_INT(dictPtr, "inertiay", pts.y);
	}
	break;
    case GID_ROTATE:
	ADD_DICT_STR(dictPtr, "gesture", "rotate");
	ADD_DICT_DOUB(dictPtr, "angle",
		      GID_ROTATE_ANGLE_FROM_ARGUMENT(gi.ullArguments));
	break;
    case GID_TWOFINGERTAP:
	ADD_DICT_STR(dictPtr, "gesture", "twofingertap");
	ADD_DICT_WIDE(dictPtr, "distance", gi.ullArguments);
	break;
    case GID_PRESSANDTAP:
	ADD_DICT_STR(dictPtr, "gesture", "pressandtap");
	pts = MAKEPOINTS(LInt);
	POINTSTOPOINT(delta, pts);
	ADD_DICT_INT(dictPtr, "deltax", delta.x);
	ADD_DICT_INT(dictPtr, "deltay", delta.y);
	break;
    }
    event.virtual.user_data = dictPtr;
    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
    return 1;
#else
    return 0;
#endif
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to jni/sdl2tk/win/tkWinX.c.
49
50
51
52
53
54
55






56
57
58
59
60
61
62
 * Perhaps this definition should be moved in another file.
 */
#ifndef WM_UNICHAR
#define WM_UNICHAR     0x0109
#define UNICODE_NOCHAR 0xFFFF
#endif







/*
 * Declarations of static variables used in this file.
 */

static const char winScreenName[] = ":0"; /* Default name of windows display. */
static HINSTANCE tkInstance = NULL;	/* Application instance handle. */
static int childClassInitialized;	/* Registered child class? */







>
>
>
>
>
>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
 * Perhaps this definition should be moved in another file.
 */
#ifndef WM_UNICHAR
#define WM_UNICHAR     0x0109
#define UNICODE_NOCHAR 0xFFFF
#endif

#if (_WIN32_WINNT >= 0x0601)
#ifndef WM_TOUCH
#define WM_TOUCH       0x0240
#endif
#endif

/*
 * Declarations of static variables used in this file.
 */

static const char winScreenName[] = ":0"; /* Default name of windows display. */
static HINSTANCE tkInstance = NULL;	/* Application instance handle. */
static int childClassInitialized;	/* Registered child class? */
77
78
79
80
81
82
83



84
85
86
87
88
89
90
 * specific date for threads.
 */

typedef struct ThreadSpecificData {
    TkDisplay *winDisplay;	/* TkDisplay structure that represents Windows
				 * screen. */
    int updatingClipboard;	/* If 1, we are updating the clipboard. */



} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations of functions used in this file.
 */








>
>
>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
 * specific date for threads.
 */

typedef struct ThreadSpecificData {
    TkDisplay *winDisplay;	/* TkDisplay structure that represents Windows
				 * screen. */
    int updatingClipboard;	/* If 1, we are updating the clipboard. */
#if TCL_UTF_MAX >= 4
    int surrogateBuffer;	/* Buffer for first of surrogate pair. */
#endif
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations of functions used in this file.
 */

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
    case TK_SETMENU:
    case TK_STATE:
    case TK_INFO:
	result = TkWinEmbeddedEventProc(hwnd, message, wParam, lParam);
	break;

    case WM_UNICHAR:
        if (wParam == UNICODE_NOCHAR) {
	    /* If wParam is UNICODE_NOCHAR and the application processes
	     * this message, then return TRUE. */
	    result = 1;
	} else {
	    /* If the event was translated, we must return 0 */
            if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
                result = 0;
	    } else {
	        result = 1;
	    }
	}
	break;

    default:
	if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    result = DefWindowProc(hwnd, message, wParam, lParam);







|





|
|

|







817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
    case TK_SETMENU:
    case TK_STATE:
    case TK_INFO:
	result = TkWinEmbeddedEventProc(hwnd, message, wParam, lParam);
	break;

    case WM_UNICHAR:
	if (wParam == UNICODE_NOCHAR) {
	    /* If wParam is UNICODE_NOCHAR and the application processes
	     * this message, then return TRUE. */
	    result = 1;
	} else {
	    /* If the event was translated, we must return 0 */
	    if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
		result = 0;
	    } else {
		result = 1;
	    }
	}
	break;

    default:
	if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    result = DefWindowProc(hwnd, message, wParam, lParam);
906
907
908
909
910
911
912







913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
    case WM_RBUTTONDBLCLK:
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
    case WM_MOUSEMOVE:
	Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam));
	return 1;








    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
	if (wParam == VK_PACKET) { 
	    /*
	     * This will trigger WM_CHAR event(s) with unicode data.
	     */
	    *resultPtr =
		PostMessageW(hwnd, message, HIWORD(lParam), LOWORD(lParam));
	    return 1;
	}
	/* else fall through */
    case WM_CLOSE:
    case WM_SETFOCUS:
    case WM_KILLFOCUS:
    case WM_DESTROYCLIPBOARD:
    case WM_UNICHAR:
    case WM_CHAR:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_MOUSEWHEEL:
	GenerateXEvent(hwnd, message, wParam, lParam);
	return 1;
    case WM_MENUCHAR:
	GenerateXEvent(hwnd, message, wParam, lParam);








>
>
>
>
>
>
>



|














<

<







915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946

947

948
949
950
951
952
953
954
    case WM_RBUTTONDBLCLK:
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
    case WM_MOUSEMOVE:
	Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam));
	return 1;

#if (_WIN32_WINNT >= 0x0601)
    case WM_TOUCH:
	return TkWinGenerateTouchEvent(hwnd, wParam, lParam);
    case WM_GESTURE:
	return TkWinGenerateGestureEvent(hwnd, wParam, lParam);
#endif

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
	if (wParam == VK_PACKET) {
	    /*
	     * This will trigger WM_CHAR event(s) with unicode data.
	     */
	    *resultPtr =
		PostMessageW(hwnd, message, HIWORD(lParam), LOWORD(lParam));
	    return 1;
	}
	/* else fall through */
    case WM_CLOSE:
    case WM_SETFOCUS:
    case WM_KILLFOCUS:
    case WM_DESTROYCLIPBOARD:
    case WM_UNICHAR:
    case WM_CHAR:

    case WM_SYSKEYUP:

    case WM_KEYUP:
    case WM_MOUSEWHEEL:
	GenerateXEvent(hwnd, message, wParam, lParam);
	return 1;
    case WM_MENUCHAR:
	GenerateXEvent(hwnd, message, wParam, lParam);

1207
1208
1209
1210
1211
1212
1213
1214
1215
1216

1217
1218
1219
1220
1221

1222
1223
1224
1225
1226
1227
1228

1229
1230
1231

1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245

	    event.type = KeyPress;
	    event.xany.send_event = -1;
	    event.xkey.keycode = 0;
	    if ((int)wParam & 0xff00) {
		int i, ch1 = wParam & 0xffff;
		char buffer[TCL_UTF_MAX+1];
#if TCL_UTF_MAX >= 4
		MSG msg;


		if ((((int)wParam & 0xfc00) == 0xd800)
			&& (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0)
			&& (msg.message == WM_CHAR)) {
		    MSG msg;
		    int ch2;


		    GetMessage(&msg, NULL, 0, 0);
		    ch2 = wParam & 0xffff;
#if TCL_UTF_MAX == 4
		    event.xkey.nbytes = Tcl_UniCharToUtf(ch1, buffer);
		    event.xkey.nbytes += Tcl_UniCharToUtf(ch2, buffer);
#else

		    ch1 = ((ch1 & 0x3ff) << 10) | (ch2 & 0x3ff);
	   	    ch1 += 0x10000;
		    event.xkey.nbytes = Tcl_UniCharToUtf(ch1, buffer);

#endif
		} else
#endif
		{
		    event.xkey.nbytes = Tcl_UniCharToUtf(ch1, buffer);
		}
		for (i=0; i<event.xkey.nbytes && i<TCL_UTF_MAX; ++i) {
		    event.xkey.trans_chars[i] = buffer[i];
		}
		event.xany.send_event = -3;
	    } else {
		event.xkey.nbytes = 1;
		event.xkey.trans_chars[0] = (char) wParam;








<
<

>
|
<
<
<
|
>
|
<
|
<
<
<
<
>
|
|
|
>

<
<
<
|
<
|







1221
1222
1223
1224
1225
1226
1227


1228
1229
1230



1231
1232
1233

1234




1235
1236
1237
1238
1239
1240



1241

1242
1243
1244
1245
1246
1247
1248
1249

	    event.type = KeyPress;
	    event.xany.send_event = -1;
	    event.xkey.keycode = 0;
	    if ((int)wParam & 0xff00) {
		int i, ch1 = wParam & 0xffff;
		char buffer[TCL_UTF_MAX+1];



#if TCL_UTF_MAX >= 4
		if ((ch1 & 0xfc00) == 0xd800) {



		    tsdPtr->surrogateBuffer = ch1;
		    return;
		}

		if ((ch1 & 0xfc00) == 0xdc00) {




		    ch1 = ((tsdPtr->surrogateBuffer & 0x3ff) << 10) |
			  (ch1 & 0x3ff);
		    ch1 += 0x10000;
		    tsdPtr->surrogateBuffer = 0;
		}
#endif



		event.xkey.nbytes = Tcl_UniCharToUtf(ch1, buffer);

		for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) {
		    event.xkey.trans_chars[i] = buffer[i];
		}
		event.xany.send_event = -3;
	    } else {
		event.xkey.nbytes = 1;
		event.xkey.trans_chars[0] = (char) wParam;

1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276

1277
1278
1279
1280


1281



1282

1283
1284
1285
1286
1287
1288
1289
1290
1291
1292

	case WM_UNICHAR: {
	    char buffer[TCL_UTF_MAX+1];
	    int i;

	    event.type = KeyPress;
	    event.xany.send_event = -3;
	    event.xkey.keycode = wParam;
#if TCL_UTF_MAX < 4
	    event.xkey.nbytes = Tcl_UniCharToUtf(((int)wParam > 0xffff) ?
		    0xfffd : (int)wParam, buffer);
#else
#if TCL_UTF_MAX == 4
	    if ((int)wParam > 0xffff) {
		Tcl_UniChar uch;

		uch = (((int)wParam - 0x10000) >> 10) & 0x3ff;

		event.xkey.nbytes = Tcl_UniCharToUtf(uch | 0xd800, buffer);
		uch = ((int)wParam - 0x10000) & 0x3ff;
		event.xkey.nbytes += Tcl_UniCharToUtf(uch | 0xdc00,
			buffer + event.xkey.nbytes);


	    } else



#endif

	    event.xkey.nbytes = Tcl_UniCharToUtf((int)wParam, buffer);
#endif
	    for (i=0; i<event.xkey.nbytes && i<TCL_UTF_MAX; ++i) {
		event.xkey.trans_chars[i] = buffer[i];
	    }
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
	    event.type = KeyRelease;
	    break;
	}








<

|
|
<
<
|
<

|
>
|
<
|
|
>
>
|
>
>
>

>

<
|







1264
1265
1266
1267
1268
1269
1270

1271
1272
1273


1274

1275
1276
1277
1278

1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289

1290
1291
1292
1293
1294
1295
1296
1297

	case WM_UNICHAR: {
	    char buffer[TCL_UTF_MAX+1];
	    int i;

	    event.type = KeyPress;
	    event.xany.send_event = -3;

#if TCL_UTF_MAX < 4
	    if ((int) wParam > 0xFFFF) {
		int high =


		    (((((int) wParam) - 0x10000) >> 10) & 0x3FF) | 0xD800;


		wParam = ((((int) wParam) - 0x10000) & 0x3FF) | 0xDC00;
		event.xkey.keycode = high;
		event.xkey.nbytes = Tcl_UniCharToUtf(high, buffer);

		for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) {
		    event.xkey.trans_chars[i] = buffer[i];
		}
		Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
		event.type = KeyRelease;
		Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
		event.type = KeyPress;
	    }
#endif
	    event.xkey.keycode = wParam;
	    event.xkey.nbytes = Tcl_UniCharToUtf((int)wParam, buffer);

	    for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) {
		event.xkey.trans_chars[i] = buffer[i];
	    }
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
	    event.type = KeyRelease;
	    break;
	}

1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
	}
	if (prevState) {
	    state |= mask;
	} else {
	    state &= ~mask;
	}
	if (HIWORD(lParam) & KF_EXTENDED) {
	    if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) {
		state |= EXTENDED_MASK;
	    } else {
		state &= ~EXTENDED_MASK;
	    }
	}
    }
    return state;
}

/*
 *----------------------------------------------------------------------







<
|
<
<
<







1383
1384
1385
1386
1387
1388
1389

1390



1391
1392
1393
1394
1395
1396
1397
	}
	if (prevState) {
	    state |= mask;
	} else {
	    state &= ~mask;
	}
	if (HIWORD(lParam) & KF_EXTENDED) {

	    state |= EXTENDED_MASK;



	}
    }
    return state;
}

/*
 *----------------------------------------------------------------------
jni/tcl/library/tzdata/America/Resolute became executable.
jni/tcl/tests/tcltest.test became executable.
Changes to undroid/build-vanilla-win32.sh.
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  # use -march=i386 -mtune=i386 for Win2000 and/or old CPUs w/o
  # SSE like VIA C3 
  echo using toolchain from /opt/mingw64/bin
  PATH="/opt/mingw64/bin:$PATH"
  STRIP="x86_64-w64-mingw32-strip"
  AR="x86_64-w64-mingw32-ar"
  RANLIB="x86_64-w64-mingw32-ranlib"
  CC="x86_64-w64-mingw32-gcc -m32 -march=i386 -mtune=i386 -DTCL_UTF_MAX=6"
  CXX="x86_64-w64-mingw32-g++ -m32 -march=i386 -mtune=i386 -fno-exceptions -DTCL_UTF_MAX=6"
  RC="x86_64-w64-mingw32-windres -F pe-i386"
  NM="x86_64-w64-mingw32-nm"
  export STRIP AR RANLIB CC CXX RC NM
else
  # would like to use -march=i386 -mtune=i386, too, but then gcc-4.8
  # cannot link due to missing atomic support for this CPU, thus must
  # have Pentium at least
  echo using toolchain prefix i686-w64-mingw32
  STRIP="i686-w64-mingw32-strip"
  AR="i686-w64-mingw32-ar"
  RANLIB="i686-w64-mingw32-ranlib"
  CC="i686-w64-mingw32-gcc -m32 -march=i586 -mtune=generic -DTCL_UTF_MAX=6"
  CXX="i686-w64-mingw32-g++ -m32 -march=i586 -mtune=generic -fno-exceptions -DTCL_UTF_MAX=6"
  RC="i686-w64-mingw32-windres -F pe-i386"
  NM="i686-w64-mingw32-nm"
  TWAPI_LDFLAGS="-L${AWDIR}/undroid/compat/win32/lib32"
  export STRIP AR RANLIB CC CXX RC NM TWAPI_LDFLAGS
fi

SUBDIRS="tcl libressl zlib curl tcludp tdom tclvfs tclkit trofs tbcload tls"







|
|











|
|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  # use -march=i386 -mtune=i386 for Win2000 and/or old CPUs w/o
  # SSE like VIA C3 
  echo using toolchain from /opt/mingw64/bin
  PATH="/opt/mingw64/bin:$PATH"
  STRIP="x86_64-w64-mingw32-strip"
  AR="x86_64-w64-mingw32-ar"
  RANLIB="x86_64-w64-mingw32-ranlib"
  CC="x86_64-w64-mingw32-gcc -m32 -march=i386 -mtune=i386 -D_WIN32_WINNT=0x0601 -DTCL_UTF_MAX=6"
  CXX="x86_64-w64-mingw32-g++ -m32 -march=i386 -mtune=i386 -fno-exceptions -D_WIN32_WINNT=0x0601 -DTCL_UTF_MAX=6"
  RC="x86_64-w64-mingw32-windres -F pe-i386"
  NM="x86_64-w64-mingw32-nm"
  export STRIP AR RANLIB CC CXX RC NM
else
  # would like to use -march=i386 -mtune=i386, too, but then gcc-4.8
  # cannot link due to missing atomic support for this CPU, thus must
  # have Pentium at least
  echo using toolchain prefix i686-w64-mingw32
  STRIP="i686-w64-mingw32-strip"
  AR="i686-w64-mingw32-ar"
  RANLIB="i686-w64-mingw32-ranlib"
  CC="i686-w64-mingw32-gcc -m32 -march=i586 -mtune=generic -D_WIN32_WINNT=0x0601 -DTCL_UTF_MAX=6"
  CXX="i686-w64-mingw32-g++ -m32 -march=i586 -mtune=generic -fno-exceptions -D_WIN32_WINNT=0x0601 -DTCL_UTF_MAX=6"
  RC="i686-w64-mingw32-windres -F pe-i386"
  NM="i686-w64-mingw32-nm"
  TWAPI_LDFLAGS="-L${AWDIR}/undroid/compat/win32/lib32"
  export STRIP AR RANLIB CC CXX RC NM TWAPI_LDFLAGS
fi

SUBDIRS="tcl libressl zlib curl tcludp tdom tclvfs tclkit trofs tbcload tls"
657
658
659
660
661
662
663

664
665
666
667
668
669
670
  echo >&3 "done"
) || fail

echo -n "build tclwmf ... "
(
  exec 3>&1
  exec >> build.log 2>&1

  cd tclwmf
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=i386-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1







>







657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
  echo >&3 "done"
) || fail

echo -n "build tclwmf ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  CC=`echo $CC | sed -e 's/-D_WIN32_WINNT=0x[0-9]\+//g'`
  cd tclwmf
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=i386-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
Changes to undroid/build-vanilla-win64.sh.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# the toolchain
if test -d /opt/mingw64/bin ; then
  echo using toolchain from /opt/mingw64/bin
  PATH="/opt/mingw64/bin:$PATH"
  STRIP="x86_64-w64-mingw32-strip"
  AR="x86_64-w64-mingw32-ar"
  RANLIB="x86_64-w64-mingw32-ranlib"
  CC="x86_64-w64-mingw32-gcc -D_WIN32_WINNT=0x0600 -DTCL_UTF_MAX=6"
  CXX="x86_64-w64-mingw32-g++ -D_WIN32_WINNT=0x0600 -DTCL_UTF_MAX=6"
  RC="x86_64-w64-mingw32-windres"
  NM="x86_64-w64-mingw32-nm"
  export STRIP AR RANLIB CC CXX RC NM
else
  echo using toolchain prefix x86_64-w64-mingw32
  STRIP="x86_64-w64-mingw32-strip"
  AR="x86_64-w64-mingw32-ar"
  RANLIB="x86_64-w64-mingw32-ranlib"
  CC="x86_64-w64-mingw32-gcc -DTCL_UTF_MAX=6"
  CXX="x86_64-w64-mingw32-g++ -DTCL_UTF_MAX=6"
  RC="x86_64-w64-mingw32-windres"
  NM="x86_64-w64-mingw32-nm"
  export STRIP AR RANLIB CC CXX RC NM
fi

SUBDIRS="tcl libressl zlib curl tcludp tdom tclvfs tclkit trofs tbcload tls"
SUBDIRS="${SUBDIRS} Memchan trf TclCurl sdl2tk"







|
|








|
|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# the toolchain
if test -d /opt/mingw64/bin ; then
  echo using toolchain from /opt/mingw64/bin
  PATH="/opt/mingw64/bin:$PATH"
  STRIP="x86_64-w64-mingw32-strip"
  AR="x86_64-w64-mingw32-ar"
  RANLIB="x86_64-w64-mingw32-ranlib"
  CC="x86_64-w64-mingw32-gcc -D_WIN32_WINNT=0x0601 -DTCL_UTF_MAX=6"
  CXX="x86_64-w64-mingw32-g++ -D_WIN32_WINNT=0x0601 -DTCL_UTF_MAX=6"
  RC="x86_64-w64-mingw32-windres"
  NM="x86_64-w64-mingw32-nm"
  export STRIP AR RANLIB CC CXX RC NM
else
  echo using toolchain prefix x86_64-w64-mingw32
  STRIP="x86_64-w64-mingw32-strip"
  AR="x86_64-w64-mingw32-ar"
  RANLIB="x86_64-w64-mingw32-ranlib"
  CC="x86_64-w64-mingw32-gcc -D_WIN32_WINNT=0x0601-DTCL_UTF_MAX=6"
  CXX="x86_64-w64-mingw32-g++ -D_WIN32_WINT=0x0601 -DTCL_UTF_MAX=6"
  RC="x86_64-w64-mingw32-windres"
  NM="x86_64-w64-mingw32-nm"
  export STRIP AR RANLIB CC CXX RC NM
fi

SUBDIRS="tcl libressl zlib curl tcludp tdom tclvfs tclkit trofs tbcload tls"
SUBDIRS="${SUBDIRS} Memchan trf TclCurl sdl2tk"
647
648
649
650
651
652
653

654
655
656
657
658
659
660
  echo >&3 "done"
) || fail

echo -n "build tclwmf ... "
(
  exec 3>&1
  exec >> build.log 2>&1

  cd tclwmf
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1







>







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
  echo >&3 "done"
) || fail

echo -n "build tclwmf ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  CC=`echo $CC | sed -e 's/-D_WIN32_WINNT=0x[0-9]\+//g'`
  cd tclwmf
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1