summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2020-05-18 22:01:28 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2020-05-18 22:01:28 (GMT)
commit742aa6e5578759ae3d318aa05164df0b9e3982d3 (patch)
tree638c96b8b121ba515a09b85a3dbaa69c26cb136b
parent6fa16c680c6af311355e3c43f9123007c5fa565b (diff)
parent1d435ce1f0cd4775332957c719ee82d78bf926b7 (diff)
downloadtk-742aa6e5578759ae3d318aa05164df0b9e3982d3.zip
tk-742aa6e5578759ae3d318aa05164df0b9e3982d3.tar.gz
tk-742aa6e5578759ae3d318aa05164df0b9e3982d3.tar.bz2
Merge 8.6
-rw-r--r--generic/tkBind.c4
-rw-r--r--generic/tkEvent.c4
-rw-r--r--generic/tkInt.h6
-rw-r--r--macosx/tkMacOSXButton.c19
-rw-r--r--macosx/tkMacOSXClipboard.c25
-rw-r--r--macosx/tkMacOSXColor.c9
-rw-r--r--macosx/tkMacOSXConstants.h4
-rw-r--r--macosx/tkMacOSXFont.c145
-rw-r--r--macosx/tkMacOSXInit.c40
-rw-r--r--macosx/tkMacOSXKeyEvent.c25
-rw-r--r--macosx/tkMacOSXKeyboard.c55
-rw-r--r--macosx/tkMacOSXMouseEvent.c4
-rw-r--r--macosx/tkMacOSXNotify.c20
-rw-r--r--macosx/tkMacOSXPrivate.h31
-rw-r--r--macosx/tkMacOSXTest.c2
-rw-r--r--win/tkWinKey.c5
-rw-r--r--win/tkWinMenu.c15
-rw-r--r--win/tkWinX.c146
-rw-r--r--xlib/X11/Xlib.h3
19 files changed, 241 insertions, 321 deletions
diff --git a/generic/tkBind.c b/generic/tkBind.c
index 48f51e3..e9d5b3a 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.c
@@ -567,7 +567,7 @@ static int eventArrayIndex[TK_LASTEVENT];
#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.
*/
@@ -3218,7 +3218,7 @@ ExpandPercents(
}
#undef SET_NUMBER
-#undef SET_UNUMBER
+#undef SET_UNUMBER
Tcl_DStringFree(&buf);
}
diff --git a/generic/tkEvent.c b/generic/tkEvent.c
index 0beb8b6..a2fa293 100644
--- a/generic/tkEvent.c
+++ b/generic/tkEvent.c
@@ -1751,13 +1751,15 @@ CleanUpTkEvent(
switch (eventPtr->type) {
case KeyPress:
case KeyRelease: {
- TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;
+#if !defined(_WIN32) && !defined(MAC_OSX_TK)
+ TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;
if (kePtr->charValuePtr != NULL) {
ckfree(kePtr->charValuePtr);
kePtr->charValuePtr = NULL;
kePtr->charValueLen = 0;
}
+#endif
break;
}
diff --git a/generic/tkInt.h b/generic/tkInt.h
index f638c56..c63748a 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -852,6 +852,11 @@ typedef struct TkWindow {
typedef struct {
XKeyEvent keyEvent; /* The real event from X11. */
+#ifdef _WIN32
+ char trans_chars[XMaxTransChars];
+ /* translated characters */
+ unsigned char nbytes;
+#elif !defined(MAC_OSC_TK)
char *charValuePtr; /* A pointer to a string that holds the key's
* %A substitution text (before backslash
* adding), or NULL if that has not been
@@ -861,6 +866,7 @@ typedef struct {
* is non-NULL. */
KeySym keysym; /* Key symbol computed after input methods
* have been invoked */
+#endif
} TkKeyEvent;
/*
diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c
index f869350..721dd03 100644
--- a/macosx/tkMacOSXButton.c
+++ b/macosx/tkMacOSXButton.c
@@ -186,9 +186,6 @@ TkpDisplayButton(
DrawParams* dpPtr = &macButtonPtr->drawParams;
int needhighlight = 0;
- if (butPtr->flags & BUTTON_DELETED) {
- return;
- }
butPtr->flags &= ~REDRAW_PENDING;
if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
return;
@@ -1048,7 +1045,14 @@ TkMacOSXComputeButtonParams(
if (drawinfo->state != kThemeStatePressed) {
drawinfo->adornment |= kThemeAdornmentDefault;
}
- if (!mbPtr->defaultPulseHandler) {
+
+ /*
+ * Older macOS systems (10.9 and earlier) use an animation to
+ * indicate the active button. This is simulated by redrawing
+ * the button periodically.
+ */
+
+ if (!mbPtr->defaultPulseHandler && ([NSApp macMinorVersion] <= 9)) {
mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
PULSE_TIMER_MSECS, PulseDefaultButtonProc, butPtr);
}
@@ -1178,6 +1182,13 @@ PulseDefaultButtonProc(ClientData clientData)
MacButton *mbPtr = clientData;
TkpDisplayButton(clientData);
+ /*
+ * Fix 40ada90762: any idle calls to TkpDisplayButton need to be canceled
+ * in case the button is destroyed and has its data freed before the idle
+ * event is handled (DestroyButton only cancels calls when REDRAW_PENDING
+ * is set, which is not the case after calling TkpDisplayButton directly).
+ */
+ Tcl_CancelIdleCall(TkpDisplayButton, clientData);
mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData);
}
diff --git a/macosx/tkMacOSXClipboard.c b/macosx/tkMacOSXClipboard.c
index 529b5fa..be1f16c 100644
--- a/macosx/tkMacOSXClipboard.c
+++ b/macosx/tkMacOSXClipboard.c
@@ -137,26 +137,19 @@ TkSelGetSelection(
string = [pb stringForType:type];
}
if (string) {
-
- /*
- * Encode the string using the encoding which is used in Tcl
- * when TCL_UTF_MAX = 3. This replaces each UTF-16 surrogate with
- * a 3-byte sequence generated using the UTF-8 algorithm. (Even
- * though UTF-8 does not allow encoding surrogates, the algorithm
- * does produce a 3-byte sequence.)
- */
-
- char *bytes = TkNSStringToUtf(string, NULL);
- result = proc(clientData, interp, bytes);
- if (bytes) {
- ckfree(bytes);
+ if (target == dispPtr->utf8Atom) {
+ result = proc(clientData, interp, string.UTF8String);
+ } else if (target == XA_STRING) {
+ const char *latin1 = [string
+ cStringUsingEncoding:NSISOLatin1StringEncoding];
+ result = proc(clientData, interp, latin1);
}
}
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "%s selection doesn't exist or form \"%s\" not defined",
- Tk_GetAtomName(tkwin, selection),
- Tk_GetAtomName(tkwin, target)));
+ "%s selection doesn't exist or form \"%s\" not defined",
+ Tk_GetAtomName(tkwin, selection),
+ Tk_GetAtomName(tkwin, target)));
Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL);
}
return result;
diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c
index 924eebf..7694b1d 100644
--- a/macosx/tkMacOSXColor.c
+++ b/macosx/tkMacOSXColor.c
@@ -280,11 +280,6 @@ SetCGColorComponents(
OSStatus err = noErr;
NSColor *bgColor, *color = nil;
CGFloat rgba[4] = {0, 0, 0, 1};
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
- NSInteger colorVariant;
- static CGFloat graphiteAccentRGBA[4] =
- {152.0 / 255, 152.0 / 255, 152.0 / 255, 1.0};
-#endif
if (!sRGB) {
sRGB = [NSColorSpace sRGBColorSpace];
@@ -372,10 +367,10 @@ SetCGColorComponents(
case 8:
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
if (@available(macOS 14, *)) {
+ color = [[NSColor controlAccentColor] colorUsingColorSpace:sRGB];
#else
- if (false) {
+ if(false) {
#endif
- color = [[NSColor controlAccentColor] colorUsingColorSpace:sRGB];
} else {
color = [[NSColor
colorForControlTint:[NSColor currentControlTint]]
diff --git a/macosx/tkMacOSXConstants.h b/macosx/tkMacOSXConstants.h
index 8ef535c..e019ea1 100644
--- a/macosx/tkMacOSXConstants.h
+++ b/macosx/tkMacOSXConstants.h
@@ -19,6 +19,10 @@
#define NSFullScreenWindowMask (1 << 14)
#endif
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1090
+typedef NSInteger NSModalResponse;
+#endif
+
/*
* Let's raise a glass for the project manager who improves our lives by
* generating deprecation warnings about pointless changes of the names
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index 89df102..7fc0113 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -103,7 +103,9 @@ static void DrawCharsInContext(Display *display, Drawable drawable,
/*
* 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.
+ * NSString that uses the DString's buffer as its character buffer. It can be
+ * constructed from a Tcl_DString and it has a DString property that handles
+ * converting from an NSString to a Tcl_DString
*/
@implementation TKNSString
@@ -111,7 +113,8 @@ static void DrawCharsInContext(Display *display, Drawable drawable,
- (instancetype)initWithTclUtfBytes:(const void *)bytes
length:(NSUInteger)len
{
- if (self = [self init]) {
+ self = [self init];
+ if (self) {
Tcl_DStringInit(&_ds);
Tcl_UtfToUniCharDString(bytes, len, &_ds);
_string = [[NSString alloc]
@@ -123,6 +126,17 @@ static void DrawCharsInContext(Display *display, Drawable drawable,
return self;
}
+- (instancetype)initWithString:(NSString *)aString
+{
+ self = [self init];
+ if (self) {
+ _string = [[NSString alloc] initWithString:aString];
+ self.UTF8String = _string.UTF8String;
+ }
+ printf("Initialized with string %s\n", self.UTF8String);
+ return self;
+}
+
- (void)dealloc
{
Tcl_DStringFree(&_ds);
@@ -140,101 +154,52 @@ static void DrawCharsInContext(Display *display, Drawable drawable,
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
- * pointer code.
- *
- */
+# ifndef __clang__
+@synthesize DString = _ds;
+#endif
-MODULE_SCOPE int
-TkUtfAtIndex(
- NSString *string,
- int index,
- char *uni,
- unsigned int *code)
+- (Tcl_DString)DString
{
- char *ptr = uni;
- UniChar uniChar = [string characterAtIndex: index];
- if (CFStringIsSurrogateHighCharacter(uniChar)) {
- UniChar lowChar = [string characterAtIndex: ++index];
- *code = CFStringGetLongCharacterForSurrogatePair(
- uniChar, lowChar);
- ptr += Tcl_UniCharToUtf(uniChar, ptr);
- ptr += Tcl_UniCharToUtf(lowChar, ptr);
- return ptr - uni;
- } else {
- *code = (int) uniChar;
- [[string substringWithRange: NSMakeRange(index, 1)]
- getCString: uni
- maxLength: XMaxTransChars
- encoding: NSUTF8StringEncoding];
- return strlen(uni);
- }
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TkNSStringToUtf --
- *
- * Encodes the unicode string represented by an NSString object with the
- * internal encoding that Tcl uses when TCL_UTF_MAX = 3. This encoding
- * is similar to UTF-8 except that non-BMP characters are encoded as two
- * successive 3-byte sequences which are constructed from UTF-16 surrogates
- * by applying the UTF-8 algorithm. Even though the UTF-8 encoding does not
- * allow encoding surrogates, the algorithm does produce a well-defined
- * 3-byte sequence.
- *
- * Results:
- * Returns a pointer to a null-terminated byte array which encodes the
- * NSString.
- *
- * Side effects:
- * Memory is allocated to hold the byte array, which must be freed with
- * ckalloc. If the pointer numBytes is not NULL the number of non-null
- * bytes written to the array is stored in the integer it references.
- */
+ if ( _ds.string == NULL) {
-MODULE_SCOPE char*
-TkNSStringToUtf(
- NSString *string,
- int *numBytes)
-{
- unsigned int code;
- int i;
- char *ptr, *bytes = ckalloc(6*[string length] + 1);
-
- ptr = bytes;
- if (ptr) {
- for (i = 0; i < [string length]; i++) {
- ptr += TkUtfAtIndex(string, i, ptr, &code);
- if (code > 0xffff){
- i++;
+ /*
+ * The DString has not been initialized. Construct it from
+ * our string's unicode characters.
+ */
+
+ char buffer[2*TCL_UTF_MAX];
+ unsigned int index, length, ch;
+
+ Tcl_DStringInit(&_ds);
+#if TCL_UTF_MAX == 3
+ for (index = 0; index < [_string length]; index++) {
+ UniChar uni = [_string characterAtIndex: index];
+
+ if (CFStringIsSurrogateHighCharacter(uni)) {
+ UniChar low = [_string characterAtIndex: ++index];
+ ch = CFStringGetLongCharacterForSurrogatePair(uni, low);
+ } else {
+ ch = uni;
}
+ length = TkUniCharToUtf(ch, buffer);
+ Tcl_DStringAppend(&_ds, buffer, length);
}
- *ptr = '\0';
- }
- if (numBytes) {
- *numBytes = ptr - bytes;
+#else
+ for (index = 0; index < [_string length]; index++) {
+ ch = (int) [_string characterAtIndex: index];
+ length = Tcl_UniCharToUtf(ch, buffer);
+ Tcl_DStringAppend(&_ds, buffer, length);
+ }
+
+#endif
}
- return bytes;
+ return _ds;
}
+
+#ifndef __clang__
+@synthesize UTF8String = _UTF8String;
+#endif
+@end
#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c
index b13b855..e806b24 100644
--- a/macosx/tkMacOSXInit.c
+++ b/macosx/tkMacOSXInit.c
@@ -623,46 +623,6 @@ TkMacOSXGetNamedSymbol(
}
/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXGetStringObjFromCFString --
- *
- * Get a string object from a CFString as efficiently as possible.
- *
- * Results:
- * New string object or NULL if conversion failed.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-MODULE_SCOPE Tcl_Obj*
-TkMacOSXGetStringObjFromCFString(
- CFStringRef str)
-{
- Tcl_Obj *obj = NULL;
- const char *c = CFStringGetCStringPtr(str, kCFStringEncodingUTF8);
-
- if (c) {
- obj = Tcl_NewStringObj(c, -1);
- } else {
- CFRange all = CFRangeMake(0, CFStringGetLength(str));
- CFIndex len;
-
- if (CFStringGetBytes(str, all, kCFStringEncodingUTF8, 0, false, NULL,
- 0, &len) > 0 && len < INT_MAX) {
- obj = Tcl_NewObj();
- Tcl_SetObjLength(obj, len);
- CFStringGetBytes(str, all, kCFStringEncodingUTF8, 0, false,
- (UInt8*) obj->bytes, len, NULL);
- }
- }
- return obj;
-}
-
-/*
* Local Variables:
* mode: objc
* c-basic-offset: 4
diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c
index ee69c35..e0b0094 100644
--- a/macosx/tkMacOSXKeyEvent.c
+++ b/macosx/tkMacOSXKeyEvent.c
@@ -247,16 +247,7 @@ static NSUInteger textInputModifiers;
}
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
@@ -351,26 +342,18 @@ static NSUInteger textInputModifiers;
* 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.
+ * byte to the special value NON_BMP.
*/
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];
+ UniChar lowChar = [str characterAtIndex:++i];
macKC.v.keychar = CFStringGetLongCharacterForSurrogatePair(
(UniChar)keychar, lowChar);
macKC.v.virtual = NON_BMP_VIRTUAL;
@@ -389,10 +372,6 @@ static NSUInteger textInputModifiers;
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);
diff --git a/macosx/tkMacOSXKeyboard.c b/macosx/tkMacOSXKeyboard.c
index db693ea..8381aa7 100644
--- a/macosx/tkMacOSXKeyboard.c
+++ b/macosx/tkMacOSXKeyboard.c
@@ -62,15 +62,13 @@
*
* 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.
+ * these "printable" events. The UCS-32 character stored in the keycode field
+ * of an XKeyEvent 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 XKeyEvent. 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
@@ -488,11 +486,18 @@ TkpGetString(
* result. */
{
(void) winPtr; /*unused*/
- int ch;
+ MacKeycode macKC;
+ char utfChars[8];
+ int length = 0;
+
+ macKC.uint = eventPtr->xkey.keycode;
+ if (IS_PRINTABLE(macKC.v.keychar)) {
+ length = TkUniCharToUtf(macKC.v.keychar, utfChars);
+ }
+ utfChars[length] = 0;
Tcl_DStringInit(dsPtr);
- return Tcl_DStringAppend(dsPtr, eventPtr->xkey.trans_chars,
- TkUtfToUniChar(eventPtr->xkey.trans_chars, &ch));
+ return Tcl_DStringAppend(dsPtr, utfChars, length);
}
/*
@@ -623,7 +628,7 @@ XKeysymToKeycode(
hPtr = Tcl_FindHashEntry(&keysym2keycode, INT2PTR(keysym));
if (hPtr != NULL) {
- return (unsigned int) Tcl_GetHashValue(hPtr);
+ return (KeyCode) Tcl_GetHashValue(hPtr);
}
/*
@@ -640,15 +645,18 @@ XKeysymToKeycode(
* xvirtual field if the key exists on the current keyboard.
*/
- hPtr = Tcl_FindHashEntry(&keysym2unichar, INT2PTR(keysym));
+ hPtr = (Tcl_HashEntry *) Tcl_FindHashEntry(&keysym2unichar,
+ INT2PTR(keysym));
if (hPtr != NULL) {
- macKC.x.keychar = (unsigned int) Tcl_GetHashValue(hPtr);
+ unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr);
+ macKC.x.keychar = (unsigned int) data;
hPtr = Tcl_FindHashEntry(&unichar2xvirtual, INT2PTR(macKC.x.keychar));
if (hPtr != NULL) {
- macKC.x.xvirtual = (unsigned int) Tcl_GetHashValue(hPtr);
+ unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr);
+ macKC.x.xvirtual = (unsigned int) data;
}
}
- return macKC.uint;
+ return (KeyCode) macKC.uint;
}
/*
@@ -667,7 +675,7 @@ XKeysymToKeycode(
* 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.
+ * keysym.
*
*----------------------------------------------------------------------
*/
@@ -718,11 +726,6 @@ TkpSetKeycodeAndState(
}
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;
- }
}
}
@@ -935,9 +938,11 @@ TkMacOSXAddVirtual(
InitHashTables();
}
- hPtr = Tcl_FindHashEntry(&unichar2xvirtual, INT2PTR(macKC.v.keychar));
+ hPtr = (Tcl_HashEntry *) Tcl_FindHashEntry(&unichar2xvirtual,
+ INT2PTR(macKC.v.keychar));
if (hPtr != NULL) {
- macKC.x.xvirtual = (unsigned int) Tcl_GetHashValue(hPtr);
+ unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr);
+ macKC.x.xvirtual = (unsigned int) data;
} else {
macKC.v.virtual = NO_VIRTUAL;
}
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index dd50d0a..435caf9 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -103,8 +103,8 @@ enum {
* ticket [d72abe6b54].
*/
- if (eventType == NSEventTypeLeftMouseDown &&
- ([eventWindow styleMask] & NSWindowStyleMaskResizable) &&
+ if (eventType == NSLeftMouseDown &&
+ ([eventWindow styleMask] & NSResizableWindowMask) &&
[NSApp macMinorVersion] > 6) {
NSRect frame = [eventWindow frame];
if (local.x < 3 || local.x > frame.size.width - 3 || local.y < 3) {
diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c
index 77e9e74..96c9a7a 100644
--- a/macosx/tkMacOSXNotify.c
+++ b/macosx/tkMacOSXNotify.c
@@ -145,18 +145,18 @@ void DebugPrintQueue(void)
/*
* 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.
+ * sends an event of type NSAppKitDefined 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) {
+ if ([theEvent type] == NSAppKitDefined) {
static Bool aWindowIsMoving = NO;
switch([theEvent subtype]) {
case 20:
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index b5b93d5..a0645f7 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -19,6 +19,10 @@
#error Objective-C compiler required
#endif
+#ifndef __clang__
+#define instancetype id
+#endif
+
#define TextStyle MacTextStyle
#import <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
@@ -283,7 +287,6 @@ MODULE_SCOPE NSImage* TkMacOSXGetNSImageWithBitmap(Display *display,
Pixmap bitmap, GC gc, int width, int height);
MODULE_SCOPE CGColorRef TkMacOSXCreateCGColor(GC gc, unsigned long pixel);
MODULE_SCOPE NSColor* TkMacOSXGetNSColor(GC gc, unsigned long pixel);
-MODULE_SCOPE Tcl_Obj * TkMacOSXGetStringObjFromCFString(CFStringRef str);
MODULE_SCOPE TkWindow* TkMacOSXGetTkWindow(NSWindow *w);
MODULE_SCOPE NSFont* TkMacOSXNSFontForFont(Tk_Font tkfont);
MODULE_SCOPE NSDictionary* TkMacOSXNSFontAttributesForFont(Tk_Font tkfont);
@@ -303,10 +306,6 @@ MODULE_SCOPE int TkMacOSXServices_Init(Tcl_Interp *interp);
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
@@ -519,17 +518,16 @@ VISIBILITY_HIDDEN
*
* 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.
+ * encoding requires 4 bytes. Instead, when using these versions of Tcl, Tk
+ * uses the CESU-8 encoding internally. This encoding is similar to UTF-8
+ * except that it allows encoding surrogate characters as 3-byte sequences
+ * using the same algorithm which UTF-8 uses for non-surrogates. This means
+ * that a non-BMP character is encoded as a string of length 6. Apple's
+ * NSString class does not provide a constructor which accepts a CESU-8 encoded
+ * byte sequence as initial data. So we add a new class which does provide
+ * such a constructor. It also has a DString property which is a DString whose
+ * string pointer is a byte sequence encoding the NSString with the current Tk
+ * encoding, namely UTF-8 if TCL_MAX >= 4 or CESU-8 if TCL_MAX = 3.
*
*---------------------------------------------------------------------------
*/
@@ -540,6 +538,7 @@ VISIBILITY_HIDDEN
NSString *_string;
}
@property const char *UTF8String;
+@property (readonly) Tcl_DString DString;
- (instancetype)initWithTclUtfBytes:(const void *)bytes
length:(NSUInteger)len;
@end
diff --git a/macosx/tkMacOSXTest.c b/macosx/tkMacOSXTest.c
index 902bf9e..0a739a1 100644
--- a/macosx/tkMacOSXTest.c
+++ b/macosx/tkMacOSXTest.c
@@ -153,7 +153,7 @@ PressButtonObjCmd(
int objc,
Tcl_Obj *const objv[])
{
- int x, y, i, value, wNum;
+ int x = 0, y = 0, i, value, wNum;
CGPoint pt;
NSPoint loc;
NSEvent *motion, *press, *release;
diff --git a/win/tkWinKey.c b/win/tkWinKey.c
index c7fa20c..4451296 100644
--- a/win/tkWinKey.c
+++ b/win/tkWinKey.c
@@ -102,9 +102,10 @@ TkpGetString(
Tcl_DStringInit(dsPtr);
if (keyEv->send_event == -1) {
- if (keyEv->nbytes > 0) {
+ TkKeyEvent *ev = (TkKeyEvent *)keyEv;
+ if (ev->nbytes > 0) {
Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(),
- keyEv->trans_chars, keyEv->nbytes, dsPtr);
+ ev->trans_chars, ev->nbytes, dsPtr);
}
} else if (keyEv->send_event == -3) {
diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c
index 8bcc826..1f345ff 100644
--- a/win/tkWinMenu.c
+++ b/win/tkWinMenu.c
@@ -2231,17 +2231,16 @@ TkWinMenuKeyObjCmd(
virtualKey = XKeysymToKeycode(winPtr->display, keySym);
scanCode = MapVirtualKeyW(virtualKey, 0);
if (0 != scanCode) {
- XKeyEvent xkey = eventPtr->xkey;
+ TkKeyEvent xkey;
+ memcpy(&xkey, eventPtr, sizeof(xkey));
CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
WM_SYSKEYDOWN, virtualKey,
(int) ((scanCode << 16) | (1 << 29)));
- if (xkey.nbytes > 0) {
- for (i = 0; i < xkey.nbytes; i++) {
- CallWindowProcW(DefWindowProcW,
- Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR,
- xkey.trans_chars[i],
- (int) ((scanCode << 16) | (1 << 29)));
- }
+ for (i = 0; i < xkey.nbytes; i++) {
+ CallWindowProcW(DefWindowProcW,
+ Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR,
+ xkey.trans_chars[i],
+ (int) ((scanCode << 16) | (1 << 29)));
}
}
}
diff --git a/win/tkWinX.c b/win/tkWinX.c
index 689268d..f445fce 100644
--- a/win/tkWinX.c
+++ b/win/tkWinX.c
@@ -104,7 +104,7 @@ static Tcl_ThreadDataKey dataKey;
static void GenerateXEvent(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
static unsigned int GetState(UINT message, WPARAM wParam, LPARAM lParam);
-static void GetTranslatedKey(XKeyEvent *xkey, UINT type);
+static void GetTranslatedKey(TkKeyEvent *xkey, UINT type);
static void UpdateInputLanguage(int charset);
static int HandleIMEComposition(HWND hwnd, LPARAM lParam);
@@ -994,7 +994,7 @@ GenerateXEvent(
WPARAM wParam,
LPARAM lParam)
{
- XEvent event;
+ union {XEvent x; TkKeyEvent key;} event;
TkWindow *winPtr;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
@@ -1020,33 +1020,33 @@ GenerateXEvent(
return;
}
- memset(&event, 0, sizeof(XEvent));
- event.xany.serial = winPtr->display->request++;
- event.xany.send_event = False;
- event.xany.display = winPtr->display;
- event.xany.window = winPtr->window;
+ memset(&event.x, 0, sizeof(XEvent));
+ event.x.xany.serial = winPtr->display->request++;
+ event.x.xany.send_event = False;
+ event.x.xany.display = winPtr->display;
+ event.x.xany.window = winPtr->window;
switch (message) {
case WM_PAINT: {
PAINTSTRUCT ps;
- event.type = Expose;
+ event.x.type = Expose;
BeginPaint(hwnd, &ps);
- event.xexpose.x = ps.rcPaint.left;
- event.xexpose.y = ps.rcPaint.top;
- event.xexpose.width = ps.rcPaint.right - ps.rcPaint.left;
- event.xexpose.height = ps.rcPaint.bottom - ps.rcPaint.top;
+ event.x.xexpose.x = ps.rcPaint.left;
+ event.x.xexpose.y = ps.rcPaint.top;
+ event.x.xexpose.width = ps.rcPaint.right - ps.rcPaint.left;
+ event.x.xexpose.height = ps.rcPaint.bottom - ps.rcPaint.top;
EndPaint(hwnd, &ps);
- event.xexpose.count = 0;
+ event.x.xexpose.count = 0;
break;
}
case WM_CLOSE:
- event.type = ClientMessage;
- event.xclient.message_type =
+ event.x.type = ClientMessage;
+ event.x.xclient.message_type =
Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS");
- event.xclient.format = 32;
- event.xclient.data.l[0] =
+ event.x.xclient.format = 32;
+ event.x.xclient.data.l[0] =
Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW");
break;
@@ -1082,10 +1082,10 @@ GenerateXEvent(
return;
}
- event.xany.window = winPtr->window;
- event.type = (message == WM_SETFOCUS) ? FocusIn : FocusOut;
- event.xfocus.mode = NotifyNormal;
- event.xfocus.detail = NotifyNonlinear;
+ event.x.xany.window = winPtr->window;
+ event.x.type = (message == WM_SETFOCUS) ? FocusIn : FocusOut;
+ event.x.xfocus.mode = NotifyNormal;
+ event.x.xfocus.detail = NotifyNonlinear;
/*
* Destroy the caret if we own it. If we are moving to another Tk
@@ -1107,10 +1107,10 @@ GenerateXEvent(
return;
}
- event.type = SelectionClear;
- event.xselectionclear.selection =
+ event.x.type = SelectionClear;
+ event.x.xselectionclear.selection =
Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD");
- event.xselectionclear.time = TkpGetMS();
+ event.x.xselectionclear.time = TkpGetMS();
break;
case WM_MOUSEWHEEL:
@@ -1139,15 +1139,15 @@ GenerateXEvent(
* Set up the common event fields.
*/
- event.xbutton.root = RootWindow(winPtr->display, winPtr->screenNum);
- event.xbutton.subwindow = None;
- event.xbutton.x = clientPoint.x;
- event.xbutton.y = clientPoint.y;
- event.xbutton.x_root = root.point.x;
- event.xbutton.y_root = root.point.y;
- event.xbutton.state = state;
- event.xbutton.time = time;
- event.xbutton.same_screen = True;
+ event.x.xbutton.root = RootWindow(winPtr->display, winPtr->screenNum);
+ event.x.xbutton.subwindow = None;
+ event.x.xbutton.x = clientPoint.x;
+ event.x.xbutton.y = clientPoint.y;
+ event.x.xbutton.x_root = root.point.x;
+ event.x.xbutton.y_root = root.point.y;
+ event.x.xbutton.state = state;
+ event.x.xbutton.time = time;
+ event.x.xbutton.same_screen = True;
/*
* Now set up event specific fields.
@@ -1179,10 +1179,10 @@ GenerateXEvent(
* TkpGetString. [Bug 1118340].
*/
- event.type = MouseWheelEvent;
- event.xany.send_event = -1;
- event.xkey.nbytes = 0;
- event.xkey.keycode = tsdPtr->vWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
+ event.x.type = MouseWheelEvent;
+ event.x.xany.send_event = -1;
+ event.key.nbytes = 0;
+ event.x.xkey.keycode = tsdPtr->vWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
tsdPtr->vWheelAcc = tsdPtr->vWheelAcc % WHEEL_DELTA;
break;
}
@@ -1211,11 +1211,11 @@ GenerateXEvent(
* TkpGetString. [Bug 1118340].
*/
- event.type = MouseWheelEvent;
- event.xany.send_event = -1;
- event.xkey.nbytes = 0;
- event.xkey.state |= ShiftMask;
- event.xkey.keycode = tsdPtr->hWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
+ event.x.type = MouseWheelEvent;
+ event.x.xany.send_event = -1;
+ event.key.nbytes = 0;
+ event.x.xkey.state |= ShiftMask;
+ event.x.xkey.keycode = tsdPtr->hWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
tsdPtr->hWheelAcc = tsdPtr->hWheelAcc % WHEEL_DELTA;
break;
}
@@ -1229,10 +1229,10 @@ GenerateXEvent(
* MBCS characters that came from the TranslateMessage call.
*/
- event.type = KeyPress;
- event.xany.send_event = -1;
- event.xkey.keycode = wParam;
- GetTranslatedKey(&event.xkey, (message == WM_KEYDOWN) ? WM_CHAR :
+ event.x.type = KeyPress;
+ event.x.xany.send_event = -1;
+ event.x.xkey.keycode = wParam;
+ GetTranslatedKey(&event.key, (message == WM_KEYDOWN) ? WM_CHAR :
WM_SYSCHAR);
break;
@@ -1244,9 +1244,9 @@ GenerateXEvent(
* WM_CHAR messages which will follow.
*/
- event.type = KeyRelease;
- event.xkey.keycode = wParam;
- event.xkey.nbytes = 0;
+ event.x.type = KeyRelease;
+ event.x.xkey.keycode = wParam;
+ event.key.nbytes = 0;
break;
case WM_CHAR:
@@ -1280,9 +1280,9 @@ GenerateXEvent(
* character.
*/
- event.type = KeyPress;
- event.xany.send_event = -1;
- event.xkey.keycode = 0;
+ event.x.type = KeyPress;
+ event.x.xany.send_event = -1;
+ event.x.xkey.keycode = 0;
if ((int)wParam & 0xff00) {
int ch1 = wParam & 0xffff;
@@ -1295,12 +1295,12 @@ GenerateXEvent(
(ch1 & 0x3ff) | 0x10000;
tsdPtr->surrogateBuffer = 0;
}
- event.xany.send_event = -3;
- event.xkey.nbytes = 0;
- event.xkey.keycode = ch1;
+ event.x.xany.send_event = -3;
+ event.key.nbytes = 0;
+ event.x.xkey.keycode = ch1;
} else {
- event.xkey.nbytes = 1;
- event.xkey.trans_chars[0] = (char) wParam;
+ event.key.nbytes = 1;
+ event.key.trans_chars[0] = (char) wParam;
if (IsDBCSLeadByte((BYTE) wParam)) {
MSG msg;
@@ -1309,22 +1309,22 @@ GenerateXEvent(
PM_NOREMOVE) != 0)
&& (msg.message == WM_CHAR)) {
GetMessageW(&msg, NULL, WM_CHAR, WM_CHAR);
- event.xkey.nbytes = 2;
- event.xkey.trans_chars[1] = (char) msg.wParam;
+ event.key.nbytes = 2;
+ event.key.trans_chars[1] = (char) msg.wParam;
}
}
}
- Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
- event.type = KeyRelease;
+ Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
+ event.x.type = KeyRelease;
break;
case WM_UNICHAR: {
- event.type = KeyPress;
- event.xany.send_event = -3;
- event.xkey.keycode = wParam;
- event.xkey.nbytes = 0;
- Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
- event.type = KeyRelease;
+ event.x.type = KeyPress;
+ event.x.xany.send_event = -3;
+ event.x.xkey.keycode = wParam;
+ event.key.nbytes = 0;
+ Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
+ event.x.type = KeyRelease;
break;
}
@@ -1345,7 +1345,7 @@ GenerateXEvent(
* Post the translated event to the main Tk event queue.
*/
- Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+ Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
}
/*
@@ -1447,7 +1447,7 @@ GetState(
static void
GetTranslatedKey(
- XKeyEvent *xkey,
+ TkKeyEvent *xkey,
UINT type)
{
MSG msg;
@@ -1470,7 +1470,7 @@ GetTranslatedKey(
*/
if ((msg.message == WM_CHAR) && (msg.lParam & 0x20000000)) {
- xkey->state = 0;
+ xkey->keyEvent.state = 0;
}
xkey->trans_chars[xkey->nbytes++] = (char) msg.wParam;
@@ -1529,7 +1529,11 @@ UpdateInputLanguage(
return;
}
- sprintf(codepage, "cp%d", charsetInfo.ciACP);
+ if (charsetInfo.ciACP == CP_UTF8) {
+ strcpy(codepage, "utf-8");
+ } else {
+ sprintf(codepage, "cp%d", charsetInfo.ciACP);
+ }
if ((encoding = Tcl_GetEncoding(NULL, codepage)) == NULL) {
/*
diff --git a/xlib/X11/Xlib.h b/xlib/X11/Xlib.h
index af8f706..7969ff5 100644
--- a/xlib/X11/Xlib.h
+++ b/xlib/X11/Xlib.h
@@ -549,9 +549,6 @@ typedef struct {
unsigned int state; /* key or button mask */
unsigned int keycode; /* detail */
Bool same_screen; /* same screen flag */
- char trans_chars[XMaxTransChars];
- /* translated characters */
- unsigned char nbytes;
} XKeyEvent;
typedef XKeyEvent XKeyPressedEvent;
typedef XKeyEvent XKeyReleasedEvent;