Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | More improvements handling characters > U+FFFF as surrogates. Add internal TkUtfPrev(), which handles jumping back over surrogate pairs. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | bug-a179564826 |
Files: | files | file ages | folders |
SHA3-256: |
95cf4257d6ba29424c067731e238f054 |
User & Date: | jan.nijtmans 2020-05-14 19:11:57 |
Context
2020-05-18
| ||
22:01 | Merge 8.6 check-in: 2a783500 user: jan.nijtmans tags: bug-a179564826 | |
2020-05-14
| ||
19:11 | More improvements handling characters > U+FFFF as surrogates. Add internal TkUtfPrev(), which handles jumping back over surrogate pairs. check-in: 95cf4257 user: jan.nijtmans tags: bug-a179564826 | |
2020-05-13
| ||
19:58 | Make bind-34.1 pass on Debian 10 with KDE/Plasma by giving the WM a more complete setup for this test. check-in: a6c87041 user: fvogel tags: core-8-6-branch | |
2020-04-06
| ||
14:52 | Better implementation of TkUtfToUniChar(), one that doesn't require cooperation of Tcl (TCL_UTF_MAX>3). Just let Tk do the splitting of 4-byte UTF-8 sequences into surrogates. check-in: 1b1c1394 user: jan.nijtmans tags: bug-a179564826 | |
Changes
Added .gitignore.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | *.a *.dll *.dylib *.exe *.exp *.lib *.o *.obj *.pdb *.res *.sl *.so */Makefile */config.cache */config.log */config.status */tkConfig.sh */wish* */tktest* */versions.vc unix/tk.pc unix/tclIndex win/Debug* win/Release* win/*.manifest win/nmhlp-out.txt win/nmakehlp.out |
Changes to .travis.yml.
︙ | ︙ | |||
110 111 112 113 114 115 116 | os: linux dist: bionic compiler: clang env: - BUILD_DIR=unix - CFGOPT="--enable-symbols" # Testing on Mac, various styles | | | | | | | | | | 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 | os: linux dist: bionic compiler: clang env: - BUILD_DIR=unix - CFGOPT="--enable-symbols" # Testing on Mac, various styles - name: "macOS/Xcode 11.4/Shared" os: osx osx_image: xcode11.4 env: - BUILD_DIR=unix - CFGOPT="--prefix=/usr/local/opt/tcl-tk --with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua CC=clang CFLAGS=-I/usr/local/opt/tcl-tk/include" - name: "macOS/Xcode 11.4/Static" os: osx osx_image: xcode11.4 env: - BUILD_DIR=unix - CFGOPT="--prefix=/usr/local/opt/tcl-tk --with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua --disable-shared CC=clang CFLAGS=-I/usr/local/opt/tcl-tk/include" - name: "macOS/Xcode 11.4/Debug" os: osx osx_image: xcode11.4 env: - BUILD_DIR=unix - CFGOPT="--prefix=/usr/local/opt/tcl-tk --with-tcl=/usr/local/opt/tcl-tk/lib --enable-aqua --enable-symbols CC=clang CFLAGS=-I/usr/local/opt/tcl-tk/include" - name: "macOS/Xcode 11.4/Shared/XQuartz" os: osx osx_image: xcode11.4 env: - BUILD_DIR=unix - CFGOPT="--prefix=/usr/local/opt/tcl-tk --with-tcl=/usr/local/opt/tcl-tk/lib --disable-corefoundation --x-includes=/opt/X11/include --x-libraries=/opt/X11/lib CC=clang CFLAGS=-I/usr/local/opt/tcl-tk/include" # Older MacOS versions - name: "macOS/Xcode 11/Shared" os: osx osx_image: xcode11 |
︙ | ︙ |
Changes to doc/bind.n.
︙ | ︙ | |||
506 507 508 509 510 511 512 513 514 515 516 517 518 519 | \fBResizeRequest\fR, and \fBExpose\fR events. .IP "\fB%x\fR, \fB%y\fR" 5 The \fIx\fR and \fIy\fR fields from the event. For \fBButtonPress\fR, \fBButtonRelease\fR, \fBMotion\fR, \fBKeyPress\fR, \fBKeyRelease\fR, and \fBMouseWheel\fR events, \fB%x\fR and \fB%y\fR indicate the position of the mouse pointer relative to the receiving window. For \fBEnter\fR and \fBLeave\fR events, the position where the mouse pointer crossed the window, relative to the receiving window. For \fBConfigure\fR and \fBCreate\fR requests, the \fIx\fR and \fIy\fR coordinates of the window relative to its parent window. .IP \fB%A\fR 5 Substitutes the UNICODE character corresponding to the event, or the empty string if the event does not correspond to a UNICODE character | > > > | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 | \fBResizeRequest\fR, and \fBExpose\fR events. .IP "\fB%x\fR, \fB%y\fR" 5 The \fIx\fR and \fIy\fR fields from the event. For \fBButtonPress\fR, \fBButtonRelease\fR, \fBMotion\fR, \fBKeyPress\fR, \fBKeyRelease\fR, and \fBMouseWheel\fR events, \fB%x\fR and \fB%y\fR indicate the position of the mouse pointer relative to the receiving window. For key events on the Macintosh these are the coordinates of the mouse at the moment when an X11 KeyEvent is sent to Tk, which could be slightly later than the time of the physical press or release. For \fBEnter\fR and \fBLeave\fR events, the position where the mouse pointer crossed the window, relative to the receiving window. For \fBConfigure\fR and \fBCreate\fR requests, the \fIx\fR and \fIy\fR coordinates of the window relative to its parent window. .IP \fB%A\fR 5 Substitutes the UNICODE character corresponding to the event, or the empty string if the event does not correspond to a UNICODE character |
︙ | ︙ |
Changes to doc/colors.n.
︙ | ︙ | |||
940 941 942 943 944 945 946 947 948 949 950 951 952 953 | predecessor. .RS .DS systemControlAccentColor systemControlTextColor systemDisabledControlTextColor systemLabelColor systemSelectedTextBackgroundColor systemSelectedTextColor systemTextBackgroundColor systemTextColor systemWindowBackgroundColor systemWindowBackgroundColor1 systemWindowBackgroundColor2 | > | 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | predecessor. .RS .DS systemControlAccentColor systemControlTextColor systemDisabledControlTextColor systemLabelColor systemLinkColor systemSelectedTextBackgroundColor systemSelectedTextColor systemTextBackgroundColor systemTextColor systemWindowBackgroundColor systemWindowBackgroundColor1 systemWindowBackgroundColor2 |
︙ | ︙ |
Changes to doc/entry.n.
︙ | ︙ | |||
444 445 446 447 448 449 450 | .IP [5] Clicking mouse button 1 with the Control key down will position the insertion cursor in the entry without affecting the selection. .IP [6] If any normal printing characters are typed in an entry, they are inserted at the point of the insertion cursor. .IP [7] | | > | | | 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | .IP [5] Clicking mouse button 1 with the Control key down will position the insertion cursor in the entry without affecting the selection. .IP [6] If any normal printing characters are typed in an entry, they are inserted at the point of the insertion cursor. .IP [7] The view in the entry can be adjusted by dragging with the middle mouse button (button 2, or button 3 in TkAqua). If the middle mouse button is clicked without moving the mouse, the selection is copied into the entry at the position of the mouse cursor. .IP [8] If the mouse is dragged out of the entry on the left or right sides while button 1 is pressed, the entry will automatically scroll to make more text visible (if there is more text off-screen on the side where the mouse left the window). .IP [9] The Left and Right keys move the insertion cursor one character to the |
︙ | ︙ |
Changes to doc/spinbox.n.
︙ | ︙ | |||
510 511 512 513 514 515 516 | .IP [5] Clicking mouse button 1 with the Control key down will position the insertion cursor in the spinbox without affecting the selection. .IP [6] If any normal printing characters are typed in a spinbox, they are inserted at the point of the insertion cursor. .IP [7] | | > | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | .IP [5] Clicking mouse button 1 with the Control key down will position the insertion cursor in the spinbox without affecting the selection. .IP [6] If any normal printing characters are typed in a spinbox, they are inserted at the point of the insertion cursor. .IP [7] The view in the spinbox can be adjusted by dragging with the middle mouse button (button 2, or button 3 in TkAqua). If the middle mouse button is clicked without moving the mouse, the selection is copied into the spinbox at the position of the mouse cursor. .IP [8] If the mouse is dragged out of the spinbox on the left or right sides while button 1 is pressed, the spinbox will automatically scroll to make more text visible (if there is more text off-screen on the side where the mouse left the window). .IP [9] The Left and Right keys move the insertion cursor one character to the |
︙ | ︙ |
Changes to doc/text.n.
︙ | ︙ | |||
2053 2054 2055 2056 2057 2058 2059 | .IP [5] Clicking mouse button 1 with the Control key down will reposition the insertion cursor without affecting the selection. .IP [6] If any normal printing characters are typed, they are inserted at the point of the insertion cursor. .IP [7] | | > | | | | 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 | .IP [5] Clicking mouse button 1 with the Control key down will reposition the insertion cursor without affecting the selection. .IP [6] If any normal printing characters are typed, they are inserted at the point of the insertion cursor. .IP [7] The view in the widget can be adjusted by dragging with the middle mouse button (button 2, or button 3 in TkAqua). If the middle mouse button is clicked without moving the mouse, the selection is copied into the text at the position of the mouse cursor. The Insert key also inserts the selection, but at the position of the insertion cursor. .IP [8] If the mouse is dragged out of the widget while button 1 is pressed, the entry will automatically scroll to make more text visible (if there is more text off-screen on the side where the mouse left the window). .IP [9] The Left and Right keys move the insertion cursor one character to the left or right; they also clear any selection in the text. If Left or Right is typed |
︙ | ︙ |
Changes to doc/ttk_entry.n.
︙ | ︙ | |||
349 350 351 352 353 354 355 | .IP \0\(bu 4 Clicking mouse button 1 with the Control key down will position the insert cursor in the entry without affecting the selection. .IP \0\(bu 4 If any normal printing characters are typed in an entry, they are inserted at the point of the insert cursor. .IP \0\(bu 4 | | > | | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | .IP \0\(bu 4 Clicking mouse button 1 with the Control key down will position the insert cursor in the entry without affecting the selection. .IP \0\(bu 4 If any normal printing characters are typed in an entry, they are inserted at the point of the insert cursor. .IP \0\(bu 4 The view in the entry can be adjusted by dragging with the middle mouse button (button 2, or button 3 in TkAqua). If the middle mouse button is clicked without moving the mouse, the selection is copied into the entry at the position of the mouse cursor. .IP \0\(bu 4 If the mouse is dragged out of the entry on the left or right sides while button 1 is pressed, the entry will automatically scroll to make more text visible (if there is more text off-screen on the side where the mouse left the window). .IP \0\(bu 4 The Left and Right keys move the insert cursor one character to the |
︙ | ︙ |
Changes to generic/tk.h.
︙ | ︙ | |||
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 | * window's parent either doesn't exist or is not * owned by this Tk application. * TK_PROP_PROPCHANGE 1 means that PropertyNotify events in the * window's children should propagate up to this * window. * TK_WM_MANAGEABLE 1 marks a window as capable of being converted * into a toplevel using [wm manage]. */ #define TK_MAPPED 1 #define TK_TOP_LEVEL 2 #define TK_ALREADY_DEAD 4 #define TK_NEED_CONFIG_NOTIFY 8 #define TK_GRAB_FLAG 0x10 #define TK_CHECKED_IC 0x20 #define TK_DONT_DESTROY_WINDOW 0x40 #define TK_WM_COLORMAP_WINDOW 0x80 #define TK_EMBEDDED 0x100 #define TK_CONTAINER 0x200 #define TK_BOTH_HALVES 0x400 #define TK_WRAPPER 0x1000 #define TK_REPARENTED 0x2000 #define TK_ANONYMOUS_WINDOW 0x4000 #define TK_HAS_WRAPPER 0x8000 #define TK_WIN_MANAGED 0x10000 #define TK_TOP_HIERARCHY 0x20000 #define TK_PROP_PROPCHANGE 0x40000 #define TK_WM_MANAGEABLE 0x80000 /* *---------------------------------------------------------------------- * * Procedure prototypes and structures used for defining new canvas items: * *---------------------------------------------------------------------- | > > > > > > | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 | * window's parent either doesn't exist or is not * owned by this Tk application. * TK_PROP_PROPCHANGE 1 means that PropertyNotify events in the * window's children should propagate up to this * window. * TK_WM_MANAGEABLE 1 marks a window as capable of being converted * into a toplevel using [wm manage]. * TK_CAN_INPUT_TEXT 1 means that this window accepts text input. * Used on macOS to indicate that key events can be * processed with the NSTextInputClient protocol. * Not currently accessible through the public API. */ #define TK_MAPPED 1 #define TK_TOP_LEVEL 2 #define TK_ALREADY_DEAD 4 #define TK_NEED_CONFIG_NOTIFY 8 #define TK_GRAB_FLAG 0x10 #define TK_CHECKED_IC 0x20 #define TK_DONT_DESTROY_WINDOW 0x40 #define TK_WM_COLORMAP_WINDOW 0x80 #define TK_EMBEDDED 0x100 #define TK_CONTAINER 0x200 #define TK_BOTH_HALVES 0x400 #define TK_WRAPPER 0x1000 #define TK_REPARENTED 0x2000 #define TK_ANONYMOUS_WINDOW 0x4000 #define TK_HAS_WRAPPER 0x8000 #define TK_WIN_MANAGED 0x10000 #define TK_TOP_HIERARCHY 0x20000 #define TK_PROP_PROPCHANGE 0x40000 #define TK_WM_MANAGEABLE 0x80000 #define TK_CAN_INPUT_TEXT 0x100000 /* *---------------------------------------------------------------------- * * Procedure prototypes and structures used for defining new canvas items: * *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to generic/tkBind.c.
︙ | ︙ | |||
339 340 341 342 343 344 345 | * Constants that define how close together two events must be in milliseconds * or pixels to meet the PAT_NEARBY constraint: */ #define NEARBY_PIXELS 5 #define NEARBY_MS 500 | < < < < < < < < | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | * Constants that define how close together two events must be in milliseconds * or pixels to meet the PAT_NEARBY constraint: */ #define NEARBY_PIXELS 5 #define NEARBY_MS 500 /* * The following structure is used in the nameTable of a virtual event table * to associate a virtual event with all the physical events that can trigger * it. */ TK_PTR_ARRAY_DEFINE(PhysOwned, PatSeq); /* define array of pattern seqs */ |
︙ | ︙ | |||
557 558 559 560 561 562 563 | #define CONFIG (1<<12) #define GRAVITY (1<<13) #define CIRC (1<<14) #define PROP (1<<15) #define COLORMAP (1<<16) #define VIRTUAL (1<<17) #define ACTIVATE (1<<18) | > | | | | > > > > > | | > > > > > > > > > > > > > | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | #define CONFIG (1<<12) #define GRAVITY (1<<13) #define CIRC (1<<14) #define PROP (1<<15) #define COLORMAP (1<<16) #define VIRTUAL (1<<17) #define ACTIVATE (1<<18) #define WHEEL (1<<19) #define MAPREQ (1<<20) #define CONFIGREQ (1<<21) #define RESIZEREQ (1<<22) #define CIRCREQ (1<<23) /* * These structs agree with xkey for the fields type, serial, send_event, display, * window, root, subwindow, time, x, y, x_root, and y_root. So when accessing * these fields we may pretend that we are using a struct xkey. */ #define HAS_XKEY_HEAD (KEY|BUTTON|MOTION|VIRTUAL|CROSSING|WHEEL) /* * The xcrossing struct puts the state field in a different location, but the other * events above agree on where state is located. */ #define HAS_XKEY_HEAD_AND_STATE (KEY|BUTTON|MOTION|VIRTUAL|WHEEL) /* * Event types which support -warp. */ #define CAN_WARP (KEY|BUTTON|MOTION|WHEEL) static const int flagArray[TK_LASTEVENT] = { /* Not used */ 0, /* Not used */ 0, /* KeyPress */ KEY, /* KeyRelease */ KEY, /* ButtonPress */ BUTTON, |
︙ | ︙ | |||
604 605 606 607 608 609 610 | /* SelectionNotify */ 0, /* ColormapNotify */ COLORMAP, /* ClientMessage */ 0, /* MappingNotify */ 0, /* VirtualEvent */ VIRTUAL, /* Activate */ ACTIVATE, /* Deactivate */ ACTIVATE, | | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | /* SelectionNotify */ 0, /* ColormapNotify */ COLORMAP, /* ClientMessage */ 0, /* MappingNotify */ 0, /* VirtualEvent */ VIRTUAL, /* Activate */ ACTIVATE, /* Deactivate */ ACTIVATE, /* MouseWheel */ WHEEL }; /* * The following table is used to map between the location where an generated * event should be queued and the string used to specify the location. */ |
︙ | ︙ | |||
1230 1231 1232 1233 1234 1235 1236 | /* type of TkPattern.info is well defined? */ assert(sizeof(Info) >= sizeof(KeySym)); assert(sizeof(Info) >= sizeof(unsigned)); /* ensure that our matching algorithm is working (when testing detail) */ assert(sizeof(Detail) == sizeof(Tk_Uid)); | < < < < | 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 | /* type of TkPattern.info is well defined? */ assert(sizeof(Info) >= sizeof(KeySym)); assert(sizeof(Info) >= sizeof(unsigned)); /* ensure that our matching algorithm is working (when testing detail) */ assert(sizeof(Detail) == sizeof(Tk_Uid)); /* test expected indices of Button1..Button5, otherwise our button handling is not working */ assert(Button1 == 1 && Button2 == 2 && Button3 == 3 && Button4 == 4 && Button5 == 5); assert(Button2Mask == (Button1Mask << 1)); assert(Button3Mask == (Button1Mask << 2)); assert(Button4Mask == (Button1Mask << 3)); assert(Button5Mask == (Button1Mask << 4)); |
︙ | ︙ | |||
2174 2175 2176 2177 2178 2179 2180 | * Ignore event types which are not in flagArray and all zeroes there. */ if (eventPtr->type >= TK_LASTEVENT || !flags) { return; } | | | 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 | * Ignore event types which are not in flagArray and all zeroes there. */ if (eventPtr->type >= TK_LASTEVENT || !flags) { return; } if (flags & HAS_XKEY_HEAD_AND_STATE) { bindPtr->curModMask = eventPtr->xkey.state; } else if (flags & CROSSING) { bindPtr->curModMask = eventPtr->xcrossing.state; } dispPtr = ((TkWindow *) tkwin)->dispPtr; bindInfoPtr = winPtr->mainPtr->bindInfo; |
︙ | ︙ | |||
2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 | assert(before); assert(eventPtr); assert(dsPtr); Tcl_DStringInit(&buf); evPtr = &eventPtr->xev; flags = (evPtr->type < TK_LASTEVENT) ? flagArray[evPtr->type] : 0; while (1) { char numStorage[TCL_INTEGER_SPACE]; const char *string; | > > > > > > > > > > | > < < | | | | | | | | | | | | | | | | | | | | < < | | | | | | | | | < < | | | < < | | | | | | < < < < | | | | | < < < | | | | | | | | | | | | | | < < < < < > > > | 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 | assert(before); assert(eventPtr); assert(dsPtr); Tcl_DStringInit(&buf); evPtr = &eventPtr->xev; flags = (evPtr->type < TK_LASTEVENT) ? flagArray[evPtr->type] : 0; #define SET_NUMBER(value) { number = (value); \ snprintf(numStorage, sizeof(numStorage), "%" TCL_LL_MODIFIER "d", number); \ string = numStorage; \ } #define SET_UNUMBER(value) { unumber = (value); \ snprintf(numStorage, sizeof(numStorage), "%" TCL_LL_MODIFIER "u", unumber); \ string = numStorage; \ } while (1) { char numStorage[TCL_INTEGER_SPACE]; const char *string; Tcl_WideInt number; /* signed */ Tcl_WideUInt unumber; /* unsigned */ /* * Find everything up to the next % character and append it to the * result string. */ for (string = before; *string && *string != '%'; ++string) ; if (string != before) { Tcl_DStringAppend(dsPtr, before, string - before); before = string; } if (!*before) { break; } /* * There's a percent sequence here. Process it. */ string = "??"; switch (before[1]) { case '#': SET_UNUMBER(evPtr->xany.serial); break; case 'a': if (flags & CONFIG) { TkpPrintWindowId(numStorage, evPtr->xconfigure.above); string = numStorage; } break; case 'b': if (flags & BUTTON) { SET_UNUMBER(evPtr->xbutton.button); } break; case 'c': if (flags & EXPOSE) { SET_NUMBER(evPtr->xexpose.count); } break; case 'd': if (flags & (CROSSING|FOCUS)) { int detail = (flags & FOCUS) ? evPtr->xfocus.detail : evPtr->xcrossing.detail; string = TkFindStateString(notifyDetail, detail); } else if (flags & CONFIGREQ) { if (evPtr->xconfigurerequest.value_mask & CWStackMode) { string = TkFindStateString(configureRequestDetail, evPtr->xconfigurerequest.detail); } else { string = ""; } } else if (flags & VIRTUAL) { XVirtualEvent *vePtr = (XVirtualEvent *) evPtr; string = vePtr->user_data ? Tcl_GetString(vePtr->user_data) : ""; } break; case 'f': if (flags & CROSSING) { SET_NUMBER(evPtr->xcrossing.focus != 0); } break; case 'h': if (flags & EXPOSE) { SET_NUMBER(evPtr->xexpose.height); } else if (flags & CONFIG) { SET_NUMBER(evPtr->xconfigure.height); } else if (flags & CREATE) { SET_NUMBER(evPtr->xcreatewindow.height); } else if (flags & CONFIGREQ) { SET_NUMBER(evPtr->xconfigurerequest.height); } else if (flags & RESIZEREQ) { SET_NUMBER(evPtr->xresizerequest.height); } break; case 'i': if (flags & CREATE) { TkpPrintWindowId(numStorage, evPtr->xcreatewindow.window); } else if (flags & CONFIGREQ) { TkpPrintWindowId(numStorage, evPtr->xconfigurerequest.window); } else if (flags & MAPREQ) { TkpPrintWindowId(numStorage, evPtr->xmaprequest.window); } else { TkpPrintWindowId(numStorage, evPtr->xany.window); } string = numStorage; break; case 'k': if (flags & KEY) { SET_UNUMBER(evPtr->xkey.keycode); } break; case 'm': if (flags & CROSSING) { string = TkFindStateString(notifyMode, evPtr->xcrossing.mode); } else if (flags & FOCUS) { string = TkFindStateString(notifyMode, evPtr->xfocus.mode); } break; case 'o': if (flags & CREATE) { SET_NUMBER(evPtr->xcreatewindow.override_redirect != 0); } else if (flags & MAP) { SET_NUMBER(evPtr->xmap.override_redirect != 0); } else if (flags & REPARENT) { SET_NUMBER(evPtr->xreparent.override_redirect != 0); } else if (flags & CONFIG) { SET_NUMBER(evPtr->xconfigure.override_redirect != 0); } break; case 'p': if (flags & CIRC) { string = TkFindStateString(circPlace, evPtr->xcirculate.place); } else if (flags & CIRCREQ) { string = TkFindStateString(circPlace, evPtr->xcirculaterequest.place); } break; case 's': if (flags & HAS_XKEY_HEAD_AND_STATE) { SET_UNUMBER(evPtr->xkey.state); } else if (flags & CROSSING) { SET_UNUMBER(evPtr->xcrossing.state); } else if (flags & PROP) { string = TkFindStateString(propNotify, evPtr->xproperty.state); } else if (flags & VISIBILITY) { string = TkFindStateString(visNotify, evPtr->xvisibility.state); } break; case 't': if (flags & HAS_XKEY_HEAD) { SET_UNUMBER(evPtr->xkey.time); } else if (flags & PROP) { SET_UNUMBER(evPtr->xproperty.time); } break; case 'v': SET_UNUMBER(evPtr->xconfigurerequest.value_mask); break; case 'w': if (flags & EXPOSE) { SET_NUMBER(evPtr->xexpose.width); } else if (flags & CONFIG) { SET_NUMBER(evPtr->xconfigure.width); } else if (flags & CREATE) { SET_NUMBER(evPtr->xcreatewindow.width); } else if (flags & CONFIGREQ) { SET_NUMBER(evPtr->xconfigurerequest.width); } else if (flags & RESIZEREQ) { SET_NUMBER(evPtr->xresizerequest.width); } break; case 'x': if (flags & HAS_XKEY_HEAD) { SET_NUMBER(evPtr->xkey.x); } else if (flags & EXPOSE) { SET_NUMBER(evPtr->xexpose.x); } else if (flags & (CREATE|CONFIG|GRAVITY)) { SET_NUMBER(evPtr->xcreatewindow.x); } else if (flags & REPARENT) { SET_NUMBER(evPtr->xreparent.x); } else if (flags & CONFIGREQ) { SET_NUMBER(evPtr->xconfigurerequest.x); } break; case 'y': if (flags & HAS_XKEY_HEAD) { SET_NUMBER(evPtr->xkey.y); } else if (flags & EXPOSE) { SET_NUMBER(evPtr->xexpose.y); } else if (flags & (CREATE|CONFIG|GRAVITY)) { SET_NUMBER(evPtr->xcreatewindow.y); } else if (flags & REPARENT) { SET_NUMBER(evPtr->xreparent.y); } else if (flags & CONFIGREQ) { SET_NUMBER(evPtr->xconfigurerequest.y); } break; case 'A': if (flags & KEY) { Tcl_DStringFree(&buf); string = TkpGetString(winPtr, evPtr, &buf); } break; case 'B': if (flags & CREATE) { SET_NUMBER(evPtr->xcreatewindow.border_width); } else if (flags & CONFIGREQ) { SET_NUMBER(evPtr->xconfigurerequest.border_width); } else if (flags & CONFIG) { SET_NUMBER(evPtr->xconfigure.border_width); } break; case 'D': if (flags & WHEEL) { SET_NUMBER((int)evPtr->xbutton.button); /* mis-use button field for this */ } break; case 'E': SET_NUMBER(evPtr->xany.send_event != 0); break; case 'K': if (flags & KEY) { const char *name = TkKeysymToString(eventPtr->detail.info); if (name) { string = name; } } break; case 'M': SET_UNUMBER(scriptCount); break; case 'N': if (flags & KEY) { SET_UNUMBER(eventPtr->detail.info); } break; case 'P': if (flags & PROP) { string = Tk_GetAtomName((Tk_Window) winPtr, evPtr->xproperty.atom); } break; case 'R': if (flags & HAS_XKEY_HEAD) { TkpPrintWindowId(numStorage, evPtr->xkey.root); string = numStorage; } break; case 'S': if (flags & HAS_XKEY_HEAD) { TkpPrintWindowId(numStorage, evPtr->xkey.subwindow); string = numStorage; } break; case 'T': SET_NUMBER(evPtr->type); break; case 'W': { Tk_Window tkwin = Tk_IdToWindow(evPtr->xany.display, evPtr->xany.window); if (tkwin) { string = Tk_PathName(tkwin); } break; } case 'X': if (flags & HAS_XKEY_HEAD) { SET_NUMBER(evPtr->xkey.x_root); } break; case 'Y': if (flags & HAS_XKEY_HEAD) { SET_NUMBER(evPtr->xkey.y_root); } break; default: numStorage[0] = before[1]; numStorage[1] = '\0'; string = numStorage; break; } { /* local scope */ int cvtFlags; unsigned spaceNeeded = Tcl_ScanElement(string, &cvtFlags); unsigned length = Tcl_DStringLength(dsPtr); Tcl_DStringSetLength(dsPtr, length + spaceNeeded); spaceNeeded = Tcl_ConvertElement( string, Tcl_DStringValue(dsPtr) + length, cvtFlags | TCL_DONT_USE_BRACES); Tcl_DStringSetLength(dsPtr, length + spaceNeeded); before += 2; } } #undef SET_NUMBER #undef SET_UNUMBER Tcl_DStringFree(&buf); } /* *---------------------------------------------------------------------- * * ChangeScreen -- |
︙ | ︙ | |||
3887 3888 3889 3890 3891 3892 3893 | if (flags & DESTROY) { /* * Event DestroyNotify should be generated by destroying the window. */ Tk_DestroyWindow(tkwin); return TCL_OK; } | | | | | 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 | if (flags & DESTROY) { /* * Event DestroyNotify should be generated by destroying the window. */ Tk_DestroyWindow(tkwin); return TCL_OK; } if (flags & HAS_XKEY_HEAD_AND_STATE) { event.general.xkey.state = pat.modMask; if (flags & KEY) { TkpSetKeycodeAndState(tkwin, pat.info, &event.general); } else if (flags & BUTTON) { event.general.xbutton.button = pat.info; } else if (flags & VIRTUAL) { event.virtual.name = pat.name; } } if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG|GRAVITY|CIRC)) { event.general.xcreatewindow.window = event.general.xany.window; } if (flags & HAS_XKEY_HEAD) { event.general.xkey.x_root = -1; event.general.xkey.y_root = -1; } if (event.general.xany.type == FocusIn || event.general.xany.type == FocusOut) { event.general.xany.send_event = GENERATED_FOCUS_EVENT_MAGIC; } |
︙ | ︙ | |||
3949 3950 3951 3952 3953 3954 3955 | } switch ((enum field) index) { case EVENT_WARP: if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) { return TCL_ERROR; } | | | 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 | } switch ((enum field) index) { case EVENT_WARP: if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) { return TCL_ERROR; } if (!(flags & CAN_WARP)) { badOpt = 1; } break; case EVENT_WHEN: pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr, queuePosition, valuePtr); if ((int) pos < -1) { return TCL_ERROR; |
︙ | ︙ | |||
4016 4017 4018 4019 4020 4021 4022 | badOpt = 1; } break; case EVENT_DELTA: if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } | | | | 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 | badOpt = 1; } break; case EVENT_DELTA: if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & WHEEL) { event.general.xbutton.button = (unsigned)number; /* mis-use button field for this */ } else { badOpt = 1; } break; case EVENT_DETAIL: number = TkFindStateNumObj(interp, optionPtr, notifyDetail, valuePtr); if (number < 0) { |
︙ | ︙ | |||
4061 4062 4063 4064 4065 4066 4067 | badOpt = 1; } break; case EVENT_KEYCODE: if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } | | | 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 | badOpt = 1; } break; case EVENT_KEYCODE: if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & KEY) { event.general.xkey.keycode = number; } else { badOpt = 1; } break; case EVENT_KEYSYM: { KeySym keysym; |
︙ | ︙ | |||
4085 4086 4087 4088 4089 4090 4091 | TkpSetKeycodeAndState(tkwin, keysym, &event.general); if (event.general.xkey.keycode == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("no keycode for keysym \"%s\"", value)); Tcl_SetErrorCode(interp, "TK", "LOOKUP", "KEYCODE", value, NULL); return TCL_ERROR; } | | | 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 | TkpSetKeycodeAndState(tkwin, keysym, &event.general); if (event.general.xkey.keycode == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("no keycode for keysym \"%s\"", value)); Tcl_SetErrorCode(interp, "TK", "LOOKUP", "KEYCODE", value, NULL); return TCL_ERROR; } if (!(flags & KEY)) { badOpt = 1; } break; } case EVENT_MODE: if ((number = TkFindStateNumObj(interp, optionPtr, notifyMode, valuePtr)) < 0) { return TCL_ERROR; |
︙ | ︙ | |||
4132 4133 4134 4135 4136 4137 4138 | badOpt = 1; } break; case EVENT_ROOT: if (!NameToWindow(interp, tkwin, valuePtr, &tkwin2)) { return TCL_ERROR; } | | | | | 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 | badOpt = 1; } break; case EVENT_ROOT: if (!NameToWindow(interp, tkwin, valuePtr, &tkwin2)) { return TCL_ERROR; } if (flags & HAS_XKEY_HEAD) { event.general.xkey.root = Tk_WindowId(tkwin2); } else { badOpt = 1; } break; case EVENT_ROOTX: if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & HAS_XKEY_HEAD) { event.general.xkey.x_root = number; } else { badOpt = 1; } break; case EVENT_ROOTY: if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & HAS_XKEY_HEAD) { event.general.xkey.y_root = number; } else { badOpt = 1; } break; case EVENT_SEND: { const char *value; |
︙ | ︙ | |||
4191 4192 4193 4194 4195 4196 4197 | case EVENT_SERIAL: if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } event.general.xany.serial = number; break; case EVENT_STATE: | | | | | | 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 | case EVENT_SERIAL: if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } event.general.xany.serial = number; break; case EVENT_STATE: if (flags & HAS_XKEY_HEAD) { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & HAS_XKEY_HEAD_AND_STATE) { event.general.xkey.state = number; } else { event.general.xcrossing.state = number; } } else if (flags & VISIBILITY) { if ((number = TkFindStateNumObj(interp, optionPtr, visNotify, valuePtr)) < 0) { return TCL_ERROR; } event.general.xvisibility.state = number; } else { badOpt = 1; } break; case EVENT_SUBWINDOW: if (!NameToWindow(interp, tkwin, valuePtr, &tkwin2)) { return TCL_ERROR; } if (flags & HAS_XKEY_HEAD) { event.general.xkey.subwindow = Tk_WindowId(tkwin2); } else { badOpt = 1; } break; case EVENT_TIME: { if (strcmp(Tcl_GetString(valuePtr), "current") == 0) { TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; BindInfo *biPtr = mainPtr->mainPtr->bindInfo; number = dispPtr->lastEventTime + (CurrentTimeInMilliSecs() - biPtr->lastCurrentTime); } else if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & HAS_XKEY_HEAD) { event.general.xkey.time = number; } else if (flags & PROP) { event.general.xproperty.time = number; } else { badOpt = 1; } break; |
︙ | ︙ | |||
4262 4263 4264 4265 4266 4267 4268 | badOpt = 1; } break; case EVENT_X: if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } | | | 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 | badOpt = 1; } break; case EVENT_X: if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & HAS_XKEY_HEAD) { event.general.xkey.x = number; /* * Only modify rootx as well if it hasn't been changed. */ if (event.general.xkey.x_root == -1) { |
︙ | ︙ | |||
4289 4290 4291 4292 4293 4294 4295 | badOpt = 1; } break; case EVENT_Y: if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } | | | 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 | badOpt = 1; } break; case EVENT_Y: if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & HAS_XKEY_HEAD) { event.general.xkey.y = number; /* * Only modify rooty as well if it hasn't been changed. */ if (event.general.xkey.y_root == -1) { |
︙ | ︙ |
Changes to generic/tkCanvText.c.
︙ | ︙ | |||
953 954 955 956 957 958 959 | * text up to the selection, draw the selection, then draw the rest of the * regular text. Drawing the regular text and then the selected text over * it would causes problems with anti-aliased text because the two * anti-aliasing colors would blend together. */ if ((selFirstChar >= 0) && (textPtr->selTextGC != textPtr->gc)) { | > | | | > > | | | > | | 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 | * text up to the selection, draw the selection, then draw the rest of the * regular text. Drawing the regular text and then the selected text over * it would causes problems with anti-aliased text because the two * anti-aliasing colors would blend together. */ if ((selFirstChar >= 0) && (textPtr->selTextGC != textPtr->gc)) { if (0 < selFirstChar) { TkDrawAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, 0, selFirstChar); } TkDrawAngledTextLayout(display, drawable, textPtr->selTextGC, textPtr->textLayout, drawableX, drawableY, textPtr->angle, selFirstChar, selLastChar + 1); if (selLastChar + 1 < textPtr->numChars) { TkDrawAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, selLastChar + 1, textPtr->numChars); } } else { TkDrawAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, 0, textPtr->numChars); } TkUnderlineAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, textPtr->underline); if (stipple != None) { XSetTSOrigin(display, textPtr->gc, 0, 0); |
︙ | ︙ |
Changes to generic/tkFont.c.
︙ | ︙ | |||
2739 2740 2741 2742 2743 2744 2745 | end = Tcl_UtfAtIndex(chunkPtr->start, index); if (xPtr != NULL) { Tk_MeasureChars(tkfont, chunkPtr->start, end - chunkPtr->start, -1, 0, &x); x += chunkPtr->x; } if (widthPtr != NULL) { | > | < | 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 | end = Tcl_UtfAtIndex(chunkPtr->start, index); if (xPtr != NULL) { Tk_MeasureChars(tkfont, chunkPtr->start, end - chunkPtr->start, -1, 0, &x); x += chunkPtr->x; } if (widthPtr != NULL) { int ch; Tk_MeasureChars(tkfont, end, TkUtfToUniChar(end, &ch), -1, 0, &w); } goto check; } index -= chunkPtr->numChars; chunkPtr++; } if (index != 0) { |
︙ | ︙ |
Changes to generic/tkInt.h.
︙ | ︙ | |||
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 | #if !defined(__cplusplus) && !defined(c_plusplus) # define c_class class #endif #if TCL_UTF_MAX > 4 # define TkUtfToUniChar Tcl_UtfToUniChar # define TkUniCharToUtf Tcl_UniCharToUtf #else MODULE_SCOPE int TkUtfToUniChar(const char *, int *); MODULE_SCOPE int TkUniCharToUtf(int, char *); #endif /* * Unsupported commands. */ MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData, | > > | 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 | #if !defined(__cplusplus) && !defined(c_plusplus) # define c_class class #endif #if TCL_UTF_MAX > 4 # define TkUtfToUniChar Tcl_UtfToUniChar # define TkUniCharToUtf Tcl_UniCharToUtf # define TkUtfPrev Tcl_UtfPrev #else MODULE_SCOPE int TkUtfToUniChar(const char *, int *); MODULE_SCOPE int TkUniCharToUtf(int, char *); MODULE_SCOPE const char *TkUtfPrev(const char *, const char *); #endif /* * Unsupported commands. */ MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData, |
︙ | ︙ |
Changes to generic/tkSelect.c.
︙ | ︙ | |||
1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 | */ if (cmdInfoPtr->interp != NULL) { if (length <= maxBytes) { cmdInfoPtr->charOffset += Tcl_NumUtfChars(string, -1); cmdInfoPtr->buffer[0] = '\0'; } else { p = string; string += count; numChars = 0; while (p < string) { | > | | 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 | */ if (cmdInfoPtr->interp != NULL) { if (length <= maxBytes) { cmdInfoPtr->charOffset += Tcl_NumUtfChars(string, -1); cmdInfoPtr->buffer[0] = '\0'; } else { Tcl_UniChar ch = 0; p = string; string += count; numChars = 0; while (p < string) { p += Tcl_UtfToUniChar(p, &ch); numChars++; } cmdInfoPtr->charOffset += numChars; length = p - string; if (length > 0) { strncpy(cmdInfoPtr->buffer, string, (size_t) length); } |
︙ | ︙ |
Changes to generic/tkTextIndex.c.
︙ | ︙ | |||
432 433 434 435 436 437 438 | * Prevent UTF-8 character from being split up by ensuring * that byteIndex falls on a character boundary. If the index * falls in the middle of a UTF-8 character, it will be * adjusted to the end of that UTF-8 character. */ start = segPtr->body.chars + (byteIndex - index); | | | 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | * Prevent UTF-8 character from being split up by ensuring * that byteIndex falls on a character boundary. If the index * falls in the middle of a UTF-8 character, it will be * adjusted to the end of that UTF-8 character. */ start = segPtr->body.chars + (byteIndex - index); p = TkUtfPrev(start, segPtr->body.chars); p += TkUtfToUniChar(p, &ch); indexPtr->byteIndex += p - start; } break; } index += segPtr->size; } |
︙ | ︙ | |||
2121 2122 2123 2124 2125 2126 2127 | } } if (!elide) { if (segPtr->typePtr == &tkTextCharType) { start = segPtr->body.chars; end = segPtr->body.chars + segSize; | | | 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 | } } if (!elide) { if (segPtr->typePtr == &tkTextCharType) { start = segPtr->body.chars; end = segPtr->body.chars + segSize; for (p = end; ; p = TkUtfPrev(p, start)) { if (charCount == 0) { dstPtr->byteIndex -= (end - p); goto backwardCharDone; } if (p == start) { break; } |
︙ | ︙ | |||
2362 2363 2364 2365 2366 2367 2368 | int ch; TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } if (offset > 0) { chSize = (segPtr->body.chars + offset | | | 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 | int ch; TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } if (offset > 0) { chSize = (segPtr->body.chars + offset - TkUtfPrev(segPtr->body.chars + offset, segPtr->body.chars)); } firstChar = 0; } if (offset == 0) { if (modifier == TKINDEX_DISPLAY) { TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr, |
︙ | ︙ |
Changes to generic/tkUtil.c.
︙ | ︙ | |||
1260 1261 1262 1263 1264 1265 1266 | /* Spit out a 4-byte UTF-8 character or 2 x 3-byte UTF-8 characters, depending on Tcl * version and/or TCL_UTF_MAX build value */ int len = Tcl_UniCharToUtf(0xD800 | ((ch - 0x10000) >> 10), buf); return len + Tcl_UniCharToUtf(0xDC00 | (ch & 0x7FF), buf + len); } return Tcl_UniCharToUtf(ch, buf); } | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 | /* Spit out a 4-byte UTF-8 character or 2 x 3-byte UTF-8 characters, depending on Tcl * version and/or TCL_UTF_MAX build value */ int len = Tcl_UniCharToUtf(0xD800 | ((ch - 0x10000) >> 10), buf); return len + Tcl_UniCharToUtf(0xDC00 | (ch & 0x7FF), buf + len); } return Tcl_UniCharToUtf(ch, buf); } /* *--------------------------------------------------------------------------- * * TkUtfPrev -- * * Almost the same as Tcl_UtfPrev. * This function is capable of jumping over a upper/lower surrogate pair. * So, might jump back up to 6 bytes. * * Results: * pointer to the first byte of the current UTF-8 character. A surrogate * pair is also handled as being a single entity. * * Side effects: * None. * *--------------------------------------------------------------------------- */ const char * TkUtfPrev( const char *src, /* The UTF-8 string. */ const char *start) /* Start position of string */ { const char *p = Tcl_UtfPrev(src, start); const char *first = Tcl_UtfPrev(p, start); int ch; return (first + TkUtfToUniChar(first, &ch) >= src) ? first : p ; } #endif /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 |
︙ | ︙ |
Changes to generic/ttk/ttkScroll.c.
︙ | ︙ | |||
100 101 102 103 104 105 106 | if (WidgetDestroyed(corePtr)) { Tcl_Release(corePtr); return TCL_ERROR; } Tcl_Release(corePtr); if (code != TCL_OK && !Tcl_InterpDeleted(interp)) { | | > > > > < < > | 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 | if (WidgetDestroyed(corePtr)) { Tcl_Release(corePtr); return TCL_ERROR; } Tcl_Release(corePtr); if (code != TCL_OK && !Tcl_InterpDeleted(interp)) { /* Add error to stack trace. * Also set the SCROLL_UPDATE_REQUIRED flag so that a later call to * TtkScrolled has an effect. Indeed, the error in the -scrollcommand * callback may later be gone, for instance the callback proc got * defined in the meantime. */ Tcl_AddErrorInfo(interp, /* @@@ "horizontal" / "vertical" */ "\n (scrolling command executed by "); Tcl_AddErrorInfo(interp, Tk_PathName(h->corePtr->tkwin)); Tcl_AddErrorInfo(interp, ")"); TtkScrollbarUpdateRequired(h); } return code; } /* UpdateScrollbarBG -- * Idle handler to update the scrollbar. */ |
︙ | ︙ |
Changes to generic/ttk/ttkTreeview.c.
︙ | ︙ | |||
2838 2839 2840 2841 2842 2843 2844 | if (!(parent->state & TTK_STATE_OPEN)) { parent->openObj = unshareObj(parent->openObj); Tcl_SetBooleanObj(parent->openObj, 1); parent->state |= TTK_STATE_OPEN; TtkRedisplayWidget(&tv->core); } } | < | 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 | if (!(parent->state & TTK_STATE_OPEN)) { parent->openObj = unshareObj(parent->openObj); Tcl_SetBooleanObj(parent->openObj, 1); parent->state |= TTK_STATE_OPEN; TtkRedisplayWidget(&tv->core); } } /* Make sure item is visible: */ rowNumber = RowNumber(tv, item); if (rowNumber < tv->tree.yscroll.first) { TtkScrollTo(tv->tree.yscrollHandle, rowNumber, 1); } else if (rowNumber >= tv->tree.yscroll.last) { |
︙ | ︙ |
Changes to library/demos/entry1.tcl.
︙ | ︙ | |||
12 13 14 15 16 17 18 | set w .entry1 catch {destroy $w} toplevel $w wm title $w "Entry Demonstration (no scrollbars)" wm iconname $w "entry1" positionWindow $w | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | set w .entry1 catch {destroy $w} toplevel $w wm title $w "Entry Demonstration (no scrollbars)" wm iconname $w "entry1" positionWindow $w label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below. You can add characters by pointing, clicking and typing. The normal Motif editing characters are supported, along with many Emacs bindings. For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor. For entries that are too large to fit in the window all at once, you can scan through the entries by dragging with mouse the middle mouse button pressed." pack $w.msg -side top ## See Code / Dismiss buttons set btns [addSeeDismiss $w.buttons $w] pack $btns -side bottom -fill x entry $w.e1 |
︙ | ︙ |
Changes to library/demos/entry2.tcl.
︙ | ︙ | |||
12 13 14 15 16 17 18 | set w .entry2 catch {destroy $w} toplevel $w wm title $w "Entry Demonstration (with scrollbars)" wm iconname $w "entry2" positionWindow $w | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | set w .entry2 catch {destroy $w} toplevel $w wm title $w "Entry Demonstration (with scrollbars)" wm iconname $w "entry2" positionWindow $w label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below, with a scrollbar for each entry. You can add characters by pointing, clicking and typing. The normal Motif editing characters are supported, along with many Emacs bindings. For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor. For entries that are too large to fit in the window all at once, you can scan through the entries with the scrollbars, or by dragging with the middle mouse button pressed." pack $w.msg -side top ## See Code / Dismiss buttons set btns [addSeeDismiss $w.buttons $w] pack $btns -side bottom -fill x frame $w.frame -borderwidth 10 |
︙ | ︙ |
Changes to library/demos/text.tcl.
︙ | ︙ | |||
53 54 55 56 57 58 59 | $w.text insert 0.0 \ {This window is a text widget. It displays one or more lines of text and allows you to edit the text. Here is a summary of the things you can do to a text widget: 1. Scrolling. Use the scrollbar to adjust the view in the text window. | | | > | > | 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 | $w.text insert 0.0 \ {This window is a text widget. It displays one or more lines of text and allows you to edit the text. Here is a summary of the things you can do to a text widget: 1. Scrolling. Use the scrollbar to adjust the view in the text window. 2. Scanning. Press the middle mouse button in the text window and drag up or down. This will drag the text at high speed to allow you to scan its contents. 3. Insert text. Press mouse button 1 to set the insertion cursor, then type text. What you type will be added to the widget. 4. Select. Press mouse button 1 and drag to select a range of characters. Once you've released the button, you can adjust the selection by pressing button 1 with the shift key down. This will reset the end of the selection nearest the mouse cursor and you can drag that end of the selection by dragging the mouse before releasing the mouse button. You can double-click to select whole words or triple-click to select whole lines. 5. Delete and replace. To delete text, select the characters you'd like to delete and type Backspace or Delete. Alternatively, you can type new text, in which case it will replace the selected text. 6. Copy the selection. To copy the selection into this window, select what you want to copy (either here or in another application), then click the middle mouse button to copy the selection to the point of the mouse cursor. 7. Edit. Text widgets support the standard Motif editing characters plus many Emacs editing characters. Backspace and Control-h erase the character to the left of the insertion cursor. Delete and Control-d erase the character to the right of the insertion cursor. Meta-backspace deletes the word to the left of the insertion cursor, and Meta-d deletes the word to the right of the insertion cursor. Control-k deletes from |
︙ | ︙ |
Changes to library/demos/widget.
︙ | ︙ | |||
79 80 81 82 83 84 85 | AAAAAAAAAAAAAAAAACH5BAEAAAoALAAAAAAQABAAAARGUMlJKwU4AztB+ODGeUiJ fGLlgeEYmGWQXmx7aXgmAUTv/74N4EAsGhOJg1DAbDqbwoJ0Sp0KB9isNis0eL/g ryhH5pgnEQA7 } # Note that this is run through the message catalog! This is because this is # actually an image of a word. | | | | | | | > > > > > > > > | 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 | AAAAAAAAAAAAAAAAACH5BAEAAAoALAAAAAAQABAAAARGUMlJKwU4AztB+ODGeUiJ fGLlgeEYmGWQXmx7aXgmAUTv/74N4EAsGhOJg1DAbDqbwoJ0Sp0KB9isNis0eL/g ryhH5pgnEQA7 } # Note that this is run through the message catalog! This is because this is # actually an image of a word. image create photo ::img::new -format PNG -data [mc { iVBORw0KGgoAAAANSUhEUgAAAB4AAAAOCAYAAAA45qw5AAACMElEQVR4AeVTAwxd QRCc2tZHGtQ2w9q2bdsOa9u2bUW1bdt2Z372JZe6DapJLqtb3h7+T8yKi5j4CsYD EUQXxETclT7kWOlH2VV+tFkdQHPSwksSISF+BauCqL0qgOcMWgGfgEkaMsHxqUBk 3plE/sOnh/qDPAPJH/CKFBivGHWzFwBRnHhlqbu1Mh6CoFNnC/JshQ9p4YC2lrKt DCAV+THiVejyhMjAbrNSrroiEfKR9g7ZfCgOog8QfnUQV62wAk68ndQ9ZbyoWO1H Y6eDY1LCQL6a9ApOp9Hi1T0+gQq2JKMlky/oTKQliKWxEZvyG575kpW4pl1aZnQK CLOVt45Lkp8uXp2SL8KO6uitNTZLdpK6s+I/eZbhpmsmWeOGOVQNKYLITzpKPAO3 tY7LSNZ7ccSLxX9y3uuOxRkg3dKESMoCHvL+GRVCutXsB3guLgDCeXOv4iWWkvwG BaS+PmlpK6SI9ApI2oC2UtrwZQEkhkH+NtolVlQXJl1I+QltuU3XEc721bIRFpa8 IA5iqTo6vNNWmkNBLQbPeXwF2g17Q94nTQAfY3YzeY+WSu8MDzQ2kpELUhSGJUHE 0zeR3rY1L+Xl5G/re+jbiK6KhThwwInsts1fbMUUcpZszKeVtggZEiGdZDe5AtHh 7vL4CGiRvvKPS8FAvq9Nr4ZkFadR2y6kggu1z4vlyIbBp6BugQ8JLEg4bTkD9eMZ QZ8hpJ3VvTtuvbWrY/ElvP/9R+Aj3603+iE3fkEAAAAASUVORK5CYII= }] #---------------------------------------------------------------- # The code below creates the main window, consisting of a menu bar and a text # widget that explains how to use the program, plus lists all of the demos as # hypertext items. #---------------------------------------------------------------- |
︙ | ︙ | |||
182 183 184 185 186 187 188 189 190 191 192 193 194 195 | -underline 1 .t tag configure hot -background black -foreground white } else { .t tag configure demo -lmargin1 1c -lmargin2 1c \ -foreground blue -underline 1 .t tag configure visited -lmargin1 1c -lmargin2 1c \ -foreground #303080 -underline 1 .t tag configure hot -foreground red -underline 1 } .t tag bind demo <ButtonRelease-1> { invoke [.t index {@%x,%y}] } set lastLine "" .t tag bind demo <Enter> { | > > > > | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | -underline 1 .t tag configure hot -background black -foreground white } else { .t tag configure demo -lmargin1 1c -lmargin2 1c \ -foreground blue -underline 1 .t tag configure visited -lmargin1 1c -lmargin2 1c \ -foreground #303080 -underline 1 if {[tk windowingsystem] eq "aqua"} { .t tag configure demo -foreground systemLinkColor .t tag configure visited -foreground purple } .t tag configure hot -foreground red -underline 1 } .t tag bind demo <ButtonRelease-1> { invoke [.t index {@%x,%y}] } set lastLine "" .t tag bind demo <Enter> { |
︙ | ︙ |
Changes to library/entry.tcl.
︙ | ︙ | |||
289 290 291 292 293 294 295 | } bind Entry <<TkAccentBackspace>> { tk::EntryBackspace %W } # A few additional bindings of my own. | > | | | | | | | | > > > > > > > > > > > > | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | } bind Entry <<TkAccentBackspace>> { tk::EntryBackspace %W } # A few additional bindings of my own. if {[tk windowingsystem] ne "aqua"} { bind Entry <2> { if {!$tk_strictMotif} { ::tk::EntryScanMark %W %x } } bind Entry <B2-Motion> { if {!$tk_strictMotif} { ::tk::EntryScanDrag %W %x } } } else { bind Entry <3> { if {!$tk_strictMotif} { ::tk::EntryScanMark %W %x } } bind Entry <B3-Motion> { if {!$tk_strictMotif} { ::tk::EntryScanDrag %W %x } } } # ::tk::EntryClosestGap -- # Given x and y coordinates, this procedure finds the closest boundary # between characters to the given coordinates and returns the index # of the character just after the boundary. |
︙ | ︙ |
Changes to library/spinbox.tcl.
︙ | ︙ | |||
276 277 278 279 280 281 282 | if {!$tk_strictMotif} { %W delete [::tk::EntryPreviousWord %W insert] insert } } # A few additional bindings of my own. | > | | | | | | | | > > > > > > > > > > > > | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | if {!$tk_strictMotif} { %W delete [::tk::EntryPreviousWord %W insert] insert } } # A few additional bindings of my own. if {[tk windowingsystem] ne "aqua"} { bind Spinbox <2> { if {!$tk_strictMotif} { ::tk::EntryScanMark %W %x } } bind Spinbox <B2-Motion> { if {!$tk_strictMotif} { ::tk::EntryScanDrag %W %x } } } else { bind Spinbox <3> { if {!$tk_strictMotif} { ::tk::EntryScanMark %W %x } } bind Spinbox <B3-Motion> { if {!$tk_strictMotif} { ::tk::EntryScanDrag %W %x } } } # ::tk::spinbox::Invoke -- # Invoke an element of the spinbox # # Arguments: |
︙ | ︙ |
Changes to library/text.tcl.
︙ | ︙ | |||
425 426 427 428 429 430 431 | bind Text <Control-h> { if {!$tk_strictMotif && [%W compare insert != 1.0]} { %W delete insert-1c %W see insert } } | > | | | | | | | | > > > > > > > > > > > > | 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 455 456 457 458 459 | bind Text <Control-h> { if {!$tk_strictMotif && [%W compare insert != 1.0]} { %W delete insert-1c %W see insert } } if {[tk windowingsystem] ne "aqua"} { bind Text <2> { if {!$tk_strictMotif} { tk::TextScanMark %W %x %y } } bind Text <B2-Motion> { if {!$tk_strictMotif} { tk::TextScanDrag %W %x %y } } } else { bind Text <3> { if {!$tk_strictMotif} { tk::TextScanMark %W %x %y } } bind Text <B3-Motion> { if {!$tk_strictMotif} { tk::TextScanDrag %W %x %y } } } set ::tk::Priv(prevPos) {} # The MouseWheel will typically only fire on Windows and MacOS X. # However, someone could use the "event generate" command to produce one # on other platforms. We must be careful not to round -ve values of %D |
︙ | ︙ |
Changes to library/tk.tcl.
︙ | ︙ | |||
458 459 460 461 462 463 464 | event add <<PasteSelection>> <ButtonRelease-3> event add <<Clear>> <Clear> event add <<ContextMenu>> <Button-2> # Official bindings # See http://support.apple.com/kb/HT1343 event add <<SelectAll>> <Command-Key-a> | < < | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | event add <<PasteSelection>> <ButtonRelease-3> event add <<Clear>> <Clear> event add <<ContextMenu>> <Button-2> # Official bindings # See http://support.apple.com/kb/HT1343 event add <<SelectAll>> <Command-Key-a> event add <<Undo>> <Command-Key-z> <Command-Lock-Key-Z> event add <<Redo>> <Shift-Command-Key-z> <Shift-Command-Lock-Key-z> event add <<NextChar>> <Right> <Control-Key-f> <Control-Lock-Key-F> event add <<SelectNextChar>> <Shift-Right> <Shift-Control-Key-F> <Shift-Control-Lock-Key-F> event add <<PrevChar>> <Left> <Control-Key-b> <Control-Lock-Key-B> event add <<SelectPrevChar>> <Shift-Left> <Shift-Control-Key-B> <Shift-Control-Lock-Key-B> event add <<NextWord>> <Option-Right> |
︙ | ︙ |
Changes to library/ttk/entry.tcl.
︙ | ︙ | |||
78 79 80 81 82 83 84 | bind TEntry <B1-Enter> { ttk::entry::DragIn %W } bind TEntry <ButtonRelease-1> { ttk::entry::Release %W } bind TEntry <<ToggleSelection>> { %W instate {!readonly !disabled} { %W icursor @%x ; focus %W } } | | > | > | | | > > > > > | 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 | bind TEntry <B1-Enter> { ttk::entry::DragIn %W } bind TEntry <ButtonRelease-1> { ttk::entry::Release %W } bind TEntry <<ToggleSelection>> { %W instate {!readonly !disabled} { %W icursor @%x ; focus %W } } ## Button2 (Button3 on Aqua) bindings: # Used for scanning and primary transfer. # Note: ButtonRelease-2 (ButtonRelease-3 on Aqua) # is mapped to <<PasteSelection>> in tk.tcl. # if {[tk windowingsystem] ne "aqua"} { bind TEntry <ButtonPress-2> { ttk::entry::ScanMark %W %x } bind TEntry <B2-Motion> { ttk::entry::ScanDrag %W %x } bind TEntry <ButtonRelease-2> { ttk::entry::ScanRelease %W %x } } else { bind TEntry <ButtonPress-3> { ttk::entry::ScanMark %W %x } bind TEntry <B3-Motion> { ttk::entry::ScanDrag %W %x } bind TEntry <ButtonRelease-3> { ttk::entry::ScanRelease %W %x } } bind TEntry <<PasteSelection>> { ttk::entry::ScanRelease %W %x } ## Keyboard navigation bindings: # bind TEntry <<PrevChar>> { ttk::entry::Move %W prevchar } bind TEntry <<NextChar>> { ttk::entry::Move %W nextchar } bind TEntry <<PrevWord>> { ttk::entry::Move %W prevword } |
︙ | ︙ |
Changes to library/ttk/treeview.tcl.
︙ | ︙ | |||
261 262 263 264 265 266 267 | # proc ttk::treeview::SelectOp {w item op} { select.$op.[$w cget -selectmode] $w $item } ## -selectmode none: # | | | | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | # proc ttk::treeview::SelectOp {w item op} { select.$op.[$w cget -selectmode] $w $item } ## -selectmode none: # proc ttk::treeview::select.choose.none {w item} { $w focus $item; $w see $item } proc ttk::treeview::select.toggle.none {w item} { $w focus $item; $w see $item } proc ttk::treeview::select.extend.none {w item} { $w focus $item; $w see $item } ## -selectmode browse: # proc ttk::treeview::select.choose.browse {w item} { BrowseTo $w $item } proc ttk::treeview::select.toggle.browse {w item} { BrowseTo $w $item } proc ttk::treeview::select.extend.browse {w item} { BrowseTo $w $item } |
︙ | ︙ |
Changes to macosx/README.
︙ | ︙ | |||
271 272 273 274 275 276 277 | appearance. Part of the implementation of the Dark Mode was to make some of the named NSColors have dynamic values. Apple calls these "semantic colors" because the name does not specify a specific color, but rather refers to the context in which the color should be used. Tk now provides the following semantic colors as system colors: systemTextColor, systemTextBackgroundColor, systemSelectedTextColor, systemSelectedTextBackgroundColor, systemControlTextColor, | | | | | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | appearance. Part of the implementation of the Dark Mode was to make some of the named NSColors have dynamic values. Apple calls these "semantic colors" because the name does not specify a specific color, but rather refers to the context in which the color should be used. Tk now provides the following semantic colors as system colors: systemTextColor, systemTextBackgroundColor, systemSelectedTextColor, systemSelectedTextBackgroundColor, systemControlTextColor, systemDisabledControlTextColor, systemLabelColor, systemLinkColor, and systemControlAccentColor. All of these except the last three were present in OSX 10.0 (and those three are simulated in systems where they do not exist). The change in 10.14 was that the RGB color value of these colors became dynamic, meaning that the color value can change when the application appearance changes. In particular, when a user selects Dark Mode in the system preferences these colors change appearance. For example systemTextColor is dark in Aqua and light in DarkAqua. One additional color, systemSelectedTabTextColor, does not exist in macOS but is used by Tk to match the different colors used |
︙ | ︙ |
Changes to macosx/tkMacOSXClipboard.c.
︙ | ︙ | |||
31 32 33 34 35 36 37 | [type isEqualToString:NSStringPboardType]) { for (TkClipboardTarget *targetPtr = dispPtr->clipTargetPtr; targetPtr; targetPtr = targetPtr->nextPtr) { if (targetPtr->type == XA_STRING || targetPtr->type == dispPtr->utf8Atom) { for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr; cbPtr; cbPtr = cbPtr->nextPtr) { | > > | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | [type isEqualToString:NSStringPboardType]) { for (TkClipboardTarget *targetPtr = dispPtr->clipTargetPtr; targetPtr; targetPtr = targetPtr->nextPtr) { if (targetPtr->type == XA_STRING || targetPtr->type == dispPtr->utf8Atom) { for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr; cbPtr; cbPtr = cbPtr->nextPtr) { NSString *s = [[TKNSString alloc] initWithTclUtfBytes:cbPtr->buffer length:cbPtr->length]; [string appendString:s]; [s release]; } break; } } } |
︙ | ︙ |
Changes to macosx/tkMacOSXColor.c.
︙ | ︙ | |||
209 210 211 212 213 214 215 216 217 218 | { "DisabledControlTextColor", semantic, 4 }, /* 178 */ { "SelectedTabTextColor", semantic, 5 }, /* 179 */ { "TextBackgroundColor", semantic, 6 }, /* 180 */ { "SelectedTextBackgroundColor", semantic, 7 }, /* 181 */ { "ControlAccentColor", semantic, 8 }, /* 182 */ /* Apple's SecondaryLabelColor is the same as their LabelColor so we roll our own. */ { "SecondaryLabelColor", ttkBackground, 14 }, /* 183 */ { NULL, 0, 0 } }; #define FIRST_SEMANTIC_COLOR 166 | > | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | { "DisabledControlTextColor", semantic, 4 }, /* 178 */ { "SelectedTabTextColor", semantic, 5 }, /* 179 */ { "TextBackgroundColor", semantic, 6 }, /* 180 */ { "SelectedTextBackgroundColor", semantic, 7 }, /* 181 */ { "ControlAccentColor", semantic, 8 }, /* 182 */ /* Apple's SecondaryLabelColor is the same as their LabelColor so we roll our own. */ { "SecondaryLabelColor", ttkBackground, 14 }, /* 183 */ { "LinkColor", semantic, 9 }, /* 184 */ { NULL, 0, 0 } }; #define FIRST_SEMANTIC_COLOR 166 #define MAX_PIXELCODE 184 /* *---------------------------------------------------------------------- * * GetEntryFromPixelCode -- * * Extract a SystemColorMapEntry from the table. |
︙ | ︙ | |||
365 366 367 368 369 370 371 | color = [[NSColor textBackgroundColor] colorUsingColorSpace:sRGB]; break; case 7: color = [[NSColor selectedTextBackgroundColor] colorUsingColorSpace:sRGB]; break; case 8: | < > | | > > > > > > > > > > | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | color = [[NSColor textBackgroundColor] colorUsingColorSpace:sRGB]; break; case 7: color = [[NSColor selectedTextBackgroundColor] colorUsingColorSpace:sRGB]; break; case 8: #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400 if (@available(macOS 14, *)) { #else if (false) { #endif color = [[NSColor controlAccentColor] colorUsingColorSpace:sRGB]; } else { color = [[NSColor colorForControlTint:[NSColor currentControlTint]] colorUsingColorSpace: sRGB]; } break; case 9: if ([NSApp macMinorVersion] >= 10) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 color = [[NSColor linkColor] colorUsingColorSpace:sRGB]; #endif } else { color = [[NSColor blueColor] colorUsingColorSpace:sRGB]; } break; default: if ([NSApp macMinorVersion] >= 10) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 color = [[NSColor labelColor] colorUsingColorSpace:sRGB]; #endif } else { |
︙ | ︙ |
Changes to macosx/tkMacOSXDialog.c.
︙ | ︙ | |||
206 207 208 209 210 211 212 | - (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError { *outError = nil; return YES; } - (void) tkFilePanelDidEnd: (NSSavePanel *) panel | > | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | - (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError { *outError = nil; return YES; } - (void) tkFilePanelDidEnd: (NSSavePanel *) panel returnCode: (NSModalResponse) returnCode contextInfo: (void *) contextInfo { FilePanelCallbackInfo *callbackInfo = contextInfo; if (returnCode == modalOK) { Tcl_Obj *resultObj; if (callbackInfo->multiple) { |
︙ | ︙ | |||
339 340 341 342 343 344 345 | static NSInteger showOpenSavePanel( NSSavePanel *panel, NSWindow *parent, FilePanelCallbackInfo *callbackInfo) { NSInteger modalReturnCode; | | | > | | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | static NSInteger showOpenSavePanel( NSSavePanel *panel, NSWindow *parent, FilePanelCallbackInfo *callbackInfo) { NSInteger modalReturnCode; if (parent && ![parent attachedSheet]) { [panel beginSheetModalForWindow:parent completionHandler:^(NSModalResponse returnCode) { [NSApp tkFilePanelDidEnd:panel returnCode:returnCode contextInfo:callbackInfo ]; }]; modalReturnCode = callbackInfo->cmdObj ? modalOther : [panel runModal]; } else { modalReturnCode = [panel runModal]; [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode contextInfo:callbackInfo]; } return modalReturnCode; } |
︙ | ︙ | |||
650 651 652 653 654 655 656 | NSString *directory = nil, *filename = nil; NSString *message = nil, *title = nil; NSWindow *parent; openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; | < < | 652 653 654 655 656 657 658 659 660 661 662 663 664 665 | NSString *directory = nil, *filename = nil; NSString *message = nil, *title = nil; NSWindow *parent; openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { goto end; } if (i + 1 == objc) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
︙ | ︙ | |||
924 925 926 927 928 929 930 | NSString *directory = nil, *filename = nil, *defaultType = nil; NSString *message = nil, *title = nil; NSWindow *parent; savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; | < < | 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | NSString *directory = nil, *filename = nil, *defaultType = nil; NSString *message = nil, *title = nil; NSWindow *parent; savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { goto end; } if (i + 1 == objc) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
︙ | ︙ | |||
1167 1168 1169 1170 1171 1172 1173 | NSString *directory = nil; NSString *message, *title; NSWindow *parent; NSOpenPanel *panel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; | < < | 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 | NSString *directory = nil; NSString *message, *title; NSWindow *parent; NSOpenPanel *panel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], chooseOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { goto end; } if (i + 1 == objc) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
︙ | ︙ |
Changes to macosx/tkMacOSXFont.c.
︙ | ︙ | |||
98 99 100 101 102 103 104 | int numBytes, int rangeStart, int rangeLength, int x, int y, double angle); #pragma mark - #pragma mark Font Helpers: /* | < < | < < < < < < < < < < < < < < | < < < < < | < < | < > | | > | | | > | > > > > > > > > | > > > > > > | | > > > > > > > | | 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 | int numBytes, int rangeStart, int rangeLength, int x, int y, double angle); #pragma mark - #pragma mark Font Helpers: /* * To avoid an extra copy, a TKNSString object wraps a Tcl_DString with an * NSString that uses the DString's buffer as its character buffer. */ @implementation TKNSString - (instancetype)initWithTclUtfBytes:(const void *)bytes length:(NSUInteger)len { if (self = [self init]) { Tcl_DStringInit(&_ds); Tcl_UtfToUniCharDString(bytes, len, &_ds); _string = [[NSString alloc] initWithCharactersNoCopy:(unichar *)Tcl_DStringValue(&_ds) length:Tcl_DStringLength(&_ds)>>1 freeWhenDone:NO]; self.UTF8String = _string.UTF8String; } return self; } - (void)dealloc { Tcl_DStringFree(&_ds); [_string release]; [super dealloc]; } - (NSUInteger)length { return _string.length; } - (unichar)characterAtIndex:(NSUInteger)index { return [_string characterAtIndex:index]; } @end /* *--------------------------------------------------------------------------- * * TkUtfAtIndex -- * * Write a sequence of bytes up to length 6 which is an encoding of a UTF-16 * character in an NSString. Also record the unicode code point of the character. * this may be a non-BMP character constructed by reading two surrogates from * the NSString. See the documentation for TKNSString in tkMacOSXPrivate.h. * * Results: * Returns the number of bytes written. * * Side effects: * Bytes are written to the char array referenced by the pointer uni and * the unicode code point is written to the integer referenced by the |
︙ | ︙ | |||
975 976 977 978 979 980 981 | (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) { *lengthPtr = 0; return 0; } if (maxLength > 32767) { maxLength = 32767; } | | | 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 | (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) { *lengthPtr = 0; return 0; } if (maxLength > 32767) { maxLength = 32767; } string = [[TKNSString alloc] initWithTclUtfBytes:source length:numBytes]; if (!string) { length = 0; fit = rangeLength; goto done; } attributedString = [[NSAttributedString alloc] initWithString:string attributes:fontPtr->nsAttributes]; |
︙ | ︙ | |||
1239 1240 1241 1242 1243 1244 1245 | double angle) { const MacFont *fontPtr = (const MacFont *) tkfont; NSString *string; NSMutableDictionary *attributes; NSAttributedString *attributedString; CTTypesetterRef typesetter; | | | | | | | | | | | | | | | > > < | > | > > > > > > | | | < < > < > | 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 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 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 | double angle) { const MacFont *fontPtr = (const MacFont *) tkfont; NSString *string; NSMutableDictionary *attributes; NSAttributedString *attributedString; CTTypesetterRef typesetter; CFIndex start, length; CTLineRef line, full=nil; MacDrawable *macWin = (MacDrawable *) drawable; TkMacOSXDrawingContext drawingContext; CGContextRef context; CGColorRef fg; NSFont *nsFont; CGAffineTransform t; CGFloat width, height, textX = (CGFloat) x, textY = (CGFloat) y; if (rangeStart < 0 || rangeLength <= 0 || rangeStart + rangeLength > numBytes || !TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) { return; } string = [[TKNSString alloc] initWithTclUtfBytes:source length:numBytes]; if (!string) { return; } context = drawingContext.context; fg = TkMacOSXCreateCGColor(gc, gc->foreground); attributes = [fontPtr->nsAttributes mutableCopy]; [attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName]; CFRelease(fg); nsFont = [attributes objectForKey:NSFontAttributeName]; [nsFont setInContext:[NSGraphicsContext graphicsContextWithGraphicsPort: context flipped:NO]]; CGContextSetTextMatrix(context, CGAffineTransformIdentity); attributedString = [[NSAttributedString alloc] initWithString:string attributes:attributes]; typesetter = CTTypesetterCreateWithAttributedString( (CFAttributedStringRef)attributedString); textX += (CGFloat) macWin->xOff; textY += (CGFloat) macWin->yOff; height = drawingContext.portBounds.size.height; textY = height - textY; t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, height); if (angle != 0.0) { t = CGAffineTransformTranslate( CGAffineTransformRotate( CGAffineTransformTranslate(t, textX, textY), angle*PI/180.0), -textX, -textY); } CGContextConcatCTM(context, t); start = Tcl_NumUtfChars(source, rangeStart); length = Tcl_NumUtfChars(source, rangeStart + rangeLength) - start; line = CTTypesetterCreateLine(typesetter, CFRangeMake(start, length)); if (start > 0) { /* * We are only drawing part of the string. To compute the x coordinate * of the part we are drawing we subtract its typographical length from * the typographical length of the full string. This accounts for the * kerning after the initial part of the string. */ full = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start + length)); width = CTLineGetTypographicBounds(full, NULL, NULL, NULL); CFRelease(full); textX += (width - CTLineGetTypographicBounds(line, NULL, NULL, NULL)); } CGContextSetTextPosition(context, textX, textY); CTLineDraw(line, context); CFRelease(line); CFRelease(typesetter); [attributedString release]; [string release]; [attributes release]; TkMacOSXRestoreDrawingContext(&drawingContext); |
︙ | ︙ |
Changes to macosx/tkMacOSXInit.c.
︙ | ︙ | |||
71 72 73 74 75 76 77 | - (void) _setupApplicationNotifications { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; #define observe(n, s) \ [nc addObserver:self selector:@selector(s) name:(n) object:nil] observe(NSApplicationDidBecomeActiveNotification, applicationActivate:); | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | - (void) _setupApplicationNotifications { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; #define observe(n, s) \ [nc addObserver:self selector:@selector(s) name:(n) object:nil] observe(NSApplicationDidBecomeActiveNotification, applicationActivate:); observe(NSApplicationWillResignActiveNotification, applicationDeactivate:); observe(NSApplicationDidUnhideNotification, applicationShowHide:); observe(NSApplicationDidHideNotification, applicationShowHide:); observe(NSApplicationDidChangeScreenParametersNotification, displayChanged:); observe(NSTextInputContextKeyboardSelectionDidChangeNotification, keyboardChanged:); #undef observe } |
︙ | ︙ |
Changes to macosx/tkMacOSXKeyEvent.c.
1 2 3 4 5 6 7 8 9 | /* * tkMacOSXKeyEvent.c -- * * This file implements functions that decode & handle keyboard events on * MacOS X. * * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]> * Copyright (c) 2012 Adrian Robert. | | > > > > > > | | < | < < < < | | | | > > > | > | < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | > | | | > | | | < < | < > | | | > > > | > > | > > > > > > | < | > | < < < < < > < < < < | < | | < < < > | > > > | > > > > > > > > | | > > | > > > > > > > > > > > | > | < < | | | > | < < < < | < < > | | > > > > | > > > > | < < < < | | < < < < > | | < < | < > > > | > > < | < < | | | | > | | > | > > > > > | > | > > > > | > > > > > | > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | /* * tkMacOSXKeyEvent.c -- * * This file implements functions that decode & handle keyboard events on * MacOS X. * * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]> * Copyright (c) 2012 Adrian Robert. * Copyright 2015-2020 Marc Culler. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMacOSXInt.h" #include "tkMacOSXConstants.h" #include "tkMacOSXWm.h" /* * See tkMacOSXPrivate.h for macros related to key event processing. */ /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_KEYBOARD #endif */ #define NS_KEYLOG 0 #define XEVENT_MOD_MASK (ControlMask | Mod1Mask | Mod3Mask | Mod4Mask) static Tk_Window keyboardGrabWinPtr = NULL; /* Current keyboard grab window. */ static NSWindow *keyboardGrabNSWindow = nil; /* Its underlying NSWindow.*/ static NSModalSession modalSession = nil; static BOOL processingCompose = NO; static Tk_Window composeWin = NULL; static int caret_x = 0, caret_y = 0, caret_height = 0; static void setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers); static void setXEventPoint(XEvent *xEvent, Tk_Window tkwin, NSWindow *w); static NSUInteger textInputModifiers; #pragma mark TKApplication(TKKeyEvent) @implementation TKApplication(TKKeyEvent) - (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent { #ifdef TK_MAC_DEBUG_EVENTS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent); #endif NSWindow *w = [theEvent window]; TkWindow *winPtr = TkMacOSXGetTkWindow(w), *grabWinPtr, *focusWinPtr; Tk_Window tkwin = (Tk_Window) winPtr; NSEventType type = [theEvent type]; NSUInteger virtual = [theEvent keyCode]; NSUInteger modifiers = ([theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask); XEvent xEvent; MacKeycode macKC; UniChar keychar = 0; Bool can_input_text, has_modifiers = NO, use_text_input = NO; static NSUInteger savedModifiers = 0; static NSMutableArray *nsEvArray = nil; if (nsEvArray == nil) { nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1]; processingCompose = NO; } if (!winPtr) { return theEvent; } /* * If a local grab is in effect, key events for windows in the * grabber's application are redirected to the grabber. Key events * for other applications are delivered normally. If a global * grab is in effect all key events are redirected to the grabber. */ grabWinPtr = winPtr->dispPtr->grabWinPtr; if (grabWinPtr) { if (winPtr->dispPtr->grabFlags || /* global grab */ grabWinPtr->mainPtr == winPtr->mainPtr){ /* same application */ winPtr =winPtr->dispPtr->focusPtr; tkwin = (Tk_Window) winPtr; } } /* * Extract the unicode character from KeyUp and KeyDown events. */ if (type == NSKeyUp || type == NSKeyDown) { if ([[theEvent characters] length] > 0) { keychar = [[theEvent characters] characterAtIndex:0]; /* * Currently, real keys always send BMP characters, but who knows? */ if (CFStringIsSurrogateHighCharacter(keychar)) { UniChar lowChar = [[theEvent characters] characterAtIndex:1]; keychar = CFStringGetLongCharacterForSurrogatePair( keychar, lowChar); } } else { /* * This is a dead key, such as Option-e, so it should go to the * TextInputClient. */ use_text_input = YES; } /* * Apple uses 0x10 for unrecognized keys. */ if (keychar == 0x10) { keychar = UNKNOWN_KEYCHAR; } #if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1 TKLog(@"-[%@(%p) %s] repeat=%d mods=%x char=%x code=%lu c=%d type=%d", [self class], self, _cmd, (type == NSKeyDown) && [theEvent isARepeat], modifiers, keychar, virtual, w, type); #endif } /* * Build a skeleton XEvent. We need to build it here, even if we will not * send it, so we can pass it to TkFocusKeyEvent to determine whether the * target widget can input text. */ setupXEvent(&xEvent, tkwin, modifiers); has_modifiers = xEvent.xkey.state & XEVENT_MOD_MASK; focusWinPtr = TkFocusKeyEvent(winPtr, &xEvent); if (focusWinPtr == NULL) { TKContentView *contentView = [w contentView]; /* * This NSEvent is being sent to a window which does not have focus. * This could mean, for example, that the user deactivated the Tk app * while the NSTextInputClient's popup character selection window was * still open. We attempt to abandon any ongoing composition operation * and discard the event. */ [contentView cancelComposingText]; return theEvent; } can_input_text = ((focusWinPtr->flags & TK_CAN_INPUT_TEXT) != 0); #if (NS_KEYLOG) TKLog(@"keyDown: %s compose sequence.\n", processingCompose == YES ? "Continue" : "Begin"); #endif /* * Decide whether this event should be processed with the NSTextInputClient * protocol. */ if (processingCompose || (type == NSKeyDown && can_input_text && !has_modifiers && IS_PRINTABLE(keychar)) ) { use_text_input = YES; } /* * If we are processing this KeyDown event as an NSTextInputClient we do * not queue an XEvent. We pass the NSEvent to our interpretKeyEvents * method. When the composition sequence is complete, the callback method * insertText: replacementRange will be called. That method generates a * keyPress XEvent with the selected character. */ if (use_text_input) { textInputModifiers = modifiers; /* * In IME the Enter key is used to terminate a composition sequence. * When there are multiple choices of input text available, and the * user's selected choice is not the default, it may be necessary to * hit the Enter key multiple times before the text is accepted and * rendered (See ticket 39de9677aa]). So when sending an Enter key * during composition, we continue sending Enter keys until the * inputText method has cleared the processingCompose flag. */ if (processingCompose && [theEvent keyCode] == 36) { [nsEvArray addObject: theEvent]; while(processingCompose) { [[w contentView] interpretKeyEvents: nsEvArray]; } [nsEvArray removeObject: theEvent]; } else { [nsEvArray addObject: theEvent]; [[w contentView] interpretKeyEvents: nsEvArray]; [nsEvArray removeObject: theEvent]; } return theEvent; } /* * We are not handling this event as an NSTextInputClient, so we need to * finish constructing the XEvent and queue it. */ macKC.v.o_s = ((modifiers & NSShiftKeyMask ? INDEX_SHIFT : 0) | (modifiers & NSAlternateKeyMask ? INDEX_OPTION : 0)); macKC.v.virtual = virtual; switch (type) { case NSFlagsChanged: /* * This XEvent is a simulated KeyPress or KeyRelease event for a * modifier key. To determine the type, note that the highest bit * where the flags differ is 1 if and only if it is a KeyPress. The * modifiers are saved so we can detect the next flag change. */ xEvent.xany.type = modifiers > savedModifiers ? KeyPress : KeyRelease; savedModifiers = modifiers; /* * Set the keychar to MOD_KEYCHAR as a signal to TkpGetKeySym (see * tkMacOSXKeyboard.c) that this is a modifier key event. */ keychar = MOD_KEYCHAR; break; case NSKeyUp: xEvent.xany.type = KeyRelease; break; case NSKeyDown: xEvent.xany.type = KeyPress; break; default: return theEvent; /* Unrecognized key event. */ } macKC.v.keychar = keychar; xEvent.xkey.keycode = macKC.uint; /* * Set the trans_chars for keychars outside of the private-use range. */ setXEventPoint(&xEvent, tkwin, w); if (IS_PRINTABLE(keychar)) { int length = TkUniCharToUtf(keychar, xEvent.xkey.trans_chars); xEvent.xkey.trans_chars[length] = 0; } /* * Finally we can queue the XEvent, inserting a KeyRelease before a * repeated KeyPress. */ if (type == NSKeyDown && [theEvent isARepeat]) { xEvent.xany.type = KeyRelease; Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); xEvent.xany.type = KeyPress; } if (xEvent.xany.type == KeyPress) { } Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); return theEvent; } @end @implementation TKContentView |
︙ | ︙ | |||
278 279 280 281 282 283 284 | /* * Implementation of the NSTextInputClient protocol. */ /* [NSTextInputClient inputText: replacementRange:] is called by * interpretKeyEvents when a composition sequence is complete. It is also | | | | > > > < < > | > < > > | | < > > | | | | | | | > > > > | > > > > > > > > > > > > > > > > > | > | > > > > > > < | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 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 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | /* * Implementation of the NSTextInputClient protocol. */ /* [NSTextInputClient inputText: replacementRange:] is called by * interpretKeyEvents when a composition sequence is complete. It is also * called when we delete working text. In that case the call is followed * immediately by doCommandBySelector: deleteBackward: */ - (void)insertText: (id)aString replacementRange: (NSRange)repRange { int i, len, state; XEvent xEvent; NSString *str, *keystr, *lower; TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); Tk_Window tkwin = (Tk_Window) winPtr; Bool sendingIMEText = NO; str = ([aString isKindOfClass: [NSAttributedString class]]) ? [aString string] : aString; len = [str length]; if (NS_KEYLOG) { TKLog(@"insertText '%@'\tlen = %d", aString, len); } /* * Clear any working text. */ if (privateWorkingText != nil) { sendingIMEText = YES; [self deleteWorkingText]; } /* * Insert the string as a sequence of keystrokes. */ setupXEvent(&xEvent, tkwin, textInputModifiers); setXEventPoint(&xEvent, tkwin, [self window]); xEvent.xany.type = KeyPress; /* * Apple evidently sets location to 0 to signal that an accented letter has * been selected from the accent menu. An unaccented letter has already * been displayed and we need to erase it before displaying the accented * letter. */ if (repRange.location == 0) { Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr; TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL); } /* * Next we generate an XEvent for each unicode character in our string. * This string could contain non-BMP characters, for example if the * emoji palette was used. * * NSString uses UTF-16 internally, which means that a non-BMP character is * represented by a sequence of two 16-bit "surrogates". We record this in * the XEvent by setting the low order 21-bits of the keycode to the UCS-32 * value value of the character and the virtual keycode in the high order * byte to the special value NON_BMP. In principle we could set the * trans_chars string to the UTF-8 string for the non-BMP character. * However, that will not work when TCL_UTF_MAX is set to 3, as is the case * for Tcl 8.6. A workaround used internally by Tcl 8.6 is to encode each * surrogate as a 3-byte sequence using the UTF-8 algorithm (ignoring the * fact that the UTF-8 encoding specification does not allow encoding * UTF-16 surrogates). This gives a 6-byte encoding of the non-BMP * character which we write into the trans_chars field of the XEvent. */ state = xEvent.xkey.state; for (i = 0; i < len; i++) { unsigned int code; UniChar keychar; MacKeycode macKC = {0}; keychar = [str characterAtIndex:i]; macKC.v.keychar = keychar; if (CFStringIsSurrogateHighCharacter(keychar)) { UniChar lowChar = [str characterAtIndex:i+1]; macKC.v.keychar = CFStringGetLongCharacterForSurrogatePair( (UniChar)keychar, lowChar); macKC.v.virtual = NON_BMP_VIRTUAL; } else if (repRange.location == 0 || sendingIMEText) { macKC.v.virtual = REPLACEMENT_VIRTUAL; } else { macKC.uint = TkMacOSXAddVirtual(macKC.uint); xEvent.xkey.state |= INDEX2STATE(macKC.x.xvirtual); } keystr = [[NSString alloc] initWithCharacters:&keychar length:1]; lower = [keystr lowercaseString]; if (![keystr isEqual: lower]) { macKC.v.o_s |= INDEX_SHIFT; xEvent.xkey.state |= ShiftMask; } if (xEvent.xkey.state & Mod2Mask) { macKC.v.o_s |= INDEX_OPTION; } TkUtfAtIndex(str, i, xEvent.xkey.trans_chars, &code); if (code > 0xFFFF){ i++; } xEvent.xkey.keycode = macKC.uint; xEvent.xany.type = KeyPress; Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); xEvent.xkey.state = state; } } /* * This required method is allowed to return nil. */ - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)theRange |
︙ | ︙ | |||
381 382 383 384 385 386 387 | TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr; NSString *temp; NSString *str; str = ([aString isKindOfClass: [NSAttributedString class]]) ? [aString string] : aString; | < | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr; NSString *temp; NSString *str; str = ([aString isKindOfClass: [NSAttributedString class]]) ? [aString string] : aString; if (focusWin) { /* * Remember the widget where the composition is happening, in case it * gets defocussed during the composition. */ |
︙ | ︙ | |||
412 413 414 415 416 417 418 419 420 421 | } /* * Use our insertText method to display the marked text. */ TkSendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL); temp = [str copy]; [self insertText: temp replacementRange:repRange]; privateWorkingText = temp; | > < < < < < < < < < < < < | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 | } /* * Use our insertText method to display the marked text. */ TkSendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL); processingCompose = YES; temp = [str copy]; [self insertText: temp replacementRange:repRange]; privateWorkingText = temp; TkSendVirtualEvent(focusWin, "TkEndIMEMarkedText", NULL); } - (BOOL)hasMarkedText { return privateWorkingText != nil; } - (NSRange)markedRange { NSRange rng = privateWorkingText != nil ? NSMakeRange(0, [privateWorkingText length]) : NSMakeRange(NSNotFound, 0); if (NS_KEYLOG) { TKLog(@"markedRange request"); } return rng; } - (void)unmarkText { if (NS_KEYLOG) { TKLog(@"unmarkText"); } [self deleteWorkingText]; processingCompose = NO; } /* * Called by the system to get a position for popup character selection windows * such as a Character Palette, or a selection menu for IME. */ - (NSRect)firstRectForCharacterRange: (NSRange)theRange |
︙ | ︙ | |||
569 570 571 572 573 574 575 576 577 578 579 580 581 582 | privateWorkingText = nil; processingCompose = NO; if (composeWin) { TkSendVirtualEvent(composeWin, "TkClearIMEMarkedText", NULL); } } } @end /* * Set up basic fields in xevent for keyboard input. */ static void | > > > > > > > > > > | | | | > > > > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 | privateWorkingText = nil; processingCompose = NO; if (composeWin) { TkSendVirtualEvent(composeWin, "TkClearIMEMarkedText", NULL); } } } - (void)cancelComposingText { if (NS_KEYLOG) { TKLog(@"cancelComposingText"); } [self deleteWorkingText]; processingCompose = NO; } @end /* * Set up basic fields in xevent for keyboard input. */ static void setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers) { unsigned int state = 0; Display *display = Tk_Display(tkwin); if (tkwin == NULL) { return; } if (modifiers) { state = (modifiers & NSAlphaShiftKeyMask ? LockMask : 0) | (modifiers & NSShiftKeyMask ? ShiftMask : 0) | (modifiers & NSControlKeyMask ? ControlMask : 0) | (modifiers & NSCommandKeyMask ? Mod1Mask : 0) | (modifiers & NSAlternateKeyMask ? Mod2Mask : 0) | (modifiers & NSNumericPadKeyMask ? Mod3Mask : 0) | (modifiers & NSFunctionKeyMask ? Mod4Mask : 0) ; } memset(xEvent, 0, sizeof(XEvent)); xEvent->xany.serial = LastKnownRequestProcessed(display); xEvent->xany.display = Tk_Display(tkwin); xEvent->xany.window = Tk_WindowId(tkwin); xEvent->xkey.root = XRootWindow(display, 0); xEvent->xkey.time = TkpGetMS(); xEvent->xkey.state = state; xEvent->xkey.same_screen = true; /* No need to initialize other fields implicitly here, * because of the memset() above. */ } static void setXEventPoint( XEvent *xEvent, Tk_Window tkwin, NSWindow *w) { TkWindow *winPtr = (TkWindow *) tkwin; NSPoint local = [w mouseLocationOutsideOfEventStream]; NSPoint global = [w tkConvertPointToScreen: local]; int win_x, win_y; if (Tk_IsEmbedded(winPtr)) { TkWindow *contPtr = TkpGetOtherWindow(winPtr); if (Tk_IsTopLevel(contPtr)) { local.x -= contPtr->wmInfoPtr->xInParent; local.y -= contPtr->wmInfoPtr->yInParent; } else { TkWindow *topPtr = TkMacOSXGetHostToplevel(winPtr)->winPtr; local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x); local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y); } } else if (winPtr->wmInfoPtr != NULL) { local.x -= winPtr->wmInfoPtr->xInParent; local.y -= winPtr->wmInfoPtr->yInParent; } tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y); local.x = win_x; local.y = win_y; global.y = TkMacOSXZeroScreenHeight() - global.y; xEvent->xbutton.x = local.x; xEvent->xbutton.y = local.y; xEvent->xbutton.x_root = global.x; xEvent->xbutton.y_root = global.y; } #pragma mark - /* *---------------------------------------------------------------------- * * XGrabKeyboard -- |
︙ | ︙ | |||
702 703 704 705 706 707 708 | } /* *---------------------------------------------------------------------- * * Tk_SetCaretPos -- * | | > > > | > > | | > > > | > < | > > > > > > | | > > > > | | > > < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 | } /* *---------------------------------------------------------------------- * * Tk_SetCaretPos -- * * This enables correct placement of the popups used for character * selection by the NSTextInputClient. It gets called by text entry * widgets whenever the cursor is drawn. It does nothing if the widget's * NSWindow is not the current KeyWindow. Otherwise it udpates the * display's caret structure and records the caret geometry in static * variables for use by the NSTextInputClient implementation. Any * widget passed to this function will be marked as being able to input * text by setting the TK_CAN_INPUT_TEXT flag. * * Results: * None * * Side effects: * Sets the CAN_INPUT_TEXT flag on the widget passed as tkwin. May update * the display's caret structure as well as the static variables caret_x, * caret_y and caret_height. * *---------------------------------------------------------------------- */ void Tk_SetCaretPos( Tk_Window tkwin, int x, int y, int height) { TkWindow *winPtr = (TkWindow *) tkwin; TkCaret *caretPtr = &(winPtr->dispPtr->caret); NSWindow *w = TkMacOSXDrawableWindow(Tk_WindowId(tkwin)); /* * Register this widget as being capable of text input, so we know we * should process (appropriate) key events for this window with the * NSTextInputClient protocol. */ winPtr->flags |= TK_CAN_INPUT_TEXT; if (w && ![w isKeyWindow]) { return; } if ((caretPtr->winPtr == winPtr && caretPtr->x == x) && (caretPtr->y == y)) { return; } /* * Update the display's caret information. */ caretPtr->winPtr = winPtr; caretPtr->x = x; caretPtr->y = y; caretPtr->height = height; /* * Record the caret geometry in static variables for use when processing * key events. We use the TKContextView coordinate system for this. */ caret_height = height; while (!Tk_IsTopLevel(tkwin)) { x += Tk_X(tkwin); y += Tk_Y(tkwin); tkwin = Tk_Parent(tkwin); if (tkwin == NULL) { return; } } caret_x = x; caret_y = Tk_Height(tkwin) - y; } /* * Local Variables: * mode: objc * c-basic-offset: 4 * fill-column: 79 * coding: utf-8 * End: */ |
Changes to macosx/tkMacOSXKeyboard.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* * tkMacOSXKeyboard.c -- * * Routines to support keyboard events on the Macintosh. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" #include "tkMacOSXConstants.h" /* | > > > > > > > | < > | > > > > > | | < < < < < | | < > > > | < < < > > > > > | < < < < | | | | | | | | | | > > > > | < | < < < | | | | | | > > > | < < < | | | > > > > > > > > > > | < < < < > > > > > > | < < > > > > > > | < < < < < < < < < < < < < < < | < < > > > > > > > > > > > > > | < < < < < < < < < > | > | < < > | < < > > | | | | > < > | > > | | | < | | | > | < < < < | | > | > | | > > | | > > > > > | > > > > > > > > > > > | > > > > | | | | > | | > | | > > | < > | | < | < | | > | > > > > | < < < | | > | | < | | < | | | | > | > | < < > > > | > | | < | > | > | > | | | > > > | | | < < > > | | | | | | < < | < > | | | > > | > | < < > > | > > | | < < < < < | | | | | > > > > > > > | | | | | > < > > > > < < < < < < | < | | | < < < < | | | | | | > | | 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 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 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 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 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 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | /* * tkMacOSXKeyboard.c -- * * Routines to support keyboard events on the Macintosh. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]> * Copyright (c) 2020 Marc Culler * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" #include "tkMacOSXConstants.h" #include "tkMacOSXKeysyms.h" /* * About keyboards * --------------- * Keyboards are complicated. This long comment is an attempt to provide * enough information about them to make it possible to read and understand * the code in this file. * * Every key on a keyboard is identified by a number between 0 and 127. In * macOS, pressing or releasing a key on the keyboard generates an NSEvent of * type KeyDown, KeyUp or FlagsChanged. The 8-bit identifier of the key that * was involved in this event is provided in the attribute [NSEvent keyCode]. * Apple also refers to this number as a "Virtual KeyCode". In this file, to * avoid confusion with other uses of the word keycode, we will refer to this * key identifier as a "virtual keycode", usually the value of a variable named * "virtual". * * Some of the keys on a keyboard, such as the Shift, Option, Command or * Control keys, are "modifier" keys. The effect of pressing or releasing a * key depends on three quantities: * - which key is being pressed or released * - which modifier keys are being held down at the moment * - the current keyboard layout * If the key is a modifier key then the effect of pressing or releasing it is * only to change the list of which modifier keys are being held down. Apple * reports this by sending an NSEvent of type FlagsChanged. X11 reports this * as a KeyPress or KeyRelease event for the modifier key. Note that there may * be combinations of modifier key states and key presses which have no effect. * * In X11 every meaningful effect from a key action is identified by a 16 bit * value known as a keysym. Every keysym has an associated string name, also * known as a keysym. The Tk bind command uses the X11 keysym string to * specify a key event which should invoke a certain action and it provides the * numeric and symbolic keysyms to the bound proc as %N and %K respectively. * An X11 XEvent which reports a KeyPress or KeyRelease does not include the * keysym. Instead it includes a platform-specific numerical value called a * keycode which is available to the bound procedure as %k. A platform port of * Tk must provide functions which convert between keycodes and numerical * keysyms. Conversion between numerical and symbolic keysyms is provided by * the generic Tk code, although platforms are allowed to provide their own by * defining the XKeysymToString and XStringToKeysym functions and undefining * the macro REDO_KEYSYM_LOOKUP. This macOS port uses the conversion provided * by the generic code. * * When the keyboard focus is on a Tk widget which provides text input, there * are some X11 KeyPress events which cause text to be inserted. We will call * these "printable" events. On macOS the text which should be inserted is * contained in the xkeys.trans_chars field of a key XEvent as a * null-terminated unicode string encoded with a special Tcl encoding. The * value of the trans_chars string in an Xevent depends on more than the three * items above. It may also depend on the sequence of keypresses that preceded * the one being reported by the XEvent. For example, on macOS an <Alt-e> * event does not cause text to be inserted but a following <a> event causes an * accented 'a' to be inserted. The events in such a composition sequence, * other than the final one, are known as "dead-key" events. * * MacOS packages the information described above in a different way. Every * meaningful effect from a key action *other than changing the state of * modifier keys* is identified by a unicode string which is provided as the * [NSEvent characters] attribute of a KeyDown or KeyUp event. FlagsChanged * events do not have characters. In principle, the characters attribute could * be an arbitrary unicode string but in practice it is always a single UTF-16 * character which we usually store in a variable named keychar. While the * keychar is a legal unicode code point, it does not necessarily represent a * glyph. MacOS uses unicode code points in the private-use range 0xF700-0xF8FF * for non-printable events which have no associated ASCII code point. For * example, pressing the F2 key generates an NSEvent with the character 0xF705, * the Backspace key produces 0x7F (ASCII del) and the Delete key produces * 0xF728. * * With the exception of modifier keys, it is possible to translate between * numerical X11 keysyms and macOS keychars; this file constructs Tcl hash * tables to do this job, using data defined in the file tkMacOSXKeysyms.h. * The code here adopts the convention that the keychar of any modifier key * is MOD_KEYCHAR. Keys which do not appear on any Macintosh keyboard, such * as the Menu key on PC keyboards, are assigned UNKNOWN_KEYCHAR. * * The macosx platform-specific scheme for generating a keycode when mapping an * NSEvent of type KeyUp, KeyDown or FlagsChanged to an XEvent of type KeyPress * or KeyRelease is as follows: * keycode = (virtual << 24) | index << 22 | keychar * where index is a 2-bit quantity whose bits indicate the state of the Option * and Shift keys. * * A few remarks are in order. First, we are using 32 bits for the keycode and * we are allowing room for up to 22 bits for the keychar. This means that * there is enough room in the keycode to hold a UTF-32 character, which only * requires 21 bits. Second, the KeyCode type for the keycode field in an * XEvent is currently defined as unsigned int, which was modified from the * unsigned short used in X11 in order to accomodate macOS. Finally, there is * no obstruction to generating KeyPress events for keys that represent letters * which do not exist on the current keyboard layout. And different keyboard * layouts can assign a given letter to different keys. So we need a * convention for what value to assign to "virtual" when computing the keycode * for a generated event. The convention used here is as follows: If there is * a key on the current keyboard which produces the keychar, use the virtual * keycode of that key. Otherwise set virtual = NO_VIRTUAL. */ /* * See tkMacOSXPrivate.h for macros and structures related to key event processing. */ /* * Hash tables and array used to translate between various key attributes. */ static Tcl_HashTable special2keysym; /* Special virtual keycode to keysym */ static Tcl_HashTable keysym2keycode; /* keysym to XEvent keycode */ static Tcl_HashTable keysym2unichar; /* keysym to unichar */ static Tcl_HashTable unichar2keysym; /* unichar to X11 keysym */ static Tcl_HashTable unichar2xvirtual; /* unichar to virtual with index */ static UniChar xvirtual2unichar[512]; /* virtual with index to unichar */ /* * Flags. */ static BOOL initialized = NO; static BOOL keyboardChanged = YES; /* * Prototypes for static functions used in this file. */ static void InitHashTables(void); static void UpdateKeymaps(void); static int KeyDataToUnicode(UniChar *uniChars, int maxChars, UInt16 keyaction, UInt32 virtual, UInt32 modifiers, UInt32 * deadKeyStatePtr); #pragma mark TKApplication(TKKeyboard) @implementation TKApplication(TKKeyboard) - (void) keyboardChanged: (NSNotification *) notification { #ifdef TK_MAC_DEBUG_NOTIFICATIONS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); #endif keyboardChanged = YES; UpdateKeymaps(); } @end #pragma mark - /* *---------------------------------------------------------------------- * * InitHashTables -- * * Creates hash tables used by some of the functions in this file. * * Results: * None. * * Side effects: * Allocates memory & creates some hash tables. * *---------------------------------------------------------------------- */ static void InitHashTables(void) { Tcl_HashEntry *hPtr; const KeyInfo *kPtr; const KeysymInfo *ksPtr; int dummy, index; Tcl_InitHashTable(&special2keysym, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(&keysym2keycode, TCL_ONE_WORD_KEYS); for (kPtr = keyArray; kPtr->virtual != 0; kPtr++) { MacKeycode macKC; macKC.v.o_s = 0; hPtr = Tcl_CreateHashEntry(&special2keysym, INT2PTR(kPtr->virtual), &dummy); Tcl_SetHashValue(hPtr, INT2PTR(kPtr->keysym)); hPtr = Tcl_CreateHashEntry(&keysym2keycode, INT2PTR(kPtr->keysym), &dummy); macKC.v.virtual = kPtr->virtual; macKC.v.keychar = kPtr->keychar; Tcl_SetHashValue(hPtr, INT2PTR(macKC.uint)); /* * The Carbon framework does not work for finding the unicode character * of a special key. But that does not depend on the keyboard layout, * so we can record the information here. */ for (index = 3; index >= 0; index--) { macKC.v.o_s = index; xvirtual2unichar[macKC.x.xvirtual] = macKC.x.keychar; } } Tcl_InitHashTable(&keysym2unichar, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(&unichar2keysym, TCL_ONE_WORD_KEYS); for (ksPtr = keysymTable; ksPtr->keysym != 0; ksPtr++) { hPtr = Tcl_CreateHashEntry(&keysym2unichar, INT2PTR(ksPtr->keysym), &dummy); Tcl_SetHashValue(hPtr, INT2PTR(ksPtr->keycode)); hPtr = Tcl_CreateHashEntry(&unichar2keysym, INT2PTR(ksPtr->keycode), &dummy); Tcl_SetHashValue(hPtr, INT2PTR(ksPtr->keysym)); } UpdateKeymaps(); initialized = YES; } /* *---------------------------------------------------------------------- * * UpdateKeymaps -- * * Called when the keyboard changes to update the hash tables that provide * maps between unicode characters and virtual keycodes with indexes. In * order for the map from characters to virtual keycodes to be * well-defined we have to ignore virtual keycodes for keypad keys, since * each keypad key has the same character as the corresponding key on the * main keyboard. * * Results: * None. * * Side effects: * Initializes, if necessary, and updates the unichar2xvirtual hash table * and the xvirtual2unichar array. * *---------------------------------------------------------------------- */ static void UpdateKeymaps() { static Bool keymapInitialized = false; Tcl_HashEntry *hPtr; int virtual, index, dummy; if (!keymapInitialized) { Tcl_InitHashTable(&unichar2xvirtual, TCL_ONE_WORD_KEYS); keymapInitialized = true; } else { Tcl_DeleteHashTable(&unichar2xvirtual); Tcl_InitHashTable(&unichar2xvirtual, TCL_ONE_WORD_KEYS); } /* * This loop goes backwards so that a lookup by keychar will provide the * minimal modifier mask. Simpler combinations will overwrite more complex * ones when constructing the table. */ for (index = 3; index >= 0; index--) { for (virtual = 0; virtual < 128; virtual++) { MacKeycode macKC; macKC.v = (keycode_v) {.virtual = virtual, .o_s = index, .keychar = 0}; int modifiers = INDEX2CARBON(index), result; UniChar keychar = 0; result = KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, virtual, modifiers, NULL); if (keychar == 0x10) { /* * This is a special key, handled in InitHashTables. */ continue; } macKC.v.keychar = keychar; if (! ON_KEYPAD(virtual)) { hPtr = Tcl_CreateHashEntry(&unichar2xvirtual, INT2PTR(macKC.x.keychar), &dummy); Tcl_SetHashValue(hPtr, INT2PTR(macKC.x.xvirtual)); } xvirtual2unichar[macKC.x.xvirtual] = macKC.x.keychar; } } } /* *---------------------------------------------------------------------- * * KeyDataToUnicode -- * * Given MacOS key event data this function generates the keychar. It * does this by using OS resources from the Carbon framework. Note that * the Carbon functions used here are not aware of the keychars in the * private-use range which macOS now uses for special keys. For those * keys this function returns 0x10 (ASCII dle). * * The parameter deadKeyStatePtr can be NULL, if no deadkey handling is * needed (which is always the case here). * * This function is called in XKeycodeToKeysym and UpdateKeymaps. * * Results: * The number of characters generated if any, 0 if we are waiting for * another byte of a dead-key sequence. * * Side Effects: * Fills in the uniChars array with a Unicode string. * *---------------------------------------------------------------------- */ static int KeyDataToUnicode( UniChar *uniChars, int maxChars, UInt16 keyaction, UInt32 virtual, UInt32 modifiers, UInt32 *deadKeyStatePtr) { static const void *layoutData = NULL; static UInt32 keyboardType = 0; UniCharCount actuallength = 0; if (keyboardChanged) { TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource(); if (currentKeyboardLayout) { CFDataRef keyLayoutData = (CFDataRef) TISGetInputSourceProperty( currentKeyboardLayout, kTISPropertyUnicodeKeyLayoutData); if (keyLayoutData) { layoutData = CFDataGetBytePtr(keyLayoutData); keyboardType = LMGetKbdType(); } CFRelease(currentKeyboardLayout); } keyboardChanged = 0; } if (layoutData) { OptionBits options = 0; UInt32 dummyState; OSStatus err; virtual &= 0xFF; modifiers = (modifiers >> 8) & 0xFF; if (!deadKeyStatePtr) { options = kUCKeyTranslateNoDeadKeysMask; dummyState = 0; deadKeyStatePtr = &dummyState; } err = ChkErr(UCKeyTranslate, layoutData, virtual, keyaction, modifiers, keyboardType, options, deadKeyStatePtr, maxChars, &actuallength, uniChars); if (!actuallength && *deadKeyStatePtr) { /* * We are waiting for another key. */ return 0; } *deadKeyStatePtr = 0; if (err != noErr) { actuallength = 0; } } return actuallength; } /* *---------------------------------------------------------------------- * * XKeycodeToKeysym -- * * This is a stub function which translates from the keycode used in an * XEvent to a numerical keysym. On macOS, the display parameter is * ignored and only the the virtual keycode stored in the .virtual bitfield * of a MacKeycode.v. * * Results: * Returns the corresponding numerical keysym, or NoSymbol if the keysym * cannot be found. * * Side effects: * None. * *---------------------------------------------------------------------- */ KeySym XKeycodeToKeysym( Display* display, KeyCode keycode, int index) { Tcl_HashEntry *hPtr; MacKeycode macKC; (void) display; /*unused*/ int modifiers, result; UniChar keychar = 0; if (!initialized) { InitHashTables(); } macKC.uint = keycode; macKC.v.o_s = index; /* * First check if the virtual keycode corresponds to a special key, such as * an Fn function key or Tab, Backspace, Home, End, etc. */ hPtr = Tcl_FindHashEntry(&special2keysym, INT2PTR(macKC.v.virtual)); if (hPtr != NULL) { return (KeySym) Tcl_GetHashValue(hPtr); } /* * If the virtual value in this keycode does not correspond to an actual * key in the current keyboard layout, try using its keychar to look up a * keysym. */ if (macKC.v.virtual > 127) { hPtr = Tcl_FindHashEntry(&unichar2keysym, INT2PTR(macKC.v.keychar)); if (hPtr != NULL) { return (KeySym) Tcl_GetHashValue(hPtr); } } /* * If the virtual keycode does belong to a key, use the virtual and the * Option-Shift from index to look up a keychar by using the Carbon * Framework; then translate the keychar to a keysym using the * unicode2keysym hash table. */ modifiers = INDEX2CARBON(macKC.v.o_s); result = KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, macKC.v.virtual, modifiers, NULL); if (result) { hPtr = Tcl_FindHashEntry(&unichar2keysym, INT2PTR(keychar)); if (hPtr != NULL) { return (KeySym) Tcl_GetHashValue(hPtr); } } return NoSymbol; } /* *---------------------------------------------------------------------- * * TkpGetString -- * * This is a stub function which retrieves the string stored in the * transchars field of an XEvent and converts it to a Tcl_DString. * * Results: * Returns a pointer to the string value of the DString. * * Side effects: * None. * *---------------------------------------------------------------------- */ |
︙ | ︙ | |||
451 452 453 454 455 456 457 | } /* *---------------------------------------------------------------------- * * XGetModifierMapping -- * | | > | < < < < < < | > | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 | } /* *---------------------------------------------------------------------- * * XGetModifierMapping -- * * X11 stub function to get the keycodes used as modifiers. This * is never called by the macOS port. * * Results: * Returns a newly allocated modifier map. * * Side effects: * Allocates a new modifier map data structure. * *---------------------------------------------------------------------- */ XModifierKeymap * XGetModifierMapping( Display *display) { XModifierKeymap *modmap; modmap = ckalloc(sizeof(XModifierKeymap)); modmap->max_keypermod = 0; modmap->modifiermap = NULL; return modmap; } /* *---------------------------------------------------------------------- * * XFreeModifiermap -- * * Deallocates a modifier map that was created by XGetModifierMapping. * This is also never called by the macOS port. * * Results: * None. * * Side effects: * Frees the datastructure referenced by modmap. * |
︙ | ︙ | |||
512 513 514 515 516 517 518 | } /* *---------------------------------------------------------------------- * * XKeysymToString, XStringToKeysym -- * | | | | | | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 | } /* *---------------------------------------------------------------------- * * XKeysymToString, XStringToKeysym -- * * These X11 stub functions map keysyms to strings & strings to keysyms. * A platform can do its own conversion by defining these and undefining * REDO_KEYSYM_LOOKUP. The macOS port defines REDO_KEYSYM_LOOKUP so these * are never called and Tk does the conversion for us. * * Results: * None. * * Side effects: * None. * |
︙ | ︙ | |||
543 544 545 546 547 548 549 | { return NoSymbol; } /* *---------------------------------------------------------------------- * | | < < < < < < < < < < < < | < < < < < < < < < < < | < < < < < < | < < < < < | < < < < < < < < < < | < < < < | < < < < < | < < < < | < < | < < < < < < < < < < < < < | > | > | | > < | < | > > > | > > | > | > > > | > > > > | > > > > > > | > | | < | < < < < < > < > > > > > < < < < < < < < < > | > | > > > > > > > > | | < | | > > > > > > > > > > | | < > | < < | | | | | > | < | > | | | < > > > | < | > | | | | | | | < < < < < | | | < | < < < | > < < < < < < | < | < < < < < < < | | < < < < < < < | | | | | | < < < < < < < | < < | | | | | | | < | | | > > > > > < < < | | | | < < < < > | < | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 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 941 942 943 944 945 946 947 948 949 950 951 952 953 | { return NoSymbol; } /* *---------------------------------------------------------------------- * * XKeysymToKeycode -- * * This is a stub function which converts a numerical keysym to the * platform-specific keycode used in a KeyPress or KeyRelease XEvent. * For macOS the keycode is an unsigned int with bitfields described * in the definition of the MacKeycode type. * * Results: * * A macOS KeyCode. See the description of keycodes at the top of this * file and the definition of the MacKeycode type in tkMacOSXPrivate.h. * * Side effects: * None. * *---------------------------------------------------------------------- */ KeyCode XKeysymToKeycode( Display *display, KeySym keysym) { Tcl_HashEntry *hPtr; MacKeycode macKC; if (!initialized) { InitHashTables(); } /* * First check for a special key. */ hPtr = Tcl_FindHashEntry(&keysym2keycode, INT2PTR(keysym)); if (hPtr != NULL) { return (unsigned int) Tcl_GetHashValue(hPtr); } /* * Initialize the keycode as if the keysym cannot be converted to anything * else. */ macKC.v.virtual = NO_VIRTUAL; macKC.v.o_s = 0; macKC.v.keychar = 0; /* * If the keysym is recognized fill in the keychar. Also fill in the * xvirtual field if the key exists on the current keyboard. */ hPtr = Tcl_FindHashEntry(&keysym2unichar, INT2PTR(keysym)); if (hPtr != NULL) { macKC.x.keychar = (unsigned int) Tcl_GetHashValue(hPtr); hPtr = Tcl_FindHashEntry(&unichar2xvirtual, INT2PTR(macKC.x.keychar)); if (hPtr != NULL) { macKC.x.xvirtual = (unsigned int) Tcl_GetHashValue(hPtr); } } return macKC.uint; } /* *---------------------------------------------------------------------- * * TkpSetKeycodeAndState -- * * This function accepts a keysym and an XEvent and sets some fields of * the XEvent. It is used by the event generate command. * * Results: * None * * Side effects: * * Modifies the XEvent. Sets the xkey.keycode to a keycode value formatted * by XKeysymToKeycode and updates the shift and option flags in * xkey.state if either of those modifiers is required to generate the * keysym. Also fills in xkey.trans_chars for printable events. * *---------------------------------------------------------------------- */ void TkpSetKeycodeAndState( Tk_Window tkwin, KeySym keysym, XEvent *eventPtr) { if (keysym == NoSymbol) { eventPtr->xkey.keycode = 0; } else { int eventIndex = STATE2INDEX(eventPtr->xkey.state); MacKeycode macKC; macKC.uint = XKeysymToKeycode(NULL, keysym); /* * We have a virtual keycode and a minimal choice for Shift and Option * modifiers which generates the keychar that corresponds to the * specified keysym. But we might not have the correct keychar yet, * because the xEvent may have specified modifiers beyond our minimal * set. For example, the events described by <Oslash>, <Shift-oslash>, * <Shift-Option-O> and <Shift-Option-o> should all produce the same * uppercase Danish O. So we may need to add the extra modifiers and * do another lookup for the keychar. We don't want to do this for * special keys, however. */ if (macKC.v.o_s != eventIndex) { macKC.v.o_s |= eventIndex; } if (macKC.v.keychar < 0xF700) { UniChar keychar = macKC.v.keychar; NSString *str, *lower, *upper; if (macKC.v.virtual != NO_VIRTUAL) { macKC.x.keychar = xvirtual2unichar[macKC.x.xvirtual]; } else { str = [[NSString alloc] initWithCharacters:&keychar length:1]; lower = [str lowercaseString]; upper = [str uppercaseString]; if (![str isEqual: lower]) { macKC.v.o_s |= INDEX_SHIFT; } if (macKC.v.o_s & INDEX_SHIFT) { macKC.v.keychar = [upper characterAtIndex:0]; } } } eventPtr->xkey.keycode = macKC.uint; eventPtr->xkey.state |= INDEX2STATE(macKC.v.o_s); if (IS_PRINTABLE(macKC.v.keychar)) { int length = TkUniCharToUtf(macKC.v.keychar, eventPtr->xkey.trans_chars); eventPtr->xkey.trans_chars[length] = 0; } } } /* *---------------------------------------------------------------------- * * TkpGetKeySym -- * * This is a stub function called in tkBind.c. Given a KeyPress or * KeyRelease XEvent, it maps the keycode in the event to a numerical * keysym. * * Results: * The return value is the keysym corresponding to eventPtr, or NoSymbol * if no matching keysym could be found. * * Side effects: * In the first call for a given display, calls TkpInitKeymapInfo. * * *---------------------------------------------------------------------- */ KeySym TkpGetKeySym( TkDisplay *dispPtr, /* Display in which to map keycode. */ XEvent *eventPtr) /* Description of X event. */ { KeySym sym; int index; MacKeycode macKC; macKC.uint = eventPtr->xkey.keycode; /* * Refresh the mapping information if it's stale. */ if (dispPtr->bindInfoStale) { TkpInitKeymapInfo(dispPtr); } /* * Modifier key events have a special mac keycode (see tkProcessKeyEvent). */ if (macKC.v.keychar == MOD_KEYCHAR) { switch (macKC.v.virtual) { case 54: return XK_Meta_R; case 55: return XK_Meta_L; case 56: return XK_Shift_L; case 57: return XK_Caps_Lock; case 58: return XK_Alt_L; case 59: return XK_Control_L; case 60: return XK_Shift_R; case 61: return XK_Alt_R; case 62: return XK_Control_R; case 63: return XK_Super_L; default: return NoSymbol; } } /* * Figure out which of the four slots in the keymap vector to use for this * key. Refer to Xlib documentation for more info on how this computation * works. */ index = STATE2INDEX(eventPtr->xkey.state); if (eventPtr->xkey.state & LockMask) { index |= INDEX_SHIFT; } /* * First do the straightforward lookup. */ sym = XKeycodeToKeysym(dispPtr->display, macKC.uint, index); /* * Special handling: If the key was shifted because of Lock, which is only * caps lock on macOS, not shift lock, and if the shifted keysym isn't * upper-case alphabetic, then switch back to the unshifted keysym. */ if ((index & INDEX_SHIFT) && !(eventPtr->xkey.state & ShiftMask)) { if ((sym == NoSymbol) || !Tcl_UniCharIsUpper(sym)) { sym = XKeycodeToKeysym(dispPtr->display, macKC.uint, index & ~INDEX_SHIFT); } } /* * Another bit of special handling: If this is a shifted key and there is * no keysym defined, then use the keysym for the unshifted key. */ if ((index & INDEX_SHIFT) && (sym == NoSymbol)) { sym = XKeycodeToKeysym(dispPtr->display, macKC.uint, index & ~INDEX_SHIFT); } return sym; } /* *-------------------------------------------------------------- * * TkpInitKeymapInfo -- * * This procedure initializes fields in the display that pertain * to modifier keys. * * Results: * None. * * Side effects: * Modifier key information in dispPtr is initialized. * *-------------------------------------------------------------- */ void TkpInitKeymapInfo( TkDisplay *dispPtr) /* Display for which to recompute keymap * information. */ { dispPtr->bindInfoStale = 0; /* * On macOS the caps lock key is always interpreted to mean that alphabetic * keys become uppercase but other keys do not get shifted. (X11 allows * a configuration option which makes the caps lock equivalent to holding * down the shift key.) * There is no offical "Mode_switch" key. */ dispPtr->lockUsage = LU_CAPS; /* This field is no longer used by tkBind.c */ dispPtr->modeModMask = 0; /* The Alt and Meta keys are interchanged on Macintosh keyboards compared * to PC keyboards. These fields could be set to make the Alt key on a PC * keyboard behave likd an Alt key. That would also require interchanging * Mod1Mask and Mod2Mask in tkMacOSXKeyEvent.c. */ dispPtr->altModMask = 0; dispPtr->metaModMask = 0; /* * The modKeyCodes table lists the keycodes that appear in KeyPress or * KeyRelease XEvents for modifier keys. In tkBind.c this table is * searched to determine whether an XEvent corresponds to a modifier key. */ if (dispPtr->modKeyCodes != NULL) { ckfree(dispPtr->modKeyCodes); } dispPtr->numModKeyCodes = NUM_MOD_KEYCODES; dispPtr->modKeyCodes = (KeyCode *)ckalloc(NUM_MOD_KEYCODES * sizeof(KeyCode)); for (int i = 0; i < NUM_MOD_KEYCODES; i++) { dispPtr->modKeyCodes[i] = XKeysymToKeycode(NULL, modKeyArray[i]); } } /* *-------------------------------------------------------------- * * TkMacOSXAddVirtual -- * * This procedure is an internal utility which accepts an unsigned int * that has been partially filled as a MacKeycode, having the Option and * Shift state set in the o_s field and the keychar field set but with the * virtual keycode blank. It looks up the virtual keycode for the keychar * (possibly NO_VIRTUAL) and returns an unsigned int which is a complete * MacKeycode with the looked up virtual keycode added. This is used when * creating XEvents for the unicode characters which are generated by the * NSTextInputClient. * * Results: * An unsigned int which is a complete MacKeycode, including a virtual * keycode which matches the Option-Shift state and keychar. * * Side effects: * None * *-------------------------------------------------------------- */ unsigned TkMacOSXAddVirtual( unsigned int keycode) { MacKeycode macKC; Tcl_HashEntry *hPtr; macKC.uint = keycode; if (!initialized) { InitHashTables(); } hPtr = Tcl_FindHashEntry(&unichar2xvirtual, INT2PTR(macKC.v.keychar)); if (hPtr != NULL) { macKC.x.xvirtual = (unsigned int) Tcl_GetHashValue(hPtr); } else { macKC.v.virtual = NO_VIRTUAL; } return macKC.uint; } /* * Local Variables: * mode: objc * c-basic-offset: 4 * fill-column: 79 * coding: utf-8 * End: */ |
Added macosx/tkMacOSXKeysyms.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 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 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 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 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 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 941 942 943 944 945 946 947 948 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 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 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 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 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 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 | /* * tkMacOSXKeysyms.h -- * * Contains data used for processing key events, some of which was * moved from tkMacOSXKeyboard.c. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]> * Copyright (c) 2020 Marc Culler * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef TKMACOSXKEYSYMS_H #define TKMACOSXKEYSYMS_H 1 /* * This table enumerates the keys on Mac keyboards which do not represent * letters. This is static data -- these keys do not change when the keyboard * layout changes. The unicode representation of a special key which is not a * modifier and does not have an ASCII code point lies in the reserved range * 0xF700 - 0xF8FF. * * The table includes every key listed in Apple's documentation of Function-Key * Unicodes which is not marked as "Not on most Macintosh keyboards", as well * as F20, which is reported to be usable in scripts even though it does not * appear on any Macintosh keyboard. */ typedef struct { int virtual; /* value of [NSEvent keyCode] */ KeySym keysym; /* X11 keysym */ KeyCode keychar; /* XEvent keycode & 0xFFFF */ } KeyInfo; static const KeyInfo keyArray[] = { {36, XK_Return, NSNewlineCharacter}, {48, XK_Tab, NSTabCharacter}, {51, XK_BackSpace, NSDeleteCharacter}, {52, XK_Return, NSNewlineCharacter}, /* Used on some Powerbooks */ {53, XK_Escape, 0x1B}, {54, XK_Meta_R, MOD_KEYCHAR}, {55, XK_Meta_L, MOD_KEYCHAR}, {56, XK_Shift_L, MOD_KEYCHAR}, {57, XK_Caps_Lock, MOD_KEYCHAR}, {58, XK_Alt_L, MOD_KEYCHAR}, {59, XK_Control_L, MOD_KEYCHAR}, {60, XK_Shift_R, MOD_KEYCHAR}, {61, XK_Alt_R, MOD_KEYCHAR}, {62, XK_Control_R, MOD_KEYCHAR}, {63, XK_Super_L, MOD_KEYCHAR}, {64, XK_F17, NSF17FunctionKey}, {65, XK_KP_Decimal, '.'}, {67, XK_KP_Multiply, '*'}, {69, XK_KP_Add, '+'}, {71, XK_Clear, NSClearLineFunctionKey}, /* Numlock on PC */ {75, XK_KP_Divide, '/'}, {76, XK_KP_Enter, NSEnterCharacter}, /* Fn Return */ {78, XK_KP_Subtract, '-'}, {79, XK_F18, NSF18FunctionKey}, {80, XK_F19, NSF19FunctionKey}, {81, XK_KP_Equal, '='}, {82, XK_KP_0, '0'}, {83, XK_KP_1, '1'}, {84, XK_KP_2, '2'}, {85, XK_KP_3, '3'}, {86, XK_KP_4, '4'}, {87, XK_KP_5, '5'}, {88, XK_KP_6, '6'}, {89, XK_KP_7, '7'}, {90, XK_F20, NSF20FunctionKey}, /* For scripting only */ {91, XK_KP_8, '8'}, {92, XK_KP_9, '9'}, {96, XK_F5, NSF5FunctionKey}, {97, XK_F6, NSF6FunctionKey}, {98, XK_F7, NSF7FunctionKey}, {99, XK_F3, NSF3FunctionKey}, {100, XK_F8, NSF8FunctionKey}, {101, XK_F9, NSF9FunctionKey}, {103, XK_F11, NSF11FunctionKey}, {105, XK_F13, NSF13FunctionKey}, {106, XK_F16, NSF16FunctionKey}, {107, XK_F14, NSF14FunctionKey}, {109, XK_F10, NSF10FunctionKey}, {110, XK_Menu, UNKNOWN_KEYCHAR}, {111, XK_F12, NSF12FunctionKey}, {113, XK_F15, NSF15FunctionKey}, {114, XK_Help, NSHelpFunctionKey}, {115, XK_Home, NSHomeFunctionKey}, /* Fn Left */ {116, XK_Page_Up, NSPageUpFunctionKey}, /* Fn Up */ {117, XK_Delete, NSDeleteFunctionKey}, /* Fn Deleete */ {118, XK_F4, NSF4FunctionKey}, {119, XK_End, NSEndFunctionKey}, /* Fn Right */ {120, XK_F2, NSF2FunctionKey}, {121, XK_Page_Down, NSPageDownFunctionKey}, /* Fn Down */ {122, XK_F1, NSF1FunctionKey}, {123, XK_Left, NSLeftArrowFunctionKey}, {124, XK_Right, NSRightArrowFunctionKey}, {125, XK_Down, NSDownArrowFunctionKey}, {126, XK_Up, NSUpArrowFunctionKey}, {0, 0, 0} }; /* * X11 keysyms for modifier keys, in order. This list includes keys * which do not appear on Apple keyboards, such as Shift_Lock and * Super_R. While most systems don't provide events for the "fn" * function key, Apple does. We map it to Super_L when processing a * FlagsChanged NSEvent. */ #define NUM_MOD_KEYCODES 14 static const KeyCode modKeyArray[NUM_MOD_KEYCODES] = { XK_Shift_L, XK_Shift_R, XK_Control_L, XK_Control_R, XK_Caps_Lock, XK_Shift_Lock, XK_Meta_L, XK_Meta_R, XK_Alt_L, XK_Alt_R, XK_Super_L, XK_Super_R, XK_Hyper_L, XK_Hyper_R, }; /* * This table pairs X11 Keysyms for alphanumeric characters with the * unicode code point for that letter. * The data comes from http://www.cl.cam.ac.uk/~mgk25/ucs/keysyms.txt */ typedef struct KeysymInfo { KeySym keysym; KeyCode keycode; } KeysymInfo; const KeysymInfo keysymTable[] = { {0x0020, 0x0020}, /* space */ {0x0021, 0x0021}, /* exclam */ {0x0022, 0x0022}, /* quotedbl */ {0x0023, 0x0023}, /* numbersign */ {0x0024, 0x0024}, /* dollar */ {0x0025, 0x0025}, /* percent */ {0x0026, 0x0026}, /* ampersand */ {0x0027, 0x0027}, /* apostrophe */ {0x0028, 0x0028}, /* parenleft */ {0x0029, 0x0029}, /* parenright */ {0x002a, 0x002a}, /* asterisk */ {0x002b, 0x002b}, /* plus */ {0x002c, 0x002c}, /* comma */ {0x002d, 0x002d}, /* minus */ {0x002e, 0x002e}, /* period */ {0x002f, 0x002f}, /* slash */ {0x0030, 0x0030}, /* 0 */ {0x0031, 0x0031}, /* 1 */ {0x0032, 0x0032}, /* 2 */ {0x0033, 0x0033}, /* 3 */ {0x0034, 0x0034}, /* 4 */ {0x0035, 0x0035}, /* 5 */ {0x0036, 0x0036}, /* 6 */ {0x0037, 0x0037}, /* 7 */ {0x0038, 0x0038}, /* 8 */ {0x0039, 0x0039}, /* 9 */ {0x003a, 0x003a}, /* colon */ {0x003b, 0x003b}, /* semicolon */ {0x003c, 0x003c}, /* less */ {0x003d, 0x003d}, /* equal */ {0x003e, 0x003e}, /* greater */ {0x003f, 0x003f}, /* question */ {0x0040, 0x0040}, /* at */ {0x0041, 0x0041}, /* A */ {0x0042, 0x0042}, /* B */ {0x0043, 0x0043}, /* C */ {0x0044, 0x0044}, /* D */ {0x0045, 0x0045}, /* E */ {0x0046, 0x0046}, /* F */ {0x0047, 0x0047}, /* G */ {0x0048, 0x0048}, /* H */ {0x0049, 0x0049}, /* I */ {0x004a, 0x004a}, /* J */ {0x004b, 0x004b}, /* K */ {0x004c, 0x004c}, /* L */ {0x004d, 0x004d}, /* M */ {0x004e, 0x004e}, /* N */ {0x004f, 0x004f}, /* O */ {0x0050, 0x0050}, /* P */ {0x0051, 0x0051}, /* Q */ {0x0052, 0x0052}, /* R */ {0x0053, 0x0053}, /* S */ {0x0054, 0x0054}, /* T */ {0x0055, 0x0055}, /* U */ {0x0056, 0x0056}, /* V */ {0x0057, 0x0057}, /* W */ {0x0058, 0x0058}, /* X */ {0x0059, 0x0059}, /* Y */ {0x005a, 0x005a}, /* Z */ {0x005b, 0x005b}, /* bracketleft */ {0x005c, 0x005c}, /* backslash */ {0x005d, 0x005d}, /* bracketright */ {0x005e, 0x005e}, /* asciicircum */ {0x005f, 0x005f}, /* underscore */ {0x0060, 0x0060}, /* grave */ {0x0061, 0x0061}, /* a */ {0x0062, 0x0062}, /* b */ {0x0063, 0x0063}, /* c */ {0x0064, 0x0064}, /* d */ {0x0065, 0x0065}, /* e */ {0x0066, 0x0066}, /* f */ {0x0067, 0x0067}, /* g */ {0x0068, 0x0068}, /* h */ {0x0069, 0x0069}, /* i */ {0x006a, 0x006a}, /* j */ {0x006b, 0x006b}, /* k */ {0x006c, 0x006c}, /* l */ {0x006d, 0x006d}, /* m */ {0x006e, 0x006e}, /* n */ {0x006f, 0x006f}, /* o */ {0x0070, 0x0070}, /* p */ {0x0071, 0x0071}, /* q */ {0x0072, 0x0072}, /* r */ {0x0073, 0x0073}, /* s */ {0x0074, 0x0074}, /* t */ {0x0075, 0x0075}, /* u */ {0x0076, 0x0076}, /* v */ {0x0077, 0x0077}, /* w */ {0x0078, 0x0078}, /* x */ {0x0079, 0x0079}, /* y */ {0x007a, 0x007a}, /* z */ {0x007b, 0x007b}, /* braceleft */ {0x007c, 0x007c}, /* bar */ {0x007d, 0x007d}, /* braceright */ {0x007e, 0x007e}, /* asciitilde */ {0x00a0, 0x00a0}, /* nobreakspace */ {0x00a1, 0x00a1}, /* exclamdown */ {0x00a2, 0x00a2}, /* cent */ {0x00a3, 0x00a3}, /* sterling */ {0x00a4, 0x00a4}, /* currency */ {0x00a5, 0x00a5}, /* yen */ {0x00a6, 0x00a6}, /* brokenbar */ {0x00a7, 0x00a7}, /* section */ {0x00a8, 0x00a8}, /* diaeresis */ {0x00a9, 0x00a9}, /* copyright */ {0x00aa, 0x00aa}, /* ordfeminine */ {0x00ab, 0x00ab}, /* guillemotleft */ {0x00ac, 0x00ac}, /* notsign */ {0x00ad, 0x00ad}, /* hyphen */ {0x00ae, 0x00ae}, /* registered */ {0x00af, 0x00af}, /* macron */ {0x00b0, 0x00b0}, /* degree */ {0x00b1, 0x00b1}, /* plusminus */ {0x00b2, 0x00b2}, /* twosuperior */ {0x00b3, 0x00b3}, /* threesuperior */ {0x00b4, 0x00b4}, /* acute */ {0x00b5, 0x00b5}, /* mu */ {0x00b6, 0x00b6}, /* paragraph */ {0x00b7, 0x00b7}, /* periodcentered */ {0x00b8, 0x00b8}, /* cedilla */ {0x00b9, 0x00b9}, /* onesuperior */ {0x00ba, 0x00ba}, /* masculine */ {0x00bb, 0x00bb}, /* guillemotright */ {0x00bc, 0x00bc}, /* onequarter */ {0x00bd, 0x00bd}, /* onehalf */ {0x00be, 0x00be}, /* threequarters */ {0x00bf, 0x00bf}, /* questiondown */ {0x00c0, 0x00c0}, /* Agrave */ {0x00c1, 0x00c1}, /* Aacute */ {0x00c2, 0x00c2}, /* Acircumflex */ {0x00c3, 0x00c3}, /* Atilde */ {0x00c4, 0x00c4}, /* Adiaeresis */ {0x00c5, 0x00c5}, /* Aring */ {0x00c6, 0x00c6}, /* AE */ {0x00c7, 0x00c7}, /* Ccedilla */ {0x00c8, 0x00c8}, /* Egrave */ {0x00c9, 0x00c9}, /* Eacute */ {0x00ca, 0x00ca}, /* Ecircumflex */ {0x00cb, 0x00cb}, /* Ediaeresis */ {0x00cc, 0x00cc}, /* Igrave */ {0x00cd, 0x00cd}, /* Iacute */ {0x00ce, 0x00ce}, /* Icircumflex */ {0x00cf, 0x00cf}, /* Idiaeresis */ {0x00d0, 0x00d0}, /* ETH */ {0x00d1, 0x00d1}, /* Ntilde */ {0x00d2, 0x00d2}, /* Ograve */ {0x00d3, 0x00d3}, /* Oacute */ {0x00d4, 0x00d4}, /* Ocircumflex */ {0x00d5, 0x00d5}, /* Otilde */ {0x00d6, 0x00d6}, /* Odiaeresis */ {0x00d7, 0x00d7}, /* multiply */ {0x00d8, 0x00d8}, /* Ooblique */ {0x00d9, 0x00d9}, /* Ugrave */ {0x00da, 0x00da}, /* Uacute */ {0x00db, 0x00db}, /* Ucircumflex */ {0x00dc, 0x00dc}, /* Udiaeresis */ {0x00dd, 0x00dd}, /* Yacute */ {0x00de, 0x00de}, /* THORN */ {0x00df, 0x00df}, /* ssharp */ {0x00e0, 0x00e0}, /* agrave */ {0x00e1, 0x00e1}, /* aacute */ {0x00e2, 0x00e2}, /* acircumflex */ {0x00e3, 0x00e3}, /* atilde */ {0x00e4, 0x00e4}, /* adiaeresis */ {0x00e5, 0x00e5}, /* aring */ {0x00e6, 0x00e6}, /* ae */ {0x00e7, 0x00e7}, /* ccedilla */ {0x00e8, 0x00e8}, /* egrave */ {0x00e9, 0x00e9}, /* eacute */ {0x00ea, 0x00ea}, /* ecircumflex */ {0x00eb, 0x00eb}, /* ediaeresis */ {0x00ec, 0x00ec}, /* igrave */ {0x00ed, 0x00ed}, /* iacute */ {0x00ee, 0x00ee}, /* icircumflex */ {0x00ef, 0x00ef}, /* idiaeresis */ {0x00f0, 0x00f0}, /* eth */ {0x00f1, 0x00f1}, /* ntilde */ {0x00f2, 0x00f2}, /* ograve */ {0x00f3, 0x00f3}, /* oacute */ {0x00f4, 0x00f4}, /* ocircumflex */ {0x00f5, 0x00f5}, /* otilde */ {0x00f6, 0x00f6}, /* odiaeresis */ {0x00f7, 0x00f7}, /* division */ {0x00f8, 0x00f8}, /* oslash */ {0x00f9, 0x00f9}, /* ugrave */ {0x00fa, 0x00fa}, /* uacute */ {0x00fb, 0x00fb}, /* ucircumflex */ {0x00fc, 0x00fc}, /* udiaeresis */ {0x00fd, 0x00fd}, /* yacute */ {0x00fe, 0x00fe}, /* thorn */ {0x00ff, 0x00ff}, /* ydiaeresis */ {0x01a1, 0x0104}, /* Aogonek */ {0x01a2, 0x02d8}, /* breve */ {0x01a3, 0x0141}, /* Lstroke */ {0x01a5, 0x013d}, /* Lcaron */ {0x01a6, 0x015a}, /* Sacute */ {0x01a9, 0x0160}, /* Scaron */ {0x01aa, 0x015e}, /* Scedilla */ {0x01ab, 0x0164}, /* Tcaron */ {0x01ac, 0x0179}, /* Zacute */ {0x01ae, 0x017d}, /* Zcaron */ {0x01af, 0x017b}, /* Zabovedot */ {0x01b1, 0x0105}, /* aogonek */ {0x01b2, 0x02db}, /* ogonek */ {0x01b3, 0x0142}, /* lstroke */ {0x01b5, 0x013e}, /* lcaron */ {0x01b6, 0x015b}, /* sacute */ {0x01b7, 0x02c7}, /* caron */ {0x01b9, 0x0161}, /* scaron */ {0x01ba, 0x015f}, /* scedilla */ {0x01bb, 0x0165}, /* tcaron */ {0x01bc, 0x017a}, /* zacute */ {0x01bd, 0x02dd}, /* doubleacute */ {0x01be, 0x017e}, /* zcaron */ {0x01bf, 0x017c}, /* zabovedot */ {0x01c0, 0x0154}, /* Racute */ {0x01c3, 0x0102}, /* Abreve */ {0x01c5, 0x0139}, /* Lacute */ {0x01c6, 0x0106}, /* Cacute */ {0x01c8, 0x010c}, /* Ccaron */ {0x01ca, 0x0118}, /* Eogonek */ {0x01cc, 0x011a}, /* Ecaron */ {0x01cf, 0x010e}, /* Dcaron */ {0x01d0, 0x0110}, /* Dstroke */ {0x01d1, 0x0143}, /* Nacute */ {0x01d2, 0x0147}, /* Ncaron */ {0x01d5, 0x0150}, /* Odoubleacute */ {0x01d8, 0x0158}, /* Rcaron */ {0x01d9, 0x016e}, /* Uring */ {0x01db, 0x0170}, /* Udoubleacute */ {0x01de, 0x0162}, /* Tcedilla */ {0x01e0, 0x0155}, /* racute */ {0x01e3, 0x0103}, /* abreve */ {0x01e5, 0x013a}, /* lacute */ {0x01e6, 0x0107}, /* cacute */ {0x01e8, 0x010d}, /* ccaron */ {0x01ea, 0x0119}, /* eogonek */ {0x01ec, 0x011b}, /* ecaron */ {0x01ef, 0x010f}, /* dcaron */ {0x01f0, 0x0111}, /* dstroke */ {0x01f1, 0x0144}, /* nacute */ {0x01f2, 0x0148}, /* ncaron */ {0x01f5, 0x0151}, /* odoubleacute */ {0x01f8, 0x0159}, /* rcaron */ {0x01f9, 0x016f}, /* uring */ {0x01fb, 0x0171}, /* udoubleacute */ {0x01fe, 0x0163}, /* tcedilla */ {0x01ff, 0x02d9}, /* abovedot */ {0x02a1, 0x0126}, /* Hstroke */ {0x02a6, 0x0124}, /* Hcircumflex */ {0x02a9, 0x0130}, /* Iabovedot */ {0x02ab, 0x011e}, /* Gbreve */ {0x02ac, 0x0134}, /* Jcircumflex */ {0x02b1, 0x0127}, /* hstroke */ {0x02b6, 0x0125}, /* hcircumflex */ {0x02b9, 0x0131}, /* idotless */ {0x02bb, 0x011f}, /* gbreve */ {0x02bc, 0x0135}, /* jcircumflex */ {0x02c5, 0x010a}, /* Cabovedot */ {0x02c6, 0x0108}, /* Ccircumflex */ {0x02d5, 0x0120}, /* Gabovedot */ {0x02d8, 0x011c}, /* Gcircumflex */ {0x02dd, 0x016c}, /* Ubreve */ {0x02de, 0x015c}, /* Scircumflex */ {0x02e5, 0x010b}, /* cabovedot */ {0x02e6, 0x0109}, /* ccircumflex */ {0x02f5, 0x0121}, /* gabovedot */ {0x02f8, 0x011d}, /* gcircumflex */ {0x02fd, 0x016d}, /* ubreve */ {0x02fe, 0x015d}, /* scircumflex */ {0x03a2, 0x0138}, /* kra */ {0x03a3, 0x0156}, /* Rcedilla */ {0x03a5, 0x0128}, /* Itilde */ {0x03a6, 0x013b}, /* Lcedilla */ {0x03aa, 0x0112}, /* Emacron */ {0x03ab, 0x0122}, /* Gcedilla */ {0x03ac, 0x0166}, /* Tslash */ {0x03b3, 0x0157}, /* rcedilla */ {0x03b5, 0x0129}, /* itilde */ {0x03b6, 0x013c}, /* lcedilla */ {0x03ba, 0x0113}, /* emacron */ {0x03bb, 0x0123}, /* gcedilla */ {0x03bc, 0x0167}, /* tslash */ {0x03bd, 0x014a}, /* ENG */ {0x03bf, 0x014b}, /* eng */ {0x03c0, 0x0100}, /* Amacron */ {0x03c7, 0x012e}, /* Iogonek */ {0x03cc, 0x0116}, /* Eabovedot */ {0x03cf, 0x012a}, /* Imacron */ {0x03d1, 0x0145}, /* Ncedilla */ {0x03d2, 0x014c}, /* Omacron */ {0x03d3, 0x0136}, /* Kcedilla */ {0x03d9, 0x0172}, /* Uogonek */ {0x03dd, 0x0168}, /* Utilde */ {0x03de, 0x016a}, /* Umacron */ {0x03e0, 0x0101}, /* amacron */ {0x03e7, 0x012f}, /* iogonek */ {0x03ec, 0x0117}, /* eabovedot */ {0x03ef, 0x012b}, /* imacron */ {0x03f1, 0x0146}, /* ncedilla */ {0x03f2, 0x014d}, /* omacron */ {0x03f3, 0x0137}, /* kcedilla */ {0x03f9, 0x0173}, /* uogonek */ {0x03fd, 0x0169}, /* utilde */ {0x03fe, 0x016b}, /* umacron */ {0x047e, 0x203e}, /* overline */ {0x04a1, 0x3002}, /* kana_fullstop */ {0x04a2, 0x300c}, /* kana_openingbracket */ {0x04a3, 0x300d}, /* kana_closingbracket */ {0x04a4, 0x3001}, /* kana_comma */ {0x04a5, 0x30fb}, /* kana_conjunctive */ {0x04a6, 0x30f2}, /* kana_WO */ {0x04a7, 0x30a1}, /* kana_a */ {0x04a8, 0x30a3}, /* kana_i */ {0x04a9, 0x30a5}, /* kana_u */ {0x04aa, 0x30a7}, /* kana_e */ {0x04ab, 0x30a9}, /* kana_o */ {0x04ac, 0x30e3}, /* kana_ya */ {0x04ad, 0x30e5}, /* kana_yu */ {0x04ae, 0x30e7}, /* kana_yo */ {0x04af, 0x30c3}, /* kana_tsu */ {0x04b0, 0x30fc}, /* prolongedsound */ {0x04b1, 0x30a2}, /* kana_A */ {0x04b2, 0x30a4}, /* kana_I */ {0x04b3, 0x30a6}, /* kana_U */ {0x04b4, 0x30a8}, /* kana_E */ {0x04b5, 0x30aa}, /* kana_O */ {0x04b6, 0x30ab}, /* kana_KA */ {0x04b7, 0x30ad}, /* kana_KI */ {0x04b8, 0x30af}, /* kana_KU */ {0x04b9, 0x30b1}, /* kana_KE */ {0x04ba, 0x30b3}, /* kana_KO */ {0x04bb, 0x30b5}, /* kana_SA */ {0x04bc, 0x30b7}, /* kana_SHI */ {0x04bd, 0x30b9}, /* kana_SU */ {0x04be, 0x30bb}, /* kana_SE */ {0x04bf, 0x30bd}, /* kana_SO */ {0x04c0, 0x30bf}, /* kana_TA */ {0x04c1, 0x30c1}, /* kana_CHI */ {0x04c2, 0x30c4}, /* kana_TSU */ {0x04c3, 0x30c6}, /* kana_TE */ {0x04c4, 0x30c8}, /* kana_TO */ {0x04c5, 0x30ca}, /* kana_NA */ {0x04c6, 0x30cb}, /* kana_NI */ {0x04c7, 0x30cc}, /* kana_NU */ {0x04c8, 0x30cd}, /* kana_NE */ {0x04c9, 0x30ce}, /* kana_NO */ {0x04ca, 0x30cf}, /* kana_HA */ {0x04cb, 0x30d2}, /* kana_HI */ {0x04cc, 0x30d5}, /* kana_FU */ {0x04cd, 0x30d8}, /* kana_HE */ {0x04ce, 0x30db}, /* kana_HO */ {0x04cf, 0x30de}, /* kana_MA */ {0x04d0, 0x30df}, /* kana_MI */ {0x04d1, 0x30e0}, /* kana_MU */ {0x04d2, 0x30e1}, /* kana_ME */ {0x04d3, 0x30e2}, /* kana_MO */ {0x04d4, 0x30e4}, /* kana_YA */ {0x04d5, 0x30e6}, /* kana_YU */ {0x04d6, 0x30e8}, /* kana_YO */ {0x04d7, 0x30e9}, /* kana_RA */ {0x04d8, 0x30ea}, /* kana_RI */ {0x04d9, 0x30eb}, /* kana_RU */ {0x04da, 0x30ec}, /* kana_RE */ {0x04db, 0x30ed}, /* kana_RO */ {0x04dc, 0x30ef}, /* kana_WA */ {0x04dd, 0x30f3}, /* kana_N */ {0x04de, 0x309b}, /* voicedsound */ {0x04df, 0x309c}, /* semivoicedsound */ {0x05ac, 0x060c}, /* Arabic_comma */ {0x05bb, 0x061b}, /* Arabic_semicolon */ {0x05bf, 0x061f}, /* Arabic_question_mark */ {0x05c1, 0x0621}, /* Arabic_hamza */ {0x05c2, 0x0622}, /* Arabic_maddaonalef */ {0x05c3, 0x0623}, /* Arabic_hamzaonalef */ {0x05c4, 0x0624}, /* Arabic_hamzaonwaw */ {0x05c5, 0x0625}, /* Arabic_hamzaunderalef */ {0x05c6, 0x0626}, /* Arabic_hamzaonyeh */ {0x05c7, 0x0627}, /* Arabic_alef */ {0x05c8, 0x0628}, /* Arabic_beh */ {0x05c9, 0x0629}, /* Arabic_tehmarbuta */ {0x05ca, 0x062a}, /* Arabic_teh */ {0x05cb, 0x062b}, /* Arabic_theh */ {0x05cc, 0x062c}, /* Arabic_jeem */ {0x05cd, 0x062d}, /* Arabic_hah */ {0x05ce, 0x062e}, /* Arabic_khah */ {0x05cf, 0x062f}, /* Arabic_dal */ {0x05d0, 0x0630}, /* Arabic_thal */ {0x05d1, 0x0631}, /* Arabic_ra */ {0x05d2, 0x0632}, /* Arabic_zain */ {0x05d3, 0x0633}, /* Arabic_seen */ {0x05d4, 0x0634}, /* Arabic_sheen */ {0x05d5, 0x0635}, /* Arabic_sad */ {0x05d6, 0x0636}, /* Arabic_dad */ {0x05d7, 0x0637}, /* Arabic_tah */ {0x05d8, 0x0638}, /* Arabic_zah */ {0x05d9, 0x0639}, /* Arabic_ain */ {0x05da, 0x063a}, /* Arabic_ghain */ {0x05e0, 0x0640}, /* Arabic_tatweel */ {0x05e1, 0x0641}, /* Arabic_feh */ {0x05e2, 0x0642}, /* Arabic_qaf */ {0x05e3, 0x0643}, /* Arabic_kaf */ {0x05e4, 0x0644}, /* Arabic_lam */ {0x05e5, 0x0645}, /* Arabic_meem */ {0x05e6, 0x0646}, /* Arabic_noon */ {0x05e7, 0x0647}, /* Arabic_ha */ {0x05e8, 0x0648}, /* Arabic_waw */ {0x05e9, 0x0649}, /* Arabic_alefmaksura */ {0x05ea, 0x064a}, /* Arabic_yeh */ {0x05eb, 0x064b}, /* Arabic_fathatan */ {0x05ec, 0x064c}, /* Arabic_dammatan */ {0x05ed, 0x064d}, /* Arabic_kasratan */ {0x05ee, 0x064e}, /* Arabic_fatha */ {0x05ef, 0x064f}, /* Arabic_damma */ {0x05f0, 0x0650}, /* Arabic_kasra */ {0x05f1, 0x0651}, /* Arabic_shadda */ {0x05f2, 0x0652}, /* Arabic_sukun */ {0x06a1, 0x0452}, /* Serbian_dje */ {0x06a2, 0x0453}, /* Macedonia_gje */ {0x06a3, 0x0451}, /* Cyrillic_io */ {0x06a4, 0x0454}, /* Ukrainian_ie */ {0x06a5, 0x0455}, /* Macedonia_dse */ {0x06a6, 0x0456}, /* Ukrainian_i */ {0x06a7, 0x0457}, /* Ukrainian_yi */ {0x06a8, 0x0458}, /* Cyrillic_je */ {0x06a9, 0x0459}, /* Cyrillic_lje */ {0x06aa, 0x045a}, /* Cyrillic_nje */ {0x06ab, 0x045b}, /* Serbian_tshe */ {0x06ac, 0x045c}, /* Macedonia_kje */ {0x06ae, 0x045e}, /* Byelorussian_shortu */ {0x06af, 0x045f}, /* Cyrillic_dzhe */ {0x06b0, 0x2116}, /* numerosign */ {0x06b1, 0x0402}, /* Serbian_DJE */ {0x06b2, 0x0403}, /* Macedonia_GJE */ {0x06b3, 0x0401}, /* Cyrillic_IO */ {0x06b4, 0x0404}, /* Ukrainian_IE */ {0x06b5, 0x0405}, /* Macedonia_DSE */ {0x06b6, 0x0406}, /* Ukrainian_I */ {0x06b7, 0x0407}, /* Ukrainian_YI */ {0x06b8, 0x0408}, /* Cyrillic_JE */ {0x06b9, 0x0409}, /* Cyrillic_LJE */ {0x06ba, 0x040a}, /* Cyrillic_NJE */ {0x06bb, 0x040b}, /* Serbian_TSHE */ {0x06bc, 0x040c}, /* Macedonia_KJE */ {0x06be, 0x040e}, /* Byelorussian_SHORTU */ {0x06bf, 0x040f}, /* Cyrillic_DZHE */ {0x06c0, 0x044e}, /* Cyrillic_yu */ {0x06c1, 0x0430}, /* Cyrillic_a */ {0x06c2, 0x0431}, /* Cyrillic_be */ {0x06c3, 0x0446}, /* Cyrillic_tse */ {0x06c4, 0x0434}, /* Cyrillic_de */ {0x06c5, 0x0435}, /* Cyrillic_ie */ {0x06c6, 0x0444}, /* Cyrillic_ef */ {0x06c7, 0x0433}, /* Cyrillic_ghe */ {0x06c8, 0x0445}, /* Cyrillic_ha */ {0x06c9, 0x0438}, /* Cyrillic_i */ {0x06ca, 0x0439}, /* Cyrillic_shorti */ {0x06cb, 0x043a}, /* Cyrillic_ka */ {0x06cc, 0x043b}, /* Cyrillic_el */ {0x06cd, 0x043c}, /* Cyrillic_em */ {0x06ce, 0x043d}, /* Cyrillic_en */ {0x06cf, 0x043e}, /* Cyrillic_o */ {0x06d0, 0x043f}, /* Cyrillic_pe */ {0x06d1, 0x044f}, /* Cyrillic_ya */ {0x06d2, 0x0440}, /* Cyrillic_er */ {0x06d3, 0x0441}, /* Cyrillic_es */ {0x06d4, 0x0442}, /* Cyrillic_te */ {0x06d5, 0x0443}, /* Cyrillic_u */ {0x06d6, 0x0436}, /* Cyrillic_zhe */ {0x06d7, 0x0432}, /* Cyrillic_ve */ {0x06d8, 0x044c}, /* Cyrillic_softsign */ {0x06d9, 0x044b}, /* Cyrillic_yeru */ {0x06da, 0x0437}, /* Cyrillic_ze */ {0x06db, 0x0448}, /* Cyrillic_sha */ {0x06dc, 0x044d}, /* Cyrillic_e */ {0x06dd, 0x0449}, /* Cyrillic_shcha */ {0x06de, 0x0447}, /* Cyrillic_che */ {0x06df, 0x044a}, /* Cyrillic_hardsign */ {0x06e0, 0x042e}, /* Cyrillic_YU */ {0x06e1, 0x0410}, /* Cyrillic_A */ {0x06e2, 0x0411}, /* Cyrillic_BE */ {0x06e3, 0x0426}, /* Cyrillic_TSE */ {0x06e4, 0x0414}, /* Cyrillic_DE */ {0x06e5, 0x0415}, /* Cyrillic_IE */ {0x06e6, 0x0424}, /* Cyrillic_EF */ {0x06e7, 0x0413}, /* Cyrillic_GHE */ {0x06e8, 0x0425}, /* Cyrillic_HA */ {0x06e9, 0x0418}, /* Cyrillic_I */ {0x06ea, 0x0419}, /* Cyrillic_SHORTI */ {0x06eb, 0x041a}, /* Cyrillic_KA */ {0x06ec, 0x041b}, /* Cyrillic_EL */ {0x06ed, 0x041c}, /* Cyrillic_EM */ {0x06ee, 0x041d}, /* Cyrillic_EN */ {0x06ef, 0x041e}, /* Cyrillic_O */ {0x06f0, 0x041f}, /* Cyrillic_PE */ {0x06f1, 0x042f}, /* Cyrillic_YA */ {0x06f2, 0x0420}, /* Cyrillic_ER */ {0x06f3, 0x0421}, /* Cyrillic_ES */ {0x06f4, 0x0422}, /* Cyrillic_TE */ {0x06f5, 0x0423}, /* Cyrillic_U */ {0x06f6, 0x0416}, /* Cyrillic_ZHE */ {0x06f7, 0x0412}, /* Cyrillic_VE */ {0x06f8, 0x042c}, /* Cyrillic_SOFTSIGN */ {0x06f9, 0x042b}, /* Cyrillic_YERU */ {0x06fa, 0x0417}, /* Cyrillic_ZE */ {0x06fb, 0x0428}, /* Cyrillic_SHA */ {0x06fc, 0x042d}, /* Cyrillic_E */ {0x06fd, 0x0429}, /* Cyrillic_SHCHA */ {0x06fe, 0x0427}, /* Cyrillic_CHE */ {0x06ff, 0x042a}, /* Cyrillic_HARDSIGN */ {0x07a1, 0x0386}, /* Greek_ALPHAaccent */ {0x07a2, 0x0388}, /* Greek_EPSILONaccent */ {0x07a3, 0x0389}, /* Greek_ETAaccent */ {0x07a4, 0x038a}, /* Greek_IOTAaccent */ {0x07a5, 0x03aa}, /* Greek_IOTAdiaeresis */ {0x07a7, 0x038c}, /* Greek_OMICRONaccent */ {0x07a8, 0x038e}, /* Greek_UPSILONaccent */ {0x07a9, 0x03ab}, /* Greek_UPSILONdieresis */ {0x07ab, 0x038f}, /* Greek_OMEGAaccent */ {0x07ae, 0x0385}, /* Greek_accentdieresis */ {0x07af, 0x2015}, /* Greek_horizbar */ {0x07b1, 0x03ac}, /* Greek_alphaaccent */ {0x07b2, 0x03ad}, /* Greek_epsilonaccent */ {0x07b3, 0x03ae}, /* Greek_etaaccent */ {0x07b4, 0x03af}, /* Greek_iotaaccent */ {0x07b5, 0x03ca}, /* Greek_iotadieresis */ {0x07b6, 0x0390}, /* Greek_iotaaccentdieresis */ {0x07b7, 0x03cc}, /* Greek_omicronaccent */ {0x07b8, 0x03cd}, /* Greek_upsilonaccent */ {0x07b9, 0x03cb}, /* Greek_upsilondieresis */ {0x07ba, 0x03b0}, /* Greek_upsilonaccentdieresis */ {0x07bb, 0x03ce}, /* Greek_omegaaccent */ {0x07c1, 0x0391}, /* Greek_ALPHA */ {0x07c2, 0x0392}, /* Greek_BETA */ {0x07c3, 0x0393}, /* Greek_GAMMA */ {0x07c4, 0x0394}, /* Greek_DELTA */ {0x07c5, 0x0395}, /* Greek_EPSILON */ {0x07c6, 0x0396}, /* Greek_ZETA */ {0x07c7, 0x0397}, /* Greek_ETA */ {0x07c8, 0x0398}, /* Greek_THETA */ {0x07c9, 0x0399}, /* Greek_IOTA */ {0x07ca, 0x039a}, /* Greek_KAPPA */ {0x07cb, 0x039b}, /* Greek_LAMDA */ {0x07cc, 0x039c}, /* Greek_MU */ {0x07cd, 0x039d}, /* Greek_NU */ {0x07ce, 0x039e}, /* Greek_XI */ {0x07cf, 0x039f}, /* Greek_OMICRON */ {0x07d0, 0x03a0}, /* Greek_PI */ {0x07d1, 0x03a1}, /* Greek_RHO */ {0x07d2, 0x03a3}, /* Greek_SIGMA */ {0x07d4, 0x03a4}, /* Greek_TAU */ {0x07d5, 0x03a5}, /* Greek_UPSILON */ {0x07d6, 0x03a6}, /* Greek_PHI */ {0x07d7, 0x03a7}, /* Greek_CHI */ {0x07d8, 0x03a8}, /* Greek_PSI */ {0x07d9, 0x03a9}, /* Greek_OMEGA */ {0x07e1, 0x03b1}, /* Greek_alpha */ {0x07e2, 0x03b2}, /* Greek_beta */ {0x07e3, 0x03b3}, /* Greek_gamma */ {0x07e4, 0x03b4}, /* Greek_delta */ {0x07e5, 0x03b5}, /* Greek_epsilon */ {0x07e6, 0x03b6}, /* Greek_zeta */ {0x07e7, 0x03b7}, /* Greek_eta */ {0x07e8, 0x03b8}, /* Greek_theta */ {0x07e9, 0x03b9}, /* Greek_iota */ {0x07ea, 0x03ba}, /* Greek_kappa */ {0x07eb, 0x03bb}, /* Greek_lambda */ {0x07ec, 0x03bc}, /* Greek_mu */ {0x07ed, 0x03bd}, /* Greek_nu */ {0x07ee, 0x03be}, /* Greek_xi */ {0x07ef, 0x03bf}, /* Greek_omicron */ {0x07f0, 0x03c0}, /* Greek_pi */ {0x07f1, 0x03c1}, /* Greek_rho */ {0x07f2, 0x03c3}, /* Greek_sigma */ {0x07f3, 0x03c2}, /* Greek_finalsmallsigma */ {0x07f4, 0x03c4}, /* Greek_tau */ {0x07f5, 0x03c5}, /* Greek_upsilon */ {0x07f6, 0x03c6}, /* Greek_phi */ {0x07f7, 0x03c7}, /* Greek_chi */ {0x07f8, 0x03c8}, /* Greek_psi */ {0x07f9, 0x03c9}, /* Greek_omega */ {0x08a1, 0x23b7}, /* leftradical */ {0x08a4, 0x2320}, /* topintegral */ {0x08a5, 0x2321}, /* botintegral */ {0x08a7, 0x23a1}, /* topleftsqbracket */ {0x08a8, 0x23a3}, /* botleftsqbracket */ {0x08a9, 0x23a4}, /* toprightsqbracket */ {0x08aa, 0x23a6}, /* botrightsqbracket */ {0x08ab, 0x239b}, /* topleftparens */ {0x08ac, 0x239d}, /* botleftparens */ {0x08ad, 0x239e}, /* toprightparens */ {0x08ae, 0x23a0}, /* botrightparens */ {0x08af, 0x23a8}, /* leftmiddlecurlybrace */ {0x08b0, 0x23ac}, /* rightmiddlecurlybrace */ {0x08bc, 0x2264}, /* lessthanequal */ {0x08bd, 0x2260}, /* notequal */ {0x08be, 0x2265}, /* greaterthanequal */ {0x08bf, 0x222b}, /* integral */ {0x08c0, 0x2234}, /* therefore */ {0x08c1, 0x221d}, /* variation */ {0x08c2, 0x221e}, /* infinity */ {0x08c5, 0x2207}, /* nabla */ {0x08c8, 0x223c}, /* approximate */ {0x08c9, 0x2243}, /* similarequal */ {0x08cd, 0x21d4}, /* ifonlyif */ {0x08ce, 0x21d2}, /* implies */ {0x08cf, 0x2261}, /* identical */ {0x08d6, 0x221a}, /* radical */ {0x08da, 0x2282}, /* includedin */ {0x08db, 0x2283}, /* includes */ {0x08dc, 0x2229}, /* intersection */ {0x08dd, 0x222a}, /* union */ {0x08de, 0x2227}, /* logicaland */ {0x08df, 0x2228}, /* logicalor */ {0x08ef, 0x2202}, /* partialderivative */ {0x08f6, 0x0192}, /* function */ {0x08fb, 0x2190}, /* leftarrow */ {0x08fc, 0x2191}, /* uparrow */ {0x08fd, 0x2192}, /* rightarrow */ {0x08fe, 0x2193}, /* downarrow */ {0x09e0, 0x25c6}, /* soliddiamond */ {0x09e1, 0x2592}, /* checkerboard */ {0x09e2, 0x2409}, /* ht */ {0x09e3, 0x240c}, /* ff */ {0x09e4, 0x240d}, /* cr */ {0x09e5, 0x240a}, /* lf */ {0x09e8, 0x2424}, /* nl */ {0x09e9, 0x240b}, /* vt */ {0x09ea, 0x2518}, /* lowrightcorner */ {0x09eb, 0x2510}, /* uprightcorner */ {0x09ec, 0x250c}, /* upleftcorner */ {0x09ed, 0x2514}, /* lowleftcorner */ {0x09ee, 0x253c}, /* crossinglines */ {0x09ef, 0x23ba}, /* horizlinescan1 */ {0x09f0, 0x23bb}, /* horizlinescan3 */ {0x09f1, 0x2500}, /* horizlinescan5 */ {0x09f2, 0x23bc}, /* horizlinescan7 */ {0x09f3, 0x23bd}, /* horizlinescan9 */ {0x09f4, 0x251c}, /* leftt */ {0x09f5, 0x2524}, /* rightt */ {0x09f6, 0x2534}, /* bott */ {0x09f7, 0x252c}, /* topt */ {0x09f8, 0x2502}, /* vertbar */ {0x0aa1, 0x2003}, /* emspace */ {0x0aa2, 0x2002}, /* enspace */ {0x0aa3, 0x2004}, /* em3space */ {0x0aa4, 0x2005}, /* em4space */ {0x0aa5, 0x2007}, /* digitspace */ {0x0aa6, 0x2008}, /* punctspace */ {0x0aa7, 0x2009}, /* thinspace */ {0x0aa8, 0x200a}, /* hairspace */ {0x0aa9, 0x2014}, /* emdash */ {0x0aaa, 0x2013}, /* endash */ {0x0aae, 0x2026}, /* ellipsis */ {0x0aaf, 0x2025}, /* doubbaselinedot */ {0x0ab0, 0x2153}, /* onethird */ {0x0ab1, 0x2154}, /* twothirds */ {0x0ab2, 0x2155}, /* onefifth */ {0x0ab3, 0x2156}, /* twofifths */ {0x0ab4, 0x2157}, /* threefifths */ {0x0ab5, 0x2158}, /* fourfifths */ {0x0ab6, 0x2159}, /* onesixth */ {0x0ab7, 0x215a}, /* fivesixths */ {0x0ab8, 0x2105}, /* careof */ {0x0abb, 0x2012}, /* figdash */ {0x0ac3, 0x215b}, /* oneeighth */ {0x0ac4, 0x215c}, /* threeeighths */ {0x0ac5, 0x215d}, /* fiveeighths */ {0x0ac6, 0x215e}, /* seveneighths */ {0x0ac9, 0x2122}, /* trademark */ {0x0ad0, 0x2018}, /* leftsinglequotemark */ {0x0ad1, 0x2019}, /* rightsinglequotemark */ {0x0ad2, 0x201c}, /* leftdoublequotemark */ {0x0ad3, 0x201d}, /* rightdoublequotemark */ {0x0ad4, 0x211e}, /* prescription */ {0x0ad6, 0x2032}, /* minutes */ {0x0ad7, 0x2033}, /* seconds */ {0x0ad9, 0x271d}, /* latincross */ {0x0aec, 0x2663}, /* club */ {0x0aed, 0x2666}, /* diamond */ {0x0aee, 0x2665}, /* heart */ {0x0af0, 0x2720}, /* maltesecross */ {0x0af1, 0x2020}, /* dagger */ {0x0af2, 0x2021}, /* doubledagger */ {0x0af3, 0x2713}, /* checkmark */ {0x0af4, 0x2717}, /* ballotcross */ {0x0af5, 0x266f}, /* musicalsharp */ {0x0af6, 0x266d}, /* musicalflat */ {0x0af7, 0x2642}, /* malesymbol */ {0x0af8, 0x2640}, /* femalesymbol */ {0x0af9, 0x260e}, /* telephone */ {0x0afa, 0x2315}, /* telephonerecorder */ {0x0afb, 0x2117}, /* phonographcopyright */ {0x0afc, 0x2038}, /* caret */ {0x0afd, 0x201a}, /* singlelowquotemark */ {0x0afe, 0x201e}, /* doublelowquotemark */ {0x0bc2, 0x22a5}, /* downtack */ {0x0bc4, 0x230a}, /* downstile */ {0x0bca, 0x2218}, /* jot */ {0x0bcc, 0x2395}, /* quad */ {0x0bce, 0x22a4}, /* uptack */ {0x0bcf, 0x25cb}, /* circle */ {0x0bd3, 0x2308}, /* upstile */ {0x0bdc, 0x22a2}, /* lefttack */ {0x0bfc, 0x22a3}, /* righttack */ {0x0cdf, 0x2017}, /* hebrew_doublelowline */ {0x0ce0, 0x05d0}, /* hebrew_aleph */ {0x0ce1, 0x05d1}, /* hebrew_bet */ {0x0ce2, 0x05d2}, /* hebrew_gimel */ {0x0ce3, 0x05d3}, /* hebrew_dalet */ {0x0ce4, 0x05d4}, /* hebrew_he */ {0x0ce5, 0x05d5}, /* hebrew_waw */ {0x0ce6, 0x05d6}, /* hebrew_zain */ {0x0ce7, 0x05d7}, /* hebrew_chet */ {0x0ce8, 0x05d8}, /* hebrew_tet */ {0x0ce9, 0x05d9}, /* hebrew_yod */ {0x0cea, 0x05da}, /* hebrew_finalkaph */ {0x0ceb, 0x05db}, /* hebrew_kaph */ {0x0cec, 0x05dc}, /* hebrew_lamed */ {0x0ced, 0x05dd}, /* hebrew_finalmem */ {0x0cee, 0x05de}, /* hebrew_mem */ {0x0cef, 0x05df}, /* hebrew_finalnun */ {0x0cf0, 0x05e0}, /* hebrew_nun */ {0x0cf1, 0x05e1}, /* hebrew_samech */ {0x0cf2, 0x05e2}, /* hebrew_ayin */ {0x0cf3, 0x05e3}, /* hebrew_finalpe */ {0x0cf4, 0x05e4}, /* hebrew_pe */ {0x0cf5, 0x05e5}, /* hebrew_finalzade */ {0x0cf6, 0x05e6}, /* hebrew_zade */ {0x0cf7, 0x05e7}, /* hebrew_qoph */ {0x0cf8, 0x05e8}, /* hebrew_resh */ {0x0cf9, 0x05e9}, /* hebrew_shin */ {0x0cfa, 0x05ea}, /* hebrew_taw */ {0x0da1, 0x0e01}, /* Thai_kokai */ {0x0da2, 0x0e02}, /* Thai_khokhai */ {0x0da3, 0x0e03}, /* Thai_khokhuat */ {0x0da4, 0x0e04}, /* Thai_khokhwai */ {0x0da5, 0x0e05}, /* Thai_khokhon */ {0x0da6, 0x0e06}, /* Thai_khorakhang */ {0x0da7, 0x0e07}, /* Thai_ngongu */ {0x0da8, 0x0e08}, /* Thai_chochan */ {0x0da9, 0x0e09}, /* Thai_choching */ {0x0daa, 0x0e0a}, /* Thai_chochang */ {0x0dab, 0x0e0b}, /* Thai_soso */ {0x0dac, 0x0e0c}, /* Thai_chochoe */ {0x0dad, 0x0e0d}, /* Thai_yoying */ {0x0dae, 0x0e0e}, /* Thai_dochada */ {0x0daf, 0x0e0f}, /* Thai_topatak */ {0x0db0, 0x0e10}, /* Thai_thothan */ {0x0db1, 0x0e11}, /* Thai_thonangmontho */ {0x0db2, 0x0e12}, /* Thai_thophuthao */ {0x0db3, 0x0e13}, /* Thai_nonen */ {0x0db4, 0x0e14}, /* Thai_dodek */ {0x0db5, 0x0e15}, /* Thai_totao */ {0x0db6, 0x0e16}, /* Thai_thothung */ {0x0db7, 0x0e17}, /* Thai_thothahan */ {0x0db8, 0x0e18}, /* Thai_thothong */ {0x0db9, 0x0e19}, /* Thai_nonu */ {0x0dba, 0x0e1a}, /* Thai_bobaimai */ {0x0dbb, 0x0e1b}, /* Thai_popla */ {0x0dbc, 0x0e1c}, /* Thai_phophung */ {0x0dbd, 0x0e1d}, /* Thai_fofa */ {0x0dbe, 0x0e1e}, /* Thai_phophan */ {0x0dbf, 0x0e1f}, /* Thai_fofan */ {0x0dc0, 0x0e20}, /* Thai_phosamphao */ {0x0dc1, 0x0e21}, /* Thai_moma */ {0x0dc2, 0x0e22}, /* Thai_yoyak */ {0x0dc3, 0x0e23}, /* Thai_rorua */ {0x0dc4, 0x0e24}, /* Thai_ru */ {0x0dc5, 0x0e25}, /* Thai_loling */ {0x0dc6, 0x0e26}, /* Thai_lu */ {0x0dc7, 0x0e27}, /* Thai_wowaen */ {0x0dc8, 0x0e28}, /* Thai_sosala */ {0x0dc9, 0x0e29}, /* Thai_sorusi */ {0x0dca, 0x0e2a}, /* Thai_sosua */ {0x0dcb, 0x0e2b}, /* Thai_hohip */ {0x0dcc, 0x0e2c}, /* Thai_lochula */ {0x0dcd, 0x0e2d}, /* Thai_oang */ {0x0dce, 0x0e2e}, /* Thai_honokhuk */ {0x0dcf, 0x0e2f}, /* Thai_paiyannoi */ {0x0dd0, 0x0e30}, /* Thai_saraa */ {0x0dd1, 0x0e31}, /* Thai_maihanakat */ {0x0dd2, 0x0e32}, /* Thai_saraaa */ {0x0dd3, 0x0e33}, /* Thai_saraam */ {0x0dd4, 0x0e34}, /* Thai_sarai */ {0x0dd5, 0x0e35}, /* Thai_saraii */ {0x0dd6, 0x0e36}, /* Thai_saraue */ {0x0dd7, 0x0e37}, /* Thai_sarauee */ {0x0dd8, 0x0e38}, /* Thai_sarau */ {0x0dd9, 0x0e39}, /* Thai_sarauu */ {0x0dda, 0x0e3a}, /* Thai_phinthu */ {0x0ddf, 0x0e3f}, /* Thai_baht */ {0x0de0, 0x0e40}, /* Thai_sarae */ {0x0de1, 0x0e41}, /* Thai_saraae */ {0x0de2, 0x0e42}, /* Thai_sarao */ {0x0de3, 0x0e43}, /* Thai_saraaimaimuan */ {0x0de4, 0x0e44}, /* Thai_saraaimaimalai */ {0x0de5, 0x0e45}, /* Thai_lakkhangyao */ {0x0de6, 0x0e46}, /* Thai_maiyamok */ {0x0de7, 0x0e47}, /* Thai_maitaikhu */ {0x0de8, 0x0e48}, /* Thai_maiek */ {0x0de9, 0x0e49}, /* Thai_maitho */ {0x0dea, 0x0e4a}, /* Thai_maitri */ {0x0deb, 0x0e4b}, /* Thai_maichattawa */ {0x0dec, 0x0e4c}, /* Thai_thanthakhat */ {0x0ded, 0x0e4d}, /* Thai_nikhahit */ {0x0df0, 0x0e50}, /* Thai_leksun */ {0x0df1, 0x0e51}, /* Thai_leknung */ {0x0df2, 0x0e52}, /* Thai_leksong */ {0x0df3, 0x0e53}, /* Thai_leksam */ {0x0df4, 0x0e54}, /* Thai_leksi */ {0x0df5, 0x0e55}, /* Thai_lekha */ {0x0df6, 0x0e56}, /* Thai_lekhok */ {0x0df7, 0x0e57}, /* Thai_lekchet */ {0x0df8, 0x0e58}, /* Thai_lekpaet */ {0x0df9, 0x0e59}, /* Thai_lekkao */ {0x13bc, 0x0152}, /* OE */ {0x13bd, 0x0153}, /* oe */ {0x13be, 0x0178}, /* Ydiaeresis */ {0x20a0, 0x20a0}, /* EcuSign */ {0x20a1, 0x20a1}, /* ColonSign */ {0x20a2, 0x20a2}, /* CruzeiroSign */ {0x20a3, 0x20a3}, /* FFrancSign */ {0x20a4, 0x20a4}, /* LiraSign */ {0x20a5, 0x20a5}, /* MillSign */ {0x20a6, 0x20a6}, /* NairaSign */ {0x20a7, 0x20a7}, /* PesetaSign */ {0x20a8, 0x20a8}, /* RupeeSign */ {0x20a9, 0x20a9}, /* WonSign */ {0x20aa, 0x20aa}, /* NewSheqelSign */ {0x20ab, 0x20ab}, /* DongSign */ {0x20ac, 0x20ac}, /* EuroSign */ {0x06ad, 0x0491}, /* Ukrainian_ghe_with_upturn */ {0x06bd, 0x0490}, /* Ukrainian_GHE_WITH_UPTURN */ {0x14a2, 0x0587}, /* Armenian_ligature_ew */ {0x14a3, 0x0589}, /* Armenian_verjaket */ {0x14aa, 0x055d}, /* Armenian_but */ {0x14ad, 0x058a}, /* Armenian_yentamna */ {0x14af, 0x055c}, /* Armenian_amanak */ {0x14b0, 0x055b}, /* Armenian_shesht */ {0x14b1, 0x055e}, /* Armenian_paruyk */ {0x14b2, 0x0531}, /* Armenian_AYB */ {0x14b3, 0x0561}, /* Armenian_ayb */ {0x14b4, 0x0532}, /* Armenian_BEN */ {0x14b5, 0x0562}, /* Armenian_ben */ {0x14b6, 0x0533}, /* Armenian_GIM */ {0x14b7, 0x0563}, /* Armenian_gim */ {0x14b8, 0x0534}, /* Armenian_DA */ {0x14b9, 0x0564}, /* Armenian_da */ {0x14ba, 0x0535}, /* Armenian_YECH */ {0x14bb, 0x0565}, /* Armenian_yech */ {0x14bc, 0x0536}, /* Armenian_ZA */ {0x14bd, 0x0566}, /* Armenian_za */ {0x14be, 0x0537}, /* Armenian_E */ {0x14bf, 0x0567}, /* Armenian_e */ {0x14c0, 0x0538}, /* Armenian_AT */ {0x14c1, 0x0568}, /* Armenian_at */ {0x14c2, 0x0539}, /* Armenian_TO */ {0x14c3, 0x0569}, /* Armenian_to */ {0x14c4, 0x053a}, /* Armenian_ZHE */ {0x14c5, 0x056a}, /* Armenian_zhe */ {0x14c6, 0x053b}, /* Armenian_INI */ {0x14c7, 0x056b}, /* Armenian_ini */ {0x14c8, 0x053c}, /* Armenian_LYUN */ {0x14c9, 0x056c}, /* Armenian_lyun */ {0x14ca, 0x053d}, /* Armenian_KHE */ {0x14cb, 0x056d}, /* Armenian_khe */ {0x14cc, 0x053e}, /* Armenian_TSA */ {0x14cd, 0x056e}, /* Armenian_tsa */ {0x14ce, 0x053f}, /* Armenian_KEN */ {0x14cf, 0x056f}, /* Armenian_ken */ {0x14d0, 0x0540}, /* Armenian_HO */ {0x14d1, 0x0570}, /* Armenian_ho */ {0x14d2, 0x0541}, /* Armenian_DZA */ {0x14d3, 0x0571}, /* Armenian_dza */ {0x14d4, 0x0542}, /* Armenian_GHAT */ {0x14d5, 0x0572}, /* Armenian_ghat */ {0x14d6, 0x0543}, /* Armenian_TCHE */ {0x14d7, 0x0573}, /* Armenian_tche */ {0x14d8, 0x0544}, /* Armenian_MEN */ {0x14d9, 0x0574}, /* Armenian_men */ {0x14da, 0x0545}, /* Armenian_HI */ {0x14db, 0x0575}, /* Armenian_hi */ {0x14dc, 0x0546}, /* Armenian_NU */ {0x14dd, 0x0576}, /* Armenian_nu */ {0x14de, 0x0547}, /* Armenian_SHA */ {0x14df, 0x0577}, /* Armenian_sha */ {0x14e0, 0x0548}, /* Armenian_VO */ {0x14e1, 0x0578}, /* Armenian_vo */ {0x14e2, 0x0549}, /* Armenian_CHA */ {0x14e3, 0x0579}, /* Armenian_cha */ {0x14e4, 0x054a}, /* Armenian_PE */ {0x14e5, 0x057a}, /* Armenian_pe */ {0x14e6, 0x054b}, /* Armenian_JE */ {0x14e7, 0x057b}, /* Armenian_je */ {0x14e8, 0x054c}, /* Armenian_RA */ {0x14e9, 0x057c}, /* Armenian_ra */ {0x14ea, 0x054d}, /* Armenian_SE */ {0x14eb, 0x057d}, /* Armenian_se */ {0x14ec, 0x054e}, /* Armenian_VEV */ {0x14ed, 0x057e}, /* Armenian_vev */ {0x14ee, 0x054f}, /* Armenian_TYUN */ {0x14ef, 0x057f}, /* Armenian_tyun */ {0x14f0, 0x0550}, /* Armenian_RE */ {0x14f1, 0x0580}, /* Armenian_re */ {0x14f2, 0x0551}, /* Armenian_TSO */ {0x14f3, 0x0581}, /* Armenian_tso */ {0x14f4, 0x0552}, /* Armenian_VYUN */ {0x14f5, 0x0582}, /* Armenian_vyun */ {0x14f6, 0x0553}, /* Armenian_PYUR */ {0x14f7, 0x0583}, /* Armenian_pyur */ {0x14f8, 0x0554}, /* Armenian_KE */ {0x14f9, 0x0584}, /* Armenian_ke */ {0x14fa, 0x0555}, /* Armenian_O */ {0x14fb, 0x0585}, /* Armenian_o */ {0x14fc, 0x0556}, /* Armenian_FE */ {0x14fd, 0x0586}, /* Armenian_fe */ {0x14fe, 0x055a}, /* Armenian_apostrophe */ {0x15d0, 0x10d0}, /* Georgian_an */ {0x15d1, 0x10d1}, /* Georgian_ban */ {0x15d2, 0x10d2}, /* Georgian_gan */ {0x15d3, 0x10d3}, /* Georgian_don */ {0x15d4, 0x10d4}, /* Georgian_en */ {0x15d5, 0x10d5}, /* Georgian_vin */ {0x15d6, 0x10d6}, /* Georgian_zen */ {0x15d7, 0x10d7}, /* Georgian_tan */ {0x15d8, 0x10d8}, /* Georgian_in */ {0x15d9, 0x10d9}, /* Georgian_kan */ {0x15da, 0x10da}, /* Georgian_las */ {0x15db, 0x10db}, /* Georgian_man */ {0x15dc, 0x10dc}, /* Georgian_nar */ {0x15dd, 0x10dd}, /* Georgian_on */ {0x15de, 0x10de}, /* Georgian_par */ {0x15df, 0x10df}, /* Georgian_zhar */ {0x15e0, 0x10e0}, /* Georgian_rae */ {0x15e1, 0x10e1}, /* Georgian_san */ {0x15e2, 0x10e2}, /* Georgian_tar */ {0x15e3, 0x10e3}, /* Georgian_un */ {0x15e4, 0x10e4}, /* Georgian_phar */ {0x15e5, 0x10e5}, /* Georgian_khar */ {0x15e6, 0x10e6}, /* Georgian_ghan */ {0x15e7, 0x10e7}, /* Georgian_qar */ {0x15e8, 0x10e8}, /* Georgian_shin */ {0x15e9, 0x10e9}, /* Georgian_chin */ {0x15ea, 0x10ea}, /* Georgian_can */ {0x15eb, 0x10eb}, /* Georgian_jil */ {0x15ec, 0x10ec}, /* Georgian_cil */ {0x15ed, 0x10ed}, /* Georgian_char */ {0x15ee, 0x10ee}, /* Georgian_xan */ {0x15ef, 0x10ef}, /* Georgian_jhan */ {0x15f0, 0x10f0}, /* Georgian_hae */ {0x15f1, 0x10f1}, /* Georgian_he */ {0x15f2, 0x10f2}, /* Georgian_hie */ {0x15f3, 0x10f3}, /* Georgian_we */ {0x15f4, 0x10f4}, /* Georgian_har */ {0x15f5, 0x10f5}, /* Georgian_hoe */ {0x15f6, 0x10f6}, /* Georgian_fi */ {0x12a1, 0x1e02}, /* Babovedot */ {0x12a2, 0x1e03}, /* babovedot */ {0x12a6, 0x1e0a}, /* Dabovedot */ {0x12a8, 0x1e80}, /* Wgrave */ {0x12aa, 0x1e82}, /* Wacute */ {0x12ab, 0x1e0b}, /* dabovedot */ {0x12ac, 0x1ef2}, /* Ygrave */ {0x12b0, 0x1e1e}, /* Fabovedot */ {0x12b1, 0x1e1f}, /* fabovedot */ {0x12b4, 0x1e40}, /* Mabovedot */ {0x12b5, 0x1e41}, /* mabovedot */ {0x12b7, 0x1e56}, /* Pabovedot */ {0x12b8, 0x1e81}, /* wgrave */ {0x12b9, 0x1e57}, /* pabovedot */ {0x12ba, 0x1e83}, /* wacute */ {0x12bb, 0x1e60}, /* Sabovedot */ {0x12bc, 0x1ef3}, /* ygrave */ {0x12bd, 0x1e84}, /* Wdiaeresis */ {0x12be, 0x1e85}, /* wdiaeresis */ {0x12bf, 0x1e61}, /* sabovedot */ {0x12d0, 0x0174}, /* Wcircumflex */ {0x12d7, 0x1e6a}, /* Tabovedot */ {0x12de, 0x0176}, /* Ycircumflex */ {0x12f0, 0x0175}, /* wcircumflex */ {0x12f7, 0x1e6b}, /* tabovedot */ {0x12fe, 0x0177}, /* ycircumflex */ {0x0590, 0x06f0}, /* Farsi_0 */ {0x0591, 0x06f1}, /* Farsi_1 */ {0x0592, 0x06f2}, /* Farsi_2 */ {0x0593, 0x06f3}, /* Farsi_3 */ {0x0594, 0x06f4}, /* Farsi_4 */ {0x0595, 0x06f5}, /* Farsi_5 */ {0x0596, 0x06f6}, /* Farsi_6 */ {0x0597, 0x06f7}, /* Farsi_7 */ {0x0598, 0x06f8}, /* Farsi_8 */ {0x0599, 0x06f9}, /* Farsi_9 */ {0x05a5, 0x066a}, /* Arabic_percent */ {0x05a6, 0x0670}, /* Arabic_superscript_alef */ {0x05a7, 0x0679}, /* Arabic_tteh */ {0x05a8, 0x067e}, /* Arabic_peh */ {0x05a9, 0x0686}, /* Arabic_tcheh */ {0x05aa, 0x0688}, /* Arabic_ddal */ {0x05ab, 0x0691}, /* Arabic_rreh */ {0x05ae, 0x06d4}, /* Arabic_fullstop */ {0x05b0, 0x0660}, /* Arabic_0 */ {0x05b1, 0x0661}, /* Arabic_1 */ {0x05b2, 0x0662}, /* Arabic_2 */ {0x05b3, 0x0663}, /* Arabic_3 */ {0x05b4, 0x0664}, /* Arabic_4 */ {0x05b5, 0x0665}, /* Arabic_5 */ {0x05b6, 0x0666}, /* Arabic_6 */ {0x05b7, 0x0667}, /* Arabic_7 */ {0x05b8, 0x0668}, /* Arabic_8 */ {0x05b9, 0x0669}, /* Arabic_9 */ {0x05f3, 0x0653}, /* Arabic_madda_above */ {0x05f4, 0x0654}, /* Arabic_hamza_above */ {0x05f5, 0x0655}, /* Arabic_hamza_below */ {0x05f6, 0x0698}, /* Arabic_jeh */ {0x05f7, 0x06a4}, /* Arabic_veh */ {0x05f8, 0x06a9}, /* Arabic_keheh */ {0x05f9, 0x06af}, /* Arabic_gaf */ {0x05fa, 0x06ba}, /* Arabic_noon_ghunna */ {0x05fb, 0x06be}, /* Arabic_heh_doachashmee */ {0x05fc, 0x06cc}, /* Farsi_yeh */ {0x05fd, 0x06d2}, /* Arabic_yeh_baree */ {0x05fe, 0x06c1}, /* Arabic_heh_goal */ {0x0680, 0x0492}, /* Cyrillic_GHE_bar */ {0x0681, 0x0496}, /* Cyrillic_ZHE_descender */ {0x0682, 0x049a}, /* Cyrillic_KA_descender */ {0x0683, 0x049c}, /* Cyrillic_KA_vertstroke */ {0x0684, 0x04a2}, /* Cyrillic_EN_descender */ {0x0685, 0x04ae}, /* Cyrillic_U_straight */ {0x0686, 0x04b0}, /* Cyrillic_U_straight_bar */ {0x0687, 0x04b2}, /* Cyrillic_HA_descender */ {0x0688, 0x04b6}, /* Cyrillic_CHE_descender */ {0x0689, 0x04b8}, /* Cyrillic_CHE_vertstroke */ {0x068a, 0x04ba}, /* Cyrillic_SHHA */ {0x068c, 0x04d8}, /* Cyrillic_SCHWA */ {0x068d, 0x04e2}, /* Cyrillic_I_macron */ {0x068e, 0x04e8}, /* Cyrillic_O_bar */ {0x068f, 0x04ee}, /* Cyrillic_U_macron */ {0x0690, 0x0493}, /* Cyrillic_ghe_bar */ {0x0691, 0x0497}, /* Cyrillic_zhe_descender */ {0x0692, 0x049b}, /* Cyrillic_ka_descender */ {0x0693, 0x049d}, /* Cyrillic_ka_vertstroke */ {0x0694, 0x04a3}, /* Cyrillic_en_descender */ {0x0695, 0x04af}, /* Cyrillic_u_straight */ {0x0696, 0x04b1}, /* Cyrillic_u_straight_bar */ {0x0697, 0x04b3}, /* Cyrillic_ha_descender */ {0x0698, 0x04b7}, /* Cyrillic_che_descender */ {0x0699, 0x04b9}, /* Cyrillic_che_vertstroke */ {0x069a, 0x04bb}, /* Cyrillic_shha */ {0x069c, 0x04d9}, /* Cyrillic_schwa */ {0x069d, 0x04e3}, /* Cyrillic_i_macron */ {0x069e, 0x04e9}, /* Cyrillic_o_bar */ {0x069f, 0x04ef}, /* Cyrillic_u_macron */ {0x16a3, 0x1e8a}, /* Xabovedot */ {0x16a6, 0x012c}, /* Ibreve */ {0x16a9, 0x01b5}, /* Zstroke */ {0x16aa, 0x01e6}, /* Gcaron */ {0x16af, 0x019f}, /* Obarred */ {0x16b3, 0x1e8b}, /* xabovedot */ {0x16b6, 0x012d}, /* ibreve */ {0x16b9, 0x01b6}, /* zstroke */ {0x16ba, 0x01e7}, /* gcaron */ {0x16bd, 0x01d2}, /* ocaron */ {0x16bf, 0x0275}, /* obarred */ {0x16c6, 0x018f}, /* SCHWA */ {0x16f6, 0x0259}, /* schwa */ {0x16d1, 0x1e36}, /* Lbelowdot */ {0x16e1, 0x1e37}, /* lbelowdot */ {0x1ea0, 0x1ea0}, /* Abelowdot */ {0x1ea1, 0x1ea1}, /* abelowdot */ {0x1ea2, 0x1ea2}, /* Ahook */ {0x1ea3, 0x1ea3}, /* ahook */ {0x1ea4, 0x1ea4}, /* Acircumflexacute */ {0x1ea5, 0x1ea5}, /* acircumflexacute */ {0x1ea6, 0x1ea6}, /* Acircumflexgrave */ {0x1ea7, 0x1ea7}, /* acircumflexgrave */ {0x1ea8, 0x1ea8}, /* Acircumflexhook */ {0x1ea9, 0x1ea9}, /* acircumflexhook */ {0x1eaa, 0x1eaa}, /* Acircumflextilde */ {0x1eab, 0x1eab}, /* acircumflextilde */ {0x1eac, 0x1eac}, /* Acircumflexbelowdot */ {0x1ead, 0x1ead}, /* acircumflexbelowdot */ {0x1eae, 0x1eae}, /* Abreveacute */ {0x1eaf, 0x1eaf}, /* abreveacute */ {0x1eb0, 0x1eb0}, /* Abrevegrave */ {0x1eb1, 0x1eb1}, /* abrevegrave */ {0x1eb2, 0x1eb2}, /* Abrevehook */ {0x1eb3, 0x1eb3}, /* abrevehook */ {0x1eb4, 0x1eb4}, /* Abrevetilde */ {0x1eb5, 0x1eb5}, /* abrevetilde */ {0x1eb6, 0x1eb6}, /* Abrevebelowdot */ {0x1eb7, 0x1eb7}, /* abrevebelowdot */ {0x1eb8, 0x1eb8}, /* Ebelowdot */ {0x1eb9, 0x1eb9}, /* ebelowdot */ {0x1eba, 0x1eba}, /* Ehook */ {0x1ebb, 0x1ebb}, /* ehook */ {0x1ebc, 0x1ebc}, /* Etilde */ {0x1ebd, 0x1ebd}, /* etilde */ {0x1ebe, 0x1ebe}, /* Ecircumflexacute */ {0x1ebf, 0x1ebf}, /* ecircumflexacute */ {0x1ec0, 0x1ec0}, /* Ecircumflexgrave */ {0x1ec1, 0x1ec1}, /* ecircumflexgrave */ {0x1ec2, 0x1ec2}, /* Ecircumflexhook */ {0x1ec3, 0x1ec3}, /* ecircumflexhook */ {0x1ec4, 0x1ec4}, /* Ecircumflextilde */ {0x1ec5, 0x1ec5}, /* ecircumflextilde */ {0x1ec6, 0x1ec6}, /* Ecircumflexbelowdot */ {0x1ec7, 0x1ec7}, /* ecircumflexbelowdot */ {0x1ec8, 0x1ec8}, /* Ihook */ {0x1ec9, 0x1ec9}, /* ihook */ {0x1eca, 0x1eca}, /* Ibelowdot */ {0x1ecb, 0x1ecb}, /* ibelowdot */ {0x1ecc, 0x1ecc}, /* Obelowdot */ {0x1ecd, 0x1ecd}, /* obelowdot */ {0x1ece, 0x1ece}, /* Ohook */ {0x1ecf, 0x1ecf}, /* ohook */ {0x1ed0, 0x1ed0}, /* Ocircumflexacute */ {0x1ed1, 0x1ed1}, /* ocircumflexacute */ {0x1ed2, 0x1ed2}, /* Ocircumflexgrave */ {0x1ed3, 0x1ed3}, /* ocircumflexgrave */ {0x1ed4, 0x1ed4}, /* Ocircumflexhook */ {0x1ed5, 0x1ed5}, /* ocircumflexhook */ {0x1ed6, 0x1ed6}, /* Ocircumflextilde */ {0x1ed7, 0x1ed7}, /* ocircumflextilde */ {0x1ed8, 0x1ed8}, /* Ocircumflexbelowdot */ {0x1ed9, 0x1ed9}, /* ocircumflexbelowdot */ {0x1eda, 0x1eda}, /* Ohornacute */ {0x1edb, 0x1edb}, /* ohornacute */ {0x1edc, 0x1edc}, /* Ohorngrave */ {0x1edd, 0x1edd}, /* ohorngrave */ {0x1ede, 0x1ede}, /* Ohornhook */ {0x1edf, 0x1edf}, /* ohornhook */ {0x1ee0, 0x1ee0}, /* Ohorntilde */ {0x1ee1, 0x1ee1}, /* ohorntilde */ {0x1ee2, 0x1ee2}, /* Ohornbelowdot */ {0x1ee3, 0x1ee3}, /* ohornbelowdot */ {0x1ee4, 0x1ee4}, /* Ubelowdot */ {0x1ee5, 0x1ee5}, /* ubelowdot */ {0x1ee6, 0x1ee6}, /* Uhook */ {0x1ee7, 0x1ee7}, /* uhook */ {0x1ee8, 0x1ee8}, /* Uhornacute */ {0x1ee9, 0x1ee9}, /* uhornacute */ {0x1eea, 0x1eea}, /* Uhorngrave */ {0x1eeb, 0x1eeb}, /* uhorngrave */ {0x1eec, 0x1eec}, /* Uhornhook */ {0x1eed, 0x1eed}, /* uhornhook */ {0x1eee, 0x1eee}, /* Uhorntilde */ {0x1eef, 0x1eef}, /* uhorntilde */ {0x1ef0, 0x1ef0}, /* Uhornbelowdot */ {0x1ef1, 0x1ef1}, /* uhornbelowdot */ {0x1ef4, 0x1ef4}, /* Ybelowdot */ {0x1ef5, 0x1ef5}, /* ybelowdot */ {0x1ef6, 0x1ef6}, /* Yhook */ {0x1ef7, 0x1ef7}, /* yhook */ {0x1ef8, 0x1ef8}, /* Ytilde */ {0x1ef9, 0x1ef9}, /* ytilde */ {0x1efa, 0x01a0}, /* Ohorn */ {0x1efb, 0x01a1}, /* ohorn */ {0x1efc, 0x01af}, /* Uhorn */ {0x1efd, 0x01b0}, /* uhorn */ {0, 0} }; #endif |
Changes to macosx/tkMacOSXMouseEvent.c.
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | - (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent { NSWindow *eventWindow = [theEvent window]; NSEventType eventType = [theEvent type]; TkWindow *winPtr = NULL, *grabWinPtr; Tk_Window tkwin; NSPoint local, global; #if 0 NSTrackingArea *trackingArea = nil; NSInteger eventNumber, clickCount, buttonNumber; #endif [NSEvent stopPeriodicEvents]; #ifdef TK_MAC_DEBUG_EVENTS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent); #endif switch (eventType) { | > < < < < < < > > > > > > > > > > > > > > > > > > > > > > | 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 | - (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent { NSWindow *eventWindow = [theEvent window]; NSEventType eventType = [theEvent type]; TkWindow *winPtr = NULL, *grabWinPtr; Tk_Window tkwin; NSPoint local, global; NSInteger button = -1; #if 0 NSTrackingArea *trackingArea = nil; NSInteger eventNumber, clickCount, buttonNumber; #endif [NSEvent stopPeriodicEvents]; #ifdef TK_MAC_DEBUG_EVENTS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent); #endif switch (eventType) { case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: button = [theEvent buttonNumber] + Button1; case NSMouseEntered: case NSMouseExited: case NSCursorUpdate: case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: case NSMouseMoved: case NSTabletPoint: case NSTabletProximity: case NSScrollWheel: break; default: /* Unrecognized mouse event. */ return theEvent; } /* * Compute the mouse position in Tk screen coordinates (global) and in the * Tk coordinates of its containing Tk Window (local). If a grab is in effect, * the local coordinates should be relative to the grab window. */ if (eventWindow) { local = [theEvent locationInWindow]; /* * Do not send ButtonPress XEvents for MouseDown NSEvents that start a * resize. (The MouseUp will be handled during LiveResize.) See * ticket [d72abe6b54]. */ if (eventType == NSEventTypeLeftMouseDown && ([eventWindow styleMask] & NSWindowStyleMaskResizable) && [NSApp macMinorVersion] > 6) { NSRect frame = [eventWindow frame]; if (local.x < 3 || local.x > frame.size.width - 3 || local.y < 3) { return theEvent; } } global = [eventWindow tkConvertPointToScreen: local]; tkwin = TkMacOSXGetCapture(); if (tkwin) { winPtr = (TkWindow *) tkwin; eventWindow = TkMacOSXDrawableWindow(winPtr->window); if (eventWindow) { local = [eventWindow tkConvertPointFromScreen: global]; |
︙ | ︙ | |||
207 208 209 210 211 212 213 | local.y = win_y; /* * Generate an XEvent for this mouse event. */ unsigned int state = 0; | < < < < < < < < | < < < < < < | < < < < | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | local.y = win_y; /* * Generate an XEvent for this mouse event. */ unsigned int state = 0; if (button > 0) { state |= TkGetButtonMask(button); } NSUInteger modifiers = [theEvent modifierFlags]; if (modifiers & NSAlphaShiftKeyMask) { state |= LockMask; } |
︙ | ︙ |
Changes to macosx/tkMacOSXNotify.c.
︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | /* * Since the contentView is the first responder for a Tk Window, it is * responsible for sending events up the responder chain. We also check the * pasteboard here. */ - (void) sendEvent: (NSEvent *) theEvent { [super sendEvent:theEvent]; [NSApp tkCheckPasteboard]; #ifdef TK_MAC_DEBUG_EVENTS fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]); DebugPrintQueue(); #endif } @end #pragma mark - /* *---------------------------------------------------------------------- | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /* * Since the contentView is the first responder for a Tk Window, it is * responsible for sending events up the responder chain. We also check the * pasteboard here. */ - (void) sendEvent: (NSEvent *) theEvent { /* * Workaround for an Apple bug. When an accented character is selected * from an NSTextInputClient popup character viewer with the mouse, Apple * sends an event of type NSEventTypeAppKitDefined and subtype 21. If that * event is sent up the responder chain it causes Apple to print a warning * to the console log and, extremely obnoxiously, also to stderr, which * says "Window move completed without beginning." Apparently they are * sending the "move completed" event without having sent the "move began" * event of subtype 20, and then announcing their error on our stderr. * Also, of course, no movement is occurring. The popup is not movable and * is just being closed. The bug has been reported to Apple. If they ever * fix it, this block should be removed. */ if ([theEvent type] == NSEventTypeAppKitDefined) { static Bool aWindowIsMoving = NO; switch([theEvent subtype]) { case 20: aWindowIsMoving = YES; break; case 21: if (aWindowIsMoving) { aWindowIsMoving = NO; break; } else { // printf("Bug!!!!\n"); return; } default: break; } } [super sendEvent:theEvent]; [NSApp tkCheckPasteboard]; #ifdef TK_MAC_DEBUG_EVENTS fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]); DebugPrintQueue(); #endif } @end #pragma mark - /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to macosx/tkMacOSXPrivate.h.
︙ | ︙ | |||
118 119 120 121 122 123 124 125 126 127 128 129 130 131 | #define TkMacOSXInitNamedSymbol(module, ret, symbol, ...) \ static ret (* symbol)(__VA_ARGS__) = (void*)(-1L); \ if (symbol == (void*)(-1L)) { \ symbol = TkMacOSXGetNamedSymbol(STRINGIFY(module), \ STRINGIFY(symbol)); \ } /* * Structure encapsulating current drawing environment. */ typedef struct TkMacOSXDrawingContext { CGContextRef context; NSView *view; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | #define TkMacOSXInitNamedSymbol(module, ret, symbol, ...) \ static ret (* symbol)(__VA_ARGS__) = (void*)(-1L); \ if (symbol == (void*)(-1L)) { \ symbol = TkMacOSXGetNamedSymbol(STRINGIFY(module), \ STRINGIFY(symbol)); \ } /* * The structure of a 32-bit XEvent keycode on macOS. It may be viewed as * an unsigned int or as having either two or three bitfields. */ typedef struct keycode_v_t { unsigned keychar: 22; /* UCS-32 character */ unsigned o_s: 2; /* State of Option and Shift keys. */ unsigned virtual: 8; /* 8-bit virtual keycode - identifies a key. */ } keycode_v; typedef struct keycode_x_t { unsigned keychar: 22; /* UCS-32 character */ unsigned xvirtual: 10; /* Combines o_s and virtual. This 10-bit integer * is used as a key for looking up the character * produced when pressing a key with a particular * Shift and Option modifier state. */ } keycode_x; typedef union MacKeycode_t { unsigned int uint; keycode_v v; keycode_x x; } MacKeycode; /* * Macros used in tkMacOSXKeyboard.c and tkMacOSXKeyEvent.c. * Note that 0x7f is del and 0xF8FF is the Apple Logo character. */ #define ON_KEYPAD(virtual) ((virtual >= 0x41) && (virtual <= 0x5C)) #define IS_PRINTABLE(keychar) ((keychar >= 0x20) && (keychar != 0x7f) && \ ((keychar < 0xF700) || keychar >= 0xF8FF)) /* * An "index" is 2-bit bitfield showing the state of the Option and Shift * keys. It is used as an index when building the keymaps and it * is the value of the o_s bitfield of a keycode_v. */ #define INDEX_SHIFT 1 #define INDEX_OPTION 2 #define INDEX2STATE(index) ((index & INDEX_SHIFT ? ShiftMask : 0) | \ (index & INDEX_OPTION ? Mod2Mask : 0)) #define INDEX2CARBON(index) ((index & INDEX_SHIFT ? shiftKey : 0) | \ (index & INDEX_OPTION ? optionKey : 0)) #define STATE2INDEX(state) ((state & ShiftMask ? INDEX_SHIFT : 0) | \ (state & Mod2Mask ? INDEX_OPTION : 0)) /* * Special values for the virtual bitfield. Actual virtual keycodes are < 128. */ #define NO_VIRTUAL 0xFF /* Not generated by a key or the NSText"InputClient. */ #define REPLACEMENT_VIRTUAL 0x80 /* A BMP char sent by the NSTextInputClient. */ #define NON_BMP_VIRTUAL 0x81 /* A non-BMP char sent by the NSTextInputClient. */ /* * A special character is used in the keycode for simulated modifier KeyPress * or KeyRelease XEvents. It is near the end of the private-use range but * different from the UniChar 0xF8FF which Apple uses for their logo character. * A different special character is used for keys, like the Menu key, which do * not appear on Macintosh keyboards. */ #define MOD_KEYCHAR 0xF8FE #define UNKNOWN_KEYCHAR 0xF8FD /* * Structure encapsulating current drawing environment. */ typedef struct TkMacOSXDrawingContext { CGContextRef context; NSView *view; |
︙ | ︙ | |||
235 236 237 238 239 240 241 242 243 244 245 246 247 248 | MODULE_SCOPE int TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE NSString* TkUtfToNSString(const char *source, size_t numBytes); MODULE_SCOPE int TkUtfAtIndex(NSString *string, int index, char *uni, unsigned int *code); MODULE_SCOPE char* TkNSStringToUtf(NSString *string, int *numBytes); #pragma mark Private Objective-C Classes #define VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu}; | > | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | MODULE_SCOPE int TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE NSString* TkUtfToNSString(const char *source, size_t numBytes); MODULE_SCOPE int TkUtfAtIndex(NSString *string, int index, char *uni, unsigned int *code); MODULE_SCOPE char* TkNSStringToUtf(NSString *string, int *numBytes); MODULE_SCOPE unsigned TkMacOSXAddVirtual(unsigned int keycode); #pragma mark Private Objective-C Classes #define VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu}; |
︙ | ︙ | |||
352 353 354 355 356 357 358 359 360 361 362 363 364 365 | Bool _needsRedisplay; } @property Bool needsRedisplay; @end @interface TKContentView(TKKeyEvent) - (void) deleteWorkingText; @end @interface TKContentView(TKWindowEvent) - (void) generateExposeEvents: (HIShapeRef) shape; - (void) tkToolbarButton: (id) sender; @end | > | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | Bool _needsRedisplay; } @property Bool needsRedisplay; @end @interface TKContentView(TKKeyEvent) - (void) deleteWorkingText; - (void) cancelComposingText; @end @interface TKContentView(TKWindowEvent) - (void) generateExposeEvents: (HIShapeRef) shape; - (void) tkToolbarButton: (id) sender; @end |
︙ | ︙ | |||
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | * declare it here to be a method of the TKMenu category. */ @interface NSApplication(TKMenu) - (void) setAppleMenu: (NSMenu *) menu; @end #endif /* _TKMACPRIV */ int TkMacOSXGetAppPath(ClientData cd, Tcl_Interp *ip, int objc, Tcl_Obj *const objv[]); /* * Local Variables: * mode: objc * c-basic-offset: 4 * fill-column: 79 * coding: utf-8 * End: */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 | * declare it here to be a method of the TKMenu category. */ @interface NSApplication(TKMenu) - (void) setAppleMenu: (NSMenu *) menu; @end /* * These methods are exposed because they are needed to prevent zombie windows * on systems with a TouchBar. The TouchBar Key-Value observer holds a * reference to the key window, which prevents deallocation of the key window * when it is closed. */ @interface NSApplication(TkWm) - (id) _setKeyWindow: (NSWindow *) window; - (id) _setMainWindow: (NSWindow *) window; @end /* *--------------------------------------------------------------------------- * * TKNSString -- * * When Tcl is compiled with TCL_UTF_MAX = 3 (the default for 8.6) it cannot * deal directly with UTF-8 encoded non-BMP characters, since their UTF-8 * encoding requires 4 bytes. * * As a workaround, these versions of Tcl encode non-BMP characters as a string * of length 6 in which the high and low UTF-16 surrogates have been encoded * using the UTF-8 algorithm. The UTF-8 encoding does not allow encoding * surrogates, so these 6-byte strings are not valid UTF-8, and hence Apple's * NString class will refuse to instantiate an NSString from the 6-byte * encoding. * * This subclass of NSString adds a new initialization method which accepts * a C string encoded with the scheme described above. * *--------------------------------------------------------------------------- */ @interface TKNSString:NSString { @private Tcl_DString _ds; NSString *_string; } @property const char *UTF8String; - (instancetype)initWithTclUtfBytes:(const void *)bytes length:(NSUInteger)len; @end #endif /* _TKMACPRIV */ int TkMacOSXGetAppPath(ClientData cd, Tcl_Interp *ip, int objc, Tcl_Obj *const objv[]); /* * Local Variables: * mode: objc * c-basic-offset: 4 * fill-column: 79 * coding: utf-8 * End: */ |
Changes to macosx/tkMacOSXTest.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #if MAC_OS_X_VERSION_MAX_ALLOWED < 1080 static int DebuggerObjCmd (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); #endif static int PressButtonObjCmd (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* *---------------------------------------------------------------------- * * TkplatformtestInit -- * | > > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #if MAC_OS_X_VERSION_MAX_ALLOWED < 1080 static int DebuggerObjCmd (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); #endif static int PressButtonObjCmd (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int InjectKeyEventObjCmd (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* *---------------------------------------------------------------------- * * TkplatformtestInit -- * |
︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 62 63 64 65 | * Add commands for platform specific tests on MacOS here. */ #if MAC_OS_X_VERSION_MAX_ALLOWED < 1080 Tcl_CreateObjCommand(interp, "debugger", DebuggerObjCmd, NULL, NULL); #endif Tcl_CreateObjCommand(interp, "pressbutton", PressButtonObjCmd, NULL, NULL); return TCL_OK; } /* *---------------------------------------------------------------------- * | > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | * Add commands for platform specific tests on MacOS here. */ #if MAC_OS_X_VERSION_MAX_ALLOWED < 1080 Tcl_CreateObjCommand(interp, "debugger", DebuggerObjCmd, NULL, NULL); #endif Tcl_CreateObjCommand(interp, "pressbutton", PressButtonObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "injectkeyevent", InjectKeyEventObjCmd, NULL, NULL); return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
215 216 217 218 219 220 221 | eventNumber:2 clickCount:1 pressure:0.0]; [NSApp postEvent:release atStart:NO]; return TCL_OK; } | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | eventNumber:2 clickCount:1 pressure:0.0]; [NSApp postEvent:release atStart:NO]; return TCL_OK; } static int InjectKeyEventObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { static const char *const optionStrings[] = { "press", "release", "flagschanged", NULL}; NSUInteger types[3] = {NSKeyDown, NSKeyUp, NSFlagsChanged}; static const char *const argStrings[] = { "-shift", "-control", "-option", "-command", "-function", "-x", "-y", NULL}; enum args {KEYEVENT_SHIFT, KEYEVENT_CONTROL, KEYEVENT_OPTION, KEYEVENT_COMMAND, KEYEVENT_FUNCTION, KEYEVENT_X, KEYEVENT_Y}; int i, index, keysym, mods = 0, x = 0, y = 0; NSString *chars = nil, *unmod = nil, *upper, *lower; NSEvent *keyEvent; NSUInteger type; MacKeycode macKC; if (objc < 3) { wrongArgs: Tcl_WrongNumArgs(interp, 1, objv, "option keysym ?arg?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } type = types[index]; if (Tcl_GetIntFromObj(interp, objv[2], &keysym) != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "keysym must be an integer")); Tcl_SetErrorCode(interp, "TK", "TEST", "INJECT", "KEYSYM", NULL); return TCL_ERROR; } macKC.uint = XKeysymToKeycode(NULL, keysym); for (i = 3; i < objc; i++) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], argStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum args) index) { case KEYEVENT_SHIFT: mods |= NSShiftKeyMask; break; case KEYEVENT_CONTROL: mods |= NSControlKeyMask; break; case KEYEVENT_OPTION: mods |= NSAlternateKeyMask; break; case KEYEVENT_COMMAND: mods |= NSCommandKeyMask; break; case KEYEVENT_FUNCTION: mods |= NSFunctionKeyMask; break; case KEYEVENT_X: if (++i >= objc) { goto wrongArgs; } if (Tcl_GetIntFromObj(interp,objv[i], &x) != TCL_OK) { return TCL_ERROR; } break; case KEYEVENT_Y: if (++i >= objc) { goto wrongArgs; } if (Tcl_GetIntFromObj(interp,objv[i], &y) != TCL_OK) { return TCL_ERROR; } break; } } if (type != NSFlagsChanged) { UniChar keychar = macKC.v.keychar; chars = [[NSString alloc] initWithCharacters: &keychar length:1]; upper = [chars uppercaseString]; lower = [chars lowercaseString]; if (![upper isEqual: lower] && [chars isEqual: upper]) { mods |= NSShiftKeyMask; } if (mods & NSShiftKeyMask) { chars = upper; unmod = lower; macKC.v.o_s |= INDEX_SHIFT; } else { unmod = chars; } if (macKC.v.o_s & INDEX_OPTION) { mods |= NSAlternateKeyMask; } } keyEvent = [NSEvent keyEventWithType:type location:NSMakePoint(x, y) modifierFlags:mods timestamp:GetCurrentEventTime() windowNumber:0 context:nil characters:chars charactersIgnoringModifiers:unmod isARepeat:NO keyCode:macKC.v.virtual]; [NSApp postEvent:keyEvent atStart:NO]; return TCL_OK; } /* * Local Variables: * mode: objc * c-basic-offset: 4 * fill-column: 79 * coding: utf-8 * End: */ |
Changes to macosx/tkMacOSXWindowEvent.c.
︙ | ︙ | |||
311 312 313 314 315 316 317 318 319 320 321 322 323 324 | } - (void) applicationDeactivate: (NSNotification *) notification { #ifdef TK_MAC_DEBUG_NOTIFICATIONS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); #endif } - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag { /* * Allowing the default response means that withdrawn windows will get | > > > > > > > > > > > > > > | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | } - (void) applicationDeactivate: (NSNotification *) notification { #ifdef TK_MAC_DEBUG_NOTIFICATIONS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); #endif /* * To prevent zombie windows on systems with a TouchBar, set the key window * to nil if the current key window is not visible. This allows a closed * Help or About window to be deallocated so it will not reappear as a * zombie when the app is reactivated. */ NSWindow *keywindow = [NSApp keyWindow]; if (keywindow && ![keywindow isVisible]) { [NSApp _setKeyWindow:nil]; [NSApp _setMainWindow:nil]; } } - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag { /* * Allowing the default response means that withdrawn windows will get |
︙ | ︙ |
Changes to macosx/tkMacOSXWm.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include "tkMacOSXPrivate.h" #include "tkScrollbar.h" #include "tkMacOSXWm.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" #include "tkMacOSXConstants.h" #define DEBUG_ZOMBIES 0 /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_WINDOWS #endif */ | > > > > > > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include "tkMacOSXPrivate.h" #include "tkScrollbar.h" #include "tkMacOSXWm.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" #include "tkMacOSXConstants.h" /* * Setting this to 1 prints when each window is freed, setting it to 2 adds * dumps of the autorelease pools, and setting it to 3 also shows each retain * and release. */ #define DEBUG_ZOMBIES 0 /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_WINDOWS #endif */ |
︙ | ︙ | |||
353 354 355 356 357 358 359 | @end #pragma mark - #pragma mark TKWindow(TKWm) @implementation TKWindow: NSWindow | < | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | @end #pragma mark - #pragma mark TKWindow(TKWm) @implementation TKWindow: NSWindow @end @implementation TKWindow(TKWm) /* * This method synchronizes Tk's understanding of the bounds of a contentView * with the window's. It is needed because there are situations when the |
︙ | ︙ | |||
426 427 428 429 430 431 432 | } return frameSize; } - (BOOL) canBecomeKeyWindow { TkWindow *winPtr = TkMacOSXGetTkWindow(self); | > | | | | | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | } return frameSize; } - (BOOL) canBecomeKeyWindow { TkWindow *winPtr = TkMacOSXGetTkWindow(self); if (!winPtr || !winPtr->wmInfoPtr) { return NO; } return (winPtr->wmInfoPtr && (winPtr->wmInfoPtr->macClass == kHelpWindowClass || winPtr->wmInfoPtr->attributes & kWindowNoActivatesAttribute) ) ? NO : YES; } #if DEBUG_ZOMBIES - (id) retain { id result = [super retain]; const char *title = [[self title] UTF8String]; if (title == nil) { title = "unnamed window"; } if (DEBUG_ZOMBIES > 2) { fprintf(stderr, "Retained <%s>. Count is: %lu\n", title, [self retainCount]); } return result; } - (id) autorelease { id result = [super autorelease]; const char *title = [[self title] UTF8String]; if (title == nil) { title = "unnamed window"; } if (DEBUG_ZOMBIES > 2) { fprintf(stderr, "Autoreleased <%s>. Count is %lu\n", title, [self retainCount]); } return result; } - (oneway void) release { const char *title = [[self title] UTF8String]; if (title == nil) { title = "unnamed window"; } if (DEBUG_ZOMBIES > 2) { fprintf(stderr, "Releasing <%s>. Count is %lu\n", title, [self retainCount]); } [super release]; } - (void) dealloc { |
︙ | ︙ | |||
875 876 877 878 879 880 881 882 883 884 885 886 887 888 | */ void TkWmDeadWindow( TkWindow *winPtr) /* Top-level window that's being deleted. */ { WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2; if (wmPtr == NULL) { return; } /* *If the dead window is a transient, remove it from the master's list. | > | 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 | */ void TkWmDeadWindow( TkWindow *winPtr) /* Top-level window that's being deleted. */ { WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2; NSWindow *ourNSWindow; if (wmPtr == NULL) { return; } /* *If the dead window is a transient, remove it from the master's list. |
︙ | ︙ | |||
948 949 950 951 952 953 954 | Transient *transientPtr = wmPtr->transientPtr; wmPtr->transientPtr = transientPtr->nextPtr; ckfree(transientPtr); } /* | | | < | | > > > > > | | < | > | | | < < < < | > > > | > > > > > > | > < | < | | < < < < < < < | | | < | > > > | | | | | | < < | < | > | > > > | | > > > > > > | 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 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 | Transient *transientPtr = wmPtr->transientPtr; wmPtr->transientPtr = transientPtr->nextPtr; ckfree(transientPtr); } /* * Unregister the NSWindow and remove all references to it from the Tk * data structures. If the NSWindow is a child, disassociate it from * the parent. Then close and release the NSWindow. */ ourNSWindow = wmPtr->window; if (ourNSWindow && !Tk_IsEmbedded(winPtr)) { NSWindow *parent = [ourNSWindow parentWindow]; TkMacOSXUnregisterMacWindow(ourNSWindow); if (winPtr->window) { ((MacDrawable *) winPtr->window)->view = nil; } wmPtr->window = NULL; if (parent) { [parent removeChildWindow:ourNSWindow]; } #if DEBUG_ZOMBIES > 1 { const char *title = [[ourNSWindow title] UTF8String]; if (title == nil) { title = "unnamed window"; } fprintf(stderr, ">>>> Closing <%s>. Count is: %lu\n", title, [ourNSWindow retainCount]); } #endif /* * When a window is closed we want to move the focus to the next * highest window. Apple's documentation says that calling the * orderOut method of the key window will accomplish this. But * experiment shows that this is not the case. So we have to reset the * key window ourselves. When the window is the last one on the screen * there is no choice for a new key window. Moreover, if the host * computer has a TouchBar then the TouchBar holds a reference to the * key window which prevents it from being deallocated until it stops * being the key window. On these systems the only option for * preventing zombies is to set the key window to nil. */ for (NSWindow *w in [NSApp orderedWindows]) { TkWindow *winPtr2 = TkMacOSXGetTkWindow(w); BOOL isOnScreen; if (!winPtr2 || !winPtr2->wmInfoPtr) { continue; } wmPtr2 = winPtr2->wmInfoPtr; isOnScreen = (wmPtr2->hints.initial_state != IconicState && wmPtr2->hints.initial_state != WithdrawnState); if (w != ourNSWindow && isOnScreen && [w canBecomeKeyWindow]) { [w makeKeyAndOrderFront:NSApp]; break; } } /* * Prevent zombies on systems with a TouchBar. */ if (ourNSWindow == [NSApp keyWindow]) { [NSApp _setKeyWindow:nil]; [NSApp _setMainWindow:nil]; } [ourNSWindow close]; [ourNSWindow release]; [NSApp _resetAutoreleasePool]; #if DEBUG_ZOMBIES > 1 fprintf(stderr, "================= Pool dump ===================\n"); [NSAutoreleasePool showPools]; #endif } /* * Deallocate the wmInfo and clear the wmInfoPtr. */ ckfree(wmPtr); winPtr->wmInfoPtr = NULL; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3785 3786 3787 3788 3789 3790 3791 | Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL); return TCL_ERROR; } TkpWmSetState(winPtr, WithdrawnState); NSWindow *win = TkMacOSXDrawableWindow(winPtr->window); | | | 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 | Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL); return TCL_ERROR; } TkpWmSetState(winPtr, WithdrawnState); NSWindow *win = TkMacOSXDrawableWindow(winPtr->window); [win orderOut:NSApp]; [win setExcludedFromWindowsMenu:YES]; /* * If this window has a transient, the transient must also be withdrawn. */ for (Transient *transientPtr = wmPtr->transientPtr; |
︙ | ︙ |
Changes to tests/bind.test.
︙ | ︙ | |||
6623 6624 6625 6626 6627 6628 6629 6630 6631 | # Old implementation failed, and returned "first", but this was wrong, # because both bindings are homogeneous equal, so the most recently defined # must be preferred. } -result {last} test bind-34.1 {-warp works relatively to a window} -setup { toplevel .top } -body { # In order to avoid platform-dependent coordinate results due to | > > | | 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 | # Old implementation failed, and returned "first", but this was wrong, # because both bindings are homogeneous equal, so the most recently defined # must be preferred. } -result {last} test bind-34.1 {-warp works relatively to a window} -setup { toplevel .top wm geometry .top +100+100 update } -body { # In order to avoid platform-dependent coordinate results due to # decorations and borders, this test warps the pointer twice # relatively to a window that moved in the meantime, and checks # how much the pointer moved wm geometry .top +200+200 update event generate .top <Motion> -x 20 -y 20 -warp 1 update idletasks ; # DoWarp is an idle callback after 50 ; # Win specific - wait for SendInput to be executed |
︙ | ︙ | |||
6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 | } else { lappend res $dim } } set res } -cleanup { } -result {ok ok ok ok} # cleanup cleanupTests return # vi:set ts=4 sw=4 et: # Local Variables: # mode: tcl # End: | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 | } else { lappend res $dim } } set res } -cleanup { } -result {ok ok ok ok} set keyInfo {} set numericKeysym {} proc testKey {window event type mods} { global keyInfo numericKeysym set keyInfo {} set numericKeysym {} bind $window <KeyPress> { set keyInfo [format "%K,0x%%X,0x%%X,%A" %N %k] set numericKeysym %N } focus -force $window update event generate $window $event if {$keyInfo == {}} { vwait keyInfo } set save $keyInfo set keyInfo {} set injectcmd [list injectkeyevent $type $numericKeysym] foreach {option} $mods { lappend injectcmd $option } eval $injectcmd if {$keyInfo == {}} { vwait keyInfo } if {$save != $keyInfo} { return "[format "0x%x" $numericKeysym] ($mods): $save != $keyInfo" } return pass } proc testKeyWithMods {window keysym type} { set result [testKey $window "<$keysym>" $type {}] if {$result != {pass}} { return $result } set result [testKey $window "<Shift-$keysym>" $type {-shift}] if {$result != {pass}} { return $result } set result [testKey $window "<Option-$keysym>" $type {-option}] if {$result != {pass}} { return $result } set result [testKey $window "<Shift-Option-$keysym>" $type {-shift -option}] if {$result != {pass}} { return $result } return pass } test bind-35.0 {Generated and real key events agree} -constraints {aqua} -body { foreach k {o O F2 Home Right Greek_sigma Greek_ALPHA} { set result [testKeyWithMods . $k press] if {$result != "pass"} { return $result } } return pass } -cleanup { } -result pass test bind-35.1 {Key events agree for entry widgets} -constraints {aqua} -setup { toplevel .new entry .new.e pack .new.e } -body { foreach k {o O F2 Home Right Greek_sigma Greek_ALPHA Menu} { set result [testKeyWithMods .new.e $k press] if {$result != "pass"} { return $result } } return pass } -cleanup { destroy .new.e destroy .new } -result pass test bind-35.2 {Can bind to function keys} -constraints {aqua} -body { global keyInfo numericKeysym bind . <KeyPress> {} bind . <KeyPress> { lappend keyInfo %K set numericKeysym %N } set keyInfo {} set numericKeysym {} focus -force . event generate . <F2> injectkeyevent press $numericKeysym -function vwait keyInfo return $keyInfo } -cleanup { } -result {F2 F2} test bind-35.3 {Events agree for modifier keys} -constraints {aqua} -setup { } -body { global keyInfo numericalKeysym set result {} bind . <KeyPress> { set keyInfo [format "%K,0x%%X,0x%%X,%A" %N %k] set numericalKeysym [format "0x%x" %N] } foreach event { {<Control_L> -control} {<Control_R> -control} {<Alt_L> -option} {<Alt_R> -option} {<Meta_L> -command} {<Meta_R> -command} {<Shift_L> -shift} {<Shift_R> -shift} } { set keyInfo {} event generate . [lindex $event 0] if {$keyInfo == {}} { vwait keyInfo } set save $keyInfo injectkeyevent flagschanged $numericKeysym [lindex $event 1] if {$keyInfo == {}} { vwait keyInfo } if {$save != $keyInfo} { return "$save != $keyInfo" } } return pass } -cleanup { } -result pass # cleanup cleanupTests return # vi:set ts=4 sw=4 et: # Local Variables: # mode: tcl # End: |
Changes to tests/canvImg.test.
︙ | ︙ | |||
799 800 801 802 803 804 805 | } -body { image create test foo -variable x image create test foo2 -variable z foo changed 0 0 0 0 40 50 foo2 changed 0 0 0 0 80 60 .c create image 50 100 -image foo -tags image -anchor nw .c create image 70 110 -image foo2 -anchor nw | | | 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 | } -body { image create test foo -variable x image create test foo2 -variable z foo changed 0 0 0 0 40 50 foo2 changed 0 0 0 0 80 60 .c create image 50 100 -image foo -tags image -anchor nw .c create image 70 110 -image foo2 -anchor nw update idletasks set z {} set timer [after 500 {lappend z "timed out"}] image create test foo -variable x vwait x after cancel $timer return $z } -cleanup { |
︙ | ︙ |
Changes to tests/canvText.test.
︙ | ︙ | |||
959 960 961 962 963 964 965 966 967 968 969 | list [expr {$bb0 eq $bb2 ? "ok" : "$bb0,$bb2"}] \ [expr {$bb1 eq $bb3 ? "ok" : "$bb1,$bb3"}] \ [expr {$bb0 eq [transpose $bb1] ? "ok" : "$bb0,$bb1"}] \ } -cleanup { destroy .c rename transpose {} } -result {ok ok ok} # cleanup cleanupTests return | > > > > > > > > > > > > > > | 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 | list [expr {$bb0 eq $bb2 ? "ok" : "$bb0,$bb2"}] \ [expr {$bb1 eq $bb3 ? "ok" : "$bb1,$bb3"}] \ [expr {$bb0 eq [transpose $bb1] ? "ok" : "$bb0,$bb1"}] \ } -cleanup { destroy .c rename transpose {} } -result {ok ok ok} test canvText-20.2 {crash on angled text selection (X11, without xft) - bug 2712f43f6e} -setup { destroy .c canvas .c -background bisque -selectforeground green2 grid .c set id [.c create text 50 150 -anchor w -text "Angled text" \ -angle 30 -font {Helvetica 32} -fill darkblue] } -body { .c select clear .c select from $id 0 .c select to $id 8 ; update ; # used to crash on X11 (--disable-xft build only) } -cleanup { destroy .c } -result {} # cleanup cleanupTests return |
Changes to tests/event.test.
︙ | ︙ | |||
856 857 858 859 860 861 862 863 864 865 866 867 868 869 | physical key - in this case, test is actually void." } } -cleanup { deleteWindows } -result {OK} # cleanup unset -nocomplain keypress_lookup rename _init_keypress_lookup {} rename _keypress_lookup {} rename _keypress {} rename _pause {} rename _text_ind_to_x_y {} rename _get_selection {} | > | 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 | physical key - in this case, test is actually void." } } -cleanup { deleteWindows } -result {OK} # cleanup update unset -nocomplain keypress_lookup rename _init_keypress_lookup {} rename _keypress_lookup {} rename _keypress {} rename _pause {} rename _text_ind_to_x_y {} rename _get_selection {} |
︙ | ︙ |
Changes to tests/frame.test.
︙ | ︙ | |||
669 670 671 672 673 674 675 | test frame-3.10 {TkCreateFrame procedure, -use option} -constraints { unix } -setup { deleteWindows } -body { toplevel .t -container 1 -width 300 -height 120 wm geometry .t +0+0 | > > | | > > > > > | | > | 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 | test frame-3.10 {TkCreateFrame procedure, -use option} -constraints { unix } -setup { deleteWindows } -body { toplevel .t -container 1 -width 300 -height 120 wm geometry .t +0+0 if {[tk windowingsystem] eq "aqua"} { update idletasks } else { update } option add *x.use [winfo id .t] toplevel .x -width 140 -height 300 -bg green if {[tk windowingsystem] eq "aqua"} { update idletasks } else { tkwait visibility .x update } list [expr {[winfo rootx .x] - [winfo rootx .t]}] \ [expr {[winfo rooty .x] - [winfo rooty .t]}] \ [winfo width .t] [winfo height .t] } -cleanup { destroy .t option clear } -result {0 0 140 300} |
︙ | ︙ | |||
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 | } return $result } -cleanup { deleteWindows } -result {1 1 1 1 1 1 1 1 1 1 1 1} test frame-12.3 {FrameWorldChanged procedure} -setup { deleteWindows } -body { # Check reaction on font change font create myfont -family courier -size 10 labelframe .f -font myfont -text Mupp place .f -x 0 -y 0 -width 40 -height 40 pack [frame .f.f] -fill both -expand 1 | > > > > | > > > > | > | 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 | } return $result } -cleanup { deleteWindows } -result {1 1 1 1 1 1 1 1 1 1 1 1} test frame-12.3 {FrameWorldChanged procedure} -setup { deleteWindows update idletasks } -body { # Check reaction on font change font create myfont -family courier -size 10 labelframe .f -font myfont -text Mupp place .f -x 0 -y 0 -width 40 -height 40 pack [frame .f.f] -fill both -expand 1 if {[tk windowingsystem] eq "aqua"} { update idletasks } else { update } set h1 [font metrics myfont -linespace] set y1 [winfo y .f.f] font configure myfont -size 20 if {[tk windowingsystem] eq "aqua"} { update idletasks } else { update } set h2 [font metrics myfont -linespace] set y2 [winfo y .f.f] expr {($h2 - $h1) - ($y2 - $y1)} } -cleanup { deleteWindows font delete myfont } -result {0} |
︙ | ︙ |
Changes to tests/text.test.
︙ | ︙ | |||
6688 6689 6690 6691 6692 6693 6694 | .t insert end "and it will be impacted by the <Delete> event received.\n" .t insert end "Therefore a <<Selection>> event must fire back." .t tag add sel 1.0 1.28 bind .t <<Selection>> "set ::retval <<Selection>>_fired" update set ::retval no_<<Selection>>_event_fired .t mark set insert 1.15 | > | | 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 | .t insert end "and it will be impacted by the <Delete> event received.\n" .t insert end "Therefore a <<Selection>> event must fire back." .t tag add sel 1.0 1.28 bind .t <<Selection>> "set ::retval <<Selection>>_fired" update set ::retval no_<<Selection>>_event_fired .t mark set insert 1.15 update idletasks focus -force .t event generate .t <Delete> update set ::retval } -cleanup { destroy .t } -result {<<Selection>>_fired} test text-27.15e {No <<Selection>> virtual event on <Delete> with cursor outside selection} -body { |
︙ | ︙ |
Changes to tests/ttk/entry.test.
︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 | test entry-2.1 "Create entry before scrollbar" -body { pack [ttk::entry .te -xscrollcommand [list .tsb set]] \ -expand true -fill both pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \ -expand false -fill x } -cleanup {destroy .te .tsb} test entry-2.2 "Initial scroll position" -body { ttk::entry .e -font fixed -width 5 -xscrollcommand scroll .e insert end "0123456789" pack .e; set timeout [after 500 {set $scrollInfo "timeout"}] vwait scrollInfo | > > > > > > > > > > > > | 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 | test entry-2.1 "Create entry before scrollbar" -body { pack [ttk::entry .te -xscrollcommand [list .tsb set]] \ -expand true -fill both pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \ -expand false -fill x } -cleanup {destroy .te .tsb} test entry-2.1.1 "Create entry before scrollbar - scrollbar catches up" -body { pack [ttk::entry .te -xscrollcommand [list .tsb set]] \ -expand true -fill both .te insert end [string repeat "abc" 50] catch {update} ; # error triggers because the -xscrollcommand callback # errors out: invalid command name ".tsb" pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \ -expand false -fill x update ; # no error lappend res [expr [lindex [.tsb get] 1] < 1] ; # scrollbar did update } -result {1} -cleanup {destroy .te .tsb} test entry-2.2 "Initial scroll position" -body { ttk::entry .e -font fixed -width 5 -xscrollcommand scroll .e insert end "0123456789" pack .e; set timeout [after 500 {set $scrollInfo "timeout"}] vwait scrollInfo |
︙ | ︙ |
Changes to tests/ttk/treeview.test.
︙ | ︙ | |||
503 504 505 506 507 508 509 510 511 512 513 514 515 516 | } } -body { .tree yview scroll 5 units .tree identify item 2 2 } -cleanup { destroy .tree } -result {I006} ### identify tests: # proc identify* {tv comps args} { foreach {x y} $args { foreach comp $comps { lappend result [$tv identify $comp $x $y] | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 | } } -body { .tree yview scroll 5 units .tree identify item 2 2 } -cleanup { destroy .tree } -result {I006} test treeview-9.2 {scrolling on see command - bug [14188104c3]} -setup { toplevel .top ttk::treeview .top.tree -show {} -height 10 -columns {label} \ -yscrollcommand [list .top.vs set] ttk::scrollbar .top.vs -command {.top.tree yview} grid .top.tree -row 0 -column 0 -sticky ns grid .top.vs -row 0 -column 1 -sticky ns update proc setrows {n} { .top.tree delete [.top.tree children {}] for {set i 1} {$i <= $n} {incr i} { .top.tree insert {} end -id row$i \ -values [list [format "Row %2.2d" $i]] } .top.tree see row1 update idletasks } } -body { setrows 10 set res [.top.vs get] setrows 20 lappend res [expr [lindex [.top.vs get] 1] < 1] } -cleanup { destroy .top } -result {0.0 1.0 1} test treeview-9.3 {scrolling on see command, requested item is closed} -setup { toplevel .top ttk::treeview .top.tree -show tree -height 10 -columns {label} \ -yscrollcommand [list .top.vs set] ttk::scrollbar .top.vs -command {.top.tree yview} grid .top.tree -row 0 -column 0 -sticky ns grid .top.vs -row 0 -column 1 -sticky ns .top.tree insert {} end -id a -text a .top.tree insert a end -id b -text b .top.tree insert b end -id c -text c .top.tree insert c end -id d -text d .top.tree insert d end -id e -text e for {set i 6} {$i <= 15} {incr i} { .top.tree insert {} end -id row$i \ -values [list [format "Row %2.2d" $i]] } update } -body { set before [lindex [.top.vs get] 1] .top.tree see e update idletasks set after [lindex [.top.vs get] 1] expr $after < $before } -cleanup { destroy .top } -result {1} ### identify tests: # proc identify* {tv comps args} { foreach {x y} $args { foreach comp $comps { lappend result [$tv identify $comp $x $y] |
︙ | ︙ |
Changes to unix/configure.
︙ | ︙ | |||
4991 4992 4993 4994 4995 4996 4997 | case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' if test $doRpath = yes; then | | | 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 | case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} |
︙ | ︙ | |||
5115 5116 5117 5118 5119 5120 5121 | "mkstemp.$ac_objext "* | \ *" mkstemp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; esac if test $doRpath = yes; then | | | | 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 | "mkstemp.$ac_objext "* | \ *" mkstemp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; esac if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi ;; IRIX-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" case $LIBOBJS in "mkstemp.$ac_objext" | \ *" mkstemp.$ac_objext" | \ "mkstemp.$ac_objext "* | \ *" mkstemp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; esac if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi if test "$GCC" = yes; then CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" |
︙ | ︙ | |||
5177 5178 5179 5180 5181 5182 5183 | "mkstemp.$ac_objext "* | \ *" mkstemp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; esac if test $doRpath = yes; then | | | 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 | "mkstemp.$ac_objext "* | \ *" mkstemp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; esac if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = yes; then |
︙ | ︙ | |||
5220 5221 5222 5223 5224 5225 5226 | SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" if test $doRpath = yes; then | | | 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 | SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} if test "`uname -m`" = "alpha"; then CFLAGS="$CFLAGS -mieee" fi |
︙ | ︙ | |||
5320 5321 5322 5323 5324 5325 5326 | CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CC} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-mshared -ldl" LD_FLAGS="-Wl,--export-dynamic" if test $doRpath = yes; then | | | | 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 | CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CC} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-mshared -ldl" LD_FLAGS="-Wl,--export-dynamic" if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' fi ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" |
︙ | ︙ | |||
5362 5363 5364 5365 5366 5367 5368 | esac SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then | | | 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 | esac SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" if test "${TCL_THREADS}" = "1"; then |
︙ | ︙ | |||
5392 5393 5394 5395 5396 5397 5398 | SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" if test $doRpath = yes; then | | | 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 | SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} if test "${TCL_THREADS}" = "1"; then # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` |
︙ | ︙ | |||
5416 5417 5418 5419 5420 5421 5422 | SHLIB_LD="${CC} -shared" SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then | | | | 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 | SHLIB_LD="${CC} -shared" SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' fi if test "${TCL_THREADS}" = "1"; then # The -pthread needs to go in the LDFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS $PTHREAD_CFLAGS" |
︙ | ︙ | |||
6006 6007 6008 6009 6010 6011 6012 | fi SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then | | | 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 | fi SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi if test "$GCC" = yes; then CFLAGS="$CFLAGS -mieee" else |
︙ | ︙ |
Changes to unix/tcl.m4.
︙ | ︙ | |||
1285 1286 1287 1288 1289 1290 1291 | AS_IF([test "$GCC" = yes], [ case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' AS_IF([test $doRpath = yes], [ | | | 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 | AS_IF([test "$GCC" = yes], [ case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]) ;; esac ], [ |
︙ | ︙ | |||
1320 1321 1322 1323 1324 1325 1326 | SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ | | | | 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 | SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) ;; IRIX-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [ CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" ], [ case $system in IRIX-6.3) |
︙ | ︙ | |||
1357 1358 1359 1360 1361 1362 1363 | SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ | | | 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 | SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported by gcc]) |
︙ | ︙ | |||
1388 1389 1390 1391 1392 1393 1394 | #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ | | | 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 | #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) AS_IF([test $do64bit = yes], [ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -m64" AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no) |
︙ | ︙ | |||
1420 1421 1422 1423 1424 1425 1426 | SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CC} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-mshared -ldl" LD_FLAGS="-Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ | | | | 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 | SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CC} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-mshared -ldl" LD_FLAGS="-Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" |
︙ | ︙ | |||
1459 1460 1461 1462 1463 1464 1465 | ;; esac SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ | | | 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 | ;; esac SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ # On OpenBSD: Compile with -pthread # Don't link with -lpthread |
︙ | ︙ | |||
1483 1484 1485 1486 1487 1488 1489 | SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" AS_IF([test $doRpath = yes], [ | | | | | 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 | SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) ;; DragonFly-*|FreeBSD-*) # This configuration from FreeBSD Ports. SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CC} -shared" SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the LDFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$LDFLAGS $PTHREAD_LIBS"]) case $system in FreeBSD-3.*) |
︙ | ︙ | |||
1706 1707 1708 1709 1710 1711 1712 | ], [ SHLIB_LD='ld -non_shared -expect_unresolved "*"' ]) SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ | | | 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 | ], [ SHLIB_LD='ld -non_shared -expect_unresolved "*"' ]) SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"]) # see pthread_intro(3) for pthread support on osf1, k.furukawa AS_IF([test "${TCL_THREADS}" = 1], [ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" |
︙ | ︙ |
Changes to unix/tkUnixFont.c.
︙ | ︙ | |||
3062 3063 3064 3065 3066 3067 3068 | int *realWidthPtr, int *realHeightPtr) { int width, height; TkFont *fontPtr = (TkFont *) tkfont; Pixmap bitmap; GC bitmapGC; XGCValues values; | | > | | | | | | | | | | | | | | | | > | | > | | | | | | | | | > | 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 | int *realWidthPtr, int *realHeightPtr) { int width, height; TkFont *fontPtr = (TkFont *) tkfont; Pixmap bitmap; GC bitmapGC; XGCValues values; XImage *image = NULL; (void) Tk_MeasureChars(tkfont, source, numBytes, -1, 0, &width); height = fontPtr->fm.ascent + fontPtr->fm.descent; if ((width > 0) && (height > 0)) { bitmap = Tk_GetPixmap(display, drawable, width, height, 1); values.graphics_exposures = False; values.foreground = BlackPixel(display, DefaultScreen(display)); bitmapGC = XCreateGC(display, bitmap, GCGraphicsExposures|GCForeground, &values); XFillRectangle(display, bitmap, bitmapGC, 0, 0, width, height); values.font = Tk_FontId(tkfont); values.foreground = WhitePixel(display, DefaultScreen(display)); values.background = BlackPixel(display, DefaultScreen(display)); XChangeGC(display, bitmapGC, GCFont|GCForeground|GCBackground, &values); Tk_DrawChars(display, bitmap, bitmapGC, tkfont, source, numBytes, 0, fontPtr->fm.ascent); XFreeGC(display, bitmapGC); image = XGetImage(display, bitmap, 0, 0, width, height, AllPlanes, ZPixmap); Tk_FreePixmap(display, bitmap); } *realWidthPtr = width; *realHeightPtr = height; return image; } static inline XImage * InitDestImage( Display *display, Drawable drawable, int width, int height, Pixmap *bitmapPtr) { Pixmap bitmap = None; XImage *image = NULL; GC bitmapGC; XGCValues values; if ((width > 0) && (height > 0)) { bitmap = Tk_GetPixmap(display, drawable, width, height, 1); values.graphics_exposures = False; values.foreground = BlackPixel(display, DefaultScreen(display)); bitmapGC = XCreateGC(display, bitmap, GCGraphicsExposures|GCForeground, &values); XFillRectangle(display, bitmap, bitmapGC, 0, 0, width, height); XFreeGC(display, bitmapGC); image = XGetImage(display, bitmap, 0, 0, width, height, AllPlanes, ZPixmap); } *bitmapPtr = bitmap; return image; } void TkDrawAngledChars( Display *display, /* Display on which to draw. */ |
︙ | ︙ |
Changes to unix/tkUnixMenu.c.
︙ | ︙ | |||
855 856 857 858 859 860 861 | int width, int height) { if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) { int len; len = Tcl_GetCharLength(mePtr->labelPtr); if (mePtr->underline < len) { | | | | 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 | int width, int height) { if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) { int len; len = Tcl_GetCharLength(mePtr->labelPtr); if (mePtr->underline < len) { int activeBorderWidth, leftEdge, ch; const char *label, *start, *end; label = Tcl_GetString(mePtr->labelPtr); start = Tcl_UtfAtIndex(label, mePtr->underline); end = start + TkUtfToUniChar(start, &ch); Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr, &activeBorderWidth); leftEdge = x + mePtr->indicatorSpace + activeBorderWidth; if (menuPtr->menuType == MENUBAR) { leftEdge += 5; } |
︙ | ︙ |
Changes to unix/tkUnixRFont.c.
︙ | ︙ | |||
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | * also allocates a new UnixFtFont. * * Results: * On error, frees fontPtr and returns NULL, otherwise returns fontPtr. * *--------------------------------------------------------------------------- */ static UnixFtFont * InitFont( Tk_Window tkwin, FcPattern *pattern, UnixFtFont *fontPtr) { FcFontSet *set; FcCharSet *charset; FcResult result; XftFont *ftFont; | > > > > > > > > > > > > > > > > > | > | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | * also allocates a new UnixFtFont. * * Results: * On error, frees fontPtr and returns NULL, otherwise returns fontPtr. * *--------------------------------------------------------------------------- */ static void FinishedWithFont( UnixFtFont *fontPtr); static int InitFontErrorProc( ClientData clientData, XErrorEvent *errorPtr) { int *errorFlagPtr = (int *) clientData; if (errorFlagPtr != NULL) { *errorFlagPtr = 1; } return 0; } static UnixFtFont * InitFont( Tk_Window tkwin, FcPattern *pattern, UnixFtFont *fontPtr) { FcFontSet *set; FcCharSet *charset; FcResult result; XftFont *ftFont; int i, iWidth, errorFlag; Tk_ErrorHandler handler; if (!fontPtr) { fontPtr = ckalloc(sizeof(UnixFtFont)); } FcConfigSubstitute(0, pattern, FcMatchPattern); XftDefaultSubstitute(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), pattern); |
︙ | ︙ | |||
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | fontPtr->ncolors = 0; fontPtr->firstColor = -1; /* * Fill in platform-specific fields of TkFont. */ ftFont = GetFont(fontPtr, 0, 0.0); fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed"); GetTkFontAttributes(ftFont, &fontPtr->font.fa); GetTkFontMetrics(ftFont, &fontPtr->font.fm); /* * Fontconfig can't report any information about the position or thickness * of underlines or overstrikes. Thus, we use some defaults that are * hacked around from backup defaults in tkUnixFont.c, which are in turn * based on recommendations in the X manual. The comments from that file * leading to these computations were: | > > > > > > > > > > > > > > > | 330 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 | fontPtr->ncolors = 0; fontPtr->firstColor = -1; /* * Fill in platform-specific fields of TkFont. */ errorFlag = 0; handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag); ftFont = GetFont(fontPtr, 0, 0.0); if ((ftFont == NULL) || errorFlag) { Tk_DeleteErrorHandler(handler); FinishedWithFont(fontPtr); ckfree(fontPtr); return NULL; } fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed"); GetTkFontAttributes(ftFont, &fontPtr->font.fa); GetTkFontMetrics(ftFont, &fontPtr->font.fm); Tk_DeleteErrorHandler(handler); if (errorFlag) { FinishedWithFont(fontPtr); ckfree(fontPtr); return NULL; } /* * Fontconfig can't report any information about the position or thickness * of underlines or overstrikes. Thus, we use some defaults that are * hacked around from backup defaults in tkUnixFont.c, which are in turn * based on recommendations in the X manual. The comments from that file * leading to these computations were: |
︙ | ︙ | |||
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | * Fontconfig at all. [Bug 1961455] */ { TkFont *fPtr = &fontPtr->font; fPtr->underlinePos = fPtr->fm.descent / 2; Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth); fPtr->underlineHeight = iWidth / 3; if (fPtr->underlineHeight == 0) { fPtr->underlineHeight = 1; } if (fPtr->underlineHeight + fPtr->underlinePos > fPtr->fm.descent) { fPtr->underlineHeight = fPtr->fm.descent - fPtr->underlinePos; if (fPtr->underlineHeight == 0) { | > > > > > > > > > | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | * Fontconfig at all. [Bug 1961455] */ { TkFont *fPtr = &fontPtr->font; fPtr->underlinePos = fPtr->fm.descent / 2; handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag); errorFlag = 0; Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth); Tk_DeleteErrorHandler(handler); if (errorFlag) { FinishedWithFont(fontPtr); ckfree(fontPtr); return NULL; } fPtr->underlineHeight = iWidth / 3; if (fPtr->underlineHeight == 0) { fPtr->underlineHeight = 1; } if (fPtr->underlineHeight + fPtr->underlinePos > fPtr->fm.descent) { fPtr->underlineHeight = fPtr->fm.descent - fPtr->underlinePos; if (fPtr->underlineHeight == 0) { |
︙ | ︙ | |||
665 666 667 668 669 670 671 | * terminating character. */ { UnixFtFont *fontPtr = (UnixFtFont *) tkfont; XftFont *ftFont; FcChar32 c; XGlyphInfo extents; int clen, curX, newX, curByte, newByte, sawNonSpace; | | > > > | 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 | * terminating character. */ { UnixFtFont *fontPtr = (UnixFtFont *) tkfont; XftFont *ftFont; FcChar32 c; XGlyphInfo extents; int clen, curX, newX, curByte, newByte, sawNonSpace; int termByte = 0, termX = 0, errorFlag = 0; Tk_ErrorHandler handler; #if DEBUG_FONTSEL char string[256]; int len = 0; #endif /* DEBUG_FONTSEL */ handler = Tk_CreateErrorHandler(fontPtr->display, -1, -1, -1, InitFontErrorProc, &errorFlag); curX = 0; curByte = 0; sawNonSpace = 0; while (numBytes > 0) { int unichar; clen = TkUtfToUniChar(source, &unichar); |
︙ | ︙ | |||
706 707 708 709 710 711 712 | } #if DEBUG_FONTSEL string[len++] = (char) c; #endif /* DEBUG_FONTSEL */ ftFont = GetFont(fontPtr, c, 0.0); | > | > > > > | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 | } #if DEBUG_FONTSEL string[len++] = (char) c; #endif /* DEBUG_FONTSEL */ ftFont = GetFont(fontPtr, c, 0.0); if (!errorFlag) { XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents); } else { extents.xOff = 0; errorFlag = 0; } newX = curX + extents.xOff; newByte = curByte + clen; if (maxLength >= 0 && newX > maxLength) { if (flags & TK_PARTIAL_OK || (flags & TK_AT_LEAST_ONE && curByte == 0)) { curX = newX; |
︙ | ︙ | |||
735 736 737 738 739 740 741 742 743 744 745 746 747 748 | } break; } curX = newX; curByte = newByte; } #if DEBUG_FONTSEL string[len] = '\0'; printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte); #endif /* DEBUG_FONTSEL */ *lengthPtr = curX; return curByte; } | > | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | } break; } curX = newX; curByte = newByte; } Tk_DeleteErrorHandler(handler); #if DEBUG_FONTSEL string[len] = '\0'; printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte); #endif /* DEBUG_FONTSEL */ *lengthPtr = curX; return curByte; } |
︙ | ︙ |
Changes to win/rules.vc.
︙ | ︙ | |||
298 299 300 301 302 303 304 | TCLINSTALL = 1 TCLDIR = $(_INSTALLDIR)\.. # NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions # later so the \.. accounts for the /lib _TCLDIR = $(_INSTALLDIR)\.. _TCL_H = $(_TCLDIR)\include\tcl.h | | | | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | TCLINSTALL = 1 TCLDIR = $(_INSTALLDIR)\.. # NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions # later so the \.. accounts for the /lib _TCLDIR = $(_INSTALLDIR)\.. _TCL_H = $(_TCLDIR)\include\tcl.h !else # exist(...) && !$(NEED_TCL_SOURCE) !if [echo _TCLDIR = \> nmakehlp.out] \ || [nmakehlp -L generic\tcl.h >> nmakehlp.out] !error *** Could not locate Tcl source directory. !endif !include nmakehlp.out TCLINSTALL = 0 TCLDIR = $(_TCLDIR) _TCL_H = $(_TCLDIR)\generic\tcl.h !endif # exist(...) && !$(NEED_TCL_SOURCE) !endif # TCLDIR !ifndef _TCL_H MSG =^ Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h. !error $(MSG) |
︙ | ︙ | |||
533 534 535 536 537 538 539 | NMAKEHLPC = nmakehlp.c !if !$(DOING_TCL) !if $(TCLINSTALL) !if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c") NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c !endif | | | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | NMAKEHLPC = nmakehlp.c !if !$(DOING_TCL) !if $(TCLINSTALL) !if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c") NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c !endif !else # !$(TCLINSTALL) !if exist("$(_TCLDIR)\win\nmakehlp.c") NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c !endif !endif # $(TCLINSTALL) !endif # !$(DOING_TCL) !endif # NMAKEHLPC |
︙ | ︙ | |||
681 682 683 684 685 686 687 | # 0 -> Use the non-thread allocator. # UNCHECKED - 1 -> when doing a debug build with symbols, use the release # C runtime, 0 -> use the debug C runtime. # USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking # CONFIG_CHECK - 1 -> check current build configuration against Tcl # configuration (ignored for Tcl itself) # _USE_64BIT_TIME_T - forces a build using 64-bit time_t for 32-bit build | | > | 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | # 0 -> Use the non-thread allocator. # UNCHECKED - 1 -> when doing a debug build with symbols, use the release # C runtime, 0 -> use the debug C runtime. # USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking # CONFIG_CHECK - 1 -> check current build configuration against Tcl # configuration (ignored for Tcl itself) # _USE_64BIT_TIME_T - forces a build using 64-bit time_t for 32-bit build # (CRT library should support this, not needed for Tcl 9.x) # TCL_UTF_MAX=4 - forces a build allowing 4-byte UTF-8 sequences internally. # (Not needed for Tcl 9.x) # Further, LINKERFLAGS are modified based on above. # Default values for all the above STATIC_BUILD = 0 TCL_THREADS = 1 DEBUG = 0 SYMBOLS = 0 |
︙ | ︙ | |||
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 | TCL_THREADS = 0 USE_THREAD_ALLOC= 0 !else TCL_THREADS = 1 USE_THREAD_ALLOC= 1 !endif !if [nmakehlp -f $(OPTS) "time64bit"] !message *** Force 64-bit time_t _USE_64BIT_TIME_T = 1 !endif !if [nmakehlp -f $(OPTS) "utfmax"] !message *** Force allowing 4-byte UTF-8 sequences internally TCL_UTF_MAX = 4 !endif # Yes, it's weird that the "symbols" option controls DEBUG and # the "pdbs" option controls SYMBOLS. That's historical. !if [nmakehlp -f $(OPTS) "symbols"] !message *** Doing symbols DEBUG = 1 | > > | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 | TCL_THREADS = 0 USE_THREAD_ALLOC= 0 !else TCL_THREADS = 1 USE_THREAD_ALLOC= 1 !endif !if "$(TCL_MAJOR_VERSION)" == "8" !if [nmakehlp -f $(OPTS) "time64bit"] !message *** Force 64-bit time_t _USE_64BIT_TIME_T = 1 !endif !if [nmakehlp -f $(OPTS) "utfmax"] !message *** Force allowing 4-byte UTF-8 sequences internally TCL_UTF_MAX = 4 !endif !endif # Yes, it's weird that the "symbols" option controls DEBUG and # the "pdbs" option controls SYMBOLS. That's historical. !if [nmakehlp -f $(OPTS) "symbols"] !message *** Doing symbols DEBUG = 1 |
︙ | ︙ | |||
1108 1109 1110 1111 1112 1113 1114 | TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) TCLLIB = $(OUT_DIR)\$(TCLLIBNAME) TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME) TCL_INCLUDES = -I"$(WIN_DIR)" -I"$(GENERICDIR)" | | | 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 | TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) TCLLIB = $(OUT_DIR)\$(TCLLIBNAME) TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME) TCL_INCLUDES = -I"$(WIN_DIR)" -I"$(GENERICDIR)" !else # !$(DOING_TCL) !if $(TCLINSTALL) # Building against an installed Tcl # When building extensions, we need to locate tclsh. Depending on version # of Tcl we are building against, this may or may not have a "t" suffix. # Try various possibilities in turn. TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe |
︙ | ︙ | |||
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 | !if $(DOING_TCL) || $(DOING_TK) LIB_INSTALL_DIR = $(_INSTALLDIR)\lib BIN_INSTALL_DIR = $(_INSTALLDIR)\bin DOC_INSTALL_DIR = $(_INSTALLDIR)\doc !if $(DOING_TCL) SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) !else # DOING_TK SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION) !endif DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include !else # extension other than Tk | > | 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 | !if $(DOING_TCL) || $(DOING_TK) LIB_INSTALL_DIR = $(_INSTALLDIR)\lib BIN_INSTALL_DIR = $(_INSTALLDIR)\bin DOC_INSTALL_DIR = $(_INSTALLDIR)\doc !if $(DOING_TCL) SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) MODULE_INSTALL_DIR = $(_INSTALLDIR)\lib\tcl$(TCL_MAJOR_VERSION) !else # DOING_TK SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION) !endif DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include !else # extension other than Tk |
︙ | ︙ | |||
1329 1330 1331 1332 1333 1334 1335 | !if $(TCL_NO_DEPRECATED) OPTDEFINES = $(OPTDEFINES) /DTCL_NO_DEPRECATED !endif !if $(USE_STUBS) # Note we do not define USE_TCL_STUBS even when building tk since some # test targets in tk do not use stubs | | | 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 | !if $(TCL_NO_DEPRECATED) OPTDEFINES = $(OPTDEFINES) /DTCL_NO_DEPRECATED !endif !if $(USE_STUBS) # Note we do not define USE_TCL_STUBS even when building tk since some # test targets in tk do not use stubs !if !$(DOING_TCL) USE_STUBS_DEFS = /DUSE_TCL_STUBS /DUSE_TCLOO_STUBS !if $(NEED_TK) USE_STUBS_DEFS = $(USE_STUBS_DEFS) /DUSE_TK_STUBS !endif !endif !endif # USE_STUBS |
︙ | ︙ | |||
1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 | !if "$(MACHINE)" == "AMD64" OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_DO64BIT !endif !if $(VCVERSION) < 1300 OPTDEFINES = $(OPTDEFINES) /DNO_STRTOI64=1 !endif !if "$(_USE_64BIT_TIME_T)" == "1" OPTDEFINES = $(OPTDEFINES) /D_USE_64BIT_TIME_T=1 !endif !if "$(TCL_UTF_MAX)" == "4" OPTDEFINES = $(OPTDEFINES) /DTCL_UTF_MAX=4 !endif # _ATL_XP_TARGETING - Newer SDK's need this to build for XP COMPILERFLAGS = /D_ATL_XP_TARGETING # Like the TEA system only set this non empty for non-Tk extensions # Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME # so we pass both !if !$(DOING_TCL) && !$(DOING_TK) PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \ /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \ | > > | 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 | !if "$(MACHINE)" == "AMD64" OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_DO64BIT !endif !if $(VCVERSION) < 1300 OPTDEFINES = $(OPTDEFINES) /DNO_STRTOI64=1 !endif !if "$(TCL_MAJOR_VERSION)" == "8" !if "$(_USE_64BIT_TIME_T)" == "1" OPTDEFINES = $(OPTDEFINES) /D_USE_64BIT_TIME_T=1 !endif !if "$(TCL_UTF_MAX)" == "4" OPTDEFINES = $(OPTDEFINES) /DTCL_UTF_MAX=4 !endif # _ATL_XP_TARGETING - Newer SDK's need this to build for XP COMPILERFLAGS = /D_ATL_XP_TARGETING !endif # Like the TEA system only set this non empty for non-Tk extensions # Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME # so we pass both !if !$(DOING_TCL) && !$(DOING_TK) PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \ /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \ |
︙ | ︙ | |||
1762 1763 1764 1765 1766 1767 1768 | !endif ################################################################ # 14. Sanity check selected options against Tcl build options # When building an extension, certain configuration options should # match the ones used when Tcl was built. Here we check and # warn on a mismatch. | | | | 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 | !endif ################################################################ # 14. Sanity check selected options against Tcl build options # When building an extension, certain configuration options should # match the ones used when Tcl was built. Here we check and # warn on a mismatch. !if !$(DOING_TCL) !if $(TCLINSTALL) # Building against an installed Tcl !if exist("$(_TCLDIR)\lib\nmake\tcl.nmake") TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake" !endif !else # !$(TCLINSTALL) - building against Tcl source !if exist("$(OUT_DIR)\tcl.nmake") TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake" !endif !endif # TCLINSTALL !if $(CONFIG_CHECK) !ifdef TCLNMAKECONFIG |
︙ | ︙ | |||
1791 1792 1793 1794 1795 1796 1797 | !if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG) !message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)). !endif !endif !endif # TCLNMAKECONFIG | | | 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 | !if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG) !message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)). !endif !endif !endif # TCLNMAKECONFIG !endif # !$(DOING_TCL) #---------------------------------------------------------- # Display stats being used. #---------------------------------------------------------- !if !$(DOING_TCL) |
︙ | ︙ |
Changes to win/tkWinFont.c.
︙ | ︙ | |||
211 212 213 214 215 216 217 | LOGFONTW* logFontPtr); static int CreateNamedSystemFont(Tcl_Interp *interp, Tk_Window tkwin, const char* name, HFONT hFont); static int LoadFontRanges(HDC hdc, HFONT hFont, USHORT **startCount, USHORT **endCount, int *symbolPtr); static void MultiFontTextOut(HDC hdc, WinFont *fontPtr, | | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | LOGFONTW* logFontPtr); static int CreateNamedSystemFont(Tcl_Interp *interp, Tk_Window tkwin, const char* name, HFONT hFont); static int LoadFontRanges(HDC hdc, HFONT hFont, USHORT **startCount, USHORT **endCount, int *symbolPtr); static void MultiFontTextOut(HDC hdc, WinFont *fontPtr, const char *source, int numBytes, double x, double y, double angle); static void ReleaseFont(WinFont *fontPtr); static inline void ReleaseSubFont(SubFont *subFontPtr); static int SeenName(const char *name, Tcl_DString *dsPtr); static inline HFONT SelectFont(HDC hdc, WinFont *fontPtr, SubFont *subFontPtr, double angle); static inline void SwapLong(PULONG p); static inline void SwapShort(USHORT *p); |
︙ | ︙ | |||
1290 1291 1292 1293 1294 1295 1296 | * colors. First we draw onto a black background and copy the white * bits. Then we draw onto a white background and copy the black bits. * Both the foreground and background bits of the font are ANDed with * the stipple pattern as they are copied. */ PatBlt(dcMem, 0, 0, size.cx, size.cy, BLACKNESS); | | | | | 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 | * colors. First we draw onto a black background and copy the white * bits. Then we draw onto a white background and copy the black bits. * Both the foreground and background bits of the font are ANDed with * the stipple pattern as they are copied. */ PatBlt(dcMem, 0, 0, size.cx, size.cy, BLACKNESS); MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, angle); BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem, 0, 0, 0xEA02E9); PatBlt(dcMem, 0, 0, size.cx, size.cy, WHITENESS); MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, angle); BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem, 0, 0, 0x8A0E06); /* * Destroy the temporary bitmap and restore the device context. */ SelectObject(dcMem, oldBitmap); DeleteObject(bitmap); DeleteDC(dcMem); SelectObject(dc, oldBrush); DeleteObject(stipple); } else if (gc->function == GXcopy) { SetTextAlign(dc, TA_LEFT | TA_BASELINE); SetTextColor(dc, gc->foreground); SetBkMode(dc, TRANSPARENT); MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, angle); } else { HBITMAP oldBitmap, bitmap; HDC dcMem; TEXTMETRICW tm; SIZE size; dcMem = CreateCompatibleDC(dc); |
︙ | ︙ | |||
1425 1426 1427 1428 1429 1430 1431 | static void MultiFontTextOut( HDC hdc, /* HDC to draw into. */ WinFont *fontPtr, /* Contains set of fonts to use when drawing * following string. */ const char *source, /* Potentially multilingual UTF-8 string. */ int numBytes, /* Length of string in bytes. */ | | > | 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 | static void MultiFontTextOut( HDC hdc, /* HDC to draw into. */ WinFont *fontPtr, /* Contains set of fonts to use when drawing * following string. */ const char *source, /* Potentially multilingual UTF-8 string. */ int numBytes, /* Length of string in bytes. */ double x, double y, /* Coordinates at which to place origin of * string when drawing. */ double angle) { int ch; SIZE size; HFONT oldFont; FontFamily *familyPtr; Tcl_DString runString; const char *p, *end, *next; SubFont *lastSubFontPtr, *thisSubFontPtr; TEXTMETRICW tm; double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0); lastSubFontPtr = &fontPtr->subFontArray[0]; oldFont = SelectFont(hdc, fontPtr, lastSubFontPtr, angle); GetTextMetricsW(hdc, &tm); end = source + numBytes; for (p = source; p < end; ) { |
︙ | ︙ | |||
1466 1467 1468 1469 1470 1471 1472 | familyPtr->textOutProc(hdc, x-(tm.tmOverhang/2), y, (WCHAR *)Tcl_DStringValue(&runString), Tcl_DStringLength(&runString)>>familyPtr->isWideFont); familyPtr->getTextExtentPoint32Proc(hdc, (WCHAR *)Tcl_DStringValue(&runString), Tcl_DStringLength(&runString) >> familyPtr->isWideFont, &size); | | > | 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 | familyPtr->textOutProc(hdc, x-(tm.tmOverhang/2), y, (WCHAR *)Tcl_DStringValue(&runString), Tcl_DStringLength(&runString)>>familyPtr->isWideFont); familyPtr->getTextExtentPoint32Proc(hdc, (WCHAR *)Tcl_DStringValue(&runString), Tcl_DStringLength(&runString) >> familyPtr->isWideFont, &size); x += cosA*size.cx; y -= sinA*size.cx; Tcl_DStringFree(&runString); } lastSubFontPtr = thisSubFontPtr; source = p; SelectFont(hdc, fontPtr, lastSubFontPtr, angle); GetTextMetricsW(hdc, &tm); } |
︙ | ︙ |
Changes to win/tkWinMenu.c.
︙ | ︙ | |||
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | int i; const char *label = (mePtr->labelPtr == NULL) ? "" : Tcl_GetString(mePtr->labelPtr); const char *accel = ((menuPtr->menuType == MENUBAR) || (mePtr->accelPtr == NULL)) ? "" : Tcl_GetString(mePtr->accelPtr); const char *p, *next; Tcl_DString itemString; /* * We have to construct the string with an ampersand preceeding the * underline character, and a tab seperating the text and the accel * text. We have to be careful with ampersands in the string. */ Tcl_DStringInit(&itemString); for (p = label, i = 0; *p != '\0'; i++, p = next) { if (i == mePtr->underline) { Tcl_DStringAppend(&itemString, "&", 1); } if (*p == '&') { Tcl_DStringAppend(&itemString, "&", 1); } | > | | | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | int i; const char *label = (mePtr->labelPtr == NULL) ? "" : Tcl_GetString(mePtr->labelPtr); const char *accel = ((menuPtr->menuType == MENUBAR) || (mePtr->accelPtr == NULL)) ? "" : Tcl_GetString(mePtr->accelPtr); const char *p, *next; Tcl_DString itemString; int ch; /* * We have to construct the string with an ampersand preceeding the * underline character, and a tab seperating the text and the accel * text. We have to be careful with ampersands in the string. */ Tcl_DStringInit(&itemString); for (p = label, i = 0; *p != '\0'; i++, p = next) { if (i == mePtr->underline) { Tcl_DStringAppend(&itemString, "&", 1); } if (*p == '&') { Tcl_DStringAppend(&itemString, "&", 1); } next = p + TkUtfToUniChar(p, &ch); Tcl_DStringAppend(&itemString, p, (int) (next - p)); } if (mePtr->accelLength > 0) { Tcl_DStringAppend(&itemString, "\t", 1); for (p = accel, i = 0; *p != '\0'; i++, p = next) { if (*p == '&') { Tcl_DStringAppend(&itemString, "&", 1); } next = p + TkUtfToUniChar(p, &ch); Tcl_DStringAppend(&itemString, p, (int) (next - p)); } } itemText = (char *)ckalloc(Tcl_DStringLength(&itemString) + 1); strcpy(itemText, Tcl_DStringValue(&itemString)); Tcl_DStringFree(&itemString); |
︙ | ︙ | |||
2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 | if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) { int len; len = Tcl_GetCharLength(mePtr->labelPtr); if (mePtr->underline < len) { const char *label, *start, *end; label = Tcl_GetString(mePtr->labelPtr); start = Tcl_UtfAtIndex(label, mePtr->underline); | > | | 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 | if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) { int len; len = Tcl_GetCharLength(mePtr->labelPtr); if (mePtr->underline < len) { const char *label, *start, *end; int ch; label = Tcl_GetString(mePtr->labelPtr); start = Tcl_UtfAtIndex(label, mePtr->underline); end = start + TkUtfToUniChar(start, &ch); Tk_UnderlineChars(menuPtr->display, d, gc, tkfont, label, x + mePtr->indicatorSpace, y + (height + fmPtr->ascent - fmPtr->descent) / 2, (int) (start - label), (int) (end - label)); } } } |
︙ | ︙ |