View | Details | Raw Unified | Return to bug 77424
Collapse All | Expand All

(-)file_not_specified_in_diff (-28 / +725 lines)
Line  Link Here
0
-- generic/tk.h
0
++ generic/tk.h
Lines 808-813 Link Here
808
    int internalBorderBottom;
808
    int internalBorderBottom;
809
    int minReqWidth;
809
    int minReqWidth;
810
    int minReqHeight;
810
    int minReqHeight;
811
#ifdef TK_USE_INPUT_METHODS
812
    Tcl_DString dummy20;	/* composedDStr */;
813
#endif /* TK_USE_INPUT_METHODS */
811
} Tk_FakeWin;
814
} Tk_FakeWin;
812
815
813
/*
816
/*
814
-- generic/tkBind.c
817
++ generic/tkBind.c
Lines 1465-1470 Link Here
1465
     */
1465
     */
1466
1466
1467
    if (winPtr->pathName == NULL) {
1467
    if (winPtr->pathName == NULL) {
1468
#ifdef TK_USE_INPUT_METHODS
1469
	winPtr->dispPtr->isComposed = 0;
1470
#endif /* TK_USE_INPUT_METHODS */
1468
	return;
1471
	return;
1469
    }
1472
    }
1470
1473
Lines 1700-1709 Link Here
1700
	    Tcl_DStringAppend(&scripts, "", 1);
1703
	    Tcl_DStringAppend(&scripts, "", 1);
1701
	}
1704
	}
1702
    }
1705
    }
1706
#ifdef TK_USE_INPUT_METHODS
1707
    winPtr->dispPtr->isComposed = 0;
1708
#endif /* TK_USE_INPUT_METHODS */
1703
    if (Tcl_DStringLength(&scripts) == 0) {
1709
    if (Tcl_DStringLength(&scripts) == 0) {
1704
	return;
1710
	return;
1705
    }
1711
    }
1706
1712
    
1707
    /*
1713
    /*
1708
     * Now go back through and evaluate the binding for each object,
1714
     * Now go back through and evaluate the binding for each object,
1709
     * in order, dealing with "break" and "continue" exceptions
1715
     * in order, dealing with "break" and "continue" exceptions
1710
-- generic/tkEvent.c
1716
++ generic/tkEvent.c
Lines 872-877 Link Here
872
	}
872
	}
873
    }
873
    }
874
874
875
#if 0
875
#ifdef TK_USE_INPUT_METHODS
876
#ifdef TK_USE_INPUT_METHODS
876
    /*
877
    /*
877
     * Pass the event to the input method(s), if there are any, and
878
     * Pass the event to the input method(s), if there are any, and
Lines 953-958 Link Here
953
	}
954
	}
954
    }
955
    }
955
#endif /* TK_USE_INPUT_METHODS */
956
#endif /* TK_USE_INPUT_METHODS */
957
#endif /* 0 */
956
958
957
    /*
959
    /*
958
     * For events where it hasn't already been done, update the current
960
     * For events where it hasn't already been done, update the current
Lines 1291-1296 Link Here
1291
	}
1293
	}
1292
    }
1294
    }
1293
1295
1296
#ifdef TK_USE_INPUT_METHODS
1297
    if (eventPtr->type == KeyPress && eventPtr->xkey.keycode == 0) {
1298
        /*
1299
         * No doubt this is a composed message from IM server.
1300
         * Tk can handle KeyPress event with zero keycode value 
1301
         * if state of the event is zero.
1302
         */
1303
        eventPtr->xkey.state = 0;
1304
	dispPtr->isComposed = 1;
1305
    }
1306
#endif /* TK_USE_INPUT_METHODS */
1307
1294
    /*
1308
    /*
1295
     * Don't filter motion events if the user 
1309
     * Don't filter motion events if the user 
1296
     * defaulting to true (1), which could be set to false (0) when the
1310
     * defaulting to true (1), which could be set to false (0) when the
1297
-- generic/tkInt.h
1311
++ generic/tkInt.h
Lines 509-514 Link Here
509
509
510
    int iconDataSize;		/* size of default iconphoto image data */
510
    int iconDataSize;		/* size of default iconphoto image data */
511
    unsigned char *iconDataPtr;	/* default iconphoto image data, if set */
511
    unsigned char *iconDataPtr;	/* default iconphoto image data, if set */
512
513
#ifdef TK_USE_INPUT_METHODS
514
    Tcl_Encoding imEncoding;   /* Tcl encoding when the first Tcl
515
                                * interp was created.
516
                                * For encoding conversion from
517
                                * XmbLookupString() to UTF.
518
				*/
519
    XIC lastFocusedIC;         /* The last focused input context on
520
                                * the display.
521
                                */
522
    int isComposed;             /* 1 if the latest KeyPress event is a
523
                                 * "Compose message" from IM server,
524
                                 * otherwise 0. */
525
#ifdef XNDestroyCallback
526
    XIMCallback destroyCallback;
527
#endif /* XNDestroyCallback */
528
#endif /* TK_USE_INPUT_METHODS */
512
} TkDisplay;
529
} TkDisplay;
513
530
514
/*
531
/*
Lines 833-838 Link Here
833
    
850
    
834
    int minReqWidth;		/* Minimum requested width. */
851
    int minReqWidth;		/* Minimum requested width. */
835
    int minReqHeight;		/* Minimum requested height. */
852
    int minReqHeight;		/* Minimum requested height. */
853
854
#ifdef TK_USE_INPUT_METHODS
855
    Tcl_DString composedDStr;  /* To prepare successive "%A" in bind
856
				* script, save a string from IM
857
				* server. */
