move XIM code to the right place, fix crash on linux

This commit is contained in:
pavlov%netscape.com 1999-09-03 16:44:56 +00:00
Родитель 4b5adf6a1f
Коммит 8db78bf7bf
8 изменённых файлов: 374 добавлений и 477 удалений

Просмотреть файл

@ -80,7 +80,7 @@ else
CXXFLAGS += $(TK_CFLAGS)
endif
DEFINES += -D_IMPL_NS_WIDGET
DEFINES += -D_IMPL_NS_WIDGET -DUSE_XIM
INCLUDES += \
-I$(srcdir)/../xpwidgets \

Просмотреть файл

@ -21,9 +21,7 @@
#include "nsWidget.h"
#include "nsWindow.h"
#ifdef USE_XIM
#include "nsTextWidget.h"
#endif
#include "nsScrollbar.h"
#include "nsIFileWidget.h"
#include "nsGUIEvent.h"
@ -31,14 +29,14 @@
#include "nsIMenuItem.h"
#include "nsIMenuListener.h"
#ifdef USE_XIM
#ifdef USE_XIM
#include "nsTextWidget.h"
#include "nsICharsetConverterManager.h"
#include "nsIPlatformCharset.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kCharsetConverterManagerCID,
NS_ICHARSETCONVERTERMANAGER_CID);
#endif /* USE_XIM */
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
#endif
#include "stdio.h"
#include "ctype.h"
@ -245,7 +243,6 @@ void UninitExposeEvent(GdkEventExpose *aGEE,
//==============================================================
#if 1
PRUint32 nsConvertCharCodeToUnicode(GdkEventKey* aGEK)
{
// ALT keys in gdk give the upper case character in string,
@ -312,39 +309,6 @@ void InitKeyPressEvent(GdkEventKey *aGEK,
}
#else
//==============================================================
void InitKeyEvent(GdkEventKey *aGEK,
gpointer p,
nsKeyEvent &anEvent,
PRUint32 aEventType)
{
anEvent.message = aEventType;
anEvent.widget = (nsWidget *) p;
anEvent.eventStructType = NS_KEY_EVENT;
if (aGEK != nsnull) {
anEvent.keyCode = nsConvertKey(aGEK->keyval) & 0x00FF;
//
// As per joki: as long as we're using ASCII rather than Unicode,
// it's okay to set the keycode to the charcode because the ns
// keycodes (e.g. VK_X) happen to map to ascii values;
// however, when we move to unicode, we'll want to send the
// unicode translation in the charCode field.
//
anEvent.charCode = aGEK->keyval;
anEvent.time = aGEK->time;
anEvent.isShift = (aGEK->state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
anEvent.isControl = (aGEK->state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
anEvent.isAlt = (aGEK->state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE;
anEvent.point.x = 0;
anEvent.point.y = 0;
}
}
#endif
//=============================================================
void UninitKeyEvent(GdkEventKey *aGEK,
gpointer p,
@ -371,26 +335,6 @@ void handle_size_allocate(GtkWidget *w, GtkAllocation *alloc, gpointer p)
delete event.windowSize;
}
#if 0
gint handle_configure_event(GtkWidget *w, GdkEventConfigure *conf, gpointer p)
{
g_print("configure_event: {x=%i, y=%i, w=%i, h=%i}\n", conf->x,
conf->y,
conf->width,
conf->height);
nsSizeEvent sevent;
InitConfigureEvent(conf, p, sevent, NS_SIZE);
nsWindow *win = (nsWindow *)p;
win->AddRef();
win->OnResize(sevent);
win->Release();
return PR_FALSE;
}
#endif
gint handle_expose_event(GtkWidget *w, GdkEventExpose *event, gpointer p)
{
if (event->type == GDK_NO_EXPOSE)
@ -506,10 +450,6 @@ void handle_scrollbar_value_changed(GtkAdjustment *adj, gpointer p)
GdkWindow *win = (GdkWindow *)widget->GetNativeData(NS_NATIVE_WINDOW);
gdk_window_get_pointer(win, &sevent.point.x, &sevent.point.y, nsnull);
#ifdef NS_GTK_REF
widget->ReleaseNativeData(NS_NATIVE_WINDOW);
#endif
widget->AddRef();
widget->OnScroll(sevent, adj->value);
widget->Release();
@ -560,30 +500,6 @@ void handle_scrollbar_value_changed(GtkAdjustment *adj, gpointer p)
#endif
}
#if 1
//==============================================================
gint handle_key_release_event(GtkWidget *w, GdkEventKey* event, gpointer p)
{
// Don't pass shift, control and alt as key release events
if (event->keyval == GDK_Shift_L
|| event->keyval == GDK_Shift_R
|| event->keyval == GDK_Control_L
|| event->keyval == GDK_Control_R)
return PR_TRUE;
nsKeyEvent kevent;
InitKeyEvent(event, p, kevent, NS_KEY_UP);
nsWindow * win = (nsWindow *) p;
win->AddRef();
win->OnKey(kevent);
win->Release();
gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_release_event");
return PR_TRUE;
}
#ifdef USE_XIM
static gint composition_start(GdkEventKey *aEvent, nsWindow *aWin,
nsEventStatus *aStatus) {
@ -716,10 +632,7 @@ gint handle_key_press_event_for_text(GtkWidget *w, GdkEventKey* event,
// gtk returns a character value for them
//
isModifier = event->state &(GDK_CONTROL_MASK|GDK_MOD1_MASK);
#ifdef DEBUG_EVENTS
if (isModifier) printf("isModifier\n");
#endif
#ifdef USE_XIM
if (event->length || !isModifier) {
static nsIUnicodeDecoder *decoder = nsnull;
if (!decoder) {
@ -735,12 +648,7 @@ gint handle_key_press_event_for_text(GtkWidget *w, GdkEventKey* event,
win->OnKey(kevent);
}
}
#else
if (event->length && !isModifier) {
InitKeyPressEvent(event,p,kevent);
win->OnKey(kevent);
}
#endif
win->Release();
gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_press_event");
@ -770,7 +678,7 @@ gint handle_key_release_event_for_text(GtkWidget *w, GdkEventKey* event,
return PR_TRUE;
}
#endif
#endif // USE_XIM
//==============================================================
gint handle_key_press_event(GtkWidget *w, GdkEventKey* event, gpointer p)
@ -815,7 +723,7 @@ gint handle_key_press_event(GtkWidget *w, GdkEventKey* event, gpointer p)
return PR_TRUE;
}
#else
//==============================================================
gint handle_key_release_event(GtkWidget *w, GdkEventKey* event, gpointer p)
{
@ -839,31 +747,6 @@ gint handle_key_release_event(GtkWidget *w, GdkEventKey* event, gpointer p)
return PR_TRUE;
}
//==============================================================
gint handle_key_press_event(GtkWidget *w, GdkEventKey* event, gpointer p)
{
// Don't pass shift, control and alt as key press events
if (event->keyval == GDK_Shift_L
|| event->keyval == GDK_Shift_R
|| event->keyval == GDK_Control_L
|| event->keyval == GDK_Control_R)
return PR_TRUE;
nsKeyEvent kevent;
InitKeyEvent(event, p, kevent, NS_KEY_DOWN);
nsWindow * win = (nsWindow *) p;
win->AddRef();
win->OnKey(kevent);
win->Release();
gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_press_event");
return PR_TRUE;
}
#endif
//==============================================================
gint nsGtkWidget_FSBCancel_Callback(GtkWidget *w, gpointer p)
{

Просмотреть файл

@ -28,13 +28,16 @@ class nsIMenu;
gint handle_configure_event(GtkWidget *w, GdkEventConfigure *conf, gpointer p);
void handle_size_allocate(GtkWidget *w, GtkAllocation *alloc, gpointer p);
gint handle_expose_event(GtkWidget *w, GdkEventExpose *event, gpointer p);
gint handle_key_release_event(GtkWidget *w, GdkEventKey* event, gpointer p);
gint handle_key_press_event(GtkWidget *w, GdkEventKey* event, gpointer p);
#ifdef USE_XIM
gint handle_key_release_event_for_text(GtkWidget *w, GdkEventKey* event, gpointer p);
gint handle_key_press_event_for_text(GtkWidget *w, GdkEventKey* event, gpointer p);
#endif
gint handle_key_release_event(GtkWidget *w, GdkEventKey* event, gpointer p);
gint handle_key_press_event(GtkWidget *w, GdkEventKey* event, gpointer p);
void handle_scrollbar_value_changed(GtkAdjustment *adjustment, gpointer p);
void menu_item_activate_handler(GtkWidget *w, gpointer p);

Просмотреть файл

@ -18,14 +18,10 @@
#include <gtk/gtk.h>
#define USE_XIM
#include "nsTextWidget.h"
#include "nsString.h"
#include "nsGtkEventHandler.h"
#define DBG 0
extern int mIsPasswordCallBacksInstalled;

Просмотреть файл

@ -16,6 +16,7 @@
* Reserved.
*/
#include "nsWidget.h"
#include "nsGtkEventHandler.h"
@ -29,6 +30,13 @@
#include <gdk/gdkx.h>
#ifdef USE_XIM
#include "nsIServiceManager.h"
#include "nsIPref.h"
#endif
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
@ -94,6 +102,16 @@ nsWidget::nsWidget()
mIsToplevel = PR_FALSE;
mUpdateArea.SetRect(0, 0, 0, 0);
sWidgetCount++;
#ifdef USE_XIM
mIMEEnable = PR_TRUE;
mIC = nsnull;
mIMECompositionUniString = nsnull;
mIMECompositionUniStringSize = 0;
#endif
}
nsWidget::~nsWidget()
@ -734,68 +752,35 @@ NS_IMETHODIMP nsWidget::Update(void)
//
//-------------------------------------------------------------------------
void *nsWidget::GetNativeData(PRUint32 aDataType)
{
switch(aDataType) {
case NS_NATIVE_WINDOW:
if (mWidget) {
#ifdef NS_GTK_REF
return (void *)gdk_window_ref(mWidget->window);
#else
return (void *)mWidget->window;
#endif
}
break;
case NS_NATIVE_DISPLAY:
return (void *)GDK_DISPLAY();
case NS_NATIVE_WIDGET:
case NS_NATIVE_PLUGIN_PORT:
if (mWidget) {
#ifdef NS_GTK_REF
gtk_widget_ref(mWidget);
#endif
return (void *)mWidget;
}
break;
case NS_NATIVE_GRAPHIC:
/* GetSharedGC ups the ref count on the GdkGC so make sure you release
* it afterwards. */
return (void *)((nsToolkit *)mToolkit)->GetSharedGC();
default:
g_print("nsWidget::GetNativeData(%i) - weird value\n", aDataType);
break;
}
return nsnull;
}
#ifdef NS_GTK_REF
void nsWidget::ReleaseNativeData(PRUint32 aDataType)
{
switch(aDataType) {
case NS_NATIVE_WINDOW:
if (mWidget) {
gdk_window_unref(mWidget->window);
}
break;
case NS_NATIVE_DISPLAY:
break;
case NS_NATIVE_WIDGET:
if (mWidget) {
gtk_widget_unref(mWidget);
}
break;
case NS_NATIVE_GRAPHIC:
gdk_gc_unref(((nsToolkit *)mToolkit)->GetSharedGC());
break;
default:
g_print("nsWidget::ReleaseNativeData(%i) - weird value\n", aDataType);
break;
case NS_NATIVE_WINDOW:
if (mWidget) {
return (void *)mWidget->window;
}
break;
case NS_NATIVE_DISPLAY:
return (void *)GDK_DISPLAY();
case NS_NATIVE_WIDGET:
case NS_NATIVE_PLUGIN_PORT:
if (mWidget) {
return (void *)mWidget;
}
break;
case NS_NATIVE_GRAPHIC:
/* GetSharedGC ups the ref count on the GdkGC so make sure you release
* it afterwards. */
return (void *)((nsToolkit *)mToolkit)->GetSharedGC();
default:
g_print("nsWidget::GetNativeData(%i) - weird value\n", aDataType);
break;
}
return nsnull;
}
#endif
//-------------------------------------------------------------------------
//
@ -804,13 +789,13 @@ void nsWidget::ReleaseNativeData(PRUint32 aDataType)
//-------------------------------------------------------------------------
NS_IMETHODIMP nsWidget::SetColorMap(nsColorMap *aColorMap)
{
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP nsWidget::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
{
NS_NOTYETIMPLEMENTED("nsWidget::Scroll");
return NS_OK;
NS_NOTYETIMPLEMENTED("nsWidget::Scroll");
return NS_OK;
}
NS_IMETHODIMP nsWidget::BeginResizingChildren(void)
@ -959,14 +944,6 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
GTK_SIGNAL_FUNC(DestroySignal),
this);
#ifdef NS_GTK_REF
if (aNativeParent) {
gtk_widget_unref(GTK_WIDGET(aNativeParent));
} else if (aParent) {
aParent->ReleaseNativeData(NS_NATIVE_WIDGET);
}
#endif
return NS_OK;
}
@ -1865,6 +1842,43 @@ nsWidget::OnFocusInSignal(GdkEventFocus * aGdkFocusEvent)
DispatchFocus(event);
Release();
#ifdef USE_XIM
if(mIMEEnable == PR_FALSE)
{
#ifdef NOISY_XIM
printf(" IME is not usable on this window\n");
#endif
return;
}
if (!mIC)
GetXIC();
if (mIC)
{
GdkWindow *gdkWindow = (GdkWindow*) GetNativeData(NS_NATIVE_WINDOW);
if (gdkWindow)
{
gdk_im_begin ((GdkIC*)mIC, gdkWindow);
}
else
{
#ifdef NOISY_XIM
printf("gdkWindow is not usable\n");
#endif
}
}
else
{
#ifdef NOISY_XIM
printf("mIC can't created yet\n");
#endif
}
#endif // USE_XIM
}
//////////////////////////////////////////////////////////////////////
/* virtual */ void
@ -1891,6 +1905,40 @@ nsWidget::OnFocusOutSignal(GdkEventFocus * aGdkFocusEvent)
DispatchFocus(event);
Release();
#ifdef USE_XIM
if(mIMEEnable == PR_FALSE)
{
#ifdef NOISY_XIM
printf(" IME is not usable on this window\n");
#endif
return;
}
if (mIC)
{
GdkWindow *gdkWindow = (GdkWindow*) GetNativeData(NS_NATIVE_WINDOW);
if (gdkWindow)
{
gdk_im_end();
}
else
{
#ifdef NOISY_XIM
printf("gdkWindow is not usable\n");
#endif
}
}
else
{
#ifdef NOISY_XIM
printf("mIC isn't created yet\n");
#endif
}
#endif
}
//////////////////////////////////////////////////////////////////////
/* virtual */ void
@ -2326,3 +2374,212 @@ void nsWidget::SetBackgroundColorNative(GdkColor *aColorNor,
gtk_style_unref(style);
}
//////////////////////////////////////////////////////////////////////
#ifdef USE_XIM
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
#define PREF_XIM_PREEDIT "xim.preedit"
#define PREF_XIM_STATUS "xim.status"
#define SUPPORTED_PREEDIT (GDK_IM_PREEDIT_AREA | \
GDK_IM_PREEDIT_POSITION | \
GDK_IM_PREEDIT_NOTHING | \
GDK_IM_PREEDIT_NONE)
// GDK_IM_PREEDIT_CALLBACKS
#define SUPPORTED_STATUS (GDK_IM_STATUS_NOTHING | \
GDK_IM_STATUS_NONE)
// GDK_IM_STATUS_AREA
// GDK_IM_STATUS_CALLBACKS
void
nsWidget::SetXIC(GdkICPrivate *aIC)
{
if(mIMEEnable == PR_FALSE) {
return;
}
mIC = aIC;
return;
}
GdkICPrivate*
nsWidget::GetXIC()
{
if(mIMEEnable == PR_FALSE)
return nsnull;
if (mIC) return mIC; // mIC is already set
// IC-per-shell, we share a single IC among all widgets of
// a single toplevel widget
nsIWidget *widget = this;
nsIWidget *root = this;
while (widget) {
root = widget;
widget = widget->GetParent();
}
nsWidget *root_win = (nsWidget*)root; // this is a toplevel window
if (!root_win->mIC) {
// create an XIC as this is a new toplevel window
// open an XIM
if (!gdk_xim_ic) {
#ifdef NOISY_XIM
printf("Try gdk_im_open()\n");
#endif
if (gdk_im_open() == FALSE){
#ifdef NOISY_XIM
printf("Can't Open IM\n");
#endif
}
} else {
#ifdef NOISY_XIM
printf("gdk_xim_ic is already created\n");
#endif
}
if (gdk_im_ready()) {
int height, width;
// fontset is hardcoded, but need to get a fontset at the
// text insertion point
GdkFont *gfontset =
gdk_fontset_load("-misc-fixed-medium-r-normal--*-130-*-*-*-*-*-0");
GdkWindow *gdkWindow = (GdkWindow*) GetNativeData(NS_NATIVE_WINDOW);
if (!gdkWindow) return nsnull;
GdkWindowPrivate *gdkWindow_private = (GdkWindowPrivate*) gdkWindow;
GdkICAttr *attr = gdk_ic_attr_new();
GdkICAttributesType attrmask = GDK_IC_ALL_REQ;
GdkIMStyle style;
PRInt32 ivalue = 0;
nsresult rv;
GdkIMStyle supported_style = (GdkIMStyle) (SUPPORTED_PREEDIT | SUPPORTED_STATUS);
style = gdk_im_decide_style(supported_style);
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
if (!NS_FAILED(rv) && (prefs)) {
rv = prefs->GetIntPref(PREF_XIM_PREEDIT, &ivalue);
if (SUPPORTED_PREEDIT & ivalue) {
style = (GdkIMStyle) ((style & GDK_IM_STATUS_MASK) | ivalue);
}
rv = prefs->GetIntPref(PREF_XIM_STATUS, &ivalue);
if (SUPPORTED_STATUS & ivalue) {
style = (GdkIMStyle) ((style & GDK_IM_PREEDIT_MASK) | ivalue);
}
}
attr->style = style;
attr->client_window = gdkWindow;
attrmask = (GdkICAttributesType) (attrmask | GDK_IC_PREEDIT_COLORMAP);
attr->preedit_colormap = gdkWindow_private->colormap;
switch (style & GDK_IM_PREEDIT_MASK)
{
case GDK_IM_PREEDIT_POSITION:
default:
attrmask = (GdkICAttributesType) (attrmask | GDK_IC_PREEDIT_POSITION_REQ);
gdk_window_get_size (gdkWindow, &width, &height);
/* need to know how to get spot location */
attr->spot_location.x = 0;
attr->spot_location.y = 0; // height;
attr->preedit_area.x = 0;
attr->preedit_area.y = 0;
attr->preedit_area.width = width;
attr->preedit_area.height = height;
attrmask = (GdkICAttributesType) (attrmask | GDK_IC_PREEDIT_AREA);
attr->preedit_fontset = gfontset;
attrmask = (GdkICAttributesType) (attrmask | GDK_IC_PREEDIT_FONTSET);
break;
}
GdkICPrivate *IC = (GdkICPrivate*) gdk_ic_new (attr, attrmask);
gdk_ic_attr_destroy(attr);
root_win->SetXIC(IC); // set to toplevel
SetXIC(IC); // set to myself
return IC;
}
} else {
mIC = root_win->mIC;
return mIC;
}
return nsnull;
}
void
nsWidget::GetXYFromPosition(unsigned long *aX,
unsigned long *aY)
{
if(mIMEEnable == PR_FALSE)
return;
if (!mIC)
return;
GdkICAttr *attr = gdk_ic_attr_new();
GdkICAttributesType attrMask = GDK_IC_PREEDIT_FONTSET;
mIC->mask = GDK_IC_PREEDIT_FONTSET; // hack
gdk_ic_get_attr((GdkIC*)mIC, attr, attrMask);
if (attr->preedit_fontset) {
*aY += attr->preedit_fontset->ascent;
}
gdk_ic_attr_destroy(attr);
return;
}
void
nsWidget::SetXICSpotLocation(nsPoint aPoint)
{
if(mIMEEnable == PR_FALSE)
{
return;
}
if (!mIC) GetXIC();
if (mIC)
{
GdkICAttr *attr = gdk_ic_attr_new();
GdkICAttributesType attrMask = GDK_IC_SPOT_LOCATION;
unsigned long x, y;
x = aPoint.x, y = aPoint.y;
GetXYFromPosition(&x, &y);
attr->spot_location.x = x;
attr->spot_location.y = y;
gdk_ic_set_attr((GdkIC*)mIC, attr, attrMask);
gdk_ic_attr_destroy(attr);
}
return;
}
#endif

Просмотреть файл

@ -21,6 +21,8 @@
#include "nsBaseWidget.h"
// XXX: This must go away when nsAutoCString moves out of nsFileSpec.h
#include "nsFileSpec.h" // for nsAutoCString()
@ -30,14 +32,8 @@ class nsIToolkit;
#include <gtk/gtk.h>
#ifndef USE_XIM
#define USE_XIM
#endif
#ifdef DEBUG
#undef NOISY_DESTROY
#else
#undef NOISY_DESTROY
#ifdef USE_XIM
#include <gdk/gdkprivate.h>
#endif
#define NSRECT_TO_GDKRECT(ns,gdk) \
@ -115,10 +111,6 @@ public:
NS_IMETHOD SetColorMap(nsColorMap *aColorMap);
void* GetNativeData(PRUint32 aDataType);
#ifdef NS_GTK_REF
void ReleaseNativeData(PRUint32 aDataType);
#endif
NS_IMETHOD GetAbsoluteBounds(nsRect &aRect);
NS_IMETHOD WidgetToScreen(const nsRect &aOldRect, nsRect &aNewRect);
@ -250,8 +242,20 @@ protected:
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
// Static method used to trampoline to OnDestroySignal
static gint DestroySignal(GtkWidget * aGtkWidget,
nsWidget* aWidget);
static gint DestroySignal(GtkWidget * aGtkWidget,
nsWidget* aWidget);
#ifdef USE_XIM
public:
PRBool mIMEEnable;
PRUnichar* mIMECompositionUniString;
PRInt32 mIMECompositionUniStringSize;
void SetXICSpotLocation(nsPoint aPoint);
#endif
private:
@ -355,6 +359,16 @@ protected:
PRBool mShown;
PRUint32 mPreferredWidth, mPreferredHeight;
#ifdef USE_XIM
GdkICPrivate *mIC;
GdkICPrivate *GetXIC();
void SetXIC(GdkICPrivate *aIC);
void GetXYFromPosition(unsigned long *aX, unsigned long *aY);
#endif /* USE_XIM */
private:
PRBool mIsDragDest;
static nsILookAndFeel *sLookAndFeel;

Просмотреть файл

@ -17,7 +17,7 @@
*/
#include <gtk/gtk.h>
#define USE_XIM
#include <gdk/gdkx.h>
#include <gtk/gtkprivate.h>
@ -35,10 +35,7 @@
#include "nsGtkEventHandler.h"
#include "nsIAppShell.h"
#include "nsClipboard.h"
#ifdef USE_XIM
#include "nsIServiceManager.h"
#include "nsIPref.h"
#endif
#include "stdio.h"
@ -63,12 +60,6 @@ nsWindow::nsWindow()
mFont = nsnull;
mMenuBar = nsnull;
#ifdef USE_XIM
mIMEEnable = PR_TRUE;
mIC = nsnull;
mIMECompositionUniString = nsnull;
mIMECompositionUniStringSize = 0;
#endif
}
//-------------------------------------------------------------------------
@ -176,64 +167,6 @@ NS_METHOD nsWindow::Destroy()
return NS_OK;
}
#ifdef USE_XIM
void
nsWindow::OnFocusInSignal(GdkEventFocus * aGdkFocusEvent)
{
nsWidget::OnFocusInSignal(aGdkFocusEvent);
if(mIMEEnable == PR_FALSE){
#ifdef NOISY_XIM
printf(" IME is not usable on this window\n");
#endif
return;
}
if (!mIC) {
GetXIC();
}
if (mIC){
GdkWindow *gdkWindow = (GdkWindow*) GetNativeData(NS_NATIVE_WINDOW);
if (gdkWindow) {
gdk_im_begin ((GdkIC*)mIC, gdkWindow);
} else {
#ifdef NOISY_XIM
printf("gdkWindow is not usable\n");
#endif
}
} else {
#ifdef NOISY_XIM
printf("mIC can't created yet\n");
#endif
}
}
void
nsWindow::OnFocusOutSignal(GdkEventFocus * aGdkFocusEvent)
{
nsWidget::OnFocusOutSignal(aGdkFocusEvent);
if(mIMEEnable == PR_FALSE){
#ifdef NOISY_XIM
printf(" IME is not usable on this window\n");
#endif
return;
}
if (mIC){
GdkWindow *gdkWindow = (GdkWindow*) GetNativeData(NS_NATIVE_WINDOW);
if (gdkWindow) {
gdk_im_end();
} else {
#ifdef NOISY_XIM
printf("gdkWindow is not usable\n");
#endif
}
} else {
#ifdef NOISY_XIM
printf("mIC isn't created yet\n");
#endif
}
}
#endif /* USE_XIM */
void
nsWindow::OnDestroySignal(GtkWidget* aGtkWidget)
{
@ -1005,176 +938,7 @@ nsWindow::OnDrawSignal(GdkRectangle * aArea)
return PR_TRUE;
}
//////////////////////////////////////////////////////////////////////
#ifdef USE_XIM
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
#define PREF_XIM_PREEDIT "xim.preedit"
#define PREF_XIM_STATUS "xim.status"
#define SUPPORTED_PREEDIT (GDK_IM_PREEDIT_AREA | \
GDK_IM_PREEDIT_POSITION | \
GDK_IM_PREEDIT_NOTHING | \
GDK_IM_PREEDIT_NONE)
// GDK_IM_PREEDIT_CALLBACKS
#define SUPPORTED_STATUS (GDK_IM_STATUS_NOTHING | \
GDK_IM_STATUS_NONE)
// GDK_IM_STATUS_AREA
// GDK_IM_STATUS_CALLBACKS
void
nsWindow::SetXIC(GdkICPrivate *aIC) {
if(mIMEEnable == PR_FALSE){
return;
}
mIC = aIC;
return;
}
GdkICPrivate*
nsWindow::GetXIC() {
if(mIMEEnable == PR_FALSE){
return nsnull;
}
if (mIC) return mIC; // mIC is already set
// IC-per-shell, we share a single IC among all widgets of
// a single toplevel widget
nsIWidget *widget = this;
nsIWidget *root = this;
while (widget) {
root = widget;
widget = widget->GetParent();
}
nsWindow *root_win = (nsWindow*)root; // this is a toplevel window
if (!root_win->mIC) {
// create an XIC as this is a new toplevel window
// open an XIM
if (!gdk_xim_ic) {
#ifdef NOISY_XIM
printf("Try gdk_im_open()\n");
#endif
if (gdk_im_open() == FALSE){
#ifdef NOISY_XIM
printf("Can't Open IM\n");
#endif
}
} else {
#ifdef NOISY_XIM
printf("gdk_xim_ic is already created\n");
#endif
}
if (gdk_im_ready()) {
int height, width;
// fontset is hardcoded, but need to get a fontset at the
// text insertion point
GdkFont *gfontset =
gdk_fontset_load("-misc-fixed-medium-r-normal--*-130-*-*-*-*-*-0");
GdkWindow *gdkWindow = (GdkWindow*) GetNativeData(NS_NATIVE_WINDOW);
if (!gdkWindow) return nsnull;
GdkWindowPrivate *gdkWindow_private = (GdkWindowPrivate*) gdkWindow;
GdkICAttr *attr = gdk_ic_attr_new();
GdkICAttributesType attrmask = GDK_IC_ALL_REQ;
GdkIMStyle style;
PRInt32 ivalue = 0;
nsresult rv;
GdkIMStyle supported_style = (GdkIMStyle) (SUPPORTED_PREEDIT | SUPPORTED_STATUS);
style = gdk_im_decide_style(supported_style);
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
if (!NS_FAILED(rv) && (prefs)) {
rv = prefs->GetIntPref(PREF_XIM_PREEDIT, &ivalue);
if (SUPPORTED_PREEDIT & ivalue) {
style = (GdkIMStyle) ((style & GDK_IM_STATUS_MASK) | ivalue);
}
rv = prefs->GetIntPref(PREF_XIM_STATUS, &ivalue);
if (SUPPORTED_STATUS & ivalue) {
style = (GdkIMStyle) ((style & GDK_IM_PREEDIT_MASK) | ivalue);
}
}
attr->style = style;
attr->client_window = gdkWindow;
attrmask = (GdkICAttributesType) (attrmask | GDK_IC_PREEDIT_COLORMAP);
attr->preedit_colormap = gdkWindow_private->colormap;
switch (style & GDK_IM_PREEDIT_MASK) {
case GDK_IM_PREEDIT_POSITION:
default:
attrmask = (GdkICAttributesType) (attrmask | GDK_IC_PREEDIT_POSITION_REQ);
gdk_window_get_size (gdkWindow, &width, &height);
/* need to know how to get spot location */
attr->spot_location.x = 0;
attr->spot_location.y = 0; // height;
attr->preedit_area.x = 0;
attr->preedit_area.y = 0;
attr->preedit_area.width = width;
attr->preedit_area.height = height;
attrmask = (GdkICAttributesType) (attrmask | GDK_IC_PREEDIT_AREA);
attr->preedit_fontset = gfontset;
attrmask = (GdkICAttributesType) (attrmask | GDK_IC_PREEDIT_FONTSET);
break;
}
GdkICPrivate *IC = (GdkICPrivate*) gdk_ic_new (attr, attrmask);
gdk_ic_attr_destroy(attr);
root_win->SetXIC(IC); // set to toplevel
SetXIC(IC); // set to myself
return IC;
}
} else {
mIC = root_win->mIC;
return mIC;
}
return nsnull;
}
void
nsWindow::GetXYFromPosition(unsigned long *aX,
unsigned long *aY) {
if(mIMEEnable == PR_FALSE){
return;
}
GdkICAttr *attr = gdk_ic_attr_new();
GdkICAttributesType attrMask = GDK_IC_PREEDIT_FONTSET;
mIC->mask = GDK_IC_PREEDIT_FONTSET; // hack
gdk_ic_get_attr((GdkIC*)mIC, attr, attrMask);
if (attr->preedit_fontset) {
*aY += attr->preedit_fontset->ascent;
}
gdk_ic_attr_destroy(attr);
return;
}
void
nsWindow::SetXICSpotLocation(nsPoint aPoint) {
if(mIMEEnable == PR_FALSE){
return;
}
if (!mIC) GetXIC();
if (mIC) {
GdkICAttr *attr = gdk_ic_attr_new();
GdkICAttributesType attrMask = GDK_IC_SPOT_LOCATION;
unsigned long x, y;
x = aPoint.x, y = aPoint.y;
GetXYFromPosition(&x, &y);
attr->spot_location.x = x;
attr->spot_location.y = y;
gdk_ic_set_attr((GdkIC*)mIC, attr, attrMask);
gdk_ic_attr_destroy(attr);
}
return;
}
#endif
ChildWindow::ChildWindow()
{
}

