Merge branch 'cleanups' into 'master'
C-side Cleanups See merge request Librem5/squeekboard!300
This commit is contained in:
124
src/dbus.c
Normal file
124
src/dbus.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "dbus.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
void
|
||||
dbus_handler_destroy(DBusHandler *service)
|
||||
{
|
||||
g_free (service->object_path);
|
||||
|
||||
if (service->connection) {
|
||||
if (service->registration_id > 0) {
|
||||
g_dbus_connection_unregister_object (service->connection,
|
||||
service->registration_id);
|
||||
service->registration_id = 0;
|
||||
}
|
||||
|
||||
g_object_unref (service->connection);
|
||||
service->connection = NULL;
|
||||
}
|
||||
|
||||
if (service->introspection_data) {
|
||||
g_dbus_node_info_unref (service->introspection_data);
|
||||
service->introspection_data = NULL;
|
||||
}
|
||||
|
||||
if (service->context) {
|
||||
g_signal_handlers_disconnect_by_data (service->context, service);
|
||||
service->context = NULL;
|
||||
}
|
||||
|
||||
free(service);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation,
|
||||
gboolean arg_visible, gpointer user_data) {
|
||||
DBusHandler *service = user_data;
|
||||
|
||||
if (service->context) {
|
||||
if (arg_visible) {
|
||||
server_context_service_show_keyboard (service->context);
|
||||
} else {
|
||||
server_context_service_hide_keyboard (service->context);
|
||||
}
|
||||
}
|
||||
sm_puri_osk0_complete_set_visible(object, invocation);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void on_visible(DBusHandler *service,
|
||||
GParamSpec *pspec,
|
||||
ServerContextService *context)
|
||||
{
|
||||
(void)pspec;
|
||||
gboolean visible;
|
||||
|
||||
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (context));
|
||||
|
||||
g_object_get (context, "visible", &visible, NULL);
|
||||
|
||||
sm_puri_osk0_set_visible(service->dbus_interface, visible);
|
||||
}
|
||||
|
||||
DBusHandler *
|
||||
dbus_handler_new (GDBusConnection *connection,
|
||||
const gchar *object_path)
|
||||
{
|
||||
DBusHandler *self = calloc(1, sizeof(DBusHandler));
|
||||
self->object_path = g_strdup(object_path);
|
||||
self->connection = connection;
|
||||
|
||||
self->dbus_interface = sm_puri_osk0_skeleton_new();
|
||||
g_signal_connect(self->dbus_interface, "handle-set-visible",
|
||||
G_CALLBACK(handle_set_visible), self);
|
||||
|
||||
if (self->connection && self->object_path) {
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(self->dbus_interface),
|
||||
self->connection,
|
||||
self->object_path,
|
||||
&error)) {
|
||||
g_warning("Error registering dbus object: %s\n", error->message);
|
||||
g_clear_error(&error);
|
||||
// TODO: return an error
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
dbus_handler_set_ui_context(DBusHandler *service,
|
||||
ServerContextService *context)
|
||||
{
|
||||
g_return_if_fail (!service->context);
|
||||
|
||||
service->context = context;
|
||||
|
||||
g_signal_connect_swapped (service->context,
|
||||
"notify::visible",
|
||||
G_CALLBACK(on_visible),
|
||||
service);
|
||||
}
|
||||
48
src/dbus.h
Normal file
48
src/dbus.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
* Copyright (C) 2019-2020 Purism, SPC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DBUS_H_
|
||||
#define DBUS_H_ 1
|
||||
|
||||
#include "server-context-service.h"
|
||||
|
||||
#include "sm.puri.OSK0.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define DBUS_SERVICE_PATH "/sm/puri/OSK0"
|
||||
#define DBUS_SERVICE_INTERFACE "sm.puri.OSK0"
|
||||
|
||||
typedef struct _DBusHandler
|
||||
{
|
||||
GDBusConnection *connection;
|
||||
SmPuriOSK0 *dbus_interface;
|
||||
GDBusNodeInfo *introspection_data;
|
||||
guint registration_id;
|
||||
char *object_path;
|
||||
|
||||
ServerContextService *context; // unowned reference
|
||||
} DBusHandler;
|
||||
|
||||
DBusHandler * dbus_handler_new (GDBusConnection *connection,
|
||||
const gchar *object_path);
|
||||
void dbus_handler_set_ui_context(DBusHandler *service,
|
||||
ServerContextService *context);
|
||||
void dbus_handler_destroy(DBusHandler*);
|
||||
G_END_DECLS
|
||||
#endif /* DBUS_H_ */
|
||||
@ -2,9 +2,6 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
|
||||
|
||||
static const struct zwp_input_method_v2_listener input_method_listener = {
|
||||
.activate = imservice_handle_input_method_activate,
|
||||
.deactivate = imservice_handle_input_method_deactivate,
|
||||
@ -15,11 +12,11 @@ static const struct zwp_input_method_v2_listener input_method_listener = {
|
||||
.unavailable = imservice_handle_unavailable,
|
||||
};
|
||||
|
||||
struct imservice* get_imservice(EekboardContextService *context,
|
||||
struct zwp_input_method_manager_v2 *manager,
|
||||
struct wl_seat *seat) {
|
||||
struct imservice* get_imservice(struct zwp_input_method_manager_v2 *manager,
|
||||
struct wl_seat *seat,
|
||||
EekboardContextService *state) {
|
||||
struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat);
|
||||
struct imservice *imservice = imservice_new(im, context);
|
||||
struct imservice *imservice = imservice_new(im, state);
|
||||
|
||||
/* Add a listener, passing the imservice instance to make it available to
|
||||
callbacks. */
|
||||
@ -28,14 +25,6 @@ struct imservice* get_imservice(EekboardContextService *context,
|
||||
return imservice;
|
||||
}
|
||||
|
||||
void imservice_make_visible(EekboardContextService *context) {
|
||||
eekboard_context_service_show_keyboard (context);
|
||||
}
|
||||
|
||||
void imservice_try_hide(EekboardContextService *context) {
|
||||
eekboard_context_service_hide_keyboard (context);
|
||||
}
|
||||
|
||||
/// Declared explicitly because _destroy is inline,
|
||||
/// making it unavailable in Rust
|
||||
void imservice_destroy_im(struct zwp_input_method_v2 *im) {
|
||||
|
||||
@ -3,16 +3,18 @@
|
||||
|
||||
#include "input-method-unstable-v2-client-protocol.h"
|
||||
#include "eek/eek-types.h"
|
||||
#include "src/server-context-service.h"
|
||||
|
||||
struct imservice;
|
||||
|
||||
struct imservice* get_imservice(EekboardContextService *context,
|
||||
struct zwp_input_method_manager_v2 *manager,
|
||||
struct wl_seat *seat);
|
||||
struct imservice* get_imservice(struct zwp_input_method_manager_v2 *manager,
|
||||
struct wl_seat *seat,
|
||||
EekboardContextService *state);
|
||||
|
||||
// Defined in Rust
|
||||
struct imservice* imservice_new(struct zwp_input_method_v2 *im,
|
||||
EekboardContextService *context);
|
||||
struct imservice* imservice_new(struct zwp_input_method_v2 *im, EekboardContextService *state);
|
||||
void imservice_set_ui(struct imservice *self, ServerContextService *ui_context);
|
||||
|
||||
void imservice_handle_input_method_activate(void *data, struct zwp_input_method_v2 *input_method);
|
||||
void imservice_handle_input_method_deactivate(void *data, struct zwp_input_method_v2 *input_method);
|
||||
void imservice_handle_surrounding_text(void *data, struct zwp_input_method_v2 *input_method,
|
||||
|
||||
@ -21,27 +21,35 @@ pub mod c {
|
||||
#[repr(transparent)]
|
||||
pub struct InputMethod(*const c_void);
|
||||
|
||||
/// EekboardContextService*
|
||||
/// ServerContextService*
|
||||
#[repr(transparent)]
|
||||
pub struct UIManager(*const c_void);
|
||||
|
||||
|
||||
/// EekboardContextService*
|
||||
#[repr(transparent)]
|
||||
pub struct StateManager(*const c_void);
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" {
|
||||
fn imservice_destroy_im(im: *mut c::InputMethod);
|
||||
fn eekboard_context_service_set_hint_purpose(imservice: *const UIManager, hint: u32, purpose: u32);
|
||||
fn eekboard_context_service_show_keyboard(imservice: *const UIManager);
|
||||
fn eekboard_context_service_hide_keyboard(imservice: *const UIManager);
|
||||
fn eekboard_context_service_set_hint_purpose(state: *const StateManager, hint: u32, purpose: u32);
|
||||
fn server_context_service_show_keyboard(imservice: *const UIManager);
|
||||
fn server_context_service_hide_keyboard(imservice: *const UIManager);
|
||||
}
|
||||
|
||||
// The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C"
|
||||
fn imservice_new(im: *const InputMethod, ui_manager: *const UIManager) -> *mut IMService {
|
||||
pub extern "C"
|
||||
fn imservice_new(
|
||||
im: *const InputMethod,
|
||||
state_manager: *const StateManager
|
||||
) -> *mut IMService {
|
||||
Box::<IMService>::into_raw(Box::new(
|
||||
IMService {
|
||||
im: im,
|
||||
ui_manager: ui_manager,
|
||||
state_manager: state_manager,
|
||||
ui_manager: None,
|
||||
pending: IMProtocolState::default(),
|
||||
current: IMProtocolState::default(),
|
||||
preedit_string: String::new(),
|
||||
@ -49,6 +57,20 @@ pub mod c {
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn imservice_set_ui(imservice: *mut IMService, ui_manager: *const UIManager) {
|
||||
if imservice.is_null() {
|
||||
panic!("Null imservice pointer");
|
||||
}
|
||||
let imservice: &mut IMService = unsafe { &mut *imservice };
|
||||
imservice.ui_manager = if ui_manager.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(ui_manager)
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: is unsafe needed here?
|
||||
#[no_mangle]
|
||||
@ -148,15 +170,20 @@ pub mod c {
|
||||
active: imservice.current.active,
|
||||
..IMProtocolState::default()
|
||||
};
|
||||
|
||||
if active_changed {
|
||||
if imservice.current.active {
|
||||
eekboard_context_service_show_keyboard(imservice.ui_manager);
|
||||
if let Some(ui) = imservice.ui_manager {
|
||||
server_context_service_show_keyboard(ui);
|
||||
}
|
||||
eekboard_context_service_set_hint_purpose(
|
||||
imservice.ui_manager,
|
||||
imservice.state_manager,
|
||||
imservice.current.content_hint.bits(),
|
||||
imservice.current.content_purpose.clone() as u32);
|
||||
} else {
|
||||
eekboard_context_service_hide_keyboard(imservice.ui_manager);
|
||||
if let Some(ui) = imservice.ui_manager {
|
||||
server_context_service_hide_keyboard(ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,7 +200,9 @@ pub mod c {
|
||||
// the keyboard is already decommissioned
|
||||
imservice.current.active = false;
|
||||
|
||||
eekboard_context_service_hide_keyboard(imservice.ui_manager);
|
||||
if let Some(ui) = imservice.ui_manager {
|
||||
server_context_service_hide_keyboard(ui);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: destroy and deallocate
|
||||
@ -320,7 +349,9 @@ pub struct IMService {
|
||||
/// Owned reference (still created and destroyed in C)
|
||||
pub im: *const c::InputMethod,
|
||||
/// Unowned reference. Be careful, it's shared with C at large
|
||||
ui_manager: *const c::UIManager,
|
||||
ui_manager: Option<*const c::UIManager>,
|
||||
/// Unowned reference. Be careful, it's shared with C at large
|
||||
state_manager: *const c::StateManager,
|
||||
|
||||
pending: IMProtocolState,
|
||||
current: IMProtocolState, // turn current into an idiomatic representation?
|
||||
|
||||
@ -332,11 +332,12 @@ pub mod c {
|
||||
.map(|place| place.button.state.clone())
|
||||
};
|
||||
|
||||
if let Some(mut state) = state {
|
||||
layout.press_key(
|
||||
if let Some(state) = state {
|
||||
seat::handle_press_key(
|
||||
layout,
|
||||
&VirtualKeyboard(virtual_keyboard),
|
||||
&mut state,
|
||||
Timestamp(time),
|
||||
&state,
|
||||
);
|
||||
// maybe TODO: draw on the display buffer here
|
||||
drawing::queue_redraw(ui_keyboard);
|
||||
@ -379,7 +380,7 @@ pub mod c {
|
||||
)})
|
||||
};
|
||||
|
||||
if let Some((mut state, _button, _view_position)) = button_info {
|
||||
if let Some((state, _button, _view_position)) = button_info {
|
||||
let mut found = false;
|
||||
for wrapped_key in pressed {
|
||||
let key: &Rc<RefCell<KeyState>> = wrapped_key.borrow();
|
||||
@ -397,7 +398,12 @@ pub mod c {
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
layout.press_key(&virtual_keyboard, &mut state, time);
|
||||
seat::handle_press_key(
|
||||
layout,
|
||||
&virtual_keyboard,
|
||||
time,
|
||||
&state,
|
||||
);
|
||||
// maybe TODO: draw on the display buffer here
|
||||
}
|
||||
} else {
|
||||
@ -653,24 +659,6 @@ impl Layout {
|
||||
}
|
||||
}
|
||||
|
||||
fn press_key(
|
||||
&mut self,
|
||||
virtual_keyboard: &VirtualKeyboard,
|
||||
rckey: &mut Rc<RefCell<KeyState>>,
|
||||
time: Timestamp,
|
||||
) {
|
||||
if !self.pressed_keys.insert(::util::Pointer(rckey.clone())) {
|
||||
eprintln!("Warning: key {:?} was already pressed", rckey);
|
||||
}
|
||||
let mut key = rckey.borrow_mut();
|
||||
virtual_keyboard.switch(
|
||||
&key.keycodes,
|
||||
PressType::Pressed,
|
||||
time,
|
||||
);
|
||||
key.pressed = PressType::Pressed;
|
||||
}
|
||||
|
||||
/// Calculates size without margins
|
||||
fn calculate_inner_size(&self) -> Size {
|
||||
Size {
|
||||
@ -864,6 +852,24 @@ mod seat {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_press_key(
|
||||
layout: &mut Layout,
|
||||
virtual_keyboard: &VirtualKeyboard,
|
||||
time: Timestamp,
|
||||
rckey: &Rc<RefCell<KeyState>>,
|
||||
) {
|
||||
if !layout.pressed_keys.insert(::util::Pointer(rckey.clone())) {
|
||||
eprintln!("Warning: key {:?} was already pressed", rckey);
|
||||
}
|
||||
let mut key = rckey.borrow_mut();
|
||||
virtual_keyboard.switch(
|
||||
&key.keycodes,
|
||||
PressType::Pressed,
|
||||
time,
|
||||
);
|
||||
key.pressed = PressType::Pressed;
|
||||
}
|
||||
|
||||
pub fn handle_release_key(
|
||||
layout: &mut Layout,
|
||||
virtual_keyboard: &VirtualKeyboard,
|
||||
|
||||
@ -12,6 +12,7 @@ config_h = configure_file(
|
||||
|
||||
sources = [
|
||||
config_h,
|
||||
'dbus.c',
|
||||
'imservice.c',
|
||||
'server-context-service.c',
|
||||
'wayland.c',
|
||||
@ -24,9 +25,7 @@ sources = [
|
||||
'../eek/eek-xml-layout.c',
|
||||
'../eek/layersurface.c',
|
||||
dbus_src,
|
||||
'../eekboard/key-emitter.c',
|
||||
'../eekboard/eekboard-context-service.c',
|
||||
'../eekboard/eekboard-service.c',
|
||||
# '../eekboard/eekboard-xklutil.c',
|
||||
squeekboard_resources,
|
||||
wl_proto_sources,
|
||||
|
||||
@ -23,22 +23,26 @@
|
||||
#include "eek/eek.h"
|
||||
#include "eek/eek-gtk-keyboard.h"
|
||||
#include "eek/layersurface.h"
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
#include "wayland.h"
|
||||
|
||||
#include "server-context-service.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_SIZE_CONSTRAINT_LANDSCAPE,
|
||||
PROP_SIZE_CONSTRAINT_PORTRAIT,
|
||||
PROP_VISIBLE,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _ServerContextServiceClass ServerContextServiceClass;
|
||||
|
||||
struct _ServerContextService {
|
||||
EekboardContextService parent;
|
||||
GObject parent;
|
||||
|
||||
EekboardContextService *state; // unowned
|
||||
|
||||
gboolean visible;
|
||||
PhoshLayerSurface *window;
|
||||
GtkWidget *widget;
|
||||
guint hiding;
|
||||
@ -50,10 +54,10 @@ struct _ServerContextService {
|
||||
};
|
||||
|
||||
struct _ServerContextServiceClass {
|
||||
EekboardContextServiceClass parent_class;
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTEXT_SERVICE);
|
||||
G_DEFINE_TYPE(ServerContextService, server_context_service, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
on_destroy (GtkWidget *widget, gpointer user_data)
|
||||
@ -65,7 +69,7 @@ on_destroy (GtkWidget *widget, gpointer user_data)
|
||||
context->window = NULL;
|
||||
context->widget = NULL;
|
||||
|
||||
eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
|
||||
//eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -76,17 +80,6 @@ on_notify_keyboard (GObject *object,
|
||||
GParamSpec *spec,
|
||||
ServerContextService *context)
|
||||
{
|
||||
const LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||
|
||||
if (!keyboard)
|
||||
g_error("Programmer error: keyboard layout was unset!");
|
||||
|
||||
// The keymap will get set even if the window is hidden.
|
||||
// It's not perfect,
|
||||
// but simpler than adding a check in the window showing procedure
|
||||
eekboard_context_service_set_keymap(EEKBOARD_CONTEXT_SERVICE(context),
|
||||
keyboard);
|
||||
|
||||
/* Recreate the keyboard widget to keep in sync with the keymap. */
|
||||
if (context->window)
|
||||
make_widget(context);
|
||||
@ -95,8 +88,8 @@ on_notify_keyboard (GObject *object,
|
||||
g_object_get (context, "visible", &visible, NULL);
|
||||
|
||||
if (visible) {
|
||||
eekboard_context_service_hide_keyboard(EEKBOARD_CONTEXT_SERVICE(context));
|
||||
eekboard_context_service_show_keyboard(EEKBOARD_CONTEXT_SERVICE(context));
|
||||
server_context_service_hide_keyboard(context);
|
||||
server_context_service_show_keyboard(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,7 +222,7 @@ make_widget (ServerContextService *context)
|
||||
context->widget = NULL;
|
||||
}
|
||||
|
||||
LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||
LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (context->state);
|
||||
|
||||
context->widget = eek_gtk_keyboard_new (keyboard);
|
||||
|
||||
@ -238,26 +231,6 @@ make_widget (ServerContextService *context)
|
||||
gtk_widget_show (context->widget);
|
||||
}
|
||||
|
||||
static void
|
||||
server_context_service_real_show_keyboard (EekboardContextService *_context)
|
||||
{
|
||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||
|
||||
if (context->hiding) {
|
||||
g_source_remove (context->hiding);
|
||||
context->hiding = 0;
|
||||
}
|
||||
|
||||
if (!context->window)
|
||||
make_window (context);
|
||||
if (!context->widget)
|
||||
make_widget (context);
|
||||
|
||||
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
||||
show_keyboard (_context);
|
||||
gtk_widget_show (GTK_WIDGET(context->window));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_hide (ServerContextService *context)
|
||||
{
|
||||
@ -268,20 +241,49 @@ on_hide (ServerContextService *context)
|
||||
}
|
||||
|
||||
static void
|
||||
server_context_service_real_hide_keyboard (EekboardContextService *_context)
|
||||
server_context_service_real_show_keyboard (ServerContextService *context)
|
||||
{
|
||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||
if (context->hiding) {
|
||||
g_source_remove (context->hiding);
|
||||
context->hiding = 0;
|
||||
}
|
||||
|
||||
if (!context->hiding)
|
||||
context->hiding = g_timeout_add (200, (GSourceFunc) on_hide, context);
|
||||
if (!context->window)
|
||||
make_window (context);
|
||||
if (!context->widget)
|
||||
make_widget (context);
|
||||
|
||||
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
||||
hide_keyboard (_context);
|
||||
context->visible = TRUE;
|
||||
gtk_widget_show (GTK_WIDGET(context->window));
|
||||
}
|
||||
|
||||
static void
|
||||
server_context_service_real_destroyed (EekboardContextService *_context)
|
||||
server_context_service_real_hide_keyboard (ServerContextService *context)
|
||||
{
|
||||
if (!context->hiding)
|
||||
context->hiding = g_timeout_add (200, (GSourceFunc) on_hide, context);
|
||||
|
||||
context->visible = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
server_context_service_show_keyboard (ServerContextService *context)
|
||||
{
|
||||
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(context));
|
||||
|
||||
if (!context->visible) {
|
||||
server_context_service_real_show_keyboard (context);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
server_context_service_hide_keyboard (ServerContextService *context)
|
||||
{
|
||||
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(context));
|
||||
|
||||
if (context->visible) {
|
||||
server_context_service_real_hide_keyboard (context);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -306,6 +308,9 @@ server_context_service_set_property (GObject *object,
|
||||
&context->size_constraint_portrait[0],
|
||||
&context->size_constraint_portrait[1]);
|
||||
break;
|
||||
case PROP_VISIBLE:
|
||||
context->visible = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@ -313,6 +318,23 @@ server_context_service_set_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
server_context_service_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
|
||||
switch (prop_id) {
|
||||
case PROP_VISIBLE:
|
||||
g_value_set_boolean (value, context->visible);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
server_context_service_dispose (GObject *object)
|
||||
{
|
||||
@ -327,15 +349,11 @@ server_context_service_dispose (GObject *object)
|
||||
static void
|
||||
server_context_service_class_init (ServerContextServiceClass *klass)
|
||||
{
|
||||
EekboardContextServiceClass *context_class = EEKBOARD_CONTEXT_SERVICE_CLASS(klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
context_class->show_keyboard = server_context_service_real_show_keyboard;
|
||||
context_class->hide_keyboard = server_context_service_real_hide_keyboard;
|
||||
context_class->destroyed = server_context_service_real_destroyed;
|
||||
|
||||
gobject_class->set_property = server_context_service_set_property;
|
||||
gobject_class->get_property = server_context_service_get_property;
|
||||
gobject_class->dispose = server_context_service_dispose;
|
||||
|
||||
pspec = g_param_spec_variant ("size-constraint-landscape",
|
||||
@ -357,24 +375,38 @@ server_context_service_class_init (ServerContextServiceClass *klass)
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SIZE_CONSTRAINT_PORTRAIT,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* Flag to indicate if keyboard is visible or not.
|
||||
*/
|
||||
pspec = g_param_spec_boolean ("visible",
|
||||
"Visible",
|
||||
"Visible",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_VISIBLE,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
server_context_service_init (ServerContextService *context)
|
||||
server_context_service_init (ServerContextService *state) {
|
||||
(void)state;
|
||||
}
|
||||
|
||||
ServerContextService *
|
||||
server_context_service_new (EekboardContextService *state)
|
||||
{
|
||||
g_signal_connect (context,
|
||||
ServerContextService *ui = g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL);
|
||||
ui->state = state;
|
||||
g_signal_connect (state,
|
||||
"notify::keyboard",
|
||||
G_CALLBACK(on_notify_keyboard),
|
||||
context);
|
||||
ui);
|
||||
return ui;
|
||||
}
|
||||
|
||||
EekboardContextService *
|
||||
server_context_service_new ()
|
||||
enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *service)
|
||||
{
|
||||
return EEKBOARD_CONTEXT_SERVICE(g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL));
|
||||
}
|
||||
|
||||
enum squeek_arrangement_kind server_context_service_get_layout_type(EekboardContextService *service)
|
||||
{
|
||||
return SERVER_CONTEXT_SERVICE(service)->last_type;
|
||||
return service->last_type;
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
#ifndef SERVER_CONTEXT_SERVICE_H
|
||||
#define SERVER_CONTEXT_SERVICE_H 1
|
||||
|
||||
#include "eekboard/eekboard-service.h"
|
||||
#include "src/layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@ -30,12 +29,16 @@ G_BEGIN_DECLS
|
||||
#define SERVER_IS_CONTEXT_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SERVER_TYPE_CONTEXT_SERVICE))
|
||||
#define SERVER_CONTEXT_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SERVER_TYPE_CONTEXT_SERVICE, ServerContextServiceClass))
|
||||
|
||||
/** Manages the liecycle of the window displaying layouts. */
|
||||
/** Manages the lifecycle of the window displaying layouts. */
|
||||
typedef struct _ServerContextService ServerContextService;
|
||||
|
||||
EekboardContextService *server_context_service_new ();
|
||||
enum squeek_arrangement_kind server_context_service_get_layout_type(EekboardContextService*);
|
||||
GType server_context_service_get_type
|
||||
(void) G_GNUC_CONST;
|
||||
|
||||
ServerContextService *server_context_service_new(EekboardContextService *state);
|
||||
enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *);
|
||||
void server_context_service_show_keyboard (ServerContextService *context);
|
||||
void server_context_service_hide_keyboard (ServerContextService *context);
|
||||
G_END_DECLS
|
||||
#endif /* SERVER_CONTEXT_SERVICE_H */
|
||||
|
||||
|
||||
@ -25,8 +25,9 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "eekboard/eekboard-service.h"
|
||||
#include "eek/eek.h"
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
#include "dbus.h"
|
||||
#include "imservice.h"
|
||||
#include "outputs.h"
|
||||
#include "server-context-service.h"
|
||||
@ -38,7 +39,9 @@
|
||||
/// Global application state
|
||||
struct squeekboard {
|
||||
struct squeek_wayland wayland;
|
||||
EekboardContextService *context;
|
||||
DBusHandler *dbus_handler;
|
||||
EekboardContextService *settings_context;
|
||||
ServerContextService *ui_context;
|
||||
struct imservice *imservice;
|
||||
};
|
||||
|
||||
@ -72,25 +75,6 @@ on_name_lost (GDBusConnection *connection,
|
||||
exit (1);
|
||||
}
|
||||
|
||||
static void
|
||||
on_destroyed (EekboardService *service,
|
||||
gpointer user_data)
|
||||
{
|
||||
(void)service;
|
||||
GMainLoop *loop = user_data;
|
||||
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
static EekboardContextService *create_context() {
|
||||
EekboardContextService *context = server_context_service_new ();
|
||||
g_object_set_data_full (G_OBJECT(context),
|
||||
"owner", g_strdup ("sender"),
|
||||
(GDestroyNotify)g_free);
|
||||
eekboard_context_service_enable (context);
|
||||
return context;
|
||||
}
|
||||
|
||||
// Wayland
|
||||
|
||||
static void
|
||||
@ -211,7 +195,7 @@ main (int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
instance.context = create_context();
|
||||
instance.settings_context = eekboard_context_service_new();
|
||||
|
||||
// set up dbus
|
||||
|
||||
@ -259,17 +243,16 @@ main (int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
|
||||
EekboardService *service = eekboard_service_new (connection, EEKBOARD_SERVICE_PATH);
|
||||
DBusHandler *service = dbus_handler_new(connection, DBUS_SERVICE_PATH);
|
||||
|
||||
if (service == NULL) {
|
||||
g_printerr ("Can't create dbus server\n");
|
||||
exit (1);
|
||||
} else {
|
||||
eekboard_service_set_context(service, instance.context);
|
||||
}
|
||||
instance.dbus_handler = service;
|
||||
|
||||
guint owner_id = g_bus_own_name_on_connection (connection,
|
||||
EEKBOARD_SERVICE_INTERFACE,
|
||||
DBUS_SERVICE_INTERFACE,
|
||||
G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||
on_name_acquired,
|
||||
on_name_lost,
|
||||
@ -282,9 +265,9 @@ main (int argc, char **argv)
|
||||
|
||||
struct imservice *imservice = NULL;
|
||||
if (instance.wayland.input_method_manager) {
|
||||
imservice = get_imservice(instance.context,
|
||||
instance.wayland.input_method_manager,
|
||||
instance.wayland.seat);
|
||||
imservice = get_imservice(instance.wayland.input_method_manager,
|
||||
instance.wayland.seat,
|
||||
instance.settings_context);
|
||||
if (imservice) {
|
||||
instance.imservice = imservice;
|
||||
} else {
|
||||
@ -292,12 +275,23 @@ main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
ServerContextService *ui_context = server_context_service_new(instance.settings_context);
|
||||
if (!ui_context) {
|
||||
g_error("Could not initialize GUI");
|
||||
exit(1);
|
||||
}
|
||||
instance.ui_context = ui_context;
|
||||
if (instance.imservice) {
|
||||
imservice_set_ui(instance.imservice, instance.ui_context);
|
||||
}
|
||||
if (instance.dbus_handler) {
|
||||
dbus_handler_set_ui_context(instance.dbus_handler, instance.ui_context);
|
||||
}
|
||||
|
||||
session_register();
|
||||
|
||||
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
g_signal_connect (service, "destroyed", G_CALLBACK(on_destroyed), loop);
|
||||
|
||||
g_main_loop_run (loop);
|
||||
|
||||
g_bus_unown_name (owner_id);
|
||||
|
||||
Reference in New Issue
Block a user