858
#endif /* TK_USE_INPUT_METHODS */
836
} TkWindow;
859
} TkWindow;
837
860
838
/*
861
/*
Lines 1089-1094 Link Here
1089
			    Tcl_Interp *interp, int objc,
1112
			    Tcl_Interp *interp, int objc,
1090
			    Tcl_Obj *CONST objv[]));
1113
			    Tcl_Obj *CONST objv[]));
1091
1114
1115
EXTERN int		TkConsoleInit _ANSI_ARGS_((Tcl_Interp *interp));
1092
EXTERN void		TkConsolePrint _ANSI_ARGS_((Tcl_Interp *interp,
1116
EXTERN void		TkConsolePrint _ANSI_ARGS_((Tcl_Interp *interp,
1093
			    int devId, CONST char *buffer, long size));
1117
			    int devId, CONST char *buffer, long size));
1094
1118
Lines 1183-1188 Link Here
1183
EXTERN int		TkUnsupported1Cmd _ANSI_ARGS_((ClientData clientData,
1207
EXTERN int		TkUnsupported1Cmd _ANSI_ARGS_((ClientData clientData,
1184
			    Tcl_Interp *interp, int argc, CONST char **argv));
1208
			    Tcl_Interp *interp, int argc, CONST char **argv));
1185
1209
1210
#ifdef TK_USE_INPUT_METHODS
1211
EXTERN XIC		TkpCreateIC _ANSI_ARGS_((TkWindow *winPtr));
1212
EXTERN void		TkpDestroyIC _ANSI_ARGS_((TkWindow *winPtr, int needDestroy));
1213
EXTERN int		Tk_ImconfigureObjCmd _ANSI_ARGS_((ClientData clientData,
1214
			    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
1215
#endif /* TK_USE_INPUT_METHODS */
1216
1186
# undef TCL_STORAGE_CLASS
1217
# undef TCL_STORAGE_CLASS
1187
# define TCL_STORAGE_CLASS DLLIMPORT
1218
# define TCL_STORAGE_CLASS DLLIMPORT
1188
1219
1189
-- generic/tkWindow.c
1220
++ generic/tkWindow.c
Lines 179-184 Link Here
179
    {"::tk::unsupported::MacWindowStyle",
179
    {"::tk::unsupported::MacWindowStyle",
180
	    		TkUnsupported1Cmd,	NULL,			1, 1},
180
	    		TkUnsupported1Cmd,	NULL,			1, 1},
181
#endif
181
#endif
182
#ifdef TK_USE_INPUT_METHODS
183
    {"::tk::unsupported::imconfigure",		NULL,
184
			Tk_ImconfigureObjCmd,	1, 1},
185
#endif
182
    {(char *) NULL,	(int (*) _ANSI_ARGS_((ClientData, Tcl_Interp *, int, CONST char **))) NULL, NULL, 0}
186
    {(char *) NULL,	(int (*) _ANSI_ARGS_((ClientData, Tcl_Interp *, int, CONST char **))) NULL, NULL, 0}
183
};
187
};
184
188
Lines 233-238 Link Here
233
			    TkWindow *winPtr, TkWindow *parentPtr,
237
			    TkWindow *winPtr, TkWindow *parentPtr,
234
			    CONST char *name));
238
			    CONST char *name));
235
static void		UnlinkWindow _ANSI_ARGS_((TkWindow *winPtr));
239
static void		UnlinkWindow _ANSI_ARGS_((TkWindow *winPtr));
240
236
241
237
/*
242
/*
238
 *----------------------------------------------------------------------
243
 *----------------------------------------------------------------------
Lines 679-684 Link Here
679
    winPtr->handlerList = NULL;
684
    winPtr->handlerList = NULL;
680
#ifdef TK_USE_INPUT_METHODS
685
#ifdef TK_USE_INPUT_METHODS
681
    winPtr->inputContext = NULL;
686
    winPtr->inputContext = NULL;
687
    Tcl_DStringInit(&(winPtr->composedDStr));
682
#endif /* TK_USE_INPUT_METHODS */
688
#endif /* TK_USE_INPUT_METHODS */
683
    winPtr->tagPtr = NULL;
689
    winPtr->tagPtr = NULL;
684
    winPtr->numTags = 0;
690
    winPtr->numTags = 0;
Lines 1471-1479 Link Here
1471
    TkBindDeadWindow(winPtr);
1477
    TkBindDeadWindow(winPtr);
1472
#ifdef TK_USE_INPUT_METHODS
1478
#ifdef TK_USE_INPUT_METHODS
1473
    if (winPtr->inputContext != NULL) {
1479
    if (winPtr->inputContext != NULL) {
1474
	XDestroyIC(winPtr->inputContext);
1480
	TkpDestroyIC(winPtr, 1);
1475
	winPtr->inputContext = NULL;
1481
	winPtr->inputContext = NULL;
1476
    }
1482
    }
1483
    Tcl_DStringFree(&(winPtr->composedDStr));
1484
    Tcl_DStringInit(&(winPtr->composedDStr));
1477
#endif /* TK_USE_INPUT_METHODS */
1485
#endif /* TK_USE_INPUT_METHODS */
1478
    if (winPtr->tagPtr != NULL) {
1486
    if (winPtr->tagPtr != NULL) {
1479
	TkFreeBindingTags(winPtr);
1487
	TkFreeBindingTags(winPtr);
1480
-- library/entry.tcl
1488
++ library/entry.tcl
Lines 217-222 Link Here
217
    }
217
    }
218
}
218
}
219
219
220
# input method configuration binding (unix only)
221
if {![string compare $tcl_platform(platform) "unix"]} {
222
    if {[string compare [info commands ::tk::unsupported::imconfigure] {}]} {
223
	bind Entry <FocusIn> {catch {::tk::unsupported::imconfigure %W}}
224
    }
225
}
226
220
# Additional emacs-like bindings:
227
# Additional emacs-like bindings:
221
228
222
bind Entry <Control-a> {
229
bind Entry <Control-a> {
223
-- library/text.tcl
230
++ library/text.tcl
Lines 391-396 Link Here
391
    }
391
    }
392
}
392
}
393
393
394
# UNIX only bindings:
395
396
if {[string equal $tcl_platform(platform) "unix"] &&
397
    [string compare [info commands ::tk::unsupported::imconfigure] {}]} {
398
    bind Text <FocusIn> {catch {::tk::unsupported::imconfigure %W}}
399
}
400
394
# Macintosh only bindings:
401
# Macintosh only bindings:
395
402
396
# if text black & highlight black -> text white, other text the same
403
# if text black & highlight black -> text white, other text the same
397
-- unix/Makefile.in
404
++ unix/Makefile.in
Lines 280-286 Link Here
280
# modify any of this stuff by hand.
280
# modify any of this stuff by hand.
281
#----------------------------------------------------------------
281
#----------------------------------------------------------------
282
282
283
AC_FLAGS		= @DEFS@
283
AC_FLAGS		= @DEFS@ @CPPFLAGS@ @X11_IMAKE_FLAGS@
284
AR			= @AR@
284
AR			= @AR@
285
RANLIB			= @RANLIB@
285
RANLIB			= @RANLIB@
286
SRC_DIR			= @srcdir@
286
SRC_DIR			= @srcdir@
Lines 349-355 Link Here
349
	tkUnixCursor.o tkUnixDraw.o tkUnixEmbed.o tkUnixEvent.o \
349
	tkUnixCursor.o tkUnixDraw.o tkUnixEmbed.o tkUnixEvent.o \
350
	tkUnixFocus.o tkUnixFont.o tkUnixInit.o tkUnixKey.o tkUnixMenu.o \
350
	tkUnixFocus.o tkUnixFont.o tkUnixInit.o tkUnixKey.o tkUnixMenu.o \
351
	tkUnixMenubu.o tkUnixScale.o tkUnixScrlbr.o tkUnixSelect.o \
351
	tkUnixMenubu.o tkUnixScale.o tkUnixScrlbr.o tkUnixSelect.o \
352
	tkUnixSend.o tkUnixWm.o tkUnixXId.o
352
	tkUnixSend.o tkUnixWm.o tkUnixXId.o tkUnixIm.o
353
353
354
AQUA_OBJS = tkMacOSXBitmap.o tkMacOSXButton.o tkMacOSXClipboard.o \
354
AQUA_OBJS = tkMacOSXBitmap.o tkMacOSXButton.o tkMacOSXClipboard.o \
355
	tkMacOSXColor.o tkMacOSXConfig.o tkMacOSXCursor.o tkMacOSXDebug.o \
355
	tkMacOSXColor.o tkMacOSXConfig.o tkMacOSXCursor.o tkMacOSXDebug.o \
Lines 420-425 Link Here
420
	$(UNIX_DIR)/tkUnixEmbed.c $(UNIX_DIR)/tkUnixEvent.c \
420
	$(UNIX_DIR)/tkUnixEmbed.c $(UNIX_DIR)/tkUnixEvent.c \
421
	$(UNIX_DIR)/tkUnixFocus.c \
421
	$(UNIX_DIR)/tkUnixFocus.c \
422
	$(UNIX_DIR)/tkUnixFont.c $(UNIX_DIR)/tkUnixInit.c \
422
	$(UNIX_DIR)/tkUnixFont.c $(UNIX_DIR)/tkUnixInit.c \
423
	$(UNIX_DIR)/tkUnixIm.c \
423
	$(UNIX_DIR)/tkUnixKey.c \
424
	$(UNIX_DIR)/tkUnixKey.c \
424
	$(UNIX_DIR)/tkUnixMenu.c $(UNIX_DIR)/tkUnixMenubu.c \
425
	$(UNIX_DIR)/tkUnixMenu.c $(UNIX_DIR)/tkUnixMenubu.c \
425
	$(UNIX_DIR)/tkUnixScale.c $(UNIX_DIR)/tkUnixScrlbr.c \
426
	$(UNIX_DIR)/tkUnixScale.c $(UNIX_DIR)/tkUnixScrlbr.c \
Lines 1073-1078 Link Here
1073
	$(CC) -c $(CC_SWITCHES) -DTK_LIBRARY=\"${TK_LIBRARY}\" \
1074
	$(CC) -c $(CC_SWITCHES) -DTK_LIBRARY=\"${TK_LIBRARY}\" \
1074
	    $(UNIX_DIR)/tkUnixInit.c
1075
	    $(UNIX_DIR)/tkUnixInit.c
1075
1076
1077
tkUnixIm.o: $(UNIX_DIR)/tkUnixIm.c
1078
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixIm.c
1079
1076
tkUnixKey.o: $(UNIX_DIR)/tkUnixKey.c
1080
tkUnixKey.o: $(UNIX_DIR)/tkUnixKey.c
1077
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixKey.c
1081
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixKey.c
1078
1082
1079
-- unix/configure.in
1083
++ unix/configure.in
Lines 528-533 Link Here
528
528
529
TK_SHARED_BUILD=${SHARED_BUILD}
529
TK_SHARED_BUILD=${SHARED_BUILD}
530
530
531
#--------------------------------------------------------------------
532
#      Checking X lib for i18n related things.
533
#--------------------------------------------------------------------
534
535
X11_IMAKE_FLAGS=""
536
tk_oldCflags=$CFLAGS
537
tk_oldLibs=$LIBS
538
CFLAGS="$CFLAGS $XINCLUDES"
539
LIBS="$XLIBSW $LIBS"
540
541
AC_MSG_CHECKING([XRegisterIMInstantiateCallback])
542
AC_TRY_LINK([
543
#include <X11/Xlib.h>
544
], [
545
XRegisterIMInstantiateCallback(0, 0, 0, 0, 0, 0);
546
], [
547
AC_MSG_RESULT(yes)
548
X11_IMAKE_FLAGS="-DHAVE_XIMREGINSTCB"
549
], [
550
AC_MSG_RESULT(no)
551
])
552
553
AC_MSG_CHECKING([XIDProc])
554
AC_TRY_COMPILE([
555
#include <X11/Xlib.h>
556
], [
557
XIDProc *a;
558
], [
559
AC_MSG_RESULT(yes)
560
], [
561
AC_MSG_RESULT(no)
562
X11_IMAKE_FLAGS="$X11_IMAKE_FLAGS -DNO_XIDPROC"
563
])
564
565
HAVE_XMKMF=""
566
AC_PATH_PROG(HAVE_XMKMF, xmkmf, "", ${PATH}:/usr/X11R6/bin:/usr/X11R5/bin:/usr/local/X11R6/bin:/usr/local/X11R5/bi:/usr/openwin/bin:/usr/X11/bin:/usr/X386/bin:/usr/sww/bin:/usr/unsupported/bin)
567
if test "X$HAVE_XMKMF" != "X"; then
568
    IMAKE_FLAGS=""
