Commit 432e4fe1 authored by Dorota Czaplejewicz's avatar Dorota Czaplejewicz
Browse files

Merge branch 'drop_key' into 'master'

Simplify renderer

See merge request Librem5/squeekboard!272
parents 6afa2133 1f69787f
......@@ -324,6 +324,9 @@ name = "rs"
version = "0.1.0"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
......
......@@ -11,6 +11,15 @@ serde = { version = "1.0.*", features = ["derive"] }
serde_yaml = "0.8.*"
xkbcommon = { version = "0.4.*", features = ["wayland"] }
[dependencies.cairo-rs]
version = "0.5.*"
[dependencies.cairo-sys-rs]
version = ""
[dependencies.gdk]
version = ""
[dependencies.gio]
version = ""
features = ["v2_44"]
......@@ -23,7 +32,6 @@ features = ["v2_44"]
version = ""
features = ["v2_44"]
[dependencies.gtk]
version = "0.5.*"
features = ["v3_22"]
......
......@@ -61,10 +61,6 @@ typedef struct _EekGtkKeyboardPrivate
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
static void render_pressed_button (GtkWidget *widget, struct button_place *place);
static void render_released_button (GtkWidget *widget,
const struct squeek_button *button);
static void
eek_gtk_keyboard_real_realize (GtkWidget *self)
{
......@@ -85,7 +81,7 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
cairo_t *cr)
{
EekGtkKeyboardPrivate *priv =
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
GtkAllocation allocation;
gtk_widget_get_allocation (self, &allocation);
......@@ -101,10 +97,7 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
gtk_widget_get_scale_factor (self));
}
// render the keyboard without any key activity (TODO: from a cached buffer)
eek_renderer_render_keyboard (priv->renderer, cr);
// render only a few remaining changes
squeek_layout_draw_all_changed(priv->keyboard->layout, EEK_GTK_KEYBOARD(self));
return FALSE;
}
......@@ -113,7 +106,7 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
GtkAllocation *allocation)
{
EekGtkKeyboardPrivate *priv =
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
if (priv->renderer)
eek_renderer_set_allocation_size (priv->renderer,
......@@ -158,8 +151,6 @@ eek_gtk_keyboard_real_button_press_event (GtkWidget *self,
return TRUE;
}
// TODO: this belongs more in gtk_keyboard, with a way to find out which key to re-render
static gboolean
eek_gtk_keyboard_real_button_release_event (GtkWidget *self,
......@@ -231,7 +222,7 @@ static void
eek_gtk_keyboard_real_unmap (GtkWidget *self)
{
EekGtkKeyboardPrivate *priv =
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
if (priv->keyboard) {
squeek_layout_release_all_only(
......@@ -248,6 +239,7 @@ eek_gtk_keyboard_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
(void)value;
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -304,7 +296,9 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
static void
eek_gtk_keyboard_init (EekGtkKeyboard *self)
{}
{
(void)self;
}
/**
* eek_gtk_keyboard_new:
......@@ -322,110 +316,7 @@ eek_gtk_keyboard_new (LevelKeyboard *keyboard)
return GTK_WIDGET(ret);
}
static void
render_pressed_button (GtkWidget *widget,
struct button_place *place)
{
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
GdkWindow *window = gtk_widget_get_window (widget);
cairo_region_t *region = gdk_window_get_clip_region (window);
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
/*
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
*/
gdk_window_end_draw_frame (window, context);
cairo_region_destroy (region);
}
void
eek_gtk_render_locked_button (EekGtkKeyboard *self, struct button_place place)
{
EekRenderer *eek_gtk_keyboard_get_renderer(EekGtkKeyboard *self) {
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
GdkWindow *window = gtk_widget_get_window (GTK_WIDGET(self));
cairo_region_t *region = gdk_window_get_clip_region (window);
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
eek_renderer_render_button (priv->renderer, cr, &place, 1.0, TRUE);
gdk_window_end_draw_frame (window, context);
cairo_region_destroy (region);
}
// TODO: does it really redraw the entire keyboard?
static void
render_released_button (GtkWidget *widget,
const struct squeek_button *button)
{
(void)button;
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
GdkWindow *window = gtk_widget_get_window (widget);
cairo_region_t *region = gdk_window_get_clip_region (window);
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
eek_renderer_render_keyboard (priv->renderer, cr);
gdk_window_end_draw_frame (window, context);
cairo_region_destroy (region);
}
void
eek_gtk_on_button_pressed (struct button_place place,
EekGtkKeyboard *self)
{
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
/* renderer may have not been set yet if the widget is a popup */
if (!priv->renderer)
return;
if (!place.row) {
return;
}
render_pressed_button (GTK_WIDGET(self), &place);
gtk_widget_queue_draw (GTK_WIDGET(self));
#if HAVE_LIBCANBERRA
ca_gtk_play_for_widget (widget, 0,
CA_PROP_EVENT_ID, "button-pressed",
CA_PROP_EVENT_DESCRIPTION, "virtual key pressed",
CA_PROP_APPLICATION_ID, "org.fedorahosted.Eekboard",
NULL);
#endif
}
void
eek_gtk_on_button_released (const struct squeek_button *button,
struct squeek_view *view,
EekGtkKeyboard *self)
{
(void)view;
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
/* renderer may have not been set yet if the widget is a popup */
if (!priv->renderer)
return;
render_released_button (GTK_WIDGET(self), button);
gtk_widget_queue_draw (GTK_WIDGET(self));
#if HAVE_LIBCANBERRA
ca_gtk_play_for_widget (widget, 0,
CA_PROP_EVENT_ID, "button-released",
CA_PROP_EVENT_DESCRIPTION, "virtual key pressed",
CA_PROP_APPLICATION_ID, "org.fedorahosted.Eekboard",
NULL);
#endif
return priv->renderer;
}
......@@ -34,8 +34,6 @@
#include "eekboard/eekboard-context-service.h"
#include "eekboard/key-emitter.h"
#include "keymap.h"
#include "src/keyboard.h"
#include "eek-keyboard.h"
void level_keyboard_deinit(LevelKeyboard *self) {
......@@ -59,8 +57,3 @@ LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek
keyboard->manager = manager;
return keyboard;
}
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard)
{
return squeek_layout_get_current_view(keyboard->layout);
}
......@@ -49,7 +49,6 @@ typedef struct _LevelKeyboard LevelKeyboard;
gchar * eek_keyboard_get_keymap
(LevelKeyboard *keyboard);
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard);
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_layout *layout);
void level_keyboard_deinit(LevelKeyboard *self);
void level_keyboard_free(LevelKeyboard *self);
......
This diff is collapsed.
......@@ -25,7 +25,6 @@
#include <pango/pangocairo.h>
#include "eek-types.h"
#include "src/layout.h"
G_BEGIN_DECLS
......@@ -36,15 +35,6 @@ struct _EekRendererClass
{
GObjectClass parent_class;
void (* render_button) (EekRenderer *self,
cairo_t *cr,
struct button_place *place,
gdouble scale,
gboolean rotate);
void (* render_keyboard) (EekRenderer *self,
cairo_t *cr);
cairo_surface_t *(* get_icon_surface) (EekRenderer *self,
const gchar *icon_name,
gint size,
......@@ -62,38 +52,15 @@ void eek_renderer_set_allocation_size
(EekRenderer *renderer,
gdouble width,
gdouble height);
void eek_renderer_get_size (EekRenderer *renderer,
gdouble *width,
gdouble *height);
void eek_renderer_get_button_bounds (EekBounds view_bounds,
struct button_place *button,
EekBounds *bounds,
gboolean rotate);
gdouble eek_renderer_get_scale (EekRenderer *renderer);
void eek_renderer_set_scale_factor (EekRenderer *renderer,
gint scale);
void eek_renderer_render_button (EekRenderer *renderer,
cairo_t *cr,
struct button_place *place,
gdouble scale,
gboolean rotate);
cairo_surface_t *eek_renderer_get_icon_surface(const gchar *icon_name,
gint size,
gint scale);
void eek_renderer_render_keyboard (EekRenderer *renderer,
cairo_t *cr);
void eek_renderer_set_border_width (EekRenderer *renderer,
gdouble border_width);
void eek_renderer_apply_transformation_for_button
(cairo_t *cr,
EekBounds view_bounds,
struct button_place *place,
gdouble scale,
gboolean rotate);
struct transformation
eek_renderer_get_transformation (EekRenderer *renderer);
......
......@@ -88,5 +88,14 @@ struct transformation {
gdouble origin_y;
gdouble scale;
};
struct squeek_button;
struct squeek_row;
/// Represents the path to the button within a view
struct button_place {
const struct squeek_row *row;
const struct squeek_button *button;
};
G_END_DECLS
#endif /* EEK_TYPES_H */
......@@ -24,7 +24,6 @@
#include "config.h"
#include "eek-keyboard.h"
#include "src/keyboard.h"
#include "src/layout.h"
#include "eek-xml-layout.h"
......
......@@ -405,7 +405,7 @@ impl Layout {
let views = HashMap::from_iter(
self.views.iter().map(|(name, view)| {(
name.clone(),
Box::new(::layout::View {
::layout::View {
bounds: ::layout::c::Bounds {
x: self.bounds.x,
y: self.bounds.y,
......@@ -413,7 +413,7 @@ impl Layout {
height: self.bounds.height,
},
rows: view.iter().map(|row| {
Box::new(::layout::Row {
::layout::Row {
angle: 0,
bounds: None,
buttons: row.split_ascii_whitespace().map(|name| {
......@@ -427,9 +427,9 @@ impl Layout {
&mut warning_handler,
))
}).collect(),
})
}
}).collect(),
})
}
)})
);
......
/*! Drawing the UI */
use cairo;
use std::cell::RefCell;
use ::keyboard;
use ::layout::{ Button, Layout };
use ::layout::c::{ EekGtkKeyboard, Point };
use glib::translate::FromGlibPtrNone;
use gtk::WidgetExt;
mod c {
use super::*;
use cairo_sys;
use std::os::raw::c_void;
// This is constructed only in C, no need for warnings
#[allow(dead_code)]
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct EekRenderer(*const c_void);
#[no_mangle]
extern "C" {
// Button and View inside CButtonPlace are safe to pass to C
// as long as they don't outlive the call
// and nothing dereferences them
#[allow(improper_ctypes)]
pub fn eek_render_button(
renderer: EekRenderer,
cr: *mut cairo_sys::cairo_t,
button: *const Button,
pressed: u64,
locked: u64,
);
}
#[no_mangle]
pub extern "C"
fn squeek_layout_draw_all_changed(
layout: *mut Layout,
renderer: EekRenderer,
cr: *mut cairo_sys::cairo_t,
) {
let layout = unsafe { &mut *layout };
let cr = unsafe { cairo::Context::from_raw_none(cr) };
let view = layout.get_current_view();
let view_position = view.bounds.get_position();
for row in &view.rows {
for button in &row.buttons {
let state = RefCell::borrow(&button.state).clone();
if state.pressed == keyboard::PressType::Pressed || state.locked {
let position = &view_position
+ row.bounds.clone().unwrap().get_position()
+ button.bounds.get_position();
render_button_at_position(
renderer, &cr,
position, button.as_ref(),
state.pressed, state.locked,
);
}
}
}
}
#[no_mangle]
pub extern "C"
fn squeek_draw_layout_base_view(
layout: *mut Layout,
renderer: EekRenderer,
cr: *mut cairo_sys::cairo_t,
) {
let layout = unsafe { &mut *layout };
let cr = unsafe { cairo::Context::from_raw_none(cr) };
let view = layout.get_current_view();
let view_position = view.bounds.get_position();
for row in &view.rows {
for button in &row.buttons {
let position = &view_position
+ row.bounds.clone().unwrap().get_position()
+ button.bounds.get_position();
render_button_at_position(
renderer, &cr,
position, button.as_ref(),
keyboard::PressType::Released, false,
);
}
}
}
}
/// Renders a button at a position (button's own bounds ignored)
pub fn render_button_at_position(
renderer: c::EekRenderer,
cr: &cairo::Context,
position: Point,
button: &Button,
pressed: keyboard::PressType,
locked: bool,
) {
cr.save();
cr.translate(position.x, position.y);
cr.rectangle(
0.0, 0.0,
button.bounds.width, button.bounds.height
);
cr.clip();
unsafe {
c::eek_render_button(
renderer,
cairo::Context::to_raw_none(&cr),
button as *const Button,
pressed as u64,
locked as u64,
)
};
cr.restore();
}
pub fn queue_redraw(keyboard: EekGtkKeyboard) {
let widget = unsafe { gtk::Widget::from_glib_none(keyboard.0) };
widget.queue_draw();
}
#ifndef __KEYBOARD_H
#define __KEYBOARD_H
#include "inttypes.h"
#include "stdbool.h"
#include "virtual-keyboard-unstable-v1-client-protocol.h"
struct squeek_key;
uint32_t squeek_key_is_pressed(struct squeek_key *key);
uint32_t squeek_key_is_locked(struct squeek_key *key);
#endif
......@@ -10,32 +10,8 @@ use ::action::Action;
use std::io::Write;
use std::iter::{ FromIterator, IntoIterator };
use ::util::CloneOwned;
/// Gathers stuff defined in C or called by C
pub mod c {
use super::*;
use ::util::c;
pub type CKeyState = c::Wrapped<KeyState>;
// The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
#[no_mangle]
pub extern "C"
fn squeek_key_is_pressed(key: CKeyState) -> u32 {
//let key = unsafe { Rc::from_raw(key.0) };
return key.clone_owned().pressed as u32;
}
#[no_mangle]
pub extern "C"
fn squeek_key_is_locked(key: CKeyState) -> u32 {
return key.clone_owned().locked as u32;
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PressType {
Released = 0,
Pressed = 1,
......
......@@ -5,8 +5,8 @@
#include <glib.h>
#include "eek/eek-element.h"
#include "eek/eek-gtk-keyboard.h"
#include "eek/eek-renderer.h"
#include "eek/eek-types.h"
#include "src/keyboard.h"
#include "virtual-keyboard-unstable-v1-client-protocol.h"
enum squeek_arrangement_kind {
......@@ -14,48 +14,22 @@ enum squeek_arrangement_kind {
ARRANGEMENT_KIND_WIDE = 1,
};
struct squeek_button;
struct squeek_row;
struct squeek_view;
struct squeek_layout;
/// Represents the path to the button within a view
struct button_place {
const struct squeek_row *row;
const struct squeek_button *button;
};
int32_t squeek_row_get_angle(const struct squeek_row*);
EekBounds squeek_row_get_bounds(const struct squeek_row*);
typedef void (*ButtonCallback) (struct squeek_button *button, gpointer user_data);
void squeek_row_foreach(struct squeek_row*,
ButtonCallback callback,
gpointer user_data);
EekBounds squeek_button_get_bounds(const struct squeek_button*);
const char *squeek_button_get_label(const struct squeek_button*);
const char *squeek_button_get_icon_name(const struct squeek_button*);
const char *squeek_button_get_name(const struct squeek_button*);
const char *squeek_button_get_outline_name(const struct squeek_button*);
struct squeek_key *squeek_button_get_key(const struct squeek_button*);
uint32_t *squeek_button_has_key(const struct squeek_button* button,
const struct squeek_key *key);
void squeek_button_print(const struct squeek_button* button);
EekBounds squeek_view_get_bounds(const struct squeek_view*);
typedef void (*RowCallback) (struct squeek_row *row, gpointer user_data);
void squeek_view_foreach(struct squeek_view*,
RowCallback callback,
gpointer user_data);
struct transformation squeek_layout_calculate_transformation(
const struct squeek_layout *layout,
double allocation_width, double allocation_size);
void
squeek_layout_place_contents(struct squeek_layout*);
struct squeek_view *squeek_layout_get_current_view(struct squeek_layout*);
struct squeek_layout *squeek_load_layout(const char *name, uint32_t type);
const char *squeek_layout_get_keymap(const struct squeek_layout*);
......@@ -75,5 +49,6 @@ void squeek_layout_drag(struct squeek_layout *layout, struct zwp_virtual_keyboar
double x_widget, double y_widget,
struct transformation widget_to_layout,
uint32_t timestamp, EekGtkKeyboard *ui_keyboard);
void squeek_layout_draw_all_changed(struct squeek_layout *layout, EekGtkKeyboard *ui_keyboard);
void squeek_layout_draw_all_changed(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr);
void squeek_draw_layout_base_view(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr);
#endif
......@@ -24,6 +24,7 @@ use std::rc::Rc;
use std::vec::Vec;
use ::action::Action;
use ::drawing;
use ::float_ord::FloatOrd;
use ::keyboard::{ KeyState, PressType };
use ::submission::{ Timestamp, VirtualKeyboard };
......@@ -34,16 +35,14 @@ use std::borrow::Borrow;
pub mod c {
use super::*;
use gtk_sys;
use std::ffi::CStr;
use std::os::raw::{ c_char, c_void };
use std::ptr;