Просмотреть файл

@ -18,10 +18,7 @@
#ifndef nsWindow_h__
#define nsWindow_h__
#define USE_XIM
#ifdef USE_XIM
#include <gdk/gdkprivate.h>
#endif
#include "nsISupports.h"
@ -97,12 +94,7 @@ public:
// in nsWidget now
// virtual PRBool OnResize(nsSizeEvent &aEvent);
#ifdef USE_XIM
PRBool mIMEEnable;
PRUnichar* mIMECompositionUniString;
PRInt32 mIMECompositionUniStringSize;
void SetXICSpotLocation(nsPoint aPoint);
#endif
protected:
@ -126,11 +118,6 @@ protected:
virtual gint OnDrawSignal(GdkRectangle * aArea);
virtual void OnRealize();
#ifdef USE_XIM
virtual void OnFocusInSignal(GdkEventFocus * aGdkFocusEvent);
virtual void OnFocusOutSignal(GdkEventFocus * aGdkFocusEvent);
#endif /* USE_XIM */
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
//////////////////////////////////////////////////////////////////////
@ -156,13 +143,6 @@ protected:
GtkWidget *mShell; /* used for toplevel windows */
nsIMenuBar *mMenuBar;
#ifdef USE_XIM
GdkICPrivate* mIC;
GdkICPrivate* GetXIC();
void SetXIC(GdkICPrivate *aIC);
void GetXYFromPosition(unsigned long *aX, unsigned long *aY);
#endif /* USE_XIM */
};
//