diff --git a/eek/Makefile.am b/eek/Makefile.am index ba3a6f0b..70ed0432 100644 --- a/eek/Makefile.am +++ b/eek/Makefile.am @@ -47,7 +47,8 @@ libeek_sources = \ $(srcdir)/eek-key.c \ $(srcdir)/eek-types.c \ $(srcdir)/eek-keysym.c \ - $(srcdir)/eek-drawing.c + $(srcdir)/eek-renderer.c \ + $(srcdir)/eek-keyboard-drawing.c libeek_keysym_sources = \ $(srcdir)/eek-special-keysym-labels.h \ @@ -63,7 +64,7 @@ libeek_marshallers_sources = \ $(srcdir)/eek-marshallers.h libeek_private_headers = \ - $(srcdir)/eek-drawing.h \ + $(srcdir)/eek-renderer.h \ $(srcdir)/eek-special-keysym-labels.h \ $(srcdir)/eek-unicode-keysym-labels.h \ $(srcdir)/eek-keyname-keysym-labels.h \ @@ -83,20 +84,16 @@ libeek_la_LIBADD = $(GOBJECT2_LIBS) $(PANGOCAIRO_LIBS) -lm if HAVE_CLUTTER libeek_clutter_public_headers = \ $(srcdir)/eek-clutter-keyboard.h \ - $(srcdir)/eek-clutter-section.h \ - $(srcdir)/eek-clutter-key.h \ - $(srcdir)/eek-clutter-drawing-context.h \ $(srcdir)/eek-clutter.h libeek_clutter_private_headers = \ - $(srcdir)/eek-clutter-key-actor.h + $(srcdir)/eek-clutter-section.h \ + $(srcdir)/eek-clutter-key.h libeek_clutter_sources = \ $(srcdir)/eek-clutter-keyboard.c \ $(srcdir)/eek-clutter-section.c \ - $(srcdir)/eek-clutter-key.c \ - $(srcdir)/eek-clutter-key-actor.c \ - $(srcdir)/eek-clutter-drawing-context.c + $(srcdir)/eek-clutter-key.c libeek_clutter_la_SOURCES = $(libeek_clutter_sources) libeek_clutter_la_CFLAGS = $(CLUTTER_CFLAGS) diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c index ec16e50f..ea4298bb 100644 --- a/eek/eek-gtk-keyboard.c +++ b/eek/eek-gtk-keyboard.c @@ -23,20 +23,19 @@ * @short_description: #EekKeyboard that can be converted into a #GtkWidget */ #include -#include #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ #include "eek-gtk-keyboard.h" -#include "eek-drawing.h" +#include "eek-renderer.h" #include "eek-keyboard.h" #include "eek-section.h" #include "eek-key.h" #include "eek-keysym.h" -G_DEFINE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, EEK_TYPE_KEYBOARD); +G_DEFINE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA); #define EEK_GTK_KEYBOARD_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate)) @@ -47,68 +46,164 @@ G_DEFINE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, EEK_TYPE_KEYBOARD); #define GDK_DRAWABLE(x) (x) #endif -enum { - KEY_SURFACE_NORMAL = 0, - KEY_SURFACE_LARGE, - KEY_SURFACE_LAST -}; - -static const gdouble key_surface_scale[KEY_SURFACE_LAST] = { - 1.0, - 1.5 -}; - struct _EekGtkKeyboardPrivate { - GtkWidget *widget; - - cairo_surface_t *keyboard_surface; - GHashTable *key_surfaces; - - PangoFontDescription *fonts[EEK_KEYSYM_CATEGORY_LAST]; - - gdouble scale; - - EekKey *key; + EekRenderer *renderer; + EekKeyboard *keyboard; + EekKey *dragged_key; }; -static void prepare_keyboard_surface (EekGtkKeyboard *keyboard); +static EekColor * color_from_gdk_color (GdkColor *gdk_color); +static void on_key_pressed (EekKeyboard *keyboard, + EekKey *key, + gpointer user_data); +static void on_key_released (EekKeyboard *keyboard, + EekKey *key, + gpointer user_data); +static void on_keysym_index_changed (EekKeyboard *keyboard, + gint group, + gint level, + gpointer user_data); static void -eek_gtk_keyboard_real_set_keysym_index (EekKeyboard *self, - gint group, - gint level) +eek_gtk_keyboard_real_realize (GtkWidget *self) { - gint g, l; + gtk_widget_set_double_buffered (self, FALSE); + gtk_widget_set_events (self, + GDK_EXPOSURE_MASK | + GDK_KEY_PRESS_MASK | + GDK_KEY_RELEASE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK); - eek_keyboard_get_keysym_index (self, &g, &l); - EEK_KEYBOARD_CLASS(eek_gtk_keyboard_parent_class)-> - set_keysym_index (self, group, level); - if (g != group || l != level) { - EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD(self); - EekGtkKeyboardPrivate *priv = - EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); + GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->realize (self); +} + +static gboolean +eek_gtk_keyboard_real_draw (GtkWidget *self, + cairo_t *cr) +{ + EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); + GtkAllocation allocation; + EekColor background; + + gtk_widget_get_allocation (self, &allocation); + + if (!priv->renderer) { GtkStyle *style; GtkStateType state; - GtkAllocation allocation; - cairo_t *cr; + PangoContext *pcontext; - if (!priv->widget || !gtk_widget_get_realized (priv->widget)) - return; + pcontext = gtk_widget_get_pango_context (self); + priv->renderer = eek_renderer_new (priv->keyboard, pcontext); - prepare_keyboard_surface (keyboard); - gtk_widget_get_allocation (priv->widget, &allocation); + eek_renderer_set_preferred_size (priv->renderer, + allocation.width, + allocation.height); - cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget))); - style = gtk_widget_get_style (priv->widget); - state = gtk_widget_get_state (priv->widget); - gdk_cairo_set_source_color (cr, &style->fg[state]); + style = gtk_widget_get_style (self); + state = gtk_widget_get_state (self); - cairo_set_source_surface (cr, priv->keyboard_surface, 0, 0); - cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); - cairo_fill (cr); - cairo_destroy (cr); + eek_renderer_set_foreground + (priv->renderer, + color_from_gdk_color (&style->fg[state])); + eek_renderer_set_background + (priv->renderer, + color_from_gdk_color (&style->bg[state])); } + + /* blank background */ + eek_renderer_get_background (priv->renderer, &background); + cairo_set_source_rgba (cr, + background.red, + background.green, + background.blue, + background.alpha); + cairo_rectangle (cr, + 0.0, + 0.0, + allocation.width, + allocation.height); + cairo_fill (cr); + + eek_renderer_render_keyboard (priv->renderer, cr); + +#if GTK_CHECK_VERSION (2, 91, 2) + GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->draw (self, cr); +#endif /* GTK_CHECK_VERSION (2, 91, 2) */ + + return FALSE; +} + +#if !GTK_CHECK_VERSION (2, 91, 2) +static gboolean +eek_gtk_keyboard_real_expose_event (GtkWidget *self, + GdkEventExpose *event) +{ + gboolean retval; + cairo_t *cr; + + cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (self))); + retval = eek_gtk_keyboard_real_draw (self, cr); + cairo_destroy (cr); + + return retval; +} +#endif /* !GTK_CHECK_VERSION (2, 91, 2) */ + +static void +eek_gtk_keyboard_real_size_allocate (GtkWidget *self, + GtkAllocation *allocation) +{ + EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); + + if (priv->renderer) + eek_renderer_set_preferred_size (priv->renderer, + allocation->width, + allocation->height); + + GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)-> + size_allocate (self, allocation); +} + +static gboolean +eek_gtk_keyboard_real_button_press_event (GtkWidget *self, + GdkEventButton *event) +{ + EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); + EekKey *key; + + key = eek_renderer_find_key_by_position (priv->renderer, + (gdouble)event->x, + (gdouble)event->y); + + if (priv->dragged_key && priv->dragged_key != key) + g_signal_emit_by_name (priv->dragged_key, "released", priv->keyboard); + if (key) { + priv->dragged_key = key; + g_signal_emit_by_name (key, "pressed", priv->keyboard); + } + + return TRUE; +} + +static gboolean +eek_gtk_keyboard_real_button_release_event (GtkWidget *self, + GdkEventButton *event) +{ + EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); + EekKey *key; + + key = eek_renderer_find_key_by_position (priv->renderer, + (gdouble)event->x, + (gdouble)event->y); + + if (priv->dragged_key) { + g_signal_emit_by_name (priv->dragged_key, "released", priv->keyboard); + priv->dragged_key = NULL; + } + + return TRUE; } static void @@ -116,50 +211,35 @@ eek_gtk_keyboard_dispose (GObject *object) { EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object); - if (priv->widget) { - g_object_unref (priv->widget); - priv->widget = NULL; + if (priv->renderer) { + g_object_unref (priv->renderer); + priv->renderer = NULL; } G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object); } -static void -eek_gtk_keyboard_finalize (GObject *object) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object); - gint i; - - cairo_surface_destroy (priv->keyboard_surface); - g_hash_table_destroy (priv->key_surfaces); - - for (i = 0; i < EEK_KEYSYM_CATEGORY_LAST; i++) - pango_font_description_free (priv->fonts[i]); - G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->finalize (object); -} - static void eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass) { - EekKeyboardClass *keyboard_class = EEK_KEYBOARD_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (gobject_class, sizeof (EekGtkKeyboardPrivate)); - keyboard_class->set_keysym_index = eek_gtk_keyboard_real_set_keysym_index; + widget_class->realize = eek_gtk_keyboard_real_realize; +#if GTK_CHECK_VERSION (2, 91, 2) + widget_class->draw = eek_gtk_keyboard_real_draw; +#else /* GTK_CHECK_VERSION (2, 91, 2) */ + widget_class->expose_event = eek_gtk_keyboard_real_expose_event; +#endif /* !GTK_CHECK_VERSION (2, 91, 2) */ + widget_class->size_allocate = eek_gtk_keyboard_real_size_allocate; + widget_class->button_press_event = + eek_gtk_keyboard_real_button_press_event; + widget_class->button_release_event = + eek_gtk_keyboard_real_button_release_event; + gobject_class->dispose = eek_gtk_keyboard_dispose; - gobject_class->finalize = eek_gtk_keyboard_finalize; -} - -static void -key_surface_free (gpointer user_data) -{ - cairo_surface_t **key_surfaces = user_data; - gint i; - - for (i = 0; i < KEY_SURFACE_LAST; i++) - cairo_surface_destroy (key_surfaces[i]); - g_slice_free1 (sizeof (cairo_surface_t *) * KEY_SURFACE_LAST, key_surfaces); } static void @@ -168,16 +248,9 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self) EekGtkKeyboardPrivate *priv; priv = self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); - priv->widget = NULL; - priv->keyboard_surface = NULL; - priv->key_surfaces = - g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - key_surface_free); - memset (priv->fonts, 0, sizeof priv->fonts); - priv->scale = 1.0; - priv->key = NULL; + priv->renderer = NULL; + priv->keyboard = NULL; + priv->dragged_key = NULL; } /** @@ -185,456 +258,135 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self) * * Create a new #EekGtkKeyboard. */ -EekKeyboard* -eek_gtk_keyboard_new (void) -{ - return g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL); -} - -struct _DrawingContext -{ - EekGtkKeyboard *keyboard; - cairo_t *cr; - GdkColor *fg, *bg; -}; -typedef struct _DrawingContext DrawingContext; - -static void on_key_pressed (EekKey *key, gpointer user_data); -static void on_key_released (EekKey *key, gpointer user_data); - -static void -prepare_keyboard_pixmap_key_callback (EekElement *element, - gpointer user_data) -{ - DrawingContext *context = user_data; - EekGtkKeyboardPrivate *priv = - EEK_GTK_KEYBOARD_GET_PRIVATE(context->keyboard); - EekKey *key = EEK_KEY(element); - EekBounds bounds; - EekOutline *outline; - cairo_surface_t **key_surfaces; - - eek_element_get_bounds (element, &bounds); - - g_signal_connect (key, "pressed", G_CALLBACK(on_key_pressed), - context->keyboard); - g_signal_connect (key, "released", G_CALLBACK(on_key_released), - context->keyboard); - - outline = eek_key_get_outline (key); - key_surfaces = g_hash_table_lookup (priv->key_surfaces, outline); - if (!key_surfaces) { - cairo_t *cr; - gint i; - - key_surfaces = g_slice_alloc (sizeof (cairo_surface_t *) * - KEY_SURFACE_LAST); - for (i = 0; i < KEY_SURFACE_LAST; i++) { - gdouble scale = key_surface_scale[i]; - key_surfaces[i] = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - bounds.width * scale, - bounds.height * scale); - cr = cairo_create (key_surfaces[i]); - cairo_scale (cr, priv->scale * scale, priv->scale * scale); - gdk_cairo_set_source_color (cr, context->bg); - cairo_rectangle (cr, 0, 0, bounds.width, bounds.height); - gdk_cairo_set_source_color (cr, context->fg); - eek_draw_outline (cr, outline); - cairo_destroy (cr); - } - - g_hash_table_insert (priv->key_surfaces, outline, key_surfaces); - } - - cairo_save (context->cr); - - cairo_translate (context->cr, bounds.x, bounds.y); - cairo_set_source_surface (context->cr, key_surfaces[0], 0, 0); - cairo_rectangle (context->cr, 0, 0, bounds.width, bounds.height); - cairo_fill (context->cr); - - cairo_move_to (context->cr, 0, 0); - gdk_cairo_set_source_color (context->cr, context->fg); - eek_draw_key_label (context->cr, key, priv->fonts); - - cairo_restore (context->cr); -} - -static void -prepare_keyboard_pixmap_section_callback (EekElement *element, - gpointer user_data) -{ - DrawingContext *context = user_data; - EekBounds bounds; - gint angle; - - eek_element_get_bounds (element, &bounds); - angle = eek_section_get_angle (EEK_SECTION(element)); - cairo_save (context->cr); - cairo_translate (context->cr, - bounds.x, - bounds.y); - cairo_rotate (context->cr, angle * M_PI / 180); - eek_container_foreach_child (EEK_CONTAINER(element), - prepare_keyboard_pixmap_key_callback, - context); - cairo_restore (context->cr); -} - -static void -drawing_context_init (DrawingContext *context, - cairo_t *cr, - EekGtkKeyboard *keyboard) -{ - EekGtkKeyboardPrivate *priv = keyboard->priv; - GtkStyle *style; - GtkStateType state; - - context->cr = cr; - context->keyboard = keyboard; - - style = gtk_widget_get_style (priv->widget); - state = gtk_widget_get_state (priv->widget); - context->fg = &style->fg[state]; - context->bg = &style->bg[state]; -} - -static void -prepare_keyboard_surface (EekGtkKeyboard *keyboard) -{ - EekGtkKeyboardPrivate *priv = keyboard->priv; - GtkAllocation allocation; - GtkStyle *style; - GtkStateType state; - DrawingContext context; - cairo_t *cr; - - gtk_widget_get_allocation (priv->widget, &allocation); - priv->keyboard_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - allocation.width, - allocation.height); - - /* blank background */ - cr = cairo_create (priv->keyboard_surface); - cairo_scale (cr, priv->scale, priv->scale); - - style = gtk_widget_get_style (priv->widget); - state = gtk_widget_get_state (priv->widget); - gdk_cairo_set_source_color (cr, &style->base[state]); - - cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); - cairo_fill (cr); - - /* draw sections on the canvas */ - drawing_context_init (&context, cr, keyboard); - eek_container_foreach_child (EEK_CONTAINER(keyboard), - prepare_keyboard_pixmap_section_callback, - &context); - cairo_destroy (cr); -} - -static void -redraw_keyboard (cairo_t *cr, - EekGtkKeyboard *keyboard, - gint x, - gint y, - gint width, - gint height) -{ - EekGtkKeyboardPrivate *priv = - EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - GtkStyle *style; - GtkStateType state; - - style = gtk_widget_get_style (priv->widget); - state = gtk_widget_get_state (priv->widget); - - if (!priv->keyboard_surface) { - PangoFontDescription *base_font; - PangoContext *context; - PangoLayout *layout; - - /* compute font sizes which fit in each key shape */ - context = gtk_widget_get_pango_context (priv->widget); - layout = pango_layout_new (context); - base_font = style->font_desc; - pango_layout_set_font_description (layout, base_font); - eek_get_fonts (EEK_KEYBOARD(keyboard), layout, priv->fonts); - g_object_unref (layout); - - prepare_keyboard_surface (keyboard); - } - g_return_if_fail (priv->keyboard_surface); - - gdk_cairo_set_source_color (cr, &style->fg[state]); - - cairo_set_source_surface (cr, - priv->keyboard_surface, - x, y); - cairo_rectangle (cr, x, y, width, height); - cairo_fill (cr); -} - -#if GTK_CHECK_VERSION (2, 91, 2) -static gboolean -on_draw (GtkWidget *widget, - cairo_t *cr, - gpointer user_data) -{ - EekGtkKeyboard *keyboard = user_data; - EekGtkKeyboardPrivate *priv = - EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - GtkAllocation allocation; - - g_return_val_if_fail (widget == priv->widget, FALSE); - - gtk_widget_get_allocation (priv->widget, &allocation); - - redraw_keyboard (cr, keyboard, 0, 0, allocation.width, allocation.height); - - return TRUE; -} -#else -static gboolean -on_expose_event (GtkWidget *widget, - GdkEventExpose *event, - gpointer user_data) -{ - EekGtkKeyboard *keyboard = user_data; - EekGtkKeyboardPrivate *priv = - EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - cairo_t *cr; - - g_return_val_if_fail (widget == priv->widget, FALSE); - - cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget))); - redraw_keyboard (cr, keyboard, - event->area.x, event->area.y, - event->area.width, event->area.height); - cairo_destroy (cr); - - return TRUE; -} -#endif - -static void -redraw_key (cairo_t *cr, - EekKey *key, - gint key_surface_type, - EekGtkKeyboard *keyboard) -{ - EekGtkKeyboardPrivate *priv = - EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - EekBounds bounds; - EekOutline *outline; - gdouble x, y; - int width, height; - GtkStyle *style; - GtkStateType state; - cairo_surface_t **key_surfaces, *large_surface; - - g_return_if_fail (priv->keyboard_surface); - - outline = eek_key_get_outline (key); - key_surfaces = g_hash_table_lookup (priv->key_surfaces, outline); - g_return_if_fail (key_surfaces); - - large_surface = key_surfaces[KEY_SURFACE_LARGE]; - width = cairo_image_surface_get_width (large_surface); - height = cairo_image_surface_get_height (large_surface); - - eek_element_get_bounds (EEK_ELEMENT(key), &bounds); - eek_element_get_absolute_position (EEK_ELEMENT(key), &x, &y); - - x -= (width - bounds.width) / 2; - y -= (height - bounds.height) / 2; - - style = gtk_widget_get_style (priv->widget); - state = gtk_widget_get_state (priv->widget); - gdk_cairo_set_source_color (cr, &style->fg[state]); - - switch (key_surface_type) { - case KEY_SURFACE_NORMAL: - cairo_set_source_surface (cr, priv->keyboard_surface, 0, 0); - cairo_scale (cr, priv->scale, priv->scale); - cairo_rectangle (cr, x, y, width, height); - cairo_fill (cr); - break; - - case KEY_SURFACE_LARGE: - cairo_scale (cr, priv->scale, priv->scale); - cairo_set_source_surface (cr, large_surface, x, y); - cairo_rectangle (cr, x, y, width, height); - cairo_fill (cr); - - cairo_move_to (cr, x, y); - gdk_cairo_set_source_color (cr, &style->fg[state]); - - cairo_scale (cr, - key_surface_scale[KEY_SURFACE_LARGE], - key_surface_scale[KEY_SURFACE_LARGE]); - eek_draw_key_label (cr, key, priv->fonts); - break; - } -} - -static void -on_key_pressed (EekKey *key, gpointer user_data) -{ - EekGtkKeyboard *keyboard = user_data; - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - cairo_t *cr; - - cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget))); - redraw_key (cr, key, KEY_SURFACE_LARGE, keyboard); - cairo_destroy (cr); - - priv->key = key; -} - -static void -on_key_released (EekKey *key, gpointer user_data) -{ - EekGtkKeyboard *keyboard = user_data; - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - cairo_t *cr; - - if (priv->key) { - cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget))); - redraw_key (cr, priv->key, KEY_SURFACE_NORMAL, keyboard); - cairo_destroy (cr); - priv->key = NULL; - } - cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget))); - redraw_key (cr, key, KEY_SURFACE_NORMAL, keyboard); - cairo_destroy (cr); -} - -static void -press_key (EekGtkKeyboard *keyboard, EekKey *key) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - if (priv->key != key) - g_signal_emit_by_name (key, "pressed", keyboard); -} - -static void -release_key (EekGtkKeyboard *keyboard) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - - if (priv->key) - g_signal_emit_by_name (priv->key, "released", keyboard); -} - -static gboolean -on_key_event (GtkWidget *widget, - GdkEventKey *event, - gpointer user_data) -{ - EekGtkKeyboard *keyboard = user_data; - EekKey *key; - - key = eek_keyboard_find_key_by_keycode (EEK_KEYBOARD(keyboard), - event->hardware_keycode); - if (!key) - return FALSE; - switch (event->type) { - case GDK_KEY_PRESS: - press_key (keyboard, key); - return TRUE; - case GDK_KEY_RELEASE: - release_key (keyboard); - return TRUE; - default: - return FALSE; - } -} - -static gboolean -on_button_event (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data) -{ - EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD(user_data); - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - EekKey *key; - gdouble x, y; - - x = (gdouble)event->x / priv->scale; - y = (gdouble)event->y / priv->scale; - key = eek_keyboard_find_key_by_position (EEK_KEYBOARD(keyboard), x, y); - if (key) - switch (event->type) { - case GDK_BUTTON_PRESS: - press_key (EEK_GTK_KEYBOARD(keyboard), key); - return TRUE; - case GDK_BUTTON_RELEASE: - release_key (EEK_GTK_KEYBOARD(keyboard)); - return TRUE; - default: - return FALSE; - } - return FALSE; -} - -static void -on_size_allocate (GtkWidget *widget, - GtkAllocation *allocation, - gpointer user_data) -{ - EekGtkKeyboard *keyboard = user_data; - EekGtkKeyboardPrivate *priv = - EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); - EekBounds bounds; - - if (priv->keyboard_surface) { - cairo_surface_destroy (priv->keyboard_surface); - priv->keyboard_surface = NULL; - } - g_hash_table_remove_all (priv->key_surfaces); - - eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds); - priv->scale = allocation->width > allocation->height ? - allocation->height / bounds.height : - allocation->width / bounds.width; -} - GtkWidget * -eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard) +eek_gtk_keyboard_new (EekKeyboard *keyboard) { - EekGtkKeyboardPrivate *priv = - EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); + GtkWidget *widget; + EekGtkKeyboardPrivate *priv; - if (!priv->widget) { - priv->widget = gtk_drawing_area_new (); - g_object_ref_sink (priv->widget); + widget = g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL); + priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget); + priv->keyboard = g_object_ref_sink (keyboard); - gtk_widget_set_double_buffered (priv->widget, FALSE); - gtk_widget_set_events (priv->widget, - GDK_EXPOSURE_MASK | - GDK_KEY_PRESS_MASK | - GDK_KEY_RELEASE_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK); -#if GTK_CHECK_VERSION (2, 91, 2) - g_signal_connect (priv->widget, "draw", - G_CALLBACK (on_draw), keyboard); -#else - g_signal_connect (priv->widget, "expose_event", - G_CALLBACK (on_expose_event), keyboard); -#endif - g_signal_connect (priv->widget, "size-allocate", - G_CALLBACK (on_size_allocate), keyboard); - g_signal_connect (priv->widget, "key-press-event", - G_CALLBACK (on_key_event), keyboard); - g_signal_connect (priv->widget, "key-release-event", - G_CALLBACK (on_key_event), keyboard); - g_signal_connect (priv->widget, "button-press-event", - G_CALLBACK (on_button_event), keyboard); - g_signal_connect (priv->widget, "button-release-event", - G_CALLBACK (on_button_event), keyboard); - eek_keyboard_realize (EEK_KEYBOARD(keyboard)); - } - return priv->widget; + g_signal_connect (priv->keyboard, "key-pressed", + G_CALLBACK(on_key_pressed), widget); + g_signal_connect (priv->keyboard, "key-released", + G_CALLBACK(on_key_released), widget); + g_signal_connect (priv->keyboard, "keysym-index-changed", + G_CALLBACK(on_keysym_index_changed), widget); + + return widget; +} + +static EekColor * +color_from_gdk_color (GdkColor *gdk_color) +{ + EekColor *color; + + color = g_slice_new (EekColor); + color->red = gdk_color->red / (gdouble)0xFFFF; + color->green = gdk_color->green / (gdouble)0xFFFF; + color->blue = gdk_color->blue / (gdouble)0xFFFF; + color->alpha = 1.0; + return color; +} + +static void +magnify_bounds (EekBounds *bounds, EekBounds *large_bounds, gdouble scale) +{ + g_assert (scale >= 1.0); + + large_bounds->width = bounds->width * scale; + large_bounds->height = bounds->height * scale; + + large_bounds->x = bounds->x - (large_bounds->width - bounds->width) / 2; + large_bounds->y = bounds->y - (large_bounds->height - bounds->height) / 2; +} + +static void +on_key_pressed (EekKeyboard *keyboard, + EekKey *key, + gpointer user_data) +{ + GtkWidget *widget = user_data; + EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget); + cairo_t *cr; + EekBounds bounds, large_bounds; + + /* renderer may have not been set yet if the widget is a popup */ + if (!priv->renderer) + return; + + cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget))); + + eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE); + magnify_bounds (&bounds, &large_bounds, 1.5); + + cairo_translate (cr, large_bounds.x, large_bounds.y); + eek_renderer_render_key (priv->renderer, cr, key, 1.5); + cairo_destroy (cr); +} + +static void +on_key_released (EekKeyboard *keyboard, + EekKey *key, + gpointer user_data) +{ + GtkWidget *widget = user_data; + EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget); + cairo_t *cr; + EekBounds bounds, large_bounds; + EekColor background; + cairo_path_t *cp; + + /* renderer may have not been set yet if the widget is a popup */ + if (!priv->renderer) + return; + + cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget))); + + eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE); + magnify_bounds (&bounds, &large_bounds, 1.5); + cairo_rectangle (cr, + large_bounds.x, + large_bounds.y, + large_bounds.width, + large_bounds.height); + cp = cairo_copy_path (cr); + cairo_clip (cr); + + eek_renderer_get_background (priv->renderer, &background); + cairo_set_source_rgba (cr, + background.red, + background.green, + background.blue, + background.alpha); + cairo_append_path (cr, cp); + cairo_fill (cr); + eek_renderer_render_keyboard (priv->renderer, cr); + cairo_path_destroy (cp); + cairo_destroy (cr); +} + +static void +on_keysym_index_changed (EekKeyboard *keyboard, + gint group, + gint level, + gpointer user_data) +{ + GtkWidget *widget = user_data; + EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget); + cairo_t *cr; + + cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget))); + g_signal_emit_by_name (widget, "draw", cr); + cairo_destroy (cr); + + /* redraw dragged key */ + if (priv->dragged_key) { + guint keysym; + + keysym = eek_key_get_keysym (priv->dragged_key); + on_key_pressed (keyboard, priv->dragged_key, NULL); + } } diff --git a/eek/eek-gtk-keyboard.h b/eek/eek-gtk-keyboard.h index 0ac3a469..78924fbc 100644 --- a/eek/eek-gtk-keyboard.h +++ b/eek/eek-gtk-keyboard.h @@ -22,6 +22,7 @@ #include #include + #include "eek-keyboard.h" G_BEGIN_DECLS @@ -39,7 +40,7 @@ typedef struct _EekGtkKeyboardPrivate EekGtkKeyboardPrivate; struct _EekGtkKeyboard { /*< private >*/ - EekKeyboard parent; + GtkDrawingArea parent; EekGtkKeyboardPrivate *priv; }; @@ -47,16 +48,15 @@ struct _EekGtkKeyboard struct _EekGtkKeyboardClass { /*< private >*/ - EekKeyboardClass parent_class; + GtkDrawingAreaClass parent_class; /*< private >*/ /* padding */ gpointer pdummy[24]; }; -GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST; -EekKeyboard *eek_gtk_keyboard_new (void); -GtkWidget *eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard); +GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST; +GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard); G_END_DECLS #endif /* EEK_GTK_KEYBOARD_H */ diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index 589d7ee9..191be519 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -63,7 +63,6 @@ struct _EekKeyboardPrivate gint group; gint level; EekLayout *layout; - gboolean is_realized; }; struct _SetKeysymIndexCallbackData { @@ -161,44 +160,6 @@ eek_keyboard_real_create_section (EekKeyboard *self) return section; } -static void -on_group_changed (EekLayout *layout, - gint new_group, - gpointer user_data) -{ - EekKeyboard *keyboard = user_data; - gint group, level; - - eek_keyboard_get_keysym_index (keyboard, &group, &level); - eek_keyboard_set_keysym_index (keyboard, new_group, level); -} - -static void -eek_keyboard_real_set_layout (EekKeyboard *self, - EekLayout *layout) -{ - EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); - - g_return_if_fail (EEK_IS_LAYOUT(layout)); - priv->layout = layout; - g_object_ref_sink (priv->layout); - g_signal_connect (priv->layout, "group-changed", - G_CALLBACK(on_group_changed), self); -} - -static void -eek_keyboard_real_realize (EekKeyboard *self) -{ - EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); - - g_return_if_fail (priv->layout); - g_return_if_fail (!priv->is_realized); - EEK_LAYOUT_GET_IFACE(priv->layout)->apply (priv->layout, self); - /* apply the initial group setting */ - on_group_changed (priv->layout, eek_layout_get_group (priv->layout), self); - priv->is_realized = TRUE; -} - struct _FindKeyByKeycodeCallbackData { EekKey *key; guint keycode; @@ -231,18 +192,6 @@ eek_keyboard_real_find_key_by_keycode (EekKeyboard *self, return NULL; } -static void -eek_keyboard_dispose (GObject *object) -{ - EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object); - - if (priv->layout) { - g_object_unref (priv->layout); - priv->layout = NULL; - } - G_OBJECT_CLASS(eek_keyboard_parent_class)->dispose (object); -} - static void eek_keyboard_set_property (GObject *object, guint prop_id, @@ -299,6 +248,14 @@ eek_keyboard_get_property (GObject *object, } } +static void +eek_keyboard_real_keysym_index_changed (EekKeyboard *self, + gint group, + gint level) +{ + /* g_debug ("keysym-index-changed"); */ +} + static void eek_keyboard_class_init (EekKeyboardClass *klass) { @@ -311,13 +268,12 @@ eek_keyboard_class_init (EekKeyboardClass *klass) klass->set_keysym_index = eek_keyboard_real_set_keysym_index; klass->get_keysym_index = eek_keyboard_real_get_keysym_index; klass->create_section = eek_keyboard_real_create_section; - klass->set_layout = eek_keyboard_real_set_layout; - klass->realize = eek_keyboard_real_realize; klass->find_key_by_keycode = eek_keyboard_real_find_key_by_keycode; + klass->keysym_index_changed = eek_keyboard_real_keysym_index_changed; + gobject_class->get_property = eek_keyboard_get_property; gobject_class->set_property = eek_keyboard_set_property; - gobject_class->dispose = eek_keyboard_dispose; /** * EekKeyboard:group: @@ -399,8 +355,8 @@ eek_keyboard_class_init (EekKeyboardClass *klass) signals[KEYSYM_INDEX_CHANGED] = g_signal_new ("keysym-index-changed", G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_FIRST, - 0, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(EekKeyboardClass, keysym_index_changed), NULL, NULL, _eek_marshal_VOID__INT_INT, @@ -418,7 +374,6 @@ eek_keyboard_init (EekKeyboard *self) priv = self->priv = EEK_KEYBOARD_GET_PRIVATE(self); priv->group = priv->level = 0; priv->layout = NULL; - priv->is_realized = FALSE; } /** @@ -474,29 +429,6 @@ eek_keyboard_create_section (EekKeyboard *keyboard) return section; } -/** - * eek_keyboard_set_layout: - * @keyboard: an #EekKeyboard - * @layout: an #EekLayout - * - * Set the layout of @keyboard to @layout. This actually turns - * @keyboard to be ready to be drawn on the screen. - */ -void -eek_keyboard_set_layout (EekKeyboard *keyboard, - EekLayout *layout) -{ - g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); - EEK_KEYBOARD_GET_CLASS(keyboard)->set_layout (keyboard, layout); -} - -void -eek_keyboard_realize (EekKeyboard *keyboard) -{ - g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); - EEK_KEYBOARD_GET_CLASS(keyboard)->realize (keyboard); -} - /** * eek_keyboard_find_key_by_keycode: * @keyboard: an #EekKeyboard @@ -514,65 +446,21 @@ eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, keycode); } -struct _FindKeyByPositionCallbackData { - gdouble x; - gdouble y; - EekKey *key; -}; -typedef struct _FindKeyByPositionCallbackData FindKeyByPositionCallbackData; - -static gboolean -section_includes_point (EekSection *section, EekPoint *point) +EekKeyboard * +eek_keyboard_new (EekLayout *layout, + gint preferred_width, + gint preferred_height) { - gint angle; - EekBounds bounds; - EekPoint rotated; - - eek_element_get_bounds (EEK_ELEMENT(section), &bounds); - rotated.x = point->x - bounds.x; - rotated.y = point->y - bounds.y; - angle = eek_section_get_angle (EEK_SECTION(section)); - eek_point_rotate (&rotated, -angle); - - if (0 <= rotated.x && 0 <= rotated.y && - rotated.x <= bounds.width && - rotated.y <= bounds.height) - return TRUE; - return FALSE; -} - -static void -find_key_by_position_section_callback (EekElement *element, - gpointer user_data) -{ - FindKeyByPositionCallbackData *data = user_data; - EekPoint point; - - if (!data->key) { - point.x = data->x; - point.y = data->y; - if (section_includes_point (EEK_SECTION(element), &point)) - data->key = eek_section_find_key_by_position (EEK_SECTION(element), - point.x, - point.y); - } -} - -EekKey * -eek_keyboard_find_key_by_position (EekKeyboard *keyboard, - gdouble x, - gdouble y) -{ - FindKeyByPositionCallbackData data; + EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL); EekBounds bounds; - eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds); - data.x = x - bounds.x; - data.y = y - bounds.y; - data.key = NULL; - /* eek_container_find() cannot be used here since sections may overlap. */ - eek_container_foreach_child (EEK_CONTAINER(keyboard), - find_key_by_position_section_callback, - &data); - return data.key; + g_return_val_if_fail (EEK_IS_LAYOUT (layout), NULL); + + bounds.x = bounds.y = 0.0; + bounds.width = preferred_width; + bounds.height = preferred_height; + eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds); + eek_layout_apply (layout, keyboard); + + return keyboard; } diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h index 7f9ce8c6..2787b1eb 100644 --- a/eek/eek-keyboard.h +++ b/eek/eek-keyboard.h @@ -63,45 +63,44 @@ struct _EekKeyboardClass EekContainerClass parent_class; /*< public >*/ - void (* set_keysym_index) (EekKeyboard *self, - gint group, - gint level); - void (* get_keysym_index) (EekKeyboard *self, - gint *group, - gint *level); + void (* set_keysym_index) (EekKeyboard *self, + gint group, + gint level); + void (* get_keysym_index) (EekKeyboard *self, + gint *group, + gint *level); - EekSection *(* create_section) (EekKeyboard *self); + EekSection *(* create_section) (EekKeyboard *self); - void (* set_layout) (EekKeyboard *self, - EekLayout *layout); - EekKey *(* find_key_by_keycode) (EekKeyboard *self, - guint keycode); - void (* realize) (EekKeyboard *self); + EekKey *(* find_key_by_keycode) (EekKeyboard *self, + guint keycode); + + /* signals */ + void (* keysym_index_changed) (EekKeyboard *self, + gint group, + gint level); /*< private >*/ /* padding */ - gpointer pdummy[24]; + gpointer pdummy[23]; }; -GType eek_keyboard_get_type (void) G_GNUC_CONST; +GType eek_keyboard_get_type (void) G_GNUC_CONST; -void eek_keyboard_set_keysym_index (EekKeyboard *keyboard, - gint group, - gint level); -void eek_keyboard_get_keysym_index (EekKeyboard *keyboard, - gint *group, - gint *level); +EekKeyboard *eek_keyboard_new (EekLayout *layout, + gint preferred_width, + gint preferred_height); +void eek_keyboard_set_keysym_index (EekKeyboard *keyboard, + gint group, + gint level); +void eek_keyboard_get_keysym_index (EekKeyboard *keyboard, + gint *group, + gint *level); -EekSection *eek_keyboard_create_section (EekKeyboard *keyboard); +EekSection *eek_keyboard_create_section (EekKeyboard *keyboard); -void eek_keyboard_set_layout (EekKeyboard *keyboard, - EekLayout *layout); -void eek_keyboard_realize (EekKeyboard *keyboard); -EekKey *eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, - guint keycode); -EekKey *eek_keyboard_find_key_by_position (EekKeyboard *keyboard, - gdouble x, - gdouble y); +EekKey *eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, + guint keycode); G_END_DECLS #endif /* EEK_KEYBOARD_H */ diff --git a/eek/eek-layout.c b/eek/eek-layout.c index 126bb852..99c0f433 100644 --- a/eek/eek-layout.c +++ b/eek/eek-layout.c @@ -108,15 +108,15 @@ eek_layout_get_type (void) * @layout: an #EekLayout * @keyboard: an #EekKeyboard * - * Apply @layout to @keyboard. This function is rarely called by user - * programs but called by the subclasses of #EekKeyboard. + * Relayout @keyboard with the @layout. */ void -eek_layout_apply (EekLayout *layout, - EekKeyboard *keyboard) +eek_layout_apply (EekLayout *layout, EekKeyboard *keyboard) { g_return_if_fail (EEK_IS_LAYOUT(layout)); - EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard); + g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); + + return EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard); } /** diff --git a/eek/eek-section.c b/eek/eek-section.c index d78502e6..7788a3a9 100644 --- a/eek/eek-section.c +++ b/eek/eek-section.c @@ -438,26 +438,3 @@ eek_section_find_key_by_keycode (EekSection *section, return EEK_SECTION_GET_CLASS(section)->find_key_by_keycode (section, keycode); } - -EekKey * -eek_section_find_key_by_position (EekSection *section, - gdouble x, - gdouble y) -{ - gint angle; - EekBounds bounds; - EekPoint point; - EekElement *key; - - eek_element_get_bounds (EEK_ELEMENT(section), &bounds); - point.x = x - bounds.x; - point.y = y - bounds.y; - angle = eek_section_get_angle (section); - eek_point_rotate (&point, -angle); - key = eek_container_find_by_position (EEK_CONTAINER(section), - point.x + bounds.x, - point.y + bounds.y); - if (!key) - return NULL; - return EEK_KEY(key); -} diff --git a/eek/eek-section.h b/eek/eek-section.h index 9b990185..76a0e1c7 100644 --- a/eek/eek-section.h +++ b/eek/eek-section.h @@ -107,9 +107,6 @@ EekKey *eek_section_create_key (EekSection *section, EekKey *eek_section_find_key_by_keycode (EekSection *section, guint keycode); -EekKey *eek_section_find_key_by_position (EekSection *section, - gdouble x, - gdouble y); G_END_DECLS #endif /* EEK_SECTION_H */ diff --git a/eek/eek-xkb-layout.c b/eek/eek-xkb-layout.c index 77efdd49..dce006c2 100644 --- a/eek/eek-xkb-layout.c +++ b/eek/eek-xkb-layout.c @@ -325,6 +325,7 @@ eek_xkb_layout_real_apply (EekLayout *layout, EekKeyboard *keyboard) g_direct_equal, NULL, outline_free); + create_keyboard (EEK_XKB_LAYOUT(layout), keyboard); } diff --git a/src/eekboard.c b/src/eekboard.c index 742dc76b..f5608697 100644 --- a/src/eekboard.c +++ b/src/eekboard.c @@ -20,13 +20,6 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ -#if HAVE_CLUTTER_GTK -#include -#if NEED_SWAP_EVENT_WORKAROUND -#include -#endif -#endif - #include #include #include @@ -40,22 +33,12 @@ #include #include -#if HAVE_CLUTTER_GTK -#include "eek/eek-clutter.h" -#endif - #include "eek/eek-gtk.h" #include "eek/eek-xkl.h" #define CSW 640 #define CSH 480 -#if HAVE_CLUTTER_GTK -#define USE_CLUTTER TRUE -#else -#define USE_CLUTTER FALSE -#endif - #ifdef EEKBOARD_ENABLE_DEBUG #define EEKBOARD_NOTE(x,a...) g_message (G_STRLOC ": " x, ##a); #else @@ -83,8 +66,6 @@ struct _Config { typedef struct _Config Config; struct _Eekboard { - gboolean use_clutter; - gboolean need_swap_event_workaround; gboolean accessibility_enabled; Config **config; gint active_config; @@ -157,13 +138,6 @@ static void eekboard_free (Eekboard *eekboard); static GtkWidget *create_widget (Eekboard *eekboard, gint initial_width, gint initial_height); -static GtkWidget *create_widget_gtk (Eekboard *eekboard, - gint initial_width, - gint initial_height); - -#if !HAVE_CLUTTER_GTK -#define create_widget create_widget_gtk -#endif static const char ui_description[] = "" @@ -226,9 +200,6 @@ static gboolean opt_list_models = FALSE; static gboolean opt_list_layouts = FALSE; static gboolean opt_list_options = FALSE; static gboolean opt_version = FALSE; -#if HAVE_CLUTTER_GTK -static gchar *opt_toolkit = NULL; -#endif static gboolean opt_popup = FALSE; static gchar *opt_config = NULL; static gboolean opt_fullscreen = FALSE; @@ -246,10 +217,6 @@ static const GOptionEntry options[] = { N_("List all available keyboard layouts and variants")}, {"list-options", 'O', 0, G_OPTION_ARG_NONE, &opt_list_options, N_("List all available keyboard layout options")}, -#if HAVE_CLUTTER_GTK - {"toolkit", 't', 0, G_OPTION_ARG_STRING, &opt_toolkit, - N_("Toolkit (\"clutter\" or \"gtk\")")}, -#endif {"popup", 'p', 0, G_OPTION_ARG_NONE, &opt_popup, N_("Start as a popup window")}, {"fullscreen", 'f', 0, G_OPTION_ARG_NONE, &opt_fullscreen, @@ -467,7 +434,7 @@ on_key_pressed (EekKeyboard *keyboard, switch (keysym) { case XK_Shift_L: case XK_Shift_R: - eekboard->modifiers |= ShiftMask; + eekboard->modifiers ^= ShiftMask; eek_keyboard_get_keysym_index (keyboard, &group, &level); eek_keyboard_set_keysym_index (keyboard, group, (eekboard->modifiers & Mod5Mask) ? 2 : @@ -475,7 +442,7 @@ on_key_pressed (EekKeyboard *keyboard, 0); break; case XK_ISO_Level3_Shift: - eekboard->modifiers |= Mod5Mask; + eekboard->modifiers ^= Mod5Mask; eek_keyboard_get_keysym_index (keyboard, &group, &level); eek_keyboard_set_keysym_index (keyboard, group, (eekboard->modifiers & Mod5Mask) ? 2 : @@ -484,11 +451,11 @@ on_key_pressed (EekKeyboard *keyboard, break; case XK_Control_L: case XK_Control_R: - eekboard->modifiers |= ControlMask; + eekboard->modifiers ^= ControlMask; break; case XK_Alt_L: case XK_Alt_R: - eekboard->modifiers |= Mod1Mask; + eekboard->modifiers ^= Mod1Mask; break; default: fakekey_press_keysym (eekboard->fakekey, keysym, eekboard->modifiers); @@ -1058,110 +1025,29 @@ create_menus (Eekboard *eekboard, -1); } -static GtkWidget * -create_widget_gtk (Eekboard *eekboard, - gint initial_width, - gint initial_height) -{ - EekBounds bounds; - - bounds.x = bounds.y = 0; - bounds.width = initial_width; - bounds.height = initial_height; - - eekboard->keyboard = eek_gtk_keyboard_new (); - eek_keyboard_set_layout (eekboard->keyboard, eekboard->layout); - eek_element_set_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds); - eekboard->on_key_pressed_id = - g_signal_connect (eekboard->keyboard, "key-pressed", - G_CALLBACK(on_key_pressed), eekboard); - eekboard->on_key_released_id = - g_signal_connect (eekboard->keyboard, "key-released", - G_CALLBACK(on_key_released), eekboard); - - eekboard->widget = - eek_gtk_keyboard_get_widget (EEK_GTK_KEYBOARD (eekboard->keyboard)); - eek_element_get_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds); - eekboard->width = bounds.width; - eekboard->height = bounds.height; - return eekboard->widget; -} - -#if HAVE_CLUTTER_GTK -#if NEED_SWAP_EVENT_WORKAROUND -static GdkFilterReturn -gtk_clutter_filter_func (GdkXEvent *native_event, - GdkEvent *event, - gpointer user_data) -{ - XEvent *xevent = native_event; - - clutter_x11_handle_event (xevent); - - return GDK_FILTER_CONTINUE; -} - -static void -on_gtk_clutter_embed_realize (GtkWidget *widget, gpointer user_data) -{ - gdk_window_add_filter (NULL, gtk_clutter_filter_func, widget); -} -#endif - -static GtkWidget * -create_widget_clutter (Eekboard *eekboard, - gint initial_width, - gint initial_height) -{ - ClutterActor *stage, *actor; - ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff }; - EekBounds bounds; - - bounds.x = bounds.y = 0; - bounds.width = initial_width; - bounds.height = initial_height; - - eekboard->keyboard = eek_clutter_keyboard_new (); - eek_keyboard_set_layout (eekboard->keyboard, eekboard->layout); - eek_element_set_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds); - eekboard->on_key_pressed_id = - g_signal_connect (eekboard->keyboard, "key-pressed", - G_CALLBACK(on_key_pressed), eekboard); - eekboard->on_key_released_id = - g_signal_connect (eekboard->keyboard, "key-released", - G_CALLBACK(on_key_released), eekboard); - - eekboard->widget = gtk_clutter_embed_new (); -#if NEED_SWAP_EVENT_WORKAROUND - if (eekboard->need_swap_event_workaround) - g_signal_connect (eekboard->widget, "realize", - G_CALLBACK(on_gtk_clutter_embed_realize), NULL); -#endif - stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(eekboard->widget)); - clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - - actor = eek_clutter_keyboard_get_actor - (EEK_CLUTTER_KEYBOARD(eekboard->keyboard)); - clutter_container_add_actor (CLUTTER_CONTAINER(stage), actor); - eek_element_get_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds); - clutter_actor_set_size (stage, bounds.width, bounds.height); - eekboard->width = bounds.width; - eekboard->height = bounds.height; - return eekboard->widget; -} - static GtkWidget * create_widget (Eekboard *eekboard, - gint initial_width, - gint initial_height) + gint initial_width, + gint initial_height) { - if (eekboard->use_clutter) - return create_widget_clutter (eekboard, initial_width, initial_height); - else - return create_widget_gtk (eekboard, initial_width, initial_height); + EekBounds bounds; + + eekboard->keyboard = eek_keyboard_new (eekboard->layout, + initial_width, + initial_height); + eekboard->on_key_pressed_id = + g_signal_connect (eekboard->keyboard, "key-pressed", + G_CALLBACK(on_key_pressed), eekboard); + eekboard->on_key_released_id = + g_signal_connect (eekboard->keyboard, "key-released", + G_CALLBACK(on_key_released), eekboard); + + eekboard->widget = eek_gtk_keyboard_new (eekboard->keyboard); + eek_element_get_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds); + eekboard->width = bounds.width; + eekboard->height = bounds.height; + return eekboard->widget; } -#endif static void parse_layouts (XklConfigRec *rec, const gchar *_layouts) @@ -1220,15 +1106,11 @@ on_xkl_state_changed (XklEngine *xklengine, } Eekboard * -eekboard_new (gboolean use_clutter, - gboolean need_swap_event_workaround, - gboolean accessibility_enabled) +eekboard_new (gboolean accessibility_enabled) { Eekboard *eekboard; eekboard = g_slice_new0 (Eekboard); - eekboard->use_clutter = use_clutter; - eekboard->need_swap_event_workaround = need_swap_event_workaround; eekboard->accessibility_enabled = accessibility_enabled; eekboard->active_config = -1; eekboard->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); @@ -1508,9 +1390,6 @@ GMarkupParser config_parser = { int main (int argc, char *argv[]) { - const gchar *env; - gboolean use_clutter = USE_CLUTTER; - gboolean need_swap_event_workaround = FALSE; gboolean accessibility_enabled = FALSE; Eekboard *eekboard; GtkWidget *widget, *vbox, *menubar, *window, *combo = NULL; @@ -1547,44 +1426,12 @@ main (int argc, char *argv[]) g_warning("AT-SPI initialization failed"); } - env = g_getenv ("EEKBOARD_DISABLE_CLUTTER"); - if (env && g_strcmp0 (env, "1") == 0) - use_clutter = FALSE; - -#if HAVE_CLUTTER_GTK - if (opt_toolkit) { - if (g_strcmp0 (opt_toolkit, "clutter") == 0) - use_clutter = TRUE; - else if (g_strcmp0 (opt_toolkit, "gtk") == 0) - use_clutter = FALSE; - else { - g_print ("Invalid toolkit \"%s\"\n", opt_toolkit); - exit (0); - } - } - - if (use_clutter && - gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) { - g_warning ("Can't init Clutter-Gtk...fallback to GTK"); - use_clutter = FALSE; - } -#ifdef NEED_SWAP_EVENT_WORKAROUND - if (use_clutter && - clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS)) { - g_warning ("Enabling GLX_INTEL_swap_event workaround for Clutter-Gtk"); - need_swap_event_workaround = TRUE; - } -#endif -#endif - - if (!use_clutter && !gtk_init_check (&argc, &argv)) { + if (!gtk_init_check (&argc, &argv)) { g_warning ("Can't init GTK"); exit (1); } - eekboard = eekboard_new (use_clutter, - need_swap_event_workaround, - accessibility_enabled); + eekboard = eekboard_new (accessibility_enabled); if (opt_list_models) { xkl_config_registry_foreach_model (eekboard->registry, print_item,