]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
wxFileSystem now compiles if wxUSE_HTML (required by wxHTML)
[wxWidgets.git] / src / gtk / window.cpp
index 2f617eaacd2cea3186db3ef45c7b30772b40f164..6be2cdd8c583ece185db64058568f155212fe62d 100644 (file)
@@ -223,18 +223,21 @@ static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget),
 
 void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window )
 {
-/*
-    wxString tmp = name;
-    tmp += wxT(" FROM ");
-    tmp += window;
+    // suppress warnings about gtk_debug_focus_in_callback being unused with
+    // this "if ( 0 )"
+    if ( 0 )
+    {
+        wxString tmp = name;
+        tmp += wxT(" FROM ");
+        tmp += window;
 
-    wxChar *s = new wxChar[tmp.Length()+1];
+        wxChar *s = new wxChar[tmp.Length()+1];
 
-    wxStrcpy( s, tmp );
+        wxStrcpy( s, tmp );
 
-    gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
-      GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s );
-*/
+        gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
+          GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s );
+    }
 }
 
 #endif // Debug
@@ -595,9 +598,6 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp
                                   gdk_event->area.width,
                                   gdk_event->area.height );
 
-    if (gdk_event->count > 0)
-        return;
-
 /*
     wxPrintf( "OnExpose from " );
     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
@@ -608,6 +608,9 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp
                                 (int)gdk_event->area.height );
 */
 
+    if (gdk_event->count > 0)
+        return;
+
     wxEraseEvent eevent( win->GetId() );
     eevent.SetEventObject( win );
     win->GetEventHandler()->ProcessEvent(eevent);
@@ -669,17 +672,12 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
     if (g_blockEventsOnDrag) return FALSE;
 
 /*
+    wxString tmp;
+    tmp += (char)gdk_event->keyval;
+    printf( "KeyDown-Code is: %s.\n", tmp.c_str() );
     printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
-    if (gdk_event->state & GDK_SHIFT_MASK)
-      printf( "ShiftDown.\n" );
-    else
-      printf( "ShiftUp.\n" );
-    if (gdk_event->state & GDK_CONTROL_MASK)
-      printf( "ControlDown.\n" );
-    else
-      printf( "ControlUp.\n" );
-    printf( "\n" );
 */
+    
     int x = 0;
     int y = 0;
     GdkModifierType state;
@@ -946,8 +944,8 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
     event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
     event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
 
-    event.m_x = (long)gdk_event->x;
-    event.m_y = (long)gdk_event->y;
+    event.m_x = (wxCoord)gdk_event->x;
+    event.m_y = (wxCoord)gdk_event->y;
 
     // Some control don't have their own X window and thus cannot get
     // any events.
@@ -1073,8 +1071,8 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
     event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
     event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
     event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
-    event.m_x = (long)gdk_event->x;
-    event.m_y = (long)gdk_event->y;
+    event.m_x = (wxCoord)gdk_event->x;
+    event.m_y = (wxCoord)gdk_event->y;
 
     // Some control don't have their own X window and thus cannot get
     // any events.
@@ -1193,8 +1191,8 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
     event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
     event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
 
-    event.m_x = (long)gdk_event->x;
-    event.m_y = (long)gdk_event->y;
+    event.m_x = (wxCoord)gdk_event->x;
+    event.m_y = (wxCoord)gdk_event->y;
 
     // Some control don't have their own X window and thus cannot get
     // any events.
@@ -1314,6 +1312,11 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(
         panel->SetLastFocus(win);
     }
 
+#ifdef HAVE_XIM
+    if (win->m_ic)
+        gdk_im_begin(win->m_ic, win->m_wxwindow->window);
+#endif
+
     wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
     event.SetEventObject( win );
 
@@ -1352,6 +1355,11 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED
     printf( ".\n" );
 */
 
+#ifdef HAVE_XIM
+    if (win->m_ic)
+        gdk_im_end();
+#endif
+
     wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
     event.SetEventObject( win );
 
@@ -1398,8 +1406,8 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_
     event.m_middleDown = (state & GDK_BUTTON2_MASK);
     event.m_rightDown = (state & GDK_BUTTON3_MASK);
 
-    event.m_x = (long)x;
-    event.m_y = (long)y;
+    event.m_x = x;
+    event.m_y = y;
 
     if (win->GetEventHandler()->ProcessEvent( event ))
     {
@@ -1444,8 +1452,8 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_
     event.m_middleDown = (state & GDK_BUTTON2_MASK);
     event.m_rightDown = (state & GDK_BUTTON3_MASK);
 
-    event.m_x = (long)x;
-    event.m_y = (long)y;
+    event.m_x = x;
+    event.m_y = y;
 
     if (win->GetEventHandler()->ProcessEvent( event ))
     {
@@ -1617,11 +1625,11 @@ wxWindow *wxWindowBase::FindFocus()
 // "realize" from m_widget
 //-----------------------------------------------------------------------------
 
-/* we cannot set colours and fonts before the widget has
-   been realized, so we do this directly after realization */
+/* We cannot set colours and fonts before the widget has
+   been realized, so we do this directly after realization. */
 
 static gint
-gtk_window_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win )
+gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
@@ -1642,6 +1650,135 @@ gtk_window_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win )
     return FALSE;
 }
 
+//-----------------------------------------------------------------------------
+// "size_allocate"
+//-----------------------------------------------------------------------------
+
+#ifdef HAVE_XIM
+    #define WXUNUSED_UNLESS_XIM(param)  param
+#else
+    #define WXUNUSED_UNLESS_XIM(param)  WXUNUSED(param)
+#endif
+
+/* Resize XIM window */
+
+static
+void gtk_wxwindow_size_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
+                                 GtkAllocation * WXUNUSED_UNLESS_XIM(alloc),
+                                 wxFrame * WXUNUSED_UNLESS_XIM(win) )
+{
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+#ifdef HAVE_XIM
+    if (!win->m_ic)
+        return;
+
+    if  (gdk_ic_get_style (win->m_ic) & GDK_IM_PREEDIT_POSITION)
+    {
+        gint width, height;
+
+        gdk_window_get_size (widget->window, &width, &height);
+        win->m_icattr->preedit_area.width = width;
+        win->m_icattr->preedit_area.height = height;
+        gdk_ic_set_attr (win->m_ic, win->m_icattr, GDK_IC_PREEDIT_AREA);
+    }
+#endif // HAVE_XIM
+}
+
+//-----------------------------------------------------------------------------
+// "realize" from m_wxwindow
+//-----------------------------------------------------------------------------
+
+/* Initialize XIM support */
+
+static gint
+gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
+                                wxWindow * WXUNUSED_UNLESS_XIM(win) )
+{
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+#ifdef HAVE_XIM
+    if (win->m_ic) return FALSE;
+    if (!widget) return FALSE;
+    if (!gdk_im_ready()) return FALSE;
+
+    win->m_icattr = gdk_ic_attr_new();
+    if (!win->m_icattr) return FALSE;
+    
+    gint width, height;
+    GdkEventMask mask;
+    GdkColormap *colormap;
+    GdkICAttr *attr = win->m_icattr;
+    unsigned attrmask = GDK_IC_ALL_REQ;
+    GdkIMStyle style;
+    GdkIMStyle supported_style = (GdkIMStyle)
+                                  (GDK_IM_PREEDIT_NONE |
+                                  GDK_IM_PREEDIT_NOTHING |
+                                  GDK_IM_PREEDIT_POSITION |
+                                  GDK_IM_STATUS_NONE |
+                                  GDK_IM_STATUS_NOTHING);
+
+    if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
+       supported_style = (GdkIMStyle)(supported_style & ~GDK_IM_PREEDIT_POSITION);
+
+    attr->style = style = gdk_im_decide_style (supported_style);
+    attr->client_window = widget->window;
+
+    if ((colormap = gtk_widget_get_colormap (widget)) !=
+           gtk_widget_get_default_colormap ())
+    {
+       attrmask |= GDK_IC_PREEDIT_COLORMAP;
+       attr->preedit_colormap = colormap;
+    }
+    
+    attrmask |= GDK_IC_PREEDIT_FOREGROUND;
+    attrmask |= GDK_IC_PREEDIT_BACKGROUND;
+    attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL];
+    attr->preedit_background = widget->style->base[GTK_STATE_NORMAL];
+
+    switch (style & GDK_IM_PREEDIT_MASK)
+    {
+       case GDK_IM_PREEDIT_POSITION:
+         if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
+           {
+             g_warning ("over-the-spot style requires fontset");
+             break;
+           }
+
+         gdk_window_get_size (widget->window, &width, &height);
+
+         attrmask |= GDK_IC_PREEDIT_POSITION_REQ;
+         attr->spot_location.x = 0;
+         attr->spot_location.y = height;
+         attr->preedit_area.x = 0;
+         attr->preedit_area.y = 0;
+         attr->preedit_area.width = width;
+         attr->preedit_area.height = height;
+         attr->preedit_fontset = widget->style->font;
+
+         break;
+    }
+       
+      win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask);
+     
+      if (win->m_ic == NULL)
+       g_warning ("Can't create input context.");
+      else
+       {
+         mask = gdk_window_get_events (widget->window);
+         mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic));
+         gdk_window_set_events (widget->window, mask);
+
+         if (GTK_WIDGET_HAS_FOCUS(widget))
+           gdk_im_begin (win->m_ic, widget->window);
+       }
+#endif
+
+    return FALSE;
+}
+
 //-----------------------------------------------------------------------------
 // InsertChild for wxWindow.
 //-----------------------------------------------------------------------------
@@ -1726,6 +1863,11 @@ void wxWindow::Init()
     m_acceptsFocus = FALSE;
 
     m_cursor = *wxSTANDARD_CURSOR;
+    
+#ifdef HAVE_XIM
+    m_ic = (GdkIC*) NULL;
+    m_icattr = (GdkICAttr*) NULL;
+#endif
 }
 
 wxWindow::wxWindow()
@@ -1901,6 +2043,13 @@ wxWindow::~wxWindow()
     if (m_parent)
         m_parent->RemoveChild( this );
 
+#ifdef HAVE_XIM
+    if (m_ic)
+        gdk_ic_destroy (m_ic);
+    if (m_icattr)
+        gdk_ic_attr_destroy (m_icattr);
+#endif
+
     if (m_widgetStyle)
     {
         gtk_style_unref( m_widgetStyle );
@@ -1978,15 +2127,46 @@ void wxWindow::PostCreation()
 #endif
     }
 
+    if (m_wxwindow && m_needParent)
+    {
+        gtk_signal_connect( GTK_OBJECT(m_wxwindow), "focus_in_event",
+            GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
+
+        gtk_signal_connect( GTK_OBJECT(m_wxwindow), "focus_out_event",
+            GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
+    }
+    else
+    {
+        // For dialogs and frames, we are interested mainly in
+       // m_widget's focus.
+       
+        gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event",
+            GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
+
+        gtk_signal_connect( GTK_OBJECT(m_widget), "focus_out_event",
+            GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
+    }
+
     GtkWidget *connect_widget = GetConnectWidget();
 
     ConnectWidget( connect_widget );
 
-   /*  we cannot set colours, fonts and cursors before the widget has
+    /* We cannot set colours, fonts and cursors before the widget has
        been realized, so we do this directly after realization */
     gtk_signal_connect( GTK_OBJECT(connect_widget), "realize",
                             GTK_SIGNAL_FUNC(gtk_window_realized_callback), (gpointer) this );
-
+    if (m_wxwindow)
+    {
+        /* Initialize XIM support.  */
+        gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize",
+                            GTK_SIGNAL_FUNC(gtk_wxwindow_realized_callback), (gpointer) this );
+                           
+        /* And resize XIM window.  */
+        gtk_signal_connect( GTK_OBJECT(m_wxwindow), "size_allocate",
+                            GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback), (gpointer)this );
+    }
+    
     m_hasVMT = TRUE;
 }
 
@@ -2007,12 +2187,6 @@ void wxWindow::ConnectWidget( GtkWidget *widget )
     gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event",
       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
 
-    gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
-      GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
-
-    gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event",
-      GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
-
     gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event",
       GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
 
@@ -2029,6 +2203,11 @@ bool wxWindow::Destroy()
     return wxWindowBase::Destroy();
 }
 
+void wxWindow::DoMoveWindow(int x, int y, int width, int height)
+{
+    gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height );
+}
+    
 void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
@@ -2089,12 +2268,10 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
             bottom_border = 5;
         }
 
-        gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow),
-                              m_widget,
-                              m_x-border,
-                              m_y-border,
-                              m_width+2*border,
-                              m_height+border+bottom_border );
+        DoMoveWindow( m_x-border,
+                      m_y-border,
+                      m_width+2*border,
+                      m_height+border+bottom_border );
     }
 
 /*
@@ -2602,8 +2779,7 @@ void wxWindow::WarpPointer( int x, int y )
 
 void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
 {
-    wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
-
+    if (!m_widget) return;
     if (!m_widget->window) return;
 
     if (eraseBackground && m_wxwindow && m_wxwindow->window)
@@ -3156,6 +3332,10 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
 
     wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
 
+/*
+    printf( "ScrollWindow: %d %d\n", dx, dy );
+*/
+
     gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
 
 /*