diff --git a/www/mozilla-devel/Makefile b/www/mozilla-devel/Makefile index 532966e00c28..93bb8d9e2905 100644 --- a/www/mozilla-devel/Makefile +++ b/www/mozilla-devel/Makefile @@ -6,7 +6,7 @@ # PORTNAME?= mozilla -PORTVERSION= 1.3b +PORTVERSION= 1.4a PORTEPOCH?= 1 CATEGORIES?= www MASTER_SITES= ${MASTER_SITE_MOZILLA} \ @@ -14,7 +14,7 @@ MASTER_SITES= ${MASTER_SITE_MOZILLA} \ MASTER_SITE_SUBDIR= mozilla/releases/${PORTNAME}${PORTVERSION:S/.rc/rc/}/src \ marcus/:local DISTFILES= ${PORTNAME}-source-${PORTVERSION:S/.rc/rc/}${EXTRACT_SUFX} \ - libart_lgpl-${PORTVERSION}${EXTRACT_SUFX}:local + libart_lgpl${EXTRACT_SUFX}:local MAINTAINER= gnome@FreeBSD.org COMMENT= The open source, standards compliant web browser @@ -30,15 +30,9 @@ WRKSRC= ${WRKDIR}/${PORTNAME} MOZILLA?= mozilla-devel -BROKEN= "Requires update to 1.4a" - -WITHOUT_CHATZILLA= "Contains a buffer overflow reported at http://online.securityfocus.com/archive/1/270249" - .if defined(WITH_GTK2) -LIB_DEPENDS+= gtk-x11-2.0.200:${PORTSDIR}/x11-toolkits/gtk20 \ - ORBit-2.0:${PORTSDIR}/devel/ORBit2 +USE_GNOME= gtk20 orbit2 .else -USE_GNOMENG= yes USE_GNOME= gtk12 orbit .endif @@ -52,7 +46,7 @@ BROKEN= Mozilla-devel and Xft2 render the mozilla-fonts \ .if defined(WITH_CALENDAR) && (defined(WITHOUT_MAILNEWS) || \ defined(WITHOUT_COMPOSER)) -BROKEN= Calendar requires Composer and Mailnews support. +BROKEN= "Calendar requires Composer and Mailnews support." .endif .if defined(WITH_CALENDAR) @@ -82,12 +76,14 @@ CONFIGURE_ARGS= \ --enable-mathml \ --disable-md \ --disable-pedantic \ + --disable-bidi \ --disable-plaintext-editor-only \ --enable-strip \ --enable-svg \ --disable-tests \ --disable-xterm-updates \ --enable-xinerama \ + --with-system-zlib \ --with-system-jpeg=${LOCALBASE} \ --with-system-mng=${LOCALBASE} \ --with-system-png=${LOCALBASE} \ @@ -116,6 +112,9 @@ CONFIGURE_ENV= MOZ_INTERNAL_LIBART_LGPL=1 .if defined(WITH_JAVASCRIPT_DEBUGGER) CONFIGURE_ARGS+= --enable-jsd \ --enable-dtd-debug +.else +CONFIGURE_ARGS+= --disable-jsd \ + --disable-dtd-debug .endif .if defined(WITH_CALENDAR) @@ -131,6 +130,7 @@ CONFIGURE_ARGS+= --disable-composer CONFIGURE_ARGS+= --enable-default-toolkit=gtk2 PKGCONFIG_FILES= mozilla-gtkmozembed.pc mozilla-js.pc mozilla-xpcom.pc \ mozilla-nspr.pc mozilla-nss.pc +EXTRA_PATCHES= ${FILESDIR}/xim_dekita2.patch .else CONFIGURE_ARGS+= --enable-default-toolkit=gtk .endif @@ -149,6 +149,10 @@ ALL_TARGET= default CONFIGURE_ARGS+= --enable-reorder .endif +.if !defined(WITHOUT_OPTIMIZE) && ${ARCH} != "alpha" +CFLAGS+= -O2 +.endif + .if ${ARCH} == "alpha" CFLAGS+= -O0 BROKEN= "core dumps on alpha during post-build" @@ -159,6 +163,17 @@ BROKEN="You must upgrade your freetype port to 1.3.1_2 or higher before installi .endif pre-everything:: + @${ECHO_MSG} "" + @${ECHO_MSG} "Mozilla has the following tunable option(s):" + @${ECHO_MSG} " WITHOUT_XFT=yes Disables Xft anti-aliasing support" + @${ECHO_MSG} " WITH_CALENDAR=yes Enables the Calendar module (requires Mailnews and Composer modules)" + @${ECHO_MSG} " WITHOUT_MAILNEWS=yes Disables the Mail and News modules" + @${ECHO_MSG} " WITHOUT_COMPOSER=yes Disables the HTML Composer module" + @${ECHO_MSG} " WITHOUT_LDAP=yes Disables LDAP support within the Mailnews module" + @${ECHO_MSG} " WITHOUT_CHATZILLA=yes Disable the Chatzilla IRC module" + @${ECHO_MSG} " WITH_JAVASCRIPT_DEBUGGER=yes Enable the DTD and JavaScript debuggers" + @${ECHO_MSG} " WITHOUT_OPTIMIZE=yes Disable -O2 optimization" + @${ECHO_MSG} "" .if defined(WITH_CALENDAR) @${ECHO_MSG} "Calendar is still beta software." @${ECHO_MSG} "Use at your own risk." diff --git a/www/mozilla-devel/distinfo b/www/mozilla-devel/distinfo index 81d931e64bf9..f271aebbd0c5 100644 --- a/www/mozilla-devel/distinfo +++ b/www/mozilla-devel/distinfo @@ -1,3 +1,2 @@ -MD5 (mozilla-source-1.3b.tar.gz) = 51c4a31cd7cf7d2a00a9b1aa343d6716 -MD5 (libart_lgpl-1.3b.tar.gz) = db14696f2bf83333f2020fa87fbe630c -MD5 (mozilla-calendar-1.3b.tar.gz) = 2e4db8a23c0960d6d8d859c2c31f97d8 +MD5 (mozilla-source-1.4a.tar.gz) = 6e060d7e2f233055e9f1fbd8b9eaf3c9 +MD5 (libart_lgpl.tar.gz) = 38bb6d37f7b90eaa266fe65e60b639ce diff --git a/www/mozilla-devel/files/patch-config_rules.mk b/www/mozilla-devel/files/patch-config_rules.mk deleted file mode 100644 index e1bc19837bdc..000000000000 --- a/www/mozilla-devel/files/patch-config_rules.mk +++ /dev/null @@ -1,15 +0,0 @@ ---- config/rules.mk.orig Sat Jan 25 16:40:16 2003 -+++ config/rules.mk Sat Jan 25 16:42:56 2003 -@@ -411,6 +411,12 @@ - endif - endif - -+ifeq ($(OS_ARCH),FreeBSD) -+ifdef IS_COMPONENT -+EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic -+endif -+endif -+ - ifeq ($(OS_ARCH),NetBSD) - ifneq (,$(filter arc cobalt hpcmips mipsco newsmips pmax sgimips,$(OS_TEST))) - ifeq ($(MODULE),layout) diff --git a/www/mozilla-devel/files/patch-nsprpub_pr_src_misc_prtime.c b/www/mozilla-devel/files/patch-nsprpub_pr_src_misc_prtime.c index 6b65ef14fbec..30f067cfaf56 100644 --- a/www/mozilla-devel/files/patch-nsprpub_pr_src_misc_prtime.c +++ b/www/mozilla-devel/files/patch-nsprpub_pr_src_misc_prtime.c @@ -1,18 +1,11 @@ ---- nsprpub/pr/src/misc/prtime.c.orig Sun Mar 31 12:17:46 2002 -+++ nsprpub/pr/src/misc/prtime.c Tue Dec 17 21:30:30 2002 -@@ -1666,12 +1666,13 @@ - * values for these two fields. +--- nsprpub/pr/src/misc/prtime.c.orig Wed Feb 26 19:01:02 2003 ++++ nsprpub/pr/src/misc/prtime.c Sun Apr 6 19:22:10 2003 +@@ -1666,7 +1666,7 @@ */ --#if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS) -+#if defined(__FreeBSD__)|| defined(SUNOS4) \ -+ || (__GLIBC__ >= 2) || defined(XP_BEOS) - if (mktime(&a) == -1) { - PR_snprintf(buf, buflen, "can't get timezone"); - return 0; - } --#endif -+#endif /* check for __FreeBSD__, too */ - - return strftime(buf, buflen, fmt, &a); - } + #if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS) \ +- || defined(NETBSD) ++ || defined(NETBSD) || defined(__FreeBSD__) + a.tm_zone = NULL; + a.tm_gmtoff = tm->tm_params.tp_gmt_offset + tm->tm_params.tp_dst_offset; + #endif diff --git a/www/mozilla-devel/files/patch-qt b/www/mozilla-devel/files/patch-qt index 032397d35040..0c2a83e6f4e0 100644 --- a/www/mozilla-devel/files/patch-qt +++ b/www/mozilla-devel/files/patch-qt @@ -1,23 +1,14 @@ ---- configure.orig Thu Feb 6 17:15:12 2003 -+++ configure Tue Feb 11 22:52:48 2003 -@@ -10974,7 +10974,7 @@ - fi - MOC=$HOST_MOC - -- QT_CFLAGS="-I${QTDIR}${QTINCDIR} -DQT_GENUINE_STR -DQT_NO_STL" -+ QT_CFLAGS="-I${QTDIR}/include/X11/qt -DQT_GENUINE_STR" - if test -z "$MOZ_DEBUG"; then - QT_CFLAGS="$QT_CFLAGS -DQT_NO_DEBUG -DNO_DEBUG" - fi -@@ -11840,9 +11840,9 @@ +--- configure.orig Mon Mar 31 16:30:08 2003 ++++ configure Sun Apr 6 19:24:52 2003 +@@ -11719,9 +11719,9 @@ --MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help pref transformiix venkman inspector irc universalchardet typeaheadfind" -+MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help pref transformiix venkman inspector universalchardet typeaheadfind" +-MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help p3p pref transformiix venkman inspector irc universalchardet typeaheadfind" ++MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help p3p pref transformiix venkman inspector universalchardet typeaheadfind" --MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT xmlterm access-builtin p3p interfaceinfo datetime finger cview" -+MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT irc xmlterm access-builtin p3p interfaceinfo datetime finger cview" +-MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT xmlterm access-builtin datetime finger cview" ++MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT irc xmlterm access-builtin datetime finger cview" # Check whether --enable-extensions or --disable-extensions was given. if test "${enable_extensions+set}" = set; then diff --git a/www/mozilla-devel/files/xim_dekita2.patch b/www/mozilla-devel/files/xim_dekita2.patch new file mode 100644 index 000000000000..0305a0ddf317 --- /dev/null +++ b/www/mozilla-devel/files/xim_dekita2.patch @@ -0,0 +1,784 @@ +Index: Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/widget/src/gtk2/Makefile.in,v +retrieving revision 1.26 +diff -u -r1.26 Makefile.in +--- widget/src/gtk2/Makefile.in 22 Mar 2003 05:29:24 -0000 1.26 ++++ widget/src/gtk2/Makefile.in 6 Apr 2003 02:56:31 -0000 +@@ -90,7 +90,7 @@ + CFLAGS += $(MOZ_GTK2_CFLAGS) + CXXFLAGS += $(MOZ_GTK2_CFLAGS) + +-#DEFINES += -DUSE_XIM ++DEFINES += -DUSE_XIM + + INCLUDES += \ + -I$(srcdir)/../xpwidgets \ +Index: nsWindow.cpp +=================================================================== +RCS file: /cvsroot/mozilla/widget/src/gtk2/nsWindow.cpp,v +retrieving revision 1.71 +diff -u -r1.71 nsWindow.cpp +--- widget/src/gtk2/nsWindow.cpp 24 Mar 2003 04:15:20 -0000 1.71 ++++ widget/src/gtk2/nsWindow.cpp 6 Apr 2003 02:56:31 -0000 +@@ -180,25 +180,24 @@ + + #ifdef USE_XIM + +-struct nsXICLookupEntry { +- PLDHashEntryHdr mKeyHash; +- nsWindow* mShellWindow; +- GtkIMContext* mXIC; +-}; +- +-PLDHashTable nsWindow::gXICLookupTable; +- +-static void IM_commit_cb (GtkIMContext *context, +- const gchar *str, +- nsWindow *window); +-static void IM_preedit_changed_cb (GtkIMContext *context, +- nsWindow *window); +-static void IMSetTextRange (const PRInt32 aLen, ++static nsWindow *gIMEFocusWindow = NULL; ++static GdkEventKey *gKeyEvent = NULL; ++static PRBool gKeyEventCommitted = PR_FALSE; ++static PRBool gKeyEventChanged = PR_FALSE; ++ ++static void IM_commit_cb (GtkIMContext *aContext, ++ const gchar *aString, ++ nsWindow *aWindow); ++static void IM_preedit_changed_cb (GtkIMContext *aContext, ++ nsWindow *aWindow); ++static void IM_set_text_range (const PRInt32 aLen, + const gchar *aPreeditString, + const PangoAttrList *aFeedback, + PRUint32 *aTextRangeListLengthResult, + nsTextRangeArray *aTextRangeListResult); + ++static GtkIMContext *IM_get_input_context(MozDrawingarea *aArea); ++ + // If after selecting profile window, the startup fail, please refer to + // http://bugzilla.gnome.org/show_bug.cgi?id=88940 + #endif +@@ -245,11 +244,8 @@ + mDragMotionTimerID = 0; + + #ifdef USE_XIM +- if (gXICLookupTable.ops == NULL) { +- PL_DHashTableInit(&gXICLookupTable, PL_DHashGetStubOps(), nsnull, +- sizeof(nsXICLookupEntry), PL_DHASH_MIN_SIZE); +- } +- mIMEShellWindow = nsnull; ++ mIMContext = nsnull; ++ mComposingText = PR_FALSE; + #endif + + #ifdef ACCESSIBILITY +@@ -257,61 +253,6 @@ + #endif + } + +-#ifdef USE_XIM +-void +-nsWindow::IMEGetShellWindow(void) +-{ +- GtkWidget* top_window = nsnull; +- GetToplevelWidget(&top_window); +- if (top_window) { +- mIMEShellWindow = get_window_for_gtk_widget(top_window); +- } +-} +- +-GtkIMContext* +-nsWindow::IMEGetContext() +-{ +- if (!mIMEShellWindow) { +- return NULL; +- } +- PLDHashEntryHdr* hash_entry; +- nsXICLookupEntry* entry; +- +- hash_entry = PL_DHashTableOperate(&gXICLookupTable, +- mIMEShellWindow, PL_DHASH_LOOKUP); +- +- if (hash_entry) { +- entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); +- if (entry->mXIC) { +- return entry->mXIC; +- } +- } +- return NULL; +-} +- +-void +-nsWindow::IMECreateContext(GdkWindow* aGdkWindow) +-{ +- PLDHashEntryHdr* hash_entry; +- nsXICLookupEntry* entry; +- GtkIMContext *im = gtk_im_multicontext_new(); +- if (im) { +- hash_entry = PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_ADD); +- if (hash_entry) { +- entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); +- entry->mShellWindow = this; +- entry->mXIC = im; +- } +- gtk_im_context_set_client_window(im, aGdkWindow); +- g_signal_connect(G_OBJECT(im), "commit", +- G_CALLBACK(IM_commit_cb), this); +- g_signal_connect(G_OBJECT(im), "preedit_changed", +- G_CALLBACK(IM_preedit_changed_cb), this); +- this->mIMEShellWindow = this; +- } +-} +-#endif +- + nsWindow::~nsWindow() + { + LOG(("nsWindow::~nsWindow() [%p]\n", (void *)this)); +@@ -397,22 +338,7 @@ + } + + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- // If this is the focus window and we have an IM context we need +- // to unset the focus on this window before we destroy the window. +- if (im && gFocusWindow == this) { +- LOGFOCUS((" gtk_im_context_focus_out() from Destroy()\n")); +- gtk_im_context_focus_out(im); +- } +- +- // if shell, delete GtkIMContext +- if (im && mShell) { +- gtk_im_context_reset(im); +- PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_REMOVE); +- g_object_unref(G_OBJECT(im)); +- } +- +- mIMEShellWindow = nsnull; ++ IMEDestroyContext(); + #endif + + // make sure that we remove ourself as the focus window +@@ -656,21 +582,26 @@ + return NS_OK; + } + +- // If there is already a focued child window, dispatch a LOSTFOCUS ++ // If there is already a focused child window, dispatch a LOSTFOCUS + // event from that widget and unset its got focus flag. +- if (gFocusWindow) ++ if (gFocusWindow) { ++#ifdef USE_XIM ++ // If the focus window and this window share the same input ++ // context we don't have to change the focus of the IME ++ // context ++ if (IM_get_input_context(this->mDrawingarea) != ++ IM_get_input_context(gFocusWindow->mDrawingarea)) ++ gFocusWindow->IMELoseFocus(); ++#endif + gFocusWindow->LoseFocus(); ++ } + + // Set this window to be the focused child window, update our has + // focus flag and dispatch a GOTFOCUS event. + gFocusWindow = this; + + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im && !mIsTopLevel) { +- LOGFOCUS((" gtk_im_context_focus_in()\n")); +- gtk_im_context_focus_in(im); +- } ++ IMESetFocus(); + #endif + + LOGFOCUS((" widget now has focus - dispatching events [%p]\n", +@@ -1165,18 +1096,6 @@ + void + nsWindow::LoseFocus(void) + { +-#ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im && !mIsTopLevel) { +- LOGFOCUS((" gtk_im_context_focus_out()\n")); +- gtk_im_context_focus_out(im); +- IMEComposeStart(); +- IMEComposeText(NULL, 0, NULL, NULL); +- IMEComposeEnd(); +- LOG(("gtk_im_context_focus_out\n")); +- } +-#endif +- + // make sure that we reset our repeat counter so the next keypress + // for this widget will get the down event + mInKeyRepeat = PR_FALSE; +@@ -1516,6 +1435,10 @@ + + foundit: + ++#ifdef USE_XIM ++ gFocusWindow->IMELoseFocus(); ++#endif ++ + gFocusWindow->LoseFocus(); + + // We only dispatch a deactivate event if we are a toplevel +@@ -1534,21 +1457,25 @@ + nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent) + { + LOGFOCUS(("OnKeyPressEvent [%p]\n", (void *)this)); ++ + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im) { +- if (gtk_im_context_filter_keypress(im, aEvent)) { +- LOGFOCUS((" keypress filtered by XIM\n")); +- return TRUE; +- } +- } ++ // if we are in the middle of composing text, XIM gets to see it ++ // before mozilla does. ++ LOGIM(("key press [%p]: composing %d val %d\n", ++ (void *)this, mComposingText, aEvent->keyval)); ++ if (IMEFilterEvent(aEvent)) ++ return TRUE; ++ LOGIM(("sending as regular key press event\n")); + #endif +- ++ ++ nsKeyEvent event; ++ nsEventStatus status; ++ + // work around for annoying things. +- if (aEvent->keyval == GDK_Tab) +- if (aEvent->state & GDK_CONTROL_MASK) +- if (aEvent->state & GDK_MOD1_MASK) +- return FALSE; ++ if (aEvent->keyval == GDK_Tab && aEvent->state & GDK_CONTROL_MASK && ++ aEvent->state & GDK_MOD1_MASK) { ++ return TRUE; ++ } + + // Don't pass shift, control and alt as key press events + if (aEvent->keyval == GDK_Shift_L +@@ -1556,9 +1483,9 @@ + || aEvent->keyval == GDK_Control_L + || aEvent->keyval == GDK_Control_R + || aEvent->keyval == GDK_Alt_L +- || aEvent->keyval == GDK_Alt_R) ++ || aEvent->keyval == GDK_Alt_R) { + return TRUE; +- ++ } + + // If the key repeat flag isn't set then set it so we don't send + // another key down event on the next key press -- DOM events are +@@ -1568,15 +1495,12 @@ + + if (!mInKeyRepeat) { + mInKeyRepeat = PR_TRUE; ++ + // send the key down event +- nsEventStatus status; +- nsKeyEvent event; + InitKeyEvent(event, aEvent, NS_KEY_DOWN); + DispatchEvent(&event, status); + } + +- nsEventStatus status; +- nsKeyEvent event; + InitKeyEvent(event, aEvent, NS_KEY_PRESS); + event.charCode = nsConvertCharCodeToUnicode(aEvent); + if (event.charCode) { +@@ -1608,25 +1532,33 @@ + key_event_to_context_menu_event(&event, &contextMenuEvent); + DispatchEvent(&contextMenuEvent, status); + } +- else ++ else { + // send the key press event + DispatchEvent(&event, status); +- return TRUE; ++ } ++ ++ // If the event was consumed, return. ++ LOGIM(("status %d\n", status)); ++ if (status == nsEventStatus_eConsumeNoDefault) { ++ LOGIM(("key press consumed\n")); ++ return TRUE; ++ } ++ ++ return FALSE; + } + + gboolean + nsWindow::OnKeyReleaseEvent(GtkWidget *aWidget, GdkEventKey *aEvent) + { + LOGFOCUS(("OnKeyReleaseEvent [%p]\n", (void *)this)); ++ + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im) { +- if (gtk_im_context_filter_keypress(im, aEvent)) { +- LOGFOCUS((" keypress filtered by XIM\n")); +- return TRUE; +- } +- } ++ if (IMEFilterEvent(aEvent)) ++ return TRUE; + #endif ++ ++ nsKeyEvent event; ++ nsEventStatus status; + + // unset the repeat flag + mInKeyRepeat = PR_FALSE; +@@ -1638,16 +1570,21 @@ + || aEvent->keyval == GDK_Control_L + || aEvent->keyval == GDK_Control_R + || aEvent->keyval == GDK_Alt_L +- || aEvent->keyval == GDK_Alt_R) ++ || aEvent->keyval == GDK_Alt_R) { + return TRUE; ++ } + +- nsKeyEvent event; + InitKeyEvent(event, aEvent, NS_KEY_UP); + +- nsEventStatus status; + DispatchEvent(&event, status); + +- return TRUE; ++ // If the event was consumed, return. ++ if (status == nsEventStatus_eConsumeNoDefault) { ++ LOGIM(("key release consumed\n")); ++ return TRUE; ++ } ++ ++ return FALSE; + } + + void +@@ -1659,7 +1596,6 @@ + // check to see if we should rollup + if (check_for_rollup(aEvent->window, aEvent->x_root, aEvent->y_root, + PR_TRUE)) { +- printf("ignoring event\n"); + return; + } + +@@ -2134,8 +2070,10 @@ + else { // must be eWindowType_toplevel + mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL); + SetDefaultIcon(); ++ + // each toplevel window gets its own window group + mWindowGroup = gtk_window_group_new(); ++ + // and add ourselves to the window group + LOG(("adding window %p to new group %p\n", + (void *)mShell, (void *)mWindowGroup)); +@@ -2165,10 +2103,6 @@ + + mDrawingarea = moz_drawingarea_new(nsnull, mContainer); + } +-#ifdef USE_XIM +- // get mIMEShellWindow and keep it +- IMEGetShellWindow(); +-#endif + } + break; + default: +@@ -2213,13 +2147,6 @@ + G_CALLBACK(property_notify_event_cb), NULL); + } + +-#ifdef USE_XIM +- if (mShell) { +- // init GtkIMContext for shell +- IMECreateContext(mShell->window); +- } +-#endif +- + if (mContainer) { + g_signal_connect_after(G_OBJECT(mContainer), "size_allocate", + G_CALLBACK(size_allocate_cb), NULL); +@@ -2262,6 +2189,13 @@ + G_CALLBACK(drag_drop_event_cb), NULL); + g_signal_connect(G_OBJECT(mContainer), "drag_data_received", + G_CALLBACK(drag_data_received_event_cb), NULL); ++ ++#ifdef USE_XIM ++ // We create input contexts for all containers, except for ++ // toplevel popup windows ++ if (mWindowType != eWindowType_popup) ++ IMECreateContext(); ++#endif + } + + LOG(("nsWindow [%p]\n", (void *)this)); +@@ -3666,8 +3600,59 @@ + #ifdef USE_XIM + + void ++nsWindow::IMEDestroyContext(void) ++{ ++ // If this is the focus window and we have an IM context we need ++ // to unset the focus on this window before we destroy the window. ++ if (gIMEFocusWindow == this) { ++ gIMEFocusWindow->IMELoseFocus(); ++ gIMEFocusWindow = nsnull; ++ } ++ ++ if (!mIMContext) ++ return; ++ ++ gtk_im_context_set_client_window(mIMContext, NULL); ++ g_object_unref(G_OBJECT(mIMContext)); ++ mIMContext = nsnull; ++} ++ ++ ++void ++nsWindow::IMESetFocus(void) ++{ ++ LOGIM(("IMESetFocus %p\n", (void *)this)); ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) ++ return; ++ ++ gtk_im_context_focus_in(im); ++ gIMEFocusWindow = this; ++} ++ ++void ++nsWindow::IMELoseFocus(void) ++{ ++ LOGIM(("IMELoseFocus %p\n", (void *)this)); ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) ++ return; ++ ++ gtk_im_context_focus_out(im); ++} ++ ++void + nsWindow::IMEComposeStart(void) + { ++ LOGIM(("IMEComposeStart [%p]\n", (void *)this)); ++ ++ if (mComposingText) { ++ NS_WARNING("tried to re-start text composition\n"); ++ return; ++ } ++ ++ mComposingText = PR_TRUE; ++ + nsCompositionEvent compEvent; + + compEvent.widget = NS_STATIC_CAST(nsIWidget *, this); +@@ -3686,6 +3671,11 @@ + const gchar *aPreeditString, + const PangoAttrList *aFeedback) + { ++ // Send our start composition event if we need to ++ if (!mComposingText) ++ IMEComposeStart(); ++ ++ LOGIM(("IMEComposeText\n")); + nsTextEvent textEvent; + + textEvent.time = 0; +@@ -3706,9 +3696,9 @@ + textEvent.rangeArray = nsnull; + + if (aPreeditString && aFeedback && (aLen > 0)) { +- IMSetTextRange(aLen, aPreeditString, aFeedback, +- &(textEvent.rangeCount), +- &(textEvent.rangeArray)); ++ IM_set_text_range(aLen, aPreeditString, aFeedback, ++ &(textEvent.rangeCount), ++ &(textEvent.rangeArray)); + } + } + +@@ -3723,6 +3713,15 @@ + void + nsWindow::IMEComposeEnd(void) + { ++ LOGIM(("IMEComposeEnd [%p]\n", (void *)this)); ++ ++ if (!mComposingText) { ++ NS_WARNING("tried to end text composition before it was started"); ++ return; ++ } ++ ++ mComposingText = PR_FALSE; ++ + nsCompositionEvent compEvent; + compEvent.widget = NS_STATIC_CAST(nsIWidget *, this); + compEvent.point.x = compEvent.point.y = 0; +@@ -3734,32 +3733,91 @@ + DispatchEvent(&compEvent, status); + } + ++GtkIMContext* ++nsWindow::IMEGetContext() ++{ ++ return IM_get_input_context(this->mDrawingarea); ++} ++ ++void ++nsWindow::IMECreateContext(void) ++{ ++ GtkIMContext *im = gtk_im_multicontext_new(); ++ if (!im) ++ return; ++ ++ gtk_im_context_set_client_window(im, GTK_WIDGET(mContainer)->window); ++ ++ g_signal_connect(G_OBJECT(im), "preedit_changed", ++ G_CALLBACK(IM_preedit_changed_cb), this); ++ g_signal_connect(G_OBJECT(im), "commit", ++ G_CALLBACK(IM_commit_cb), this); ++ ++ mIMContext = im; ++} ++ ++PRBool ++nsWindow::IMEFilterEvent(GdkEventKey *aEvent) ++{ ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) ++ return FALSE; ++ ++ gKeyEvent = aEvent; ++ gboolean filtered = gtk_im_context_filter_keypress(im, aEvent); ++ gKeyEvent = NULL; ++ ++ LOGIM(("key filtered: %d committed: %d changed: %d\n", ++ filtered, gKeyEventCommitted, gKeyEventChanged)); ++ ++ // We filter the key event if the event was not committed (because ++ // it's probably part of a composition) or if the key event was ++ // committed _and_ changed. This way we still let key press ++ // events go through as simple key press events instead of ++ // composed characters. ++ ++ PRBool retval = PR_FALSE; ++ if (filtered && ++ (!gKeyEventCommitted || (gKeyEventCommitted && gKeyEventChanged))) ++ retval = PR_TRUE; ++ ++ gKeyEventChanged = PR_FALSE; ++ gKeyEventCommitted = PR_FALSE; ++ gKeyEventChanged = PR_FALSE; ++ ++ return retval; ++} ++ + /* static */ + void +-IM_preedit_changed_cb(GtkIMContext *context, +- nsWindow *awindow) ++IM_preedit_changed_cb(GtkIMContext *aContext, ++ nsWindow *aWindow) + { + gchar *preedit_string; + gint cursor_pos; + PangoAttrList *feedback_list; + +- // call for focused window +- nsWindow *window = gFocusWindow; +- if (!window) return; ++ // if gFocusWindow is null, use the last focused gIMEFocusWindow ++ nsWindow *window = gFocusWindow ? gFocusWindow : gIMEFocusWindow; ++ if (!window) ++ return; + + // Should use cursor_pos ? +- gtk_im_context_get_preedit_string(context, &preedit_string, ++ gtk_im_context_get_preedit_string(aContext, &preedit_string, + &feedback_list, &cursor_pos); + + LOGIM(("preedit string is: %s length is: %d\n", + preedit_string, strlen(preedit_string))); + + if (!preedit_string || !*preedit_string) { +- window->IMEComposeStart(); ++ LOGIM(("preedit ended\n")); + window->IMEComposeText(NULL, 0, NULL, NULL); ++ window->IMEComposeEnd(); + return; + } + ++ LOGIM(("preedit len %d\n", strlen(preedit_string))); ++ + gunichar2 * uniStr; + glong uniStrLen; + +@@ -3775,47 +3833,68 @@ + return; + } + +- if (window && (uniStrLen > 0)) { +- window->IMEComposeStart(); ++ if (uniStrLen) { + window->IMEComposeText(NS_STATIC_CAST(const PRUnichar *, uniStr), + uniStrLen, preedit_string, feedback_list); + } + + g_free(preedit_string); + g_free(uniStr); ++ + if (feedback_list) + pango_attr_list_unref(feedback_list); + } + + /* static */ + void +-IM_commit_cb (GtkIMContext *context, +- const gchar *utf8_str, +- nsWindow *awindow) ++IM_commit_cb (GtkIMContext *aContext, ++ const gchar *aUtf8_str, ++ nsWindow *aWindow) + { +- gunichar2 * uniStr; ++ gunichar2 *uniStr; + glong uniStrLen; + +- // call for focused window +- nsWindow *window = gFocusWindow; +- if (!window) return; ++ LOGIM(("IM_commit_cb\n")); + +- uniStr = NULL; +- uniStrLen = 0; +- uniStr = g_utf8_to_utf16(utf8_str, -1, NULL, &uniStrLen, NULL); ++ gKeyEventCommitted = PR_TRUE; + +- // Will free it in call function, don't need +- // g_free((void *)utf8_str)); ++ // if gFocusWindow is null, use the last focused gIMEFocusWindow ++ nsWindow *window = gFocusWindow ? gFocusWindow : gIMEFocusWindow; + +- LOGIM(("IM_commit_cb\n")); ++ if (!window) ++ return; ++ ++ /* If IME doesn't change they keyevent that generated this commit, ++ don't send it through XIM - just send it as a normal key press ++ event. */ ++ ++ if (gKeyEvent) { ++ char keyval_utf8[8]; /* should have at least 6 bytes of space */ ++ gint keyval_utf8_len; ++ guint32 keyval_unicode; ++ ++ keyval_unicode = gdk_keyval_to_unicode(gKeyEvent->keyval); ++ keyval_utf8_len = g_unichar_to_utf8(keyval_unicode, keyval_utf8); ++ keyval_utf8[keyval_utf8_len] = '\0'; ++ ++ if (!strcmp(aUtf8_str, keyval_utf8)) { ++ gKeyEventChanged = PR_FALSE; ++ return; ++ } ++ } ++ ++ gKeyEventChanged = PR_TRUE; ++ ++ uniStr = NULL; ++ uniStrLen = 0; ++ uniStr = g_utf8_to_utf16(aUtf8_str, -1, NULL, &uniStrLen, NULL); + + if (!uniStr) { + LOGIM(("utf80utf16 string tranfer failed!\n")); + return; + } + +- if (window && (uniStrLen > 0)) { +- window->IMEComposeStart(); ++ if (uniStrLen) { + window->IMEComposeText((const PRUnichar *)uniStr, + (PRInt32)uniStrLen, NULL, NULL); + window->IMEComposeEnd(); +@@ -3834,11 +3913,11 @@ + + /* static */ + void +-IMSetTextRange (const PRInt32 aLen, +- const gchar *aPreeditString, +- const PangoAttrList *aFeedback, +- PRUint32 *aTextRangeListLengthResult, +- nsTextRangeArray *aTextRangeListResult) ++IM_set_text_range(const PRInt32 aLen, ++ const gchar *aPreeditString, ++ const PangoAttrList *aFeedback, ++ PRUint32 *aTextRangeListLengthResult, ++ nsTextRangeArray *aTextRangeListResult) + { + if (aLen == 0) { + aTextRangeListLengthResult = 0; +@@ -3941,6 +4020,18 @@ + *aTextRangeListLengthResult = count + 1; + + pango_attr_iterator_destroy(aFeedbackIterator); ++} ++ ++/* static */ ++GtkIMContext * ++IM_get_input_context(MozDrawingarea *aArea) ++{ ++ GtkWidget *owningWidget = ++ get_gtk_widget_for_gdk_window(aArea->inner_window); ++ ++ nsWindow *owningWindow = get_window_for_gtk_widget(owningWidget); ++ ++ return owningWindow->mIMContext; + } + + #endif +Index: nsWindow.h +=================================================================== +RCS file: /cvsroot/mozilla/widget/src/gtk2/nsWindow.h,v +retrieving revision 1.32 +diff -u -r1.32 nsWindow.h +--- widget/src/gtk2/nsWindow.h 17 Feb 2003 18:50:01 -0000 1.32 ++++ widget/src/gtk2/nsWindow.h 6 Apr 2003 02:56:31 -0000 +@@ -239,19 +239,22 @@ + static guint32 mLastButtonPressTime; + + #ifdef USE_XIM +- void IMEComposeStart(void); +- void IMEComposeText(const PRUnichar *aText, +- const PRInt32 aLen, +- const gchar *aPreeditString, +- const PangoAttrList *aFeedback); +- void IMEComposeEnd(void); ++ void IMEDestroyContext (void); ++ void IMESetFocus (void); ++ void IMELoseFocus (void); ++ void IMEComposeStart (void); ++ void IMEComposeText (const PRUnichar *aText, ++ const PRInt32 aLen, ++ const gchar *aPreeditString, ++ const PangoAttrList *aFeedback); ++ void IMEComposeEnd (void); ++ GtkIMContext* IMEGetContext (void); ++ void IMECreateContext (void); ++ PRBool IMEFilterEvent (GdkEventKey *aEvent); ++ ++ GtkIMContext *mIMContext; ++ PRBool mComposingText; + +- void IMEGetShellWindow(void); +- GtkIMContext* IMEGetContext(void); +- void IMECreateContext(GdkWindow* aGdkWindow); +- +- nsWindow* mIMEShellWindow; +- static PLDHashTable gXICLookupTable; + #endif + + private: diff --git a/www/seamonkey/Makefile b/www/seamonkey/Makefile index 532966e00c28..93bb8d9e2905 100644 --- a/www/seamonkey/Makefile +++ b/www/seamonkey/Makefile @@ -6,7 +6,7 @@ # PORTNAME?= mozilla -PORTVERSION= 1.3b +PORTVERSION= 1.4a PORTEPOCH?= 1 CATEGORIES?= www MASTER_SITES= ${MASTER_SITE_MOZILLA} \ @@ -14,7 +14,7 @@ MASTER_SITES= ${MASTER_SITE_MOZILLA} \ MASTER_SITE_SUBDIR= mozilla/releases/${PORTNAME}${PORTVERSION:S/.rc/rc/}/src \ marcus/:local DISTFILES= ${PORTNAME}-source-${PORTVERSION:S/.rc/rc/}${EXTRACT_SUFX} \ - libart_lgpl-${PORTVERSION}${EXTRACT_SUFX}:local + libart_lgpl${EXTRACT_SUFX}:local MAINTAINER= gnome@FreeBSD.org COMMENT= The open source, standards compliant web browser @@ -30,15 +30,9 @@ WRKSRC= ${WRKDIR}/${PORTNAME} MOZILLA?= mozilla-devel -BROKEN= "Requires update to 1.4a" - -WITHOUT_CHATZILLA= "Contains a buffer overflow reported at http://online.securityfocus.com/archive/1/270249" - .if defined(WITH_GTK2) -LIB_DEPENDS+= gtk-x11-2.0.200:${PORTSDIR}/x11-toolkits/gtk20 \ - ORBit-2.0:${PORTSDIR}/devel/ORBit2 +USE_GNOME= gtk20 orbit2 .else -USE_GNOMENG= yes USE_GNOME= gtk12 orbit .endif @@ -52,7 +46,7 @@ BROKEN= Mozilla-devel and Xft2 render the mozilla-fonts \ .if defined(WITH_CALENDAR) && (defined(WITHOUT_MAILNEWS) || \ defined(WITHOUT_COMPOSER)) -BROKEN= Calendar requires Composer and Mailnews support. +BROKEN= "Calendar requires Composer and Mailnews support." .endif .if defined(WITH_CALENDAR) @@ -82,12 +76,14 @@ CONFIGURE_ARGS= \ --enable-mathml \ --disable-md \ --disable-pedantic \ + --disable-bidi \ --disable-plaintext-editor-only \ --enable-strip \ --enable-svg \ --disable-tests \ --disable-xterm-updates \ --enable-xinerama \ + --with-system-zlib \ --with-system-jpeg=${LOCALBASE} \ --with-system-mng=${LOCALBASE} \ --with-system-png=${LOCALBASE} \ @@ -116,6 +112,9 @@ CONFIGURE_ENV= MOZ_INTERNAL_LIBART_LGPL=1 .if defined(WITH_JAVASCRIPT_DEBUGGER) CONFIGURE_ARGS+= --enable-jsd \ --enable-dtd-debug +.else +CONFIGURE_ARGS+= --disable-jsd \ + --disable-dtd-debug .endif .if defined(WITH_CALENDAR) @@ -131,6 +130,7 @@ CONFIGURE_ARGS+= --disable-composer CONFIGURE_ARGS+= --enable-default-toolkit=gtk2 PKGCONFIG_FILES= mozilla-gtkmozembed.pc mozilla-js.pc mozilla-xpcom.pc \ mozilla-nspr.pc mozilla-nss.pc +EXTRA_PATCHES= ${FILESDIR}/xim_dekita2.patch .else CONFIGURE_ARGS+= --enable-default-toolkit=gtk .endif @@ -149,6 +149,10 @@ ALL_TARGET= default CONFIGURE_ARGS+= --enable-reorder .endif +.if !defined(WITHOUT_OPTIMIZE) && ${ARCH} != "alpha" +CFLAGS+= -O2 +.endif + .if ${ARCH} == "alpha" CFLAGS+= -O0 BROKEN= "core dumps on alpha during post-build" @@ -159,6 +163,17 @@ BROKEN="You must upgrade your freetype port to 1.3.1_2 or higher before installi .endif pre-everything:: + @${ECHO_MSG} "" + @${ECHO_MSG} "Mozilla has the following tunable option(s):" + @${ECHO_MSG} " WITHOUT_XFT=yes Disables Xft anti-aliasing support" + @${ECHO_MSG} " WITH_CALENDAR=yes Enables the Calendar module (requires Mailnews and Composer modules)" + @${ECHO_MSG} " WITHOUT_MAILNEWS=yes Disables the Mail and News modules" + @${ECHO_MSG} " WITHOUT_COMPOSER=yes Disables the HTML Composer module" + @${ECHO_MSG} " WITHOUT_LDAP=yes Disables LDAP support within the Mailnews module" + @${ECHO_MSG} " WITHOUT_CHATZILLA=yes Disable the Chatzilla IRC module" + @${ECHO_MSG} " WITH_JAVASCRIPT_DEBUGGER=yes Enable the DTD and JavaScript debuggers" + @${ECHO_MSG} " WITHOUT_OPTIMIZE=yes Disable -O2 optimization" + @${ECHO_MSG} "" .if defined(WITH_CALENDAR) @${ECHO_MSG} "Calendar is still beta software." @${ECHO_MSG} "Use at your own risk." diff --git a/www/seamonkey/distinfo b/www/seamonkey/distinfo index 81d931e64bf9..f271aebbd0c5 100644 --- a/www/seamonkey/distinfo +++ b/www/seamonkey/distinfo @@ -1,3 +1,2 @@ -MD5 (mozilla-source-1.3b.tar.gz) = 51c4a31cd7cf7d2a00a9b1aa343d6716 -MD5 (libart_lgpl-1.3b.tar.gz) = db14696f2bf83333f2020fa87fbe630c -MD5 (mozilla-calendar-1.3b.tar.gz) = 2e4db8a23c0960d6d8d859c2c31f97d8 +MD5 (mozilla-source-1.4a.tar.gz) = 6e060d7e2f233055e9f1fbd8b9eaf3c9 +MD5 (libart_lgpl.tar.gz) = 38bb6d37f7b90eaa266fe65e60b639ce diff --git a/www/seamonkey/files/patch-config_rules.mk b/www/seamonkey/files/patch-config_rules.mk deleted file mode 100644 index e1bc19837bdc..000000000000 --- a/www/seamonkey/files/patch-config_rules.mk +++ /dev/null @@ -1,15 +0,0 @@ ---- config/rules.mk.orig Sat Jan 25 16:40:16 2003 -+++ config/rules.mk Sat Jan 25 16:42:56 2003 -@@ -411,6 +411,12 @@ - endif - endif - -+ifeq ($(OS_ARCH),FreeBSD) -+ifdef IS_COMPONENT -+EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic -+endif -+endif -+ - ifeq ($(OS_ARCH),NetBSD) - ifneq (,$(filter arc cobalt hpcmips mipsco newsmips pmax sgimips,$(OS_TEST))) - ifeq ($(MODULE),layout) diff --git a/www/seamonkey/files/patch-nsprpub_pr_src_misc_prtime.c b/www/seamonkey/files/patch-nsprpub_pr_src_misc_prtime.c index 6b65ef14fbec..30f067cfaf56 100644 --- a/www/seamonkey/files/patch-nsprpub_pr_src_misc_prtime.c +++ b/www/seamonkey/files/patch-nsprpub_pr_src_misc_prtime.c @@ -1,18 +1,11 @@ ---- nsprpub/pr/src/misc/prtime.c.orig Sun Mar 31 12:17:46 2002 -+++ nsprpub/pr/src/misc/prtime.c Tue Dec 17 21:30:30 2002 -@@ -1666,12 +1666,13 @@ - * values for these two fields. +--- nsprpub/pr/src/misc/prtime.c.orig Wed Feb 26 19:01:02 2003 ++++ nsprpub/pr/src/misc/prtime.c Sun Apr 6 19:22:10 2003 +@@ -1666,7 +1666,7 @@ */ --#if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS) -+#if defined(__FreeBSD__)|| defined(SUNOS4) \ -+ || (__GLIBC__ >= 2) || defined(XP_BEOS) - if (mktime(&a) == -1) { - PR_snprintf(buf, buflen, "can't get timezone"); - return 0; - } --#endif -+#endif /* check for __FreeBSD__, too */ - - return strftime(buf, buflen, fmt, &a); - } + #if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS) \ +- || defined(NETBSD) ++ || defined(NETBSD) || defined(__FreeBSD__) + a.tm_zone = NULL; + a.tm_gmtoff = tm->tm_params.tp_gmt_offset + tm->tm_params.tp_dst_offset; + #endif diff --git a/www/seamonkey/files/patch-qt b/www/seamonkey/files/patch-qt index 032397d35040..0c2a83e6f4e0 100644 --- a/www/seamonkey/files/patch-qt +++ b/www/seamonkey/files/patch-qt @@ -1,23 +1,14 @@ ---- configure.orig Thu Feb 6 17:15:12 2003 -+++ configure Tue Feb 11 22:52:48 2003 -@@ -10974,7 +10974,7 @@ - fi - MOC=$HOST_MOC - -- QT_CFLAGS="-I${QTDIR}${QTINCDIR} -DQT_GENUINE_STR -DQT_NO_STL" -+ QT_CFLAGS="-I${QTDIR}/include/X11/qt -DQT_GENUINE_STR" - if test -z "$MOZ_DEBUG"; then - QT_CFLAGS="$QT_CFLAGS -DQT_NO_DEBUG -DNO_DEBUG" - fi -@@ -11840,9 +11840,9 @@ +--- configure.orig Mon Mar 31 16:30:08 2003 ++++ configure Sun Apr 6 19:24:52 2003 +@@ -11719,9 +11719,9 @@ --MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help pref transformiix venkman inspector irc universalchardet typeaheadfind" -+MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help pref transformiix venkman inspector universalchardet typeaheadfind" +-MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help p3p pref transformiix venkman inspector irc universalchardet typeaheadfind" ++MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help p3p pref transformiix venkman inspector universalchardet typeaheadfind" --MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT xmlterm access-builtin p3p interfaceinfo datetime finger cview" -+MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT irc xmlterm access-builtin p3p interfaceinfo datetime finger cview" +-MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT xmlterm access-builtin datetime finger cview" ++MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT irc xmlterm access-builtin datetime finger cview" # Check whether --enable-extensions or --disable-extensions was given. if test "${enable_extensions+set}" = set; then diff --git a/www/seamonkey/files/xim_dekita2.patch b/www/seamonkey/files/xim_dekita2.patch new file mode 100644 index 000000000000..0305a0ddf317 --- /dev/null +++ b/www/seamonkey/files/xim_dekita2.patch @@ -0,0 +1,784 @@ +Index: Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/widget/src/gtk2/Makefile.in,v +retrieving revision 1.26 +diff -u -r1.26 Makefile.in +--- widget/src/gtk2/Makefile.in 22 Mar 2003 05:29:24 -0000 1.26 ++++ widget/src/gtk2/Makefile.in 6 Apr 2003 02:56:31 -0000 +@@ -90,7 +90,7 @@ + CFLAGS += $(MOZ_GTK2_CFLAGS) + CXXFLAGS += $(MOZ_GTK2_CFLAGS) + +-#DEFINES += -DUSE_XIM ++DEFINES += -DUSE_XIM + + INCLUDES += \ + -I$(srcdir)/../xpwidgets \ +Index: nsWindow.cpp +=================================================================== +RCS file: /cvsroot/mozilla/widget/src/gtk2/nsWindow.cpp,v +retrieving revision 1.71 +diff -u -r1.71 nsWindow.cpp +--- widget/src/gtk2/nsWindow.cpp 24 Mar 2003 04:15:20 -0000 1.71 ++++ widget/src/gtk2/nsWindow.cpp 6 Apr 2003 02:56:31 -0000 +@@ -180,25 +180,24 @@ + + #ifdef USE_XIM + +-struct nsXICLookupEntry { +- PLDHashEntryHdr mKeyHash; +- nsWindow* mShellWindow; +- GtkIMContext* mXIC; +-}; +- +-PLDHashTable nsWindow::gXICLookupTable; +- +-static void IM_commit_cb (GtkIMContext *context, +- const gchar *str, +- nsWindow *window); +-static void IM_preedit_changed_cb (GtkIMContext *context, +- nsWindow *window); +-static void IMSetTextRange (const PRInt32 aLen, ++static nsWindow *gIMEFocusWindow = NULL; ++static GdkEventKey *gKeyEvent = NULL; ++static PRBool gKeyEventCommitted = PR_FALSE; ++static PRBool gKeyEventChanged = PR_FALSE; ++ ++static void IM_commit_cb (GtkIMContext *aContext, ++ const gchar *aString, ++ nsWindow *aWindow); ++static void IM_preedit_changed_cb (GtkIMContext *aContext, ++ nsWindow *aWindow); ++static void IM_set_text_range (const PRInt32 aLen, + const gchar *aPreeditString, + const PangoAttrList *aFeedback, + PRUint32 *aTextRangeListLengthResult, + nsTextRangeArray *aTextRangeListResult); + ++static GtkIMContext *IM_get_input_context(MozDrawingarea *aArea); ++ + // If after selecting profile window, the startup fail, please refer to + // http://bugzilla.gnome.org/show_bug.cgi?id=88940 + #endif +@@ -245,11 +244,8 @@ + mDragMotionTimerID = 0; + + #ifdef USE_XIM +- if (gXICLookupTable.ops == NULL) { +- PL_DHashTableInit(&gXICLookupTable, PL_DHashGetStubOps(), nsnull, +- sizeof(nsXICLookupEntry), PL_DHASH_MIN_SIZE); +- } +- mIMEShellWindow = nsnull; ++ mIMContext = nsnull; ++ mComposingText = PR_FALSE; + #endif + + #ifdef ACCESSIBILITY +@@ -257,61 +253,6 @@ + #endif + } + +-#ifdef USE_XIM +-void +-nsWindow::IMEGetShellWindow(void) +-{ +- GtkWidget* top_window = nsnull; +- GetToplevelWidget(&top_window); +- if (top_window) { +- mIMEShellWindow = get_window_for_gtk_widget(top_window); +- } +-} +- +-GtkIMContext* +-nsWindow::IMEGetContext() +-{ +- if (!mIMEShellWindow) { +- return NULL; +- } +- PLDHashEntryHdr* hash_entry; +- nsXICLookupEntry* entry; +- +- hash_entry = PL_DHashTableOperate(&gXICLookupTable, +- mIMEShellWindow, PL_DHASH_LOOKUP); +- +- if (hash_entry) { +- entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); +- if (entry->mXIC) { +- return entry->mXIC; +- } +- } +- return NULL; +-} +- +-void +-nsWindow::IMECreateContext(GdkWindow* aGdkWindow) +-{ +- PLDHashEntryHdr* hash_entry; +- nsXICLookupEntry* entry; +- GtkIMContext *im = gtk_im_multicontext_new(); +- if (im) { +- hash_entry = PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_ADD); +- if (hash_entry) { +- entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); +- entry->mShellWindow = this; +- entry->mXIC = im; +- } +- gtk_im_context_set_client_window(im, aGdkWindow); +- g_signal_connect(G_OBJECT(im), "commit", +- G_CALLBACK(IM_commit_cb), this); +- g_signal_connect(G_OBJECT(im), "preedit_changed", +- G_CALLBACK(IM_preedit_changed_cb), this); +- this->mIMEShellWindow = this; +- } +-} +-#endif +- + nsWindow::~nsWindow() + { + LOG(("nsWindow::~nsWindow() [%p]\n", (void *)this)); +@@ -397,22 +338,7 @@ + } + + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- // If this is the focus window and we have an IM context we need +- // to unset the focus on this window before we destroy the window. +- if (im && gFocusWindow == this) { +- LOGFOCUS((" gtk_im_context_focus_out() from Destroy()\n")); +- gtk_im_context_focus_out(im); +- } +- +- // if shell, delete GtkIMContext +- if (im && mShell) { +- gtk_im_context_reset(im); +- PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_REMOVE); +- g_object_unref(G_OBJECT(im)); +- } +- +- mIMEShellWindow = nsnull; ++ IMEDestroyContext(); + #endif + + // make sure that we remove ourself as the focus window +@@ -656,21 +582,26 @@ + return NS_OK; + } + +- // If there is already a focued child window, dispatch a LOSTFOCUS ++ // If there is already a focused child window, dispatch a LOSTFOCUS + // event from that widget and unset its got focus flag. +- if (gFocusWindow) ++ if (gFocusWindow) { ++#ifdef USE_XIM ++ // If the focus window and this window share the same input ++ // context we don't have to change the focus of the IME ++ // context ++ if (IM_get_input_context(this->mDrawingarea) != ++ IM_get_input_context(gFocusWindow->mDrawingarea)) ++ gFocusWindow->IMELoseFocus(); ++#endif + gFocusWindow->LoseFocus(); ++ } + + // Set this window to be the focused child window, update our has + // focus flag and dispatch a GOTFOCUS event. + gFocusWindow = this; + + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im && !mIsTopLevel) { +- LOGFOCUS((" gtk_im_context_focus_in()\n")); +- gtk_im_context_focus_in(im); +- } ++ IMESetFocus(); + #endif + + LOGFOCUS((" widget now has focus - dispatching events [%p]\n", +@@ -1165,18 +1096,6 @@ + void + nsWindow::LoseFocus(void) + { +-#ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im && !mIsTopLevel) { +- LOGFOCUS((" gtk_im_context_focus_out()\n")); +- gtk_im_context_focus_out(im); +- IMEComposeStart(); +- IMEComposeText(NULL, 0, NULL, NULL); +- IMEComposeEnd(); +- LOG(("gtk_im_context_focus_out\n")); +- } +-#endif +- + // make sure that we reset our repeat counter so the next keypress + // for this widget will get the down event + mInKeyRepeat = PR_FALSE; +@@ -1516,6 +1435,10 @@ + + foundit: + ++#ifdef USE_XIM ++ gFocusWindow->IMELoseFocus(); ++#endif ++ + gFocusWindow->LoseFocus(); + + // We only dispatch a deactivate event if we are a toplevel +@@ -1534,21 +1457,25 @@ + nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent) + { + LOGFOCUS(("OnKeyPressEvent [%p]\n", (void *)this)); ++ + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im) { +- if (gtk_im_context_filter_keypress(im, aEvent)) { +- LOGFOCUS((" keypress filtered by XIM\n")); +- return TRUE; +- } +- } ++ // if we are in the middle of composing text, XIM gets to see it ++ // before mozilla does. ++ LOGIM(("key press [%p]: composing %d val %d\n", ++ (void *)this, mComposingText, aEvent->keyval)); ++ if (IMEFilterEvent(aEvent)) ++ return TRUE; ++ LOGIM(("sending as regular key press event\n")); + #endif +- ++ ++ nsKeyEvent event; ++ nsEventStatus status; ++ + // work around for annoying things. +- if (aEvent->keyval == GDK_Tab) +- if (aEvent->state & GDK_CONTROL_MASK) +- if (aEvent->state & GDK_MOD1_MASK) +- return FALSE; ++ if (aEvent->keyval == GDK_Tab && aEvent->state & GDK_CONTROL_MASK && ++ aEvent->state & GDK_MOD1_MASK) { ++ return TRUE; ++ } + + // Don't pass shift, control and alt as key press events + if (aEvent->keyval == GDK_Shift_L +@@ -1556,9 +1483,9 @@ + || aEvent->keyval == GDK_Control_L + || aEvent->keyval == GDK_Control_R + || aEvent->keyval == GDK_Alt_L +- || aEvent->keyval == GDK_Alt_R) ++ || aEvent->keyval == GDK_Alt_R) { + return TRUE; +- ++ } + + // If the key repeat flag isn't set then set it so we don't send + // another key down event on the next key press -- DOM events are +@@ -1568,15 +1495,12 @@ + + if (!mInKeyRepeat) { + mInKeyRepeat = PR_TRUE; ++ + // send the key down event +- nsEventStatus status; +- nsKeyEvent event; + InitKeyEvent(event, aEvent, NS_KEY_DOWN); + DispatchEvent(&event, status); + } + +- nsEventStatus status; +- nsKeyEvent event; + InitKeyEvent(event, aEvent, NS_KEY_PRESS); + event.charCode = nsConvertCharCodeToUnicode(aEvent); + if (event.charCode) { +@@ -1608,25 +1532,33 @@ + key_event_to_context_menu_event(&event, &contextMenuEvent); + DispatchEvent(&contextMenuEvent, status); + } +- else ++ else { + // send the key press event + DispatchEvent(&event, status); +- return TRUE; ++ } ++ ++ // If the event was consumed, return. ++ LOGIM(("status %d\n", status)); ++ if (status == nsEventStatus_eConsumeNoDefault) { ++ LOGIM(("key press consumed\n")); ++ return TRUE; ++ } ++ ++ return FALSE; + } + + gboolean + nsWindow::OnKeyReleaseEvent(GtkWidget *aWidget, GdkEventKey *aEvent) + { + LOGFOCUS(("OnKeyReleaseEvent [%p]\n", (void *)this)); ++ + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im) { +- if (gtk_im_context_filter_keypress(im, aEvent)) { +- LOGFOCUS((" keypress filtered by XIM\n")); +- return TRUE; +- } +- } ++ if (IMEFilterEvent(aEvent)) ++ return TRUE; + #endif ++ ++ nsKeyEvent event; ++ nsEventStatus status; + + // unset the repeat flag + mInKeyRepeat = PR_FALSE; +@@ -1638,16 +1570,21 @@ + || aEvent->keyval == GDK_Control_L + || aEvent->keyval == GDK_Control_R + || aEvent->keyval == GDK_Alt_L +- || aEvent->keyval == GDK_Alt_R) ++ || aEvent->keyval == GDK_Alt_R) { + return TRUE; ++ } + +- nsKeyEvent event; + InitKeyEvent(event, aEvent, NS_KEY_UP); + +- nsEventStatus status; + DispatchEvent(&event, status); + +- return TRUE; ++ // If the event was consumed, return. ++ if (status == nsEventStatus_eConsumeNoDefault) { ++ LOGIM(("key release consumed\n")); ++ return TRUE; ++ } ++ ++ return FALSE; + } + + void +@@ -1659,7 +1596,6 @@ + // check to see if we should rollup + if (check_for_rollup(aEvent->window, aEvent->x_root, aEvent->y_root, + PR_TRUE)) { +- printf("ignoring event\n"); + return; + } + +@@ -2134,8 +2070,10 @@ + else { // must be eWindowType_toplevel + mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL); + SetDefaultIcon(); ++ + // each toplevel window gets its own window group + mWindowGroup = gtk_window_group_new(); ++ + // and add ourselves to the window group + LOG(("adding window %p to new group %p\n", + (void *)mShell, (void *)mWindowGroup)); +@@ -2165,10 +2103,6 @@ + + mDrawingarea = moz_drawingarea_new(nsnull, mContainer); + } +-#ifdef USE_XIM +- // get mIMEShellWindow and keep it +- IMEGetShellWindow(); +-#endif + } + break; + default: +@@ -2213,13 +2147,6 @@ + G_CALLBACK(property_notify_event_cb), NULL); + } + +-#ifdef USE_XIM +- if (mShell) { +- // init GtkIMContext for shell +- IMECreateContext(mShell->window); +- } +-#endif +- + if (mContainer) { + g_signal_connect_after(G_OBJECT(mContainer), "size_allocate", + G_CALLBACK(size_allocate_cb), NULL); +@@ -2262,6 +2189,13 @@ + G_CALLBACK(drag_drop_event_cb), NULL); + g_signal_connect(G_OBJECT(mContainer), "drag_data_received", + G_CALLBACK(drag_data_received_event_cb), NULL); ++ ++#ifdef USE_XIM ++ // We create input contexts for all containers, except for ++ // toplevel popup windows ++ if (mWindowType != eWindowType_popup) ++ IMECreateContext(); ++#endif + } + + LOG(("nsWindow [%p]\n", (void *)this)); +@@ -3666,8 +3600,59 @@ + #ifdef USE_XIM + + void ++nsWindow::IMEDestroyContext(void) ++{ ++ // If this is the focus window and we have an IM context we need ++ // to unset the focus on this window before we destroy the window. ++ if (gIMEFocusWindow == this) { ++ gIMEFocusWindow->IMELoseFocus(); ++ gIMEFocusWindow = nsnull; ++ } ++ ++ if (!mIMContext) ++ return; ++ ++ gtk_im_context_set_client_window(mIMContext, NULL); ++ g_object_unref(G_OBJECT(mIMContext)); ++ mIMContext = nsnull; ++} ++ ++ ++void ++nsWindow::IMESetFocus(void) ++{ ++ LOGIM(("IMESetFocus %p\n", (void *)this)); ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) ++ return; ++ ++ gtk_im_context_focus_in(im); ++ gIMEFocusWindow = this; ++} ++ ++void ++nsWindow::IMELoseFocus(void) ++{ ++ LOGIM(("IMELoseFocus %p\n", (void *)this)); ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) ++ return; ++ ++ gtk_im_context_focus_out(im); ++} ++ ++void + nsWindow::IMEComposeStart(void) + { ++ LOGIM(("IMEComposeStart [%p]\n", (void *)this)); ++ ++ if (mComposingText) { ++ NS_WARNING("tried to re-start text composition\n"); ++ return; ++ } ++ ++ mComposingText = PR_TRUE; ++ + nsCompositionEvent compEvent; + + compEvent.widget = NS_STATIC_CAST(nsIWidget *, this); +@@ -3686,6 +3671,11 @@ + const gchar *aPreeditString, + const PangoAttrList *aFeedback) + { ++ // Send our start composition event if we need to ++ if (!mComposingText) ++ IMEComposeStart(); ++ ++ LOGIM(("IMEComposeText\n")); + nsTextEvent textEvent; + + textEvent.time = 0; +@@ -3706,9 +3696,9 @@ + textEvent.rangeArray = nsnull; + + if (aPreeditString && aFeedback && (aLen > 0)) { +- IMSetTextRange(aLen, aPreeditString, aFeedback, +- &(textEvent.rangeCount), +- &(textEvent.rangeArray)); ++ IM_set_text_range(aLen, aPreeditString, aFeedback, ++ &(textEvent.rangeCount), ++ &(textEvent.rangeArray)); + } + } + +@@ -3723,6 +3713,15 @@ + void + nsWindow::IMEComposeEnd(void) + { ++ LOGIM(("IMEComposeEnd [%p]\n", (void *)this)); ++ ++ if (!mComposingText) { ++ NS_WARNING("tried to end text composition before it was started"); ++ return; ++ } ++ ++ mComposingText = PR_FALSE; ++ + nsCompositionEvent compEvent; + compEvent.widget = NS_STATIC_CAST(nsIWidget *, this); + compEvent.point.x = compEvent.point.y = 0; +@@ -3734,32 +3733,91 @@ + DispatchEvent(&compEvent, status); + } + ++GtkIMContext* ++nsWindow::IMEGetContext() ++{ ++ return IM_get_input_context(this->mDrawingarea); ++} ++ ++void ++nsWindow::IMECreateContext(void) ++{ ++ GtkIMContext *im = gtk_im_multicontext_new(); ++ if (!im) ++ return; ++ ++ gtk_im_context_set_client_window(im, GTK_WIDGET(mContainer)->window); ++ ++ g_signal_connect(G_OBJECT(im), "preedit_changed", ++ G_CALLBACK(IM_preedit_changed_cb), this); ++ g_signal_connect(G_OBJECT(im), "commit", ++ G_CALLBACK(IM_commit_cb), this); ++ ++ mIMContext = im; ++} ++ ++PRBool ++nsWindow::IMEFilterEvent(GdkEventKey *aEvent) ++{ ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) ++ return FALSE; ++ ++ gKeyEvent = aEvent; ++ gboolean filtered = gtk_im_context_filter_keypress(im, aEvent); ++ gKeyEvent = NULL; ++ ++ LOGIM(("key filtered: %d committed: %d changed: %d\n", ++ filtered, gKeyEventCommitted, gKeyEventChanged)); ++ ++ // We filter the key event if the event was not committed (because ++ // it's probably part of a composition) or if the key event was ++ // committed _and_ changed. This way we still let key press ++ // events go through as simple key press events instead of ++ // composed characters. ++ ++ PRBool retval = PR_FALSE; ++ if (filtered && ++ (!gKeyEventCommitted || (gKeyEventCommitted && gKeyEventChanged))) ++ retval = PR_TRUE; ++ ++ gKeyEventChanged = PR_FALSE; ++ gKeyEventCommitted = PR_FALSE; ++ gKeyEventChanged = PR_FALSE; ++ ++ return retval; ++} ++ + /* static */ + void +-IM_preedit_changed_cb(GtkIMContext *context, +- nsWindow *awindow) ++IM_preedit_changed_cb(GtkIMContext *aContext, ++ nsWindow *aWindow) + { + gchar *preedit_string; + gint cursor_pos; + PangoAttrList *feedback_list; + +- // call for focused window +- nsWindow *window = gFocusWindow; +- if (!window) return; ++ // if gFocusWindow is null, use the last focused gIMEFocusWindow ++ nsWindow *window = gFocusWindow ? gFocusWindow : gIMEFocusWindow; ++ if (!window) ++ return; + + // Should use cursor_pos ? +- gtk_im_context_get_preedit_string(context, &preedit_string, ++ gtk_im_context_get_preedit_string(aContext, &preedit_string, + &feedback_list, &cursor_pos); + + LOGIM(("preedit string is: %s length is: %d\n", + preedit_string, strlen(preedit_string))); + + if (!preedit_string || !*preedit_string) { +- window->IMEComposeStart(); ++ LOGIM(("preedit ended\n")); + window->IMEComposeText(NULL, 0, NULL, NULL); ++ window->IMEComposeEnd(); + return; + } + ++ LOGIM(("preedit len %d\n", strlen(preedit_string))); ++ + gunichar2 * uniStr; + glong uniStrLen; + +@@ -3775,47 +3833,68 @@ + return; + } + +- if (window && (uniStrLen > 0)) { +- window->IMEComposeStart(); ++ if (uniStrLen) { + window->IMEComposeText(NS_STATIC_CAST(const PRUnichar *, uniStr), + uniStrLen, preedit_string, feedback_list); + } + + g_free(preedit_string); + g_free(uniStr); ++ + if (feedback_list) + pango_attr_list_unref(feedback_list); + } + + /* static */ + void +-IM_commit_cb (GtkIMContext *context, +- const gchar *utf8_str, +- nsWindow *awindow) ++IM_commit_cb (GtkIMContext *aContext, ++ const gchar *aUtf8_str, ++ nsWindow *aWindow) + { +- gunichar2 * uniStr; ++ gunichar2 *uniStr; + glong uniStrLen; + +- // call for focused window +- nsWindow *window = gFocusWindow; +- if (!window) return; ++ LOGIM(("IM_commit_cb\n")); + +- uniStr = NULL; +- uniStrLen = 0; +- uniStr = g_utf8_to_utf16(utf8_str, -1, NULL, &uniStrLen, NULL); ++ gKeyEventCommitted = PR_TRUE; + +- // Will free it in call function, don't need +- // g_free((void *)utf8_str)); ++ // if gFocusWindow is null, use the last focused gIMEFocusWindow ++ nsWindow *window = gFocusWindow ? gFocusWindow : gIMEFocusWindow; + +- LOGIM(("IM_commit_cb\n")); ++ if (!window) ++ return; ++ ++ /* If IME doesn't change they keyevent that generated this commit, ++ don't send it through XIM - just send it as a normal key press ++ event. */ ++ ++ if (gKeyEvent) { ++ char keyval_utf8[8]; /* should have at least 6 bytes of space */ ++ gint keyval_utf8_len; ++ guint32 keyval_unicode; ++ ++ keyval_unicode = gdk_keyval_to_unicode(gKeyEvent->keyval); ++ keyval_utf8_len = g_unichar_to_utf8(keyval_unicode, keyval_utf8); ++ keyval_utf8[keyval_utf8_len] = '\0'; ++ ++ if (!strcmp(aUtf8_str, keyval_utf8)) { ++ gKeyEventChanged = PR_FALSE; ++ return; ++ } ++ } ++ ++ gKeyEventChanged = PR_TRUE; ++ ++ uniStr = NULL; ++ uniStrLen = 0; ++ uniStr = g_utf8_to_utf16(aUtf8_str, -1, NULL, &uniStrLen, NULL); + + if (!uniStr) { + LOGIM(("utf80utf16 string tranfer failed!\n")); + return; + } + +- if (window && (uniStrLen > 0)) { +- window->IMEComposeStart(); ++ if (uniStrLen) { + window->IMEComposeText((const PRUnichar *)uniStr, + (PRInt32)uniStrLen, NULL, NULL); + window->IMEComposeEnd(); +@@ -3834,11 +3913,11 @@ + + /* static */ + void +-IMSetTextRange (const PRInt32 aLen, +- const gchar *aPreeditString, +- const PangoAttrList *aFeedback, +- PRUint32 *aTextRangeListLengthResult, +- nsTextRangeArray *aTextRangeListResult) ++IM_set_text_range(const PRInt32 aLen, ++ const gchar *aPreeditString, ++ const PangoAttrList *aFeedback, ++ PRUint32 *aTextRangeListLengthResult, ++ nsTextRangeArray *aTextRangeListResult) + { + if (aLen == 0) { + aTextRangeListLengthResult = 0; +@@ -3941,6 +4020,18 @@ + *aTextRangeListLengthResult = count + 1; + + pango_attr_iterator_destroy(aFeedbackIterator); ++} ++ ++/* static */ ++GtkIMContext * ++IM_get_input_context(MozDrawingarea *aArea) ++{ ++ GtkWidget *owningWidget = ++ get_gtk_widget_for_gdk_window(aArea->inner_window); ++ ++ nsWindow *owningWindow = get_window_for_gtk_widget(owningWidget); ++ ++ return owningWindow->mIMContext; + } + + #endif +Index: nsWindow.h +=================================================================== +RCS file: /cvsroot/mozilla/widget/src/gtk2/nsWindow.h,v +retrieving revision 1.32 +diff -u -r1.32 nsWindow.h +--- widget/src/gtk2/nsWindow.h 17 Feb 2003 18:50:01 -0000 1.32 ++++ widget/src/gtk2/nsWindow.h 6 Apr 2003 02:56:31 -0000 +@@ -239,19 +239,22 @@ + static guint32 mLastButtonPressTime; + + #ifdef USE_XIM +- void IMEComposeStart(void); +- void IMEComposeText(const PRUnichar *aText, +- const PRInt32 aLen, +- const gchar *aPreeditString, +- const PangoAttrList *aFeedback); +- void IMEComposeEnd(void); ++ void IMEDestroyContext (void); ++ void IMESetFocus (void); ++ void IMELoseFocus (void); ++ void IMEComposeStart (void); ++ void IMEComposeText (const PRUnichar *aText, ++ const PRInt32 aLen, ++ const gchar *aPreeditString, ++ const PangoAttrList *aFeedback); ++ void IMEComposeEnd (void); ++ GtkIMContext* IMEGetContext (void); ++ void IMECreateContext (void); ++ PRBool IMEFilterEvent (GdkEventKey *aEvent); ++ ++ GtkIMContext *mIMContext; ++ PRBool mComposingText; + +- void IMEGetShellWindow(void); +- GtkIMContext* IMEGetContext(void); +- void IMECreateContext(GdkWindow* aGdkWindow); +- +- nsWindow* mIMEShellWindow; +- static PLDHashTable gXICLookupTable; + #endif + + private: diff --git a/www/seamonkey2/Makefile b/www/seamonkey2/Makefile index 532966e00c28..93bb8d9e2905 100644 --- a/www/seamonkey2/Makefile +++ b/www/seamonkey2/Makefile @@ -6,7 +6,7 @@ # PORTNAME?= mozilla -PORTVERSION= 1.3b +PORTVERSION= 1.4a PORTEPOCH?= 1 CATEGORIES?= www MASTER_SITES= ${MASTER_SITE_MOZILLA} \ @@ -14,7 +14,7 @@ MASTER_SITES= ${MASTER_SITE_MOZILLA} \ MASTER_SITE_SUBDIR= mozilla/releases/${PORTNAME}${PORTVERSION:S/.rc/rc/}/src \ marcus/:local DISTFILES= ${PORTNAME}-source-${PORTVERSION:S/.rc/rc/}${EXTRACT_SUFX} \ - libart_lgpl-${PORTVERSION}${EXTRACT_SUFX}:local + libart_lgpl${EXTRACT_SUFX}:local MAINTAINER= gnome@FreeBSD.org COMMENT= The open source, standards compliant web browser @@ -30,15 +30,9 @@ WRKSRC= ${WRKDIR}/${PORTNAME} MOZILLA?= mozilla-devel -BROKEN= "Requires update to 1.4a" - -WITHOUT_CHATZILLA= "Contains a buffer overflow reported at http://online.securityfocus.com/archive/1/270249" - .if defined(WITH_GTK2) -LIB_DEPENDS+= gtk-x11-2.0.200:${PORTSDIR}/x11-toolkits/gtk20 \ - ORBit-2.0:${PORTSDIR}/devel/ORBit2 +USE_GNOME= gtk20 orbit2 .else -USE_GNOMENG= yes USE_GNOME= gtk12 orbit .endif @@ -52,7 +46,7 @@ BROKEN= Mozilla-devel and Xft2 render the mozilla-fonts \ .if defined(WITH_CALENDAR) && (defined(WITHOUT_MAILNEWS) || \ defined(WITHOUT_COMPOSER)) -BROKEN= Calendar requires Composer and Mailnews support. +BROKEN= "Calendar requires Composer and Mailnews support." .endif .if defined(WITH_CALENDAR) @@ -82,12 +76,14 @@ CONFIGURE_ARGS= \ --enable-mathml \ --disable-md \ --disable-pedantic \ + --disable-bidi \ --disable-plaintext-editor-only \ --enable-strip \ --enable-svg \ --disable-tests \ --disable-xterm-updates \ --enable-xinerama \ + --with-system-zlib \ --with-system-jpeg=${LOCALBASE} \ --with-system-mng=${LOCALBASE} \ --with-system-png=${LOCALBASE} \ @@ -116,6 +112,9 @@ CONFIGURE_ENV= MOZ_INTERNAL_LIBART_LGPL=1 .if defined(WITH_JAVASCRIPT_DEBUGGER) CONFIGURE_ARGS+= --enable-jsd \ --enable-dtd-debug +.else +CONFIGURE_ARGS+= --disable-jsd \ + --disable-dtd-debug .endif .if defined(WITH_CALENDAR) @@ -131,6 +130,7 @@ CONFIGURE_ARGS+= --disable-composer CONFIGURE_ARGS+= --enable-default-toolkit=gtk2 PKGCONFIG_FILES= mozilla-gtkmozembed.pc mozilla-js.pc mozilla-xpcom.pc \ mozilla-nspr.pc mozilla-nss.pc +EXTRA_PATCHES= ${FILESDIR}/xim_dekita2.patch .else CONFIGURE_ARGS+= --enable-default-toolkit=gtk .endif @@ -149,6 +149,10 @@ ALL_TARGET= default CONFIGURE_ARGS+= --enable-reorder .endif +.if !defined(WITHOUT_OPTIMIZE) && ${ARCH} != "alpha" +CFLAGS+= -O2 +.endif + .if ${ARCH} == "alpha" CFLAGS+= -O0 BROKEN= "core dumps on alpha during post-build" @@ -159,6 +163,17 @@ BROKEN="You must upgrade your freetype port to 1.3.1_2 or higher before installi .endif pre-everything:: + @${ECHO_MSG} "" + @${ECHO_MSG} "Mozilla has the following tunable option(s):" + @${ECHO_MSG} " WITHOUT_XFT=yes Disables Xft anti-aliasing support" + @${ECHO_MSG} " WITH_CALENDAR=yes Enables the Calendar module (requires Mailnews and Composer modules)" + @${ECHO_MSG} " WITHOUT_MAILNEWS=yes Disables the Mail and News modules" + @${ECHO_MSG} " WITHOUT_COMPOSER=yes Disables the HTML Composer module" + @${ECHO_MSG} " WITHOUT_LDAP=yes Disables LDAP support within the Mailnews module" + @${ECHO_MSG} " WITHOUT_CHATZILLA=yes Disable the Chatzilla IRC module" + @${ECHO_MSG} " WITH_JAVASCRIPT_DEBUGGER=yes Enable the DTD and JavaScript debuggers" + @${ECHO_MSG} " WITHOUT_OPTIMIZE=yes Disable -O2 optimization" + @${ECHO_MSG} "" .if defined(WITH_CALENDAR) @${ECHO_MSG} "Calendar is still beta software." @${ECHO_MSG} "Use at your own risk." diff --git a/www/seamonkey2/distinfo b/www/seamonkey2/distinfo index 81d931e64bf9..f271aebbd0c5 100644 --- a/www/seamonkey2/distinfo +++ b/www/seamonkey2/distinfo @@ -1,3 +1,2 @@ -MD5 (mozilla-source-1.3b.tar.gz) = 51c4a31cd7cf7d2a00a9b1aa343d6716 -MD5 (libart_lgpl-1.3b.tar.gz) = db14696f2bf83333f2020fa87fbe630c -MD5 (mozilla-calendar-1.3b.tar.gz) = 2e4db8a23c0960d6d8d859c2c31f97d8 +MD5 (mozilla-source-1.4a.tar.gz) = 6e060d7e2f233055e9f1fbd8b9eaf3c9 +MD5 (libart_lgpl.tar.gz) = 38bb6d37f7b90eaa266fe65e60b639ce diff --git a/www/seamonkey2/files/patch-config_rules.mk b/www/seamonkey2/files/patch-config_rules.mk deleted file mode 100644 index e1bc19837bdc..000000000000 --- a/www/seamonkey2/files/patch-config_rules.mk +++ /dev/null @@ -1,15 +0,0 @@ ---- config/rules.mk.orig Sat Jan 25 16:40:16 2003 -+++ config/rules.mk Sat Jan 25 16:42:56 2003 -@@ -411,6 +411,12 @@ - endif - endif - -+ifeq ($(OS_ARCH),FreeBSD) -+ifdef IS_COMPONENT -+EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic -+endif -+endif -+ - ifeq ($(OS_ARCH),NetBSD) - ifneq (,$(filter arc cobalt hpcmips mipsco newsmips pmax sgimips,$(OS_TEST))) - ifeq ($(MODULE),layout) diff --git a/www/seamonkey2/files/patch-nsprpub_pr_src_misc_prtime.c b/www/seamonkey2/files/patch-nsprpub_pr_src_misc_prtime.c index 6b65ef14fbec..30f067cfaf56 100644 --- a/www/seamonkey2/files/patch-nsprpub_pr_src_misc_prtime.c +++ b/www/seamonkey2/files/patch-nsprpub_pr_src_misc_prtime.c @@ -1,18 +1,11 @@ ---- nsprpub/pr/src/misc/prtime.c.orig Sun Mar 31 12:17:46 2002 -+++ nsprpub/pr/src/misc/prtime.c Tue Dec 17 21:30:30 2002 -@@ -1666,12 +1666,13 @@ - * values for these two fields. +--- nsprpub/pr/src/misc/prtime.c.orig Wed Feb 26 19:01:02 2003 ++++ nsprpub/pr/src/misc/prtime.c Sun Apr 6 19:22:10 2003 +@@ -1666,7 +1666,7 @@ */ --#if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS) -+#if defined(__FreeBSD__)|| defined(SUNOS4) \ -+ || (__GLIBC__ >= 2) || defined(XP_BEOS) - if (mktime(&a) == -1) { - PR_snprintf(buf, buflen, "can't get timezone"); - return 0; - } --#endif -+#endif /* check for __FreeBSD__, too */ - - return strftime(buf, buflen, fmt, &a); - } + #if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS) \ +- || defined(NETBSD) ++ || defined(NETBSD) || defined(__FreeBSD__) + a.tm_zone = NULL; + a.tm_gmtoff = tm->tm_params.tp_gmt_offset + tm->tm_params.tp_dst_offset; + #endif diff --git a/www/seamonkey2/files/patch-qt b/www/seamonkey2/files/patch-qt index 032397d35040..0c2a83e6f4e0 100644 --- a/www/seamonkey2/files/patch-qt +++ b/www/seamonkey2/files/patch-qt @@ -1,23 +1,14 @@ ---- configure.orig Thu Feb 6 17:15:12 2003 -+++ configure Tue Feb 11 22:52:48 2003 -@@ -10974,7 +10974,7 @@ - fi - MOC=$HOST_MOC - -- QT_CFLAGS="-I${QTDIR}${QTINCDIR} -DQT_GENUINE_STR -DQT_NO_STL" -+ QT_CFLAGS="-I${QTDIR}/include/X11/qt -DQT_GENUINE_STR" - if test -z "$MOZ_DEBUG"; then - QT_CFLAGS="$QT_CFLAGS -DQT_NO_DEBUG -DNO_DEBUG" - fi -@@ -11840,9 +11840,9 @@ +--- configure.orig Mon Mar 31 16:30:08 2003 ++++ configure Sun Apr 6 19:24:52 2003 +@@ -11719,9 +11719,9 @@ --MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help pref transformiix venkman inspector irc universalchardet typeaheadfind" -+MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help pref transformiix venkman inspector universalchardet typeaheadfind" +-MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help p3p pref transformiix venkman inspector irc universalchardet typeaheadfind" ++MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help p3p pref transformiix venkman inspector universalchardet typeaheadfind" --MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT xmlterm access-builtin p3p interfaceinfo datetime finger cview" -+MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT irc xmlterm access-builtin p3p interfaceinfo datetime finger cview" +-MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT xmlterm access-builtin datetime finger cview" ++MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT irc xmlterm access-builtin datetime finger cview" # Check whether --enable-extensions or --disable-extensions was given. if test "${enable_extensions+set}" = set; then diff --git a/www/seamonkey2/files/xim_dekita2.patch b/www/seamonkey2/files/xim_dekita2.patch new file mode 100644 index 000000000000..0305a0ddf317 --- /dev/null +++ b/www/seamonkey2/files/xim_dekita2.patch @@ -0,0 +1,784 @@ +Index: Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/widget/src/gtk2/Makefile.in,v +retrieving revision 1.26 +diff -u -r1.26 Makefile.in +--- widget/src/gtk2/Makefile.in 22 Mar 2003 05:29:24 -0000 1.26 ++++ widget/src/gtk2/Makefile.in 6 Apr 2003 02:56:31 -0000 +@@ -90,7 +90,7 @@ + CFLAGS += $(MOZ_GTK2_CFLAGS) + CXXFLAGS += $(MOZ_GTK2_CFLAGS) + +-#DEFINES += -DUSE_XIM ++DEFINES += -DUSE_XIM + + INCLUDES += \ + -I$(srcdir)/../xpwidgets \ +Index: nsWindow.cpp +=================================================================== +RCS file: /cvsroot/mozilla/widget/src/gtk2/nsWindow.cpp,v +retrieving revision 1.71 +diff -u -r1.71 nsWindow.cpp +--- widget/src/gtk2/nsWindow.cpp 24 Mar 2003 04:15:20 -0000 1.71 ++++ widget/src/gtk2/nsWindow.cpp 6 Apr 2003 02:56:31 -0000 +@@ -180,25 +180,24 @@ + + #ifdef USE_XIM + +-struct nsXICLookupEntry { +- PLDHashEntryHdr mKeyHash; +- nsWindow* mShellWindow; +- GtkIMContext* mXIC; +-}; +- +-PLDHashTable nsWindow::gXICLookupTable; +- +-static void IM_commit_cb (GtkIMContext *context, +- const gchar *str, +- nsWindow *window); +-static void IM_preedit_changed_cb (GtkIMContext *context, +- nsWindow *window); +-static void IMSetTextRange (const PRInt32 aLen, ++static nsWindow *gIMEFocusWindow = NULL; ++static GdkEventKey *gKeyEvent = NULL; ++static PRBool gKeyEventCommitted = PR_FALSE; ++static PRBool gKeyEventChanged = PR_FALSE; ++ ++static void IM_commit_cb (GtkIMContext *aContext, ++ const gchar *aString, ++ nsWindow *aWindow); ++static void IM_preedit_changed_cb (GtkIMContext *aContext, ++ nsWindow *aWindow); ++static void IM_set_text_range (const PRInt32 aLen, + const gchar *aPreeditString, + const PangoAttrList *aFeedback, + PRUint32 *aTextRangeListLengthResult, + nsTextRangeArray *aTextRangeListResult); + ++static GtkIMContext *IM_get_input_context(MozDrawingarea *aArea); ++ + // If after selecting profile window, the startup fail, please refer to + // http://bugzilla.gnome.org/show_bug.cgi?id=88940 + #endif +@@ -245,11 +244,8 @@ + mDragMotionTimerID = 0; + + #ifdef USE_XIM +- if (gXICLookupTable.ops == NULL) { +- PL_DHashTableInit(&gXICLookupTable, PL_DHashGetStubOps(), nsnull, +- sizeof(nsXICLookupEntry), PL_DHASH_MIN_SIZE); +- } +- mIMEShellWindow = nsnull; ++ mIMContext = nsnull; ++ mComposingText = PR_FALSE; + #endif + + #ifdef ACCESSIBILITY +@@ -257,61 +253,6 @@ + #endif + } + +-#ifdef USE_XIM +-void +-nsWindow::IMEGetShellWindow(void) +-{ +- GtkWidget* top_window = nsnull; +- GetToplevelWidget(&top_window); +- if (top_window) { +- mIMEShellWindow = get_window_for_gtk_widget(top_window); +- } +-} +- +-GtkIMContext* +-nsWindow::IMEGetContext() +-{ +- if (!mIMEShellWindow) { +- return NULL; +- } +- PLDHashEntryHdr* hash_entry; +- nsXICLookupEntry* entry; +- +- hash_entry = PL_DHashTableOperate(&gXICLookupTable, +- mIMEShellWindow, PL_DHASH_LOOKUP); +- +- if (hash_entry) { +- entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); +- if (entry->mXIC) { +- return entry->mXIC; +- } +- } +- return NULL; +-} +- +-void +-nsWindow::IMECreateContext(GdkWindow* aGdkWindow) +-{ +- PLDHashEntryHdr* hash_entry; +- nsXICLookupEntry* entry; +- GtkIMContext *im = gtk_im_multicontext_new(); +- if (im) { +- hash_entry = PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_ADD); +- if (hash_entry) { +- entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); +- entry->mShellWindow = this; +- entry->mXIC = im; +- } +- gtk_im_context_set_client_window(im, aGdkWindow); +- g_signal_connect(G_OBJECT(im), "commit", +- G_CALLBACK(IM_commit_cb), this); +- g_signal_connect(G_OBJECT(im), "preedit_changed", +- G_CALLBACK(IM_preedit_changed_cb), this); +- this->mIMEShellWindow = this; +- } +-} +-#endif +- + nsWindow::~nsWindow() + { + LOG(("nsWindow::~nsWindow() [%p]\n", (void *)this)); +@@ -397,22 +338,7 @@ + } + + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- // If this is the focus window and we have an IM context we need +- // to unset the focus on this window before we destroy the window. +- if (im && gFocusWindow == this) { +- LOGFOCUS((" gtk_im_context_focus_out() from Destroy()\n")); +- gtk_im_context_focus_out(im); +- } +- +- // if shell, delete GtkIMContext +- if (im && mShell) { +- gtk_im_context_reset(im); +- PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_REMOVE); +- g_object_unref(G_OBJECT(im)); +- } +- +- mIMEShellWindow = nsnull; ++ IMEDestroyContext(); + #endif + + // make sure that we remove ourself as the focus window +@@ -656,21 +582,26 @@ + return NS_OK; + } + +- // If there is already a focued child window, dispatch a LOSTFOCUS ++ // If there is already a focused child window, dispatch a LOSTFOCUS + // event from that widget and unset its got focus flag. +- if (gFocusWindow) ++ if (gFocusWindow) { ++#ifdef USE_XIM ++ // If the focus window and this window share the same input ++ // context we don't have to change the focus of the IME ++ // context ++ if (IM_get_input_context(this->mDrawingarea) != ++ IM_get_input_context(gFocusWindow->mDrawingarea)) ++ gFocusWindow->IMELoseFocus(); ++#endif + gFocusWindow->LoseFocus(); ++ } + + // Set this window to be the focused child window, update our has + // focus flag and dispatch a GOTFOCUS event. + gFocusWindow = this; + + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im && !mIsTopLevel) { +- LOGFOCUS((" gtk_im_context_focus_in()\n")); +- gtk_im_context_focus_in(im); +- } ++ IMESetFocus(); + #endif + + LOGFOCUS((" widget now has focus - dispatching events [%p]\n", +@@ -1165,18 +1096,6 @@ + void + nsWindow::LoseFocus(void) + { +-#ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im && !mIsTopLevel) { +- LOGFOCUS((" gtk_im_context_focus_out()\n")); +- gtk_im_context_focus_out(im); +- IMEComposeStart(); +- IMEComposeText(NULL, 0, NULL, NULL); +- IMEComposeEnd(); +- LOG(("gtk_im_context_focus_out\n")); +- } +-#endif +- + // make sure that we reset our repeat counter so the next keypress + // for this widget will get the down event + mInKeyRepeat = PR_FALSE; +@@ -1516,6 +1435,10 @@ + + foundit: + ++#ifdef USE_XIM ++ gFocusWindow->IMELoseFocus(); ++#endif ++ + gFocusWindow->LoseFocus(); + + // We only dispatch a deactivate event if we are a toplevel +@@ -1534,21 +1457,25 @@ + nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent) + { + LOGFOCUS(("OnKeyPressEvent [%p]\n", (void *)this)); ++ + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im) { +- if (gtk_im_context_filter_keypress(im, aEvent)) { +- LOGFOCUS((" keypress filtered by XIM\n")); +- return TRUE; +- } +- } ++ // if we are in the middle of composing text, XIM gets to see it ++ // before mozilla does. ++ LOGIM(("key press [%p]: composing %d val %d\n", ++ (void *)this, mComposingText, aEvent->keyval)); ++ if (IMEFilterEvent(aEvent)) ++ return TRUE; ++ LOGIM(("sending as regular key press event\n")); + #endif +- ++ ++ nsKeyEvent event; ++ nsEventStatus status; ++ + // work around for annoying things. +- if (aEvent->keyval == GDK_Tab) +- if (aEvent->state & GDK_CONTROL_MASK) +- if (aEvent->state & GDK_MOD1_MASK) +- return FALSE; ++ if (aEvent->keyval == GDK_Tab && aEvent->state & GDK_CONTROL_MASK && ++ aEvent->state & GDK_MOD1_MASK) { ++ return TRUE; ++ } + + // Don't pass shift, control and alt as key press events + if (aEvent->keyval == GDK_Shift_L +@@ -1556,9 +1483,9 @@ + || aEvent->keyval == GDK_Control_L + || aEvent->keyval == GDK_Control_R + || aEvent->keyval == GDK_Alt_L +- || aEvent->keyval == GDK_Alt_R) ++ || aEvent->keyval == GDK_Alt_R) { + return TRUE; +- ++ } + + // If the key repeat flag isn't set then set it so we don't send + // another key down event on the next key press -- DOM events are +@@ -1568,15 +1495,12 @@ + + if (!mInKeyRepeat) { + mInKeyRepeat = PR_TRUE; ++ + // send the key down event +- nsEventStatus status; +- nsKeyEvent event; + InitKeyEvent(event, aEvent, NS_KEY_DOWN); + DispatchEvent(&event, status); + } + +- nsEventStatus status; +- nsKeyEvent event; + InitKeyEvent(event, aEvent, NS_KEY_PRESS); + event.charCode = nsConvertCharCodeToUnicode(aEvent); + if (event.charCode) { +@@ -1608,25 +1532,33 @@ + key_event_to_context_menu_event(&event, &contextMenuEvent); + DispatchEvent(&contextMenuEvent, status); + } +- else ++ else { + // send the key press event + DispatchEvent(&event, status); +- return TRUE; ++ } ++ ++ // If the event was consumed, return. ++ LOGIM(("status %d\n", status)); ++ if (status == nsEventStatus_eConsumeNoDefault) { ++ LOGIM(("key press consumed\n")); ++ return TRUE; ++ } ++ ++ return FALSE; + } + + gboolean + nsWindow::OnKeyReleaseEvent(GtkWidget *aWidget, GdkEventKey *aEvent) + { + LOGFOCUS(("OnKeyReleaseEvent [%p]\n", (void *)this)); ++ + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im) { +- if (gtk_im_context_filter_keypress(im, aEvent)) { +- LOGFOCUS((" keypress filtered by XIM\n")); +- return TRUE; +- } +- } ++ if (IMEFilterEvent(aEvent)) ++ return TRUE; + #endif ++ ++ nsKeyEvent event; ++ nsEventStatus status; + + // unset the repeat flag + mInKeyRepeat = PR_FALSE; +@@ -1638,16 +1570,21 @@ + || aEvent->keyval == GDK_Control_L + || aEvent->keyval == GDK_Control_R + || aEvent->keyval == GDK_Alt_L +- || aEvent->keyval == GDK_Alt_R) ++ || aEvent->keyval == GDK_Alt_R) { + return TRUE; ++ } + +- nsKeyEvent event; + InitKeyEvent(event, aEvent, NS_KEY_UP); + +- nsEventStatus status; + DispatchEvent(&event, status); + +- return TRUE; ++ // If the event was consumed, return. ++ if (status == nsEventStatus_eConsumeNoDefault) { ++ LOGIM(("key release consumed\n")); ++ return TRUE; ++ } ++ ++ return FALSE; + } + + void +@@ -1659,7 +1596,6 @@ + // check to see if we should rollup + if (check_for_rollup(aEvent->window, aEvent->x_root, aEvent->y_root, + PR_TRUE)) { +- printf("ignoring event\n"); + return; + } + +@@ -2134,8 +2070,10 @@ + else { // must be eWindowType_toplevel + mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL); + SetDefaultIcon(); ++ + // each toplevel window gets its own window group + mWindowGroup = gtk_window_group_new(); ++ + // and add ourselves to the window group + LOG(("adding window %p to new group %p\n", + (void *)mShell, (void *)mWindowGroup)); +@@ -2165,10 +2103,6 @@ + + mDrawingarea = moz_drawingarea_new(nsnull, mContainer); + } +-#ifdef USE_XIM +- // get mIMEShellWindow and keep it +- IMEGetShellWindow(); +-#endif + } + break; + default: +@@ -2213,13 +2147,6 @@ + G_CALLBACK(property_notify_event_cb), NULL); + } + +-#ifdef USE_XIM +- if (mShell) { +- // init GtkIMContext for shell +- IMECreateContext(mShell->window); +- } +-#endif +- + if (mContainer) { + g_signal_connect_after(G_OBJECT(mContainer), "size_allocate", + G_CALLBACK(size_allocate_cb), NULL); +@@ -2262,6 +2189,13 @@ + G_CALLBACK(drag_drop_event_cb), NULL); + g_signal_connect(G_OBJECT(mContainer), "drag_data_received", + G_CALLBACK(drag_data_received_event_cb), NULL); ++ ++#ifdef USE_XIM ++ // We create input contexts for all containers, except for ++ // toplevel popup windows ++ if (mWindowType != eWindowType_popup) ++ IMECreateContext(); ++#endif + } + + LOG(("nsWindow [%p]\n", (void *)this)); +@@ -3666,8 +3600,59 @@ + #ifdef USE_XIM + + void ++nsWindow::IMEDestroyContext(void) ++{ ++ // If this is the focus window and we have an IM context we need ++ // to unset the focus on this window before we destroy the window. ++ if (gIMEFocusWindow == this) { ++ gIMEFocusWindow->IMELoseFocus(); ++ gIMEFocusWindow = nsnull; ++ } ++ ++ if (!mIMContext) ++ return; ++ ++ gtk_im_context_set_client_window(mIMContext, NULL); ++ g_object_unref(G_OBJECT(mIMContext)); ++ mIMContext = nsnull; ++} ++ ++ ++void ++nsWindow::IMESetFocus(void) ++{ ++ LOGIM(("IMESetFocus %p\n", (void *)this)); ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) ++ return; ++ ++ gtk_im_context_focus_in(im); ++ gIMEFocusWindow = this; ++} ++ ++void ++nsWindow::IMELoseFocus(void) ++{ ++ LOGIM(("IMELoseFocus %p\n", (void *)this)); ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) ++ return; ++ ++ gtk_im_context_focus_out(im); ++} ++ ++void + nsWindow::IMEComposeStart(void) + { ++ LOGIM(("IMEComposeStart [%p]\n", (void *)this)); ++ ++ if (mComposingText) { ++ NS_WARNING("tried to re-start text composition\n"); ++ return; ++ } ++ ++ mComposingText = PR_TRUE; ++ + nsCompositionEvent compEvent; + + compEvent.widget = NS_STATIC_CAST(nsIWidget *, this); +@@ -3686,6 +3671,11 @@ + const gchar *aPreeditString, + const PangoAttrList *aFeedback) + { ++ // Send our start composition event if we need to ++ if (!mComposingText) ++ IMEComposeStart(); ++ ++ LOGIM(("IMEComposeText\n")); + nsTextEvent textEvent; + + textEvent.time = 0; +@@ -3706,9 +3696,9 @@ + textEvent.rangeArray = nsnull; + + if (aPreeditString && aFeedback && (aLen > 0)) { +- IMSetTextRange(aLen, aPreeditString, aFeedback, +- &(textEvent.rangeCount), +- &(textEvent.rangeArray)); ++ IM_set_text_range(aLen, aPreeditString, aFeedback, ++ &(textEvent.rangeCount), ++ &(textEvent.rangeArray)); + } + } + +@@ -3723,6 +3713,15 @@ + void + nsWindow::IMEComposeEnd(void) + { ++ LOGIM(("IMEComposeEnd [%p]\n", (void *)this)); ++ ++ if (!mComposingText) { ++ NS_WARNING("tried to end text composition before it was started"); ++ return; ++ } ++ ++ mComposingText = PR_FALSE; ++ + nsCompositionEvent compEvent; + compEvent.widget = NS_STATIC_CAST(nsIWidget *, this); + compEvent.point.x = compEvent.point.y = 0; +@@ -3734,32 +3733,91 @@ + DispatchEvent(&compEvent, status); + } + ++GtkIMContext* ++nsWindow::IMEGetContext() ++{ ++ return IM_get_input_context(this->mDrawingarea); ++} ++ ++void ++nsWindow::IMECreateContext(void) ++{ ++ GtkIMContext *im = gtk_im_multicontext_new(); ++ if (!im) ++ return; ++ ++ gtk_im_context_set_client_window(im, GTK_WIDGET(mContainer)->window); ++ ++ g_signal_connect(G_OBJECT(im), "preedit_changed", ++ G_CALLBACK(IM_preedit_changed_cb), this); ++ g_signal_connect(G_OBJECT(im), "commit", ++ G_CALLBACK(IM_commit_cb), this); ++ ++ mIMContext = im; ++} ++ ++PRBool ++nsWindow::IMEFilterEvent(GdkEventKey *aEvent) ++{ ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) ++ return FALSE; ++ ++ gKeyEvent = aEvent; ++ gboolean filtered = gtk_im_context_filter_keypress(im, aEvent); ++ gKeyEvent = NULL; ++ ++ LOGIM(("key filtered: %d committed: %d changed: %d\n", ++ filtered, gKeyEventCommitted, gKeyEventChanged)); ++ ++ // We filter the key event if the event was not committed (because ++ // it's probably part of a composition) or if the key event was ++ // committed _and_ changed. This way we still let key press ++ // events go through as simple key press events instead of ++ // composed characters. ++ ++ PRBool retval = PR_FALSE; ++ if (filtered && ++ (!gKeyEventCommitted || (gKeyEventCommitted && gKeyEventChanged))) ++ retval = PR_TRUE; ++ ++ gKeyEventChanged = PR_FALSE; ++ gKeyEventCommitted = PR_FALSE; ++ gKeyEventChanged = PR_FALSE; ++ ++ return retval; ++} ++ + /* static */ + void +-IM_preedit_changed_cb(GtkIMContext *context, +- nsWindow *awindow) ++IM_preedit_changed_cb(GtkIMContext *aContext, ++ nsWindow *aWindow) + { + gchar *preedit_string; + gint cursor_pos; + PangoAttrList *feedback_list; + +- // call for focused window +- nsWindow *window = gFocusWindow; +- if (!window) return; ++ // if gFocusWindow is null, use the last focused gIMEFocusWindow ++ nsWindow *window = gFocusWindow ? gFocusWindow : gIMEFocusWindow; ++ if (!window) ++ return; + + // Should use cursor_pos ? +- gtk_im_context_get_preedit_string(context, &preedit_string, ++ gtk_im_context_get_preedit_string(aContext, &preedit_string, + &feedback_list, &cursor_pos); + + LOGIM(("preedit string is: %s length is: %d\n", + preedit_string, strlen(preedit_string))); + + if (!preedit_string || !*preedit_string) { +- window->IMEComposeStart(); ++ LOGIM(("preedit ended\n")); + window->IMEComposeText(NULL, 0, NULL, NULL); ++ window->IMEComposeEnd(); + return; + } + ++ LOGIM(("preedit len %d\n", strlen(preedit_string))); ++ + gunichar2 * uniStr; + glong uniStrLen; + +@@ -3775,47 +3833,68 @@ + return; + } + +- if (window && (uniStrLen > 0)) { +- window->IMEComposeStart(); ++ if (uniStrLen) { + window->IMEComposeText(NS_STATIC_CAST(const PRUnichar *, uniStr), + uniStrLen, preedit_string, feedback_list); + } + + g_free(preedit_string); + g_free(uniStr); ++ + if (feedback_list) + pango_attr_list_unref(feedback_list); + } + + /* static */ + void +-IM_commit_cb (GtkIMContext *context, +- const gchar *utf8_str, +- nsWindow *awindow) ++IM_commit_cb (GtkIMContext *aContext, ++ const gchar *aUtf8_str, ++ nsWindow *aWindow) + { +- gunichar2 * uniStr; ++ gunichar2 *uniStr; + glong uniStrLen; + +- // call for focused window +- nsWindow *window = gFocusWindow; +- if (!window) return; ++ LOGIM(("IM_commit_cb\n")); + +- uniStr = NULL; +- uniStrLen = 0; +- uniStr = g_utf8_to_utf16(utf8_str, -1, NULL, &uniStrLen, NULL); ++ gKeyEventCommitted = PR_TRUE; + +- // Will free it in call function, don't need +- // g_free((void *)utf8_str)); ++ // if gFocusWindow is null, use the last focused gIMEFocusWindow ++ nsWindow *window = gFocusWindow ? gFocusWindow : gIMEFocusWindow; + +- LOGIM(("IM_commit_cb\n")); ++ if (!window) ++ return; ++ ++ /* If IME doesn't change they keyevent that generated this commit, ++ don't send it through XIM - just send it as a normal key press ++ event. */ ++ ++ if (gKeyEvent) { ++ char keyval_utf8[8]; /* should have at least 6 bytes of space */ ++ gint keyval_utf8_len; ++ guint32 keyval_unicode; ++ ++ keyval_unicode = gdk_keyval_to_unicode(gKeyEvent->keyval); ++ keyval_utf8_len = g_unichar_to_utf8(keyval_unicode, keyval_utf8); ++ keyval_utf8[keyval_utf8_len] = '\0'; ++ ++ if (!strcmp(aUtf8_str, keyval_utf8)) { ++ gKeyEventChanged = PR_FALSE; ++ return; ++ } ++ } ++ ++ gKeyEventChanged = PR_TRUE; ++ ++ uniStr = NULL; ++ uniStrLen = 0; ++ uniStr = g_utf8_to_utf16(aUtf8_str, -1, NULL, &uniStrLen, NULL); + + if (!uniStr) { + LOGIM(("utf80utf16 string tranfer failed!\n")); + return; + } + +- if (window && (uniStrLen > 0)) { +- window->IMEComposeStart(); ++ if (uniStrLen) { + window->IMEComposeText((const PRUnichar *)uniStr, + (PRInt32)uniStrLen, NULL, NULL); + window->IMEComposeEnd(); +@@ -3834,11 +3913,11 @@ + + /* static */ + void +-IMSetTextRange (const PRInt32 aLen, +- const gchar *aPreeditString, +- const PangoAttrList *aFeedback, +- PRUint32 *aTextRangeListLengthResult, +- nsTextRangeArray *aTextRangeListResult) ++IM_set_text_range(const PRInt32 aLen, ++ const gchar *aPreeditString, ++ const PangoAttrList *aFeedback, ++ PRUint32 *aTextRangeListLengthResult, ++ nsTextRangeArray *aTextRangeListResult) + { + if (aLen == 0) { + aTextRangeListLengthResult = 0; +@@ -3941,6 +4020,18 @@ + *aTextRangeListLengthResult = count + 1; + + pango_attr_iterator_destroy(aFeedbackIterator); ++} ++ ++/* static */ ++GtkIMContext * ++IM_get_input_context(MozDrawingarea *aArea) ++{ ++ GtkWidget *owningWidget = ++ get_gtk_widget_for_gdk_window(aArea->inner_window); ++ ++ nsWindow *owningWindow = get_window_for_gtk_widget(owningWidget); ++ ++ return owningWindow->mIMContext; + } + + #endif +Index: nsWindow.h +=================================================================== +RCS file: /cvsroot/mozilla/widget/src/gtk2/nsWindow.h,v +retrieving revision 1.32 +diff -u -r1.32 nsWindow.h +--- widget/src/gtk2/nsWindow.h 17 Feb 2003 18:50:01 -0000 1.32 ++++ widget/src/gtk2/nsWindow.h 6 Apr 2003 02:56:31 -0000 +@@ -239,19 +239,22 @@ + static guint32 mLastButtonPressTime; + + #ifdef USE_XIM +- void IMEComposeStart(void); +- void IMEComposeText(const PRUnichar *aText, +- const PRInt32 aLen, +- const gchar *aPreeditString, +- const PangoAttrList *aFeedback); +- void IMEComposeEnd(void); ++ void IMEDestroyContext (void); ++ void IMESetFocus (void); ++ void IMELoseFocus (void); ++ void IMEComposeStart (void); ++ void IMEComposeText (const PRUnichar *aText, ++ const PRInt32 aLen, ++ const gchar *aPreeditString, ++ const PangoAttrList *aFeedback); ++ void IMEComposeEnd (void); ++ GtkIMContext* IMEGetContext (void); ++ void IMECreateContext (void); ++ PRBool IMEFilterEvent (GdkEventKey *aEvent); ++ ++ GtkIMContext *mIMContext; ++ PRBool mComposingText; + +- void IMEGetShellWindow(void); +- GtkIMContext* IMEGetContext(void); +- void IMECreateContext(GdkWindow* aGdkWindow); +- +- nsWindow* mIMEShellWindow; +- static PLDHashTable gXICLookupTable; + #endif + + private: