+#ifndef __WXUNIVERSAL__
+ GtkPizza *pizza = GTK_PIZZA (widget);
+
+ if (win->GetThemeEnabled())
+ {
+ wxWindow *parent = win->GetParent();
+ while (parent && !parent->IsTopLevel())
+ parent = parent->GetParent();
+ if (!parent)
+ parent = win;
+
+ gtk_paint_flat_box (parent->m_widget->style,
+ pizza->bin_window,
+ GTK_STATE_NORMAL,
+ GTK_SHADOW_NONE,
+ &gdk_event->area,
+ parent->m_widget,
+ (char *)"base",
+ 0, 0, -1, -1);
+ }
+#endif
+
+ win->GetUpdateRegion().Union( gdk_event->area.x,
+ gdk_event->area.y,
+ gdk_event->area.width,
+ gdk_event->area.height );
+
+ // Actual redrawing takes place in idle time.
+ win->Update();
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// "event" of m_wxwindow
+//-----------------------------------------------------------------------------
+
+// GTK thinks it is clever and filters out a certain amount of "unneeded"
+// expose events. We need them, of course, so we override the main event
+// procedure in GtkWidget by giving our own handler for all system events.
+// There, we look for expose events ourselves whereas all other events are
+// handled normally.
+
+gint gtk_window_event_event_callback( GtkWidget *widget,
+ GdkEventExpose *event,
+ wxWindow *win )
+{
+ if (event->type == GDK_EXPOSE)
+ {
+ gint ret = gtk_window_expose_callback( widget, event, win );
+ return ret;
+ }
+
+ return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// "draw" of m_wxwindow
+//-----------------------------------------------------------------------------
+
+// This callback is a complete replacement of the gtk_pizza_draw() function,
+// which disabled.
+
+static void gtk_window_draw_callback( GtkWidget *widget,
+ GdkRectangle *rect,
+ wxWindow *win )
+{
+ DEBUG_MAIN_THREAD
+
+ if (g_isIdle)
+ wxapp_install_idle_handler();
+
+ // The wxNO_FULL_REPAINT_ON_RESIZE flag only works if
+ // there are no child windows.
+ if ((win->HasFlag(wxNO_FULL_REPAINT_ON_RESIZE)) &&
+ (win->GetChildren().GetCount() == 0))
+ {
+ return;
+ }
+
+/*
+ if (win->GetName() == wxT("panel"))
+ {
+ wxPrintf( wxT("OnDraw from ") );
+ if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+ wxPrintf( win->GetClassInfo()->GetClassName() );
+ wxPrintf( wxT(" %d %d %d %d\n"), (int)rect->x,
+ (int)rect->y,
+ (int)rect->width,
+ (int)rect->height );
+ }
+*/
+
+#ifndef __WXUNIVERSAL__
+ GtkPizza *pizza = GTK_PIZZA (widget);
+
+ if (win->GetThemeEnabled())
+ {
+ wxWindow *parent = win->GetParent();
+ while (parent && !parent->IsTopLevel())
+ parent = parent->GetParent();
+ if (!parent)
+ parent = win;
+
+ gtk_paint_flat_box (parent->m_widget->style,
+ pizza->bin_window,
+ GTK_STATE_NORMAL,
+ GTK_SHADOW_NONE,
+ rect,
+ parent->m_widget,
+ (char *)"base",
+ 0, 0, -1, -1);
+ }
+
+
+ if (!(GTK_WIDGET_APP_PAINTABLE (widget)) &&
+ (pizza->clear_on_draw))
+ {
+ gdk_window_clear_area( pizza->bin_window,
+ rect->x, rect->y, rect->width, rect->height);
+ }
+#endif
+
+ win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
+
+ // Actual redrawing takes place in idle time.
+
+ win->Update();
+
+#ifndef __WXUNIVERSAL__
+ // Redraw child widgets
+ GList *children = pizza->children;
+ while (children)
+ {
+ GtkPizzaChild *child = (GtkPizzaChild*) children->data;
+ children = children->next;
+
+ GdkRectangle child_area;
+ if (gtk_widget_intersect (child->widget, rect, &child_area))
+ {
+ gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ );
+ }
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// "key_press_event" from any window
+//-----------------------------------------------------------------------------
+
+// turn on to see the key event codes on the console
+#undef DEBUG_KEY_EVENTS
+
+static gint gtk_window_key_press_callback( GtkWidget *widget,
+ GdkEventKey *gdk_event,
+ wxWindow *win )
+{
+ DEBUG_MAIN_THREAD
+
+ if (g_isIdle)
+ wxapp_install_idle_handler();
+
+ if (!win->m_hasVMT) return FALSE;
+ if (g_blockEventsOnDrag) return FALSE;
+
+
+ int x = 0;
+ int y = 0;
+ GdkModifierType state;
+ if (gdk_event->window)
+ gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
+
+ bool ret = FALSE;
+
+ long key_code = map_to_unmodified_wx_keysym( gdk_event );
+
+#ifdef DEBUG_KEY_EVENTS
+ wxPrintf(_T("Key press event: %d => %ld\n"), gdk_event->keyval, key_code);
+#endif // DEBUG_KEY_EVENTS
+
+ /* sending unknown key events doesn't really make sense */
+ if (key_code == 0)
+ return FALSE;
+
+ wxKeyEvent event( wxEVT_KEY_DOWN );
+ event.SetTimestamp( gdk_event->time );
+ event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+ event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+ event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+ event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+ event.m_keyCode = key_code;
+ event.m_scanCode = gdk_event->keyval;
+ event.m_x = x;
+ event.m_y = y;
+ event.SetEventObject( win );
+ ret = win->GetEventHandler()->ProcessEvent( event );
+
+#if wxUSE_ACCEL
+ if (!ret)
+ {
+ wxWindowGTK *ancestor = win;
+ while (ancestor)
+ {
+ int command = ancestor->GetAcceleratorTable()->GetCommand( event );
+ if (command != -1)
+ {
+ wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
+ ret = ancestor->GetEventHandler()->ProcessEvent( command_event );
+ break;
+ }
+ if (ancestor->IsTopLevel())
+ break;
+ ancestor = ancestor->GetParent();
+ }
+ }
+#endif // wxUSE_ACCEL
+
+ /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
+ will only be sent if it is not in an accelerator table. */
+ if ( !ret )
+ {
+ key_code = map_to_wx_keysym( gdk_event );
+
+ if ( key_code )
+ {
+#ifdef DEBUG_KEY_EVENTS
+ wxPrintf(_T("Char event: %ld\n"), key_code);
+#endif // DEBUG_KEY_EVENTS
+
+ // reuse the ame event object, just change its type and use the
+ // translated keycode instead of the raw one
+ event.SetEventType(wxEVT_CHAR);
+ event.m_keyCode = key_code;
+
+ ret = win->GetEventHandler()->ProcessEvent( event );
+ }
+ }
+
+ /* win is a control: tab can be propagated up */
+ if ( !ret &&
+ ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
+// VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may
+// have this style, yet choose not to process this particular TAB in which
+// case TAB must still work as a navigational character
+#if 0
+ !win->HasFlag(wxTE_PROCESS_TAB) &&
+#endif // 0
+ win->GetParent() && (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
+ {
+ wxNavigationKeyEvent new_event;
+ new_event.SetEventObject( win->GetParent() );
+ /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
+ new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
+ /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
+ new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
+ new_event.SetCurrentFocus( win );
+ ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event );
+ }
+
+ /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
+ if ( !ret &&
+ (gdk_event->keyval == GDK_Escape) )
+ {
+ wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
+ new_event.SetEventObject( win );
+ ret = win->GetEventHandler()->ProcessEvent( new_event );
+ }
+
+ /* Doesn't work. */
+#if 0 // (GTK_MINOR_VERSION > 0)
+ /* Pressing F10 will activate the menu bar of the top frame. */
+ if ( (!ret) &&
+ (gdk_event->keyval == GDK_F10) )
+ {
+ wxWindowGTK *ancestor = win;
+ while (ancestor)
+ {
+ if (wxIsKindOf(ancestor,wxFrame))
+ {
+ wxFrame *frame = (wxFrame*) ancestor;
+ wxMenuBar *menubar = frame->GetMenuBar();
+ if (menubar)
+ {
+ wxNode *node = menubar->GetMenus().First();
+ if (node)
+ {
+ wxMenu *firstMenu = (wxMenu*) node->Data();
+ gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
+ ret = TRUE;
+ break;
+ }
+ }
+ }
+ ancestor = ancestor->GetParent();
+ }