569
    if test -d ImakeCheck; then
570
        rm -rf ImakeCheck
571
    fi
572
    mkdir ImakeCheck
573
    cat << EOF > ImakeCheck/Imakefile
574
SRCS = dummy.c
575
OBJS = dummy.o
576
577
ComplexProgramTarget(dummy)
578
EOF
579
    cat << EOF > ImakeCheck/dummy.c
580
static int justAnInt = 0;
581
EOF
582
    (cd ./ImakeCheck; rm -f Makefile Makefile.*; eval $HAVE_XMKMF) > /dev/null 2>&1
583
    for i in `(cd ./ImakeCheck; make -n dummy.o)`
584
    do
585
        case $i in -D*) IMAKE_FLAGS="$IMAKE_FLAGS $i";; esac
586
    done
587
    if test "X$IMAKE_FLAGS" != "X"; then
588
        AC_MSG_RESULT(Add these flags for proper compile: $IMAKE_FLAGS)
589
        X11_IMAKE_FLAGS="$X11_IMAKE_FLAGS $IMAKE_FLAGS"
590
    fi
591
    rm -rf ImakeCheck
592
fi
593
594
# At last check FreeBSD and have -lxpg4.
595
AC_MSG_CHECKING([system version (for additional locale library)])
596
if test -f /usr/lib/NextStep/software_version; then
597
    system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
598
else
599
    system=`uname -s`-`uname -r`
600
    if test "$?" -ne 0 ; then
601
        system=unknown
602
    else
603
        # Special check for weird MP-RAS system (uname returns weird
604
        # results, and the version is kept in special file).
605
    
606
        if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
607
            system=MP-RAS-`awk '{print $3}' /etc/.relid'`
608
        fi
609
        if test "`uname -s`" = "AIX" ; then
610
            system=AIX-`uname -v`.`uname -r`
611
        fi
612
    fi
613
fi
614
615
case $system in
616
    FreeBSD-*)
617
       LIBS="$XLIBSW -lxpg4 $tk_oldLibs"
618
       CFLAGS="$CFLAGS $X11_IMAKE_FLAGS"
619
       AC_TRY_COMPILE([
620
#include <locale.h>
621
], [
622
(void)setlocale(LC_ALL, "");
623
], [
624
AC_MSG_RESULT(use xpg4 library.)
625
XLIBSW="$XLIBSW -lxpg4"
626
], [
627
AC_MSG_RESULT(no need other libraries.)
628
])
629
       ;;
630
    *)
631
       AC_MSG_RESULT(No additional library is needed.)
632
       ;;
633
esac
634
635
CFLAGS=$tk_oldCflags
636
LIBS=$tk_oldLibs
637
531
AC_SUBST(TK_VERSION)
638
AC_SUBST(TK_VERSION)
532
AC_SUBST(TK_MAJOR_VERSION)
639
AC_SUBST(TK_MAJOR_VERSION)
533
AC_SUBST(TK_MINOR_VERSION)
640
AC_SUBST(TK_MINOR_VERSION)
Lines 548-553 Link Here
548
AC_SUBST(TK_DBGX)
655
AC_SUBST(TK_DBGX)
549
656
550
AC_SUBST(TK_SHARED_BUILD)
657
AC_SUBST(TK_SHARED_BUILD)
658
AC_SUBST(X11_IMAKE_FLAGS)
551
AC_SUBST(LD_LIBRARY_PATH_VAR)
659
AC_SUBST(LD_LIBRARY_PATH_VAR)
552
660
553
AC_SUBST(TK_BUILD_LIB_SPEC)
661
AC_SUBST(TK_BUILD_LIB_SPEC)
554
-- unix/tkConfig.sh.in
662
++ unix/tkConfig.sh.in
Lines 20-26 Link Here
20
TK_PATCH_LEVEL='@TK_PATCH_LEVEL@'
20
TK_PATCH_LEVEL='@TK_PATCH_LEVEL@'
21
21
22
# -D flags for use with the C compiler.
22
# -D flags for use with the C compiler.
23
TK_DEFS='@DEFS@'
23
TK_DEFS='@DEFS@ @X11_IMAKE_FLAGS@'
24
24
25
# Flag, 1: we built a shared lib, 0 we didn't
25
# Flag, 1: we built a shared lib, 0 we didn't
26
TK_SHARED_BUILD=@TK_SHARED_BUILD@
26
TK_SHARED_BUILD=@TK_SHARED_BUILD@
27
-- unix/tkUnixEvent.c
27
++ unix/tkUnixEvent.c
Lines 200-206 Link Here
200
	 * not be run for with these new releases.
200
	 * not be run for with these new releases.
201
	 */
201
	 */
202
202
203
#if defined(TK_USE_INPUT_METHODS) && defined(PEEK_XCLOSEIM)
203
#ifdef PEEK_XCLOSEIM
204
	int do_peek = 0;
204
	int do_peek = 0;
205
	struct XIMPeek *peek;
205
	struct XIMPeek *peek;
206
206
Lines 229-234 Link Here
229
#endif
229
#endif
230
	XCloseIM(dispPtr->inputMethod);
230
	XCloseIM(dispPtr->inputMethod);
231
    }
231
    }
232
    if (dispPtr->imEncoding != NULL) {
233
	Tcl_FreeEncoding(dispPtr->imEncoding);
234
    }
232
#endif
235
#endif
233
236
234
    if (dispPtr->display != 0) {
237
    if (dispPtr->display != 0) {
Lines 354-359 Link Here
354
357
355
    while (numFound > 0) {
358
    while (numFound > 0) {
356
	XNextEvent(display, &event);
359
	XNextEvent(display, &event);
360
	/*
361
	 * To avoid Tk freezing by IM server's protocol bugs,
362
	 * Re-check queued event after an event is filterd.
363
	 *
364
	 *      m-hirano
365
	 */
366
	if (XFilterEvent(&event, None) == True) {
367
	    numFound = XEventsQueued(display, QueuedAlready);
368
	    continue;
369
	}
357
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
370
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
358
	numFound--;
371
	numFound--;
359
    }
372
    }
Lines 623-629 Link Here
623
     */
636
     */
624
    TransferXEventsToTcl(display);
637
    TransferXEventsToTcl(display);
625
}
638
}
639
626
#ifdef TK_USE_INPUT_METHODS
640
#ifdef TK_USE_INPUT_METHODS
641
static int
642
CanInitiateIm()
643
{
644
    static int inited = 0;
645
    static int ret = 0;
646
    char *locale;
647
    
648
    /*
649
     * Determine the current encoding from the LC_* or LANG environment
650
     * variables.  We previously used setlocale() to determine the locale,
651
     * but this does not work on some systems (e.g. Linux/i386 RH 5.0).
652
     */
653
    locale = getenv("LC_ALL");
654
    
655
    if (locale == NULL || locale[0] == '\0') {
656
	locale = getenv("LC_CTYPE");
657
    }
658
    if (locale == NULL || locale[0] == '\0') {
659
	locale = getenv("LANG");
660
    }
661
    if (locale == NULL || locale[0] == '\0') {
662
	return False;
663
    }
664
    
665
    if (inited == 0) {
666
	char *curSpec = setlocale(LC_ALL, NULL);
667
	
668
	inited = 1;
669
	
670
	if (strcmp(locale, "C") == 0 ||
671
	    strcmp(locale, "POSIX") == 0) {
672
	    goto Checked;
673
	}
674
675
	/*
676
	 * Ok I know, everyone of core Tcl/Tk developer hates this.
677
	 * believe it or not, it must be needed to call
678
	 * setlocale(3)/_Xsetlocale() VERY HERE. This is what the X
679
	 * input method wants.
680
	 * Note that X11's i18n implementation should be ONLY governed
681
	 * by LC_CTYPE. This is clearly/explicitly specified in X11
682
	 * documente Chapter 13. Thus, If there are some X11
683
	 * implementation that need using LC_ALL to initialize i18n
684
	 * subsystem, I won't care about such a X library.
685
	 * But, we are still on edge of darkside. ctype(3) routines
686
	 * are governed by LC_CTYPE.... Need to create "Locale
687
	 * independent ctype libraries" for Tcl/Tk...
688
	 *
689
	 *      m-hirano
690
	 */
691
	
692
	/*
693
	 * OK, First of all, setting WHOLE locale to "C".
694
	 */
695
	(void)setlocale(LC_ALL, "C");
696
	if (setlocale(LC_CTYPE, locale) == NULL) {
697
	    /*
698
	     * Reset to old locale.
699
	     */
700
	    if (setlocale(LC_ALL, curSpec) == NULL) {
701
		(void)setlocale(LC_ALL, "C");
702
	    }
703
	    goto Checked;
704
	} else {
705
	    /*
706
	     * For insurance, reset LC_NUMERIC to "C" for Tcl numeric parsing.
707
	     */
708
	    (void)setlocale(LC_NUMERIC, "C");
709
	}
710
	if (XSupportsLocale() != True) {
711
	    goto Checked;
712
	}
713
	ret = True;
714
	/*
715
	 * At last, Setting the locale modifiers.
716
	 */
717
	(void)XSetLocaleModifiers("");
718
    }
719
720
Checked:
721
    return ret;
722
}
723
724
/*
725
 *----------------------------------------------------------------------
726
 *
727
 * IMInstantiateCallback
728
 *
729
 *     Whenever IM server become available, this function will be called.
730
 *
731
 * Results:
732
 *     OpenIM() is called.
733
 *
734
 * Side effects:
735
 *     None.
736
 *
737
 *----------------------------------------------------------------------
738
 */
739
void
740
IMInstantiateCallback(display, clientData, callData)
741
Display *display;
742
XPointer clientData;
743
XPointer callData;
744
{
745
    TkDisplay *dispPtr = (TkDisplay *)clientData;
746
747
    if (display == dispPtr->display &&
748
	dispPtr->inputMethod == NULL) {
749
	OpenIM(dispPtr);
750
    }
751
}
752
753
/*
754
 *----------------------------------------------------------------------
755
 *
756
 * IMDestroyCallback
757
 *
758
 *     Whenever IM server stops the service, this function will be called.
759
 *
760
 * Results:
761
 *     the XIM opened before is marked as unusable.
762
 *
763
 * Side effects:
764
 *     XIC using this XIM will be useless.
765
 *
766
 *----------------------------------------------------------------------
767
 */
768
void
769
IMDestroyCallback(im, clientData, callData)
770
XIM im;
771
XPointer clientData;
772
XPointer callData;
773
{
774
    TkDisplay *dispPtr = (TkDisplay *)clientData;
775
    if (im == dispPtr->inputMethod) {
776
	Tcl_HashTable winTable = dispPtr->winTable;
777
	Tcl_HashEntry *entry = NULL;
778
	Tcl_HashSearch search;
779
	TkWindow *winPtr;
780
781
	/*
782
	 * We must not call XCloseIM() or XDestroyIC().
783
	 * because the XIM and XIC are destroyed by Xlib 
784
	 * automatically.
785
	 */
786
	for (entry = Tcl_FirstHashEntry(&winTable, &search); entry != NULL;
787
	     entry = Tcl_NextHashEntry(&search)) {
788
	    winPtr = (TkWindow *)Tcl_GetHashValue(entry);
789
	    if (winPtr->dispPtr->display == dispPtr->display &&
790
		winPtr->dispPtr->inputMethod == im &&
791
		winPtr->inputContext != NULL) {
792
		TkpDestroyIC(winPtr, 0);
793
	    }
794
	    Tcl_DStringFree(&(winPtr->composedDStr));
795
	    Tcl_DStringInit(&(winPtr->composedDStr));
796
	}
797
	dispPtr->inputMethod = NULL;
798
	dispPtr->lastFocusedIC = NULL;
799
#ifdef HAVE_XIMREGINSTCB
800
#ifdef NO_XIDPROC
801
	XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
802
				       (XIMProc)IMInstantiateCallback, (XPointer *)dispPtr);
803
#else
804
	XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
805
				       (XIDProc)IMInstantiateCallback, (XPointer)dispPtr);
806
#endif /* NO_XIDPROC */
807
#endif /* HAVE_XIMREGINSTCB */
808
    }
809
}
627
810
628
/* 
811
/* 
629
 *--------------------------------------------------------------
812
 *--------------------------------------------------------------
Lines 650-662 Link Here
650
{
833
{
651
    unsigned short i;
834
    unsigned short i;
652
    XIMStyles *stylePtr;
835
    XIMStyles *stylePtr;
836
    int styleFound = 0;
653
837
654
    if (XSetLocaleModifiers("") == NULL) {
838
    dispPtr->inputMethod = NULL;
655
	goto error;
839
    dispPtr->imEncoding = NULL;
840
    dispPtr->lastFocusedIC = NULL;
841
    dispPtr->isComposed = 0;
842
    
843
    if (CanInitiateIm() == False) {
844
	return;
656
    }
845
    }
657
846
658
    dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
847
    dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
659
    if (dispPtr->inputMethod == NULL) {
848
    if (dispPtr->inputMethod == NULL) {
849
#ifdef HAVE_XIMREGINSTCB
850
	/*
851
	 * Maybe no IM server is available right now.
852
	 * Try to register instantiate callback.
853
	 */
854
#ifdef NO_XIDPROC
855
	XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
856
				       (XIMProc)IMInstantiateCallback, (XPointer *)dispPtr);
857
#else
858
	XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
859
				       (XIDProc)IMInstantiateCallback, (XPointer)dispPtr);
860
#endif /* NO_XIDPROC */
861
#endif /* HAVE_XIMREGINSTCB */
660
	return;
862
	return;
661
    }
863
    }
662
864
Lines 681-692 Link Here
681
    for (i = 0; i < stylePtr->count_styles; i++) {
883
    for (i = 0; i < stylePtr->count_styles; i++) {
682
	if (stylePtr->supported_styles[i]
884
	if (stylePtr->supported_styles[i]
683
		== (XIMPreeditNothing | XIMStatusNothing)) {
885
		== (XIMPreeditNothing | XIMStatusNothing)) {
684
	    XFree(stylePtr);
886
	    styleFound = 1;
685
	    return;
686
	}
887
	}
687
    }
888
    }
688
    XFree(stylePtr);
889
    XFree(stylePtr);
689
890
891
    if (styleFound == 1) {
892
	/*
893
	 * Create a Tcl_Encoding for XmbLookupString() conversion.
894
	 */
895
	dispPtr->imEncoding = Tcl_GetEncoding(NULL, Tcl_GetEncodingName(NULL));
896
#ifdef XNDestroyCallback
897
	dispPtr->destroyCallback.client_data = (XPointer)dispPtr;
898
	dispPtr->destroyCallback.callback = (XIMProc)IMDestroyCallback;
899
	(void)XSetIMValues(dispPtr->inputMethod,
900
			   XNDestroyCallback, &(dispPtr->destroyCallback), NULL);
901
#endif /* XNDestroyCallback */ 
902
	return;
903
    }
904
690
    error:
905
    error:
691
906
692
    if (dispPtr->inputMethod) {
907
    if (dispPtr->inputMethod) {
693
-- unix/tkUnixIm.c
908
++ unix/tkUnixIm.c
Line 0 Link Here
0
-- unix/tkUnixKey.c
1
/* 
2
 * tkUnixIm.c --
3
 *
4
 *      This file contains modules to implement the XIM protocol session.
5
 *	This is the shrinked version of tkXIM.c, worte for tk8.0jp.
6
 *
7
 *	Author:	m-hirano@sra.co.jp
8
 *
9
 * Copyright 1999, 2000 Software Research Associates, Inc.
10
 *
11
 * Permission to use, copy, modify, and distribute this software and its
12
 * documentation for any purpose and without fee is hereby granted, provided
13
 * that the above copyright notice appear in all copies and that both that
14
 * copyright notice and this permission notice appear in supporting
15
 * documentation, and that the name of Software Research Associates not be
16
 * used in advertising or publicity pertaining to distribution of the
17
 * software without specific, written prior permission.  Software Research
18
 * Associates makes no representations about the suitability of this software
19
 * for any purpose.  It is provided "as is" without express or implied
20
 * warranty.
21
 */
22
23
#if 0
24
static char rcsid[] = "$Header: /home/m-hirano/cvsroot/tcltk/tk8.1/unix/tkUnixIm.c,v 1.1 1999/05/10 00:39:16 m-hirano Exp $";
25
#endif
26
27
#include "tkPort.h"
28
#include "tkInt.h"
29
30
#ifdef TK_USE_INPUT_METHODS
31
32
static void		TkpIMGenericHandler _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr));
33
static TkWindow *	GetToplevel _ANSI_ARGS_((TkWindow *winPtr));
34
static void		TkpCreateIMGenericHandler _ANSI_ARGS_((Tk_Window tkwin));
35
static void		TkpDeleteIMGenericHandler _ANSI_ARGS_((Tk_Window tkwin));
36
37
static TkWindow *
38
GetToplevel(winPtr)
39
     TkWindow *winPtr;
40
{
41
    while (!(winPtr->flags & TK_TOP_LEVEL)) {
42
	winPtr = winPtr->parentPtr;
43
	if (winPtr == NULL) {
44
	    return NULL;
45
	}
46
    }
47
    return winPtr;
48
}
49
50
51
static void
52
TkpIMGenericHandler(clientData, eventPtr)
53
     ClientData clientData;
54
     XEvent *eventPtr;
55
{
56
    Tk_Window tkwin = (Tk_Window)clientData;
57
    TkWindow *winPtr = (TkWindow *)clientData;
58
    
59
    if (eventPtr->xany.window != Tk_WindowId(tkwin) ||
60
	winPtr->inputContext == NULL ||
61
	!(winPtr->flags & TK_CHECKED_IC)) {
62
	/*
63
	 * Why ME ???
64
	 */
65
	return;
66
    }
67
68
    /*
69
     * Well, should I care about Enter/Leave ?
70
     */
71
72
    switch (eventPtr->type) {
73
        case KeyPress:
74
        case FocusIn: {
75
	    Window root, child;
76
	    int rootX, rootY;
77
	    int wX, wY;
78
	    unsigned int mask;
79
80
	    /*
81
	     * Care about case mouse pointer is not on winPtr->window.
82
	     * In such a case, IM server can't fetch any events from Tk.
83
	     */
84
85
	    if (XQueryPointer(winPtr->display,
86
			      RootWindow(winPtr->display, winPtr->screenNum),
87
			      &root, &child, &rootX, &rootY, &wX, &wY, &mask) == True) {
88
		TkWindow *pWin = (TkWindow *)Tk_CoordsToWindow(rootX, rootY,
89
							       (Tk_Window)winPtr);
90
		if (pWin != NULL && (pWin->window != winPtr->window)) {
91
#if 0
92
		    /*
93
		     * Code belows are what I REALLY want to do. But,
94
		     * in XIMPreeditPosition mode, IM server use the
95
		     * focus window as key event source window and as
96
		     * PreeditArea window by X11 specification. I want
97
		     * IM server to use this focus window ONLY as key
98
		     * event source. Means:
99
		     *
100
		     * 	o PreeditArea and PreeditPosition take place
101
		     * 	  within client window (winPtr->window).
102
		     *	o KeyPress event source is the window in which
103
		     *	  mouse pointer is (pWin->window).
104
		     */
105
106
		    if (XSetICValues(winPtr->inputContext, XNFocusWindow,
107
				     pWin->window, NULL) != NULL) {
108
			fprintf(stderr, "debugIC: can't set IC focus to pointer window 0x%08x\n",
109
				pWin->window);
110
		    } else {
111
			fprintf(stderr, "debugIC: set IC focus to pointer window 0x%08x\n",
112
				pWin->window);
113
		    }
114
#endif
115
		    /*
116
		     * Check pWin and winPtr are in same toplevel.
117
		     * If they are NOT, don't change focus. 
118
		     */
119
		    TkWindow *pTop = GetToplevel(pWin);
120
		    TkWindow *wTop = GetToplevel(winPtr);
121
		    if (pTop == wTop) {
122
			TkpChangeFocus(winPtr, 1);
123
		    }
124
		}
125
	    }
126
	    /*
127
	     * Get current focused window.
128
	     */
129
	    if (winPtr->dispPtr->lastFocusedIC != winPtr->inputContext) {
130
		winPtr->dispPtr->lastFocusedIC = winPtr->inputContext;
131
		XSetICFocus(winPtr->inputContext);
132
	    }
133
	    break;
134
	}
135
136
        case FocusOut: {
137
	    winPtr->dispPtr->lastFocusedIC = None;
138
	    XUnsetICFocus(winPtr->inputContext);
139
	    break;
140
	}
141
142
	case DestroyNotify: {
143
	    winPtr->dispPtr->lastFocusedIC = NULL;
144
	    XUnsetICFocus(winPtr->inputContext);
145
	    TkpDeleteIMGenericHandler(tkwin);
146
	    break;
147
	}
148
    }
149
}
150
151
152
static void
153
TkpCreateIMGenericHandler(tkwin)
154
     Tk_Window tkwin;
155
{
156
    Tk_CreateEventHandler(tkwin, FocusChangeMask|StructureNotifyMask|KeyPressMask
157
#if 0
158
			  EnterWindowMask|LeaveWindowMask,
159
#else
160
			  ,
161
#endif
162
			  (Tk_EventProc *)TkpIMGenericHandler,
163
			  (ClientData)tkwin);
164
}
165
166
167
static void
168
TkpDeleteIMGenericHandler(tkwin)
169
     Tk_Window tkwin;
170
{
171
    Tk_DeleteEventHandler(tkwin, FocusChangeMask|StructureNotifyMask|KeyPressMask
172
#if 0
173
			  EnterWindowMask|LeaveWindowMask,
174
#else
175
			  ,
176
#endif
177
			  (Tk_EventProc *)TkpIMGenericHandler,
178
			  (ClientData)tkwin);
179
}
180
181
182
XIC
183
TkpCreateIC(winPtr)
184
     TkWindow *winPtr;
185
{
186
    if (winPtr->dispPtr->inputMethod != NULL &&
187
	!(winPtr->flags & TK_CHECKED_IC)) {
188
	winPtr->inputContext =
189
		XCreateIC(winPtr->dispPtr->inputMethod,
190
			  XNInputStyle, XIMPreeditNothing|XIMStatusNothing,
191
			  XNClientWindow, winPtr->window,
192
			  XNFocusWindow, winPtr->window,
193
			  NULL);
194
	if (winPtr->inputContext != NULL) {
195
	    TkpCreateIMGenericHandler((Tk_Window)winPtr);
196
	}
197
    }
198
    winPtr->flags |= TK_CHECKED_IC;
199
    return winPtr->inputContext;
200
}
201
202
203
void
204
TkpDestroyIC(winPtr, needDestroy)
205
     TkWindow *winPtr;
206
     int needDestroy;
207
{
208
    TkpDeleteIMGenericHandler((Tk_Window)winPtr);
209
    if (winPtr->inputContext == winPtr->dispPtr->lastFocusedIC) {
210
	winPtr->dispPtr->lastFocusedIC = None;
211
    }
212
    if (needDestroy == 1 &&
213
	winPtr->inputContext != NULL) {
214
	XDestroyIC(winPtr->inputContext);
215
    }
216
    winPtr->flags &= ~(TK_CHECKED_IC);
217
    winPtr->inputContext = NULL;
218
}
219
220
221
int
222
Tk_ImconfigureObjCmd(clientData, interp, objc, objv)
223
     ClientData clientData;	/* Main window associated with
224
				 * interpreter. */
225
     Tcl_Interp *interp;	/* Current interpreter. */
226
     int objc;			/* Number of arguments. */
227
     Tcl_Obj *CONST objv[];	/* Argument objects. */
228
{
229
    Tk_Window tkwin = (Tk_Window)clientData;
230
    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
231
232
    if (objc < 2) {
233
	Tcl_WrongNumArgs(interp, 1, objv, "path ?option? ?arg? ...");
234
	return TCL_ERROR;
235
    }
236
237
    tkwin = Tk_NameToWindow(interp, Tcl_GetStringFromObj(objv[1], NULL), tkwin);
238
    if (tkwin == NULL) {
239
	return TCL_ERROR;
240
    }
241
242
    if ((((TkWindow *)tkwin)->dispPtr->flags & TK_DISPLAY_USE_IM) == 0) {
243
	/*
244
	 * Destroy XIC and leave.
245
	 */
246
	TkpDestroyIC((TkWindow *)tkwin, 1);
247
	return TCL_OK;
248
    }
249
250
    if (((TkWindow *)tkwin)->dispPtr->inputMethod == NULL) {
251
	Tcl_AppendStringsToObj(resultPtr, "No IM server is available.", NULL);
252
	return TCL_ERROR;
253
    }
254
255
    Tcl_AppendStringsToObj(resultPtr,
256
			  (TkpCreateIC((TkWindow *)tkwin) != NULL) ? "1" : "0",
257
			  NULL);
258
    return TCL_OK;
259
}
260
261
#endif /* TK_USE_INPUT_METHODS */
262
++ unix/tkUnixKey.c
Lines 88-93 Link Here
88
    Status status;
88
    Status status;
89
#ifdef TK_USE_INPUT_METHODS
89
#ifdef TK_USE_INPUT_METHODS
90
    TkDisplay *dispPtr = winPtr->dispPtr;
90
    TkDisplay *dispPtr = winPtr->dispPtr;
91
    Bool validString = False;
92
    Bool usePreviousComposed = False;
91
#endif
93
#endif
92
94
93
    /*
95
    /*
Lines 98-105 Link Here
98
    Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
100
    Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
99
101
100
#ifdef TK_USE_INPUT_METHODS
102
#ifdef TK_USE_INPUT_METHODS
101
    if ((dispPtr->flags & TK_DISPLAY_USE_IM)
103
    if ((winPtr->inputContext != NULL)
102
	    && (winPtr->inputContext != NULL)
103
	    && (eventPtr->type == KeyPress)) {
104
	    && (eventPtr->type == KeyPress)) {
104
#if TK_XIM_SPOT
105
#if TK_XIM_SPOT
105
	XVaNestedList preedit_attr;
106
	XVaNestedList preedit_attr;
Lines 119-124 Link Here
119
		    Tcl_DStringValue(&buf), len, (KeySym *) NULL, &status);
120
		    Tcl_DStringValue(&buf), len, (KeySym *) NULL, &status);
120
	}
121
	}
121
	if ((status != XLookupChars) && (status != XLookupBoth)) {
122
	if ((status != XLookupChars) && (status != XLookupBoth)) {
123
	    if (dispPtr->isComposed == 1 &&
124
		Tcl_DStringLength(&(winPtr->composedDStr)) > 0 &&
125
		dispPtr->flags & TK_DISPLAY_USE_IM) {
126
		usePreviousComposed = True;
127
	    }
122
	    len = 0;
128
	    len = 0;
123
	}
129
	}
124
130
Lines 136-145 Link Here
136
	    XFree(preedit_attr);
142
	    XFree(preedit_attr);
137
	}
143
	}
138
#endif
144
#endif
145
	if (dispPtr->flags & TK_DISPLAY_USE_IM) {
146
	    validString = True;
147
	}
139
    } else {
148
    } else {
140
	len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
149
	len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
141
		Tcl_DStringLength(&buf), (KeySym *) NULL,
150
		Tcl_DStringLength(&buf), (KeySym *) NULL,
142
		(XComposeStatus *) NULL);
151
		(XComposeStatus *) NULL);
152
	validString = True;
143
    }
153
    }
144
#else /* TK_USE_INPUT_METHODS */
154
#else /* TK_USE_INPUT_METHODS */
145
    len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
155
    len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
Lines 147-156 Link Here
147
	    (XComposeStatus *) NULL);
157
	    (XComposeStatus *) NULL);
148
#endif /* TK_USE_INPUT_METHODS */
158
#endif /* TK_USE_INPUT_METHODS */
149
    Tcl_DStringSetLength(&buf, len);
159
    Tcl_DStringSetLength(&buf, len);
150
160
#ifdef TK_USE_INPUT_METHODS
161
    if (validString == True) {
162
	if (usePreviousComposed == False) {
163
	    Tcl_ExternalToUtfDString(dispPtr->imEncoding,
164
				     Tcl_DStringValue(&buf), len, dsPtr);
165
	    Tcl_DStringFree(&(winPtr->composedDStr));
166
	    Tcl_DStringInit(&(winPtr->composedDStr));
167
	    Tcl_DStringAppend(&(winPtr->composedDStr),
168
			      Tcl_DStringValue(dsPtr),
169
			      Tcl_DStringLength(dsPtr));
170
	} else {
171
	    Tcl_DStringFree(dsPtr);
172
	    Tcl_DStringInit(dsPtr);
173
	    Tcl_DStringAppend(dsPtr,
174
			      Tcl_DStringValue(&(winPtr->composedDStr)),
175
			      Tcl_DStringLength(&(winPtr->composedDStr)));
176
	}
177
    } else {
178
	Tcl_DStringFree(dsPtr);
179
	Tcl_DStringInit(dsPtr);
180
    }
181
#else
151
    Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&buf), len, dsPtr);
182
    Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&buf), len, dsPtr);
183
#endif
152
    Tcl_DStringFree(&buf);
184
    Tcl_DStringFree(&buf);
153
185
    
154
    return Tcl_DStringValue(dsPtr);
186
    return Tcl_DStringValue(dsPtr);
155
}
187
}
156
188
157
-- unix/tkUnixPort.h
189
++ unix/tkUnixPort.h
Lines 81-86 Link Here
81
#include <X11/Xproto.h>
81
#include <X11/Xproto.h>
82
#include <X11/Xresource.h>
82
#include <X11/Xresource.h>
83
#include <X11/Xutil.h>
83
#include <X11/Xutil.h>
84
#include <X11/Xlocale.h>
84
85
85
/*
86
/*
86
 * The following macro defines the type of the mask arguments to
87
 * The following macro defines the type of the mask arguments to

Return to bug 77424