submission: Create a new wrapper over imservice
This commit is contained in:
@ -1,7 +1,18 @@
|
||||
#include "imservice.h"
|
||||
#include "submission.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
struct imservice;
|
||||
|
||||
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,
|
||||
const char *text, uint32_t cursor, uint32_t anchor);
|
||||
void imservice_handle_commit_state(void *data, struct zwp_input_method_v2 *input_method);
|
||||
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose);
|
||||
void imservice_handle_text_change_cause(void *data, struct zwp_input_method_v2 *input_method, uint32_t cause);
|
||||
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method);
|
||||
|
||||
static const struct zwp_input_method_v2_listener input_method_listener = {
|
||||
.activate = imservice_handle_input_method_activate,
|
||||
.deactivate = imservice_handle_input_method_deactivate,
|
||||
@ -12,17 +23,22 @@ static const struct zwp_input_method_v2_listener input_method_listener = {
|
||||
.unavailable = imservice_handle_unavailable,
|
||||
};
|
||||
|
||||
struct imservice* get_imservice(struct zwp_input_method_manager_v2 *manager,
|
||||
struct submission* get_submission(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, state);
|
||||
return submission_new(im, state);
|
||||
}
|
||||
|
||||
/* Add a listener, passing the imservice instance to make it available to
|
||||
callbacks. */
|
||||
/// Un-inlined
|
||||
struct zwp_input_method_v2 *imservice_manager_get_input_method(struct zwp_input_method_manager_v2 *manager,
|
||||
struct wl_seat *seat) {
|
||||
return zwp_input_method_manager_v2_get_input_method(manager, seat);
|
||||
}
|
||||
|
||||
/// Un-inlined to let Rust link to it
|
||||
void imservice_connect_listeners(struct zwp_input_method_v2 *im, struct imservice* imservice) {
|
||||
zwp_input_method_v2_add_listener(im, &input_method_listener, imservice);
|
||||
|
||||
return imservice;
|
||||
}
|
||||
|
||||
/// Declared explicitly because _destroy is inline,
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
#ifndef __IMSERVICE_H
|
||||
#define __IMSERVICE_H
|
||||
|
||||
#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(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 *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,
|
||||
const char *text, uint32_t cursor, uint32_t anchor);
|
||||
void imservice_handle_commit_state(void *data, struct zwp_input_method_v2 *input_method);
|
||||
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose);
|
||||
void imservice_handle_text_change_cause(void *data, struct zwp_input_method_v2 *input_method, uint32_t cause);
|
||||
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method);
|
||||
|
||||
#endif
|
||||
|
||||
@ -15,23 +15,20 @@ pub mod c {
|
||||
|
||||
use std::os::raw::{c_char, c_void};
|
||||
|
||||
pub use ::submission::c::UIManager;
|
||||
pub use ::submission::c::StateManager;
|
||||
|
||||
// The following defined in C
|
||||
|
||||
/// struct zwp_input_method_v2*
|
||||
#[repr(transparent)]
|
||||
pub struct InputMethod(*const c_void);
|
||||
|
||||
/// 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);
|
||||
#[allow(improper_ctypes)] // IMService will never be dereferenced in C
|
||||
pub fn imservice_connect_listeners(im: *mut InputMethod, imservice: *const IMService);
|
||||
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);
|
||||
@ -39,39 +36,6 @@ pub mod c {
|
||||
|
||||
// The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn imservice_new(
|
||||
im: *const InputMethod,
|
||||
state_manager: *const StateManager
|
||||
) -> *mut IMService {
|
||||
Box::<IMService>::into_raw(Box::new(
|
||||
IMService {
|
||||
im: im,
|
||||
state_manager: state_manager,
|
||||
ui_manager: None,
|
||||
pending: IMProtocolState::default(),
|
||||
current: IMProtocolState::default(),
|
||||
preedit_string: String::new(),
|
||||
serial: Wrapping(0u32),
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
#[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]
|
||||
pub unsafe extern "C"
|
||||
@ -349,12 +313,38 @@ 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: Option<*const c::UIManager>,
|
||||
/// Unowned reference. Be careful, it's shared with C at large
|
||||
state_manager: *const c::StateManager,
|
||||
/// Unowned reference. Be careful, it's shared with C at large
|
||||
pub ui_manager: Option<*const c::UIManager>,
|
||||
|
||||
pending: IMProtocolState,
|
||||
current: IMProtocolState, // turn current into an idiomatic representation?
|
||||
preedit_string: String,
|
||||
serial: Wrapping<u32>,
|
||||
}
|
||||
|
||||
impl IMService {
|
||||
pub fn new(
|
||||
im: *mut c::InputMethod,
|
||||
state_manager: *const c::StateManager,
|
||||
) -> Box<IMService> {
|
||||
// IMService will be referenced to by C,
|
||||
// so it needs to stay in the same place in memory via Box
|
||||
let imservice = Box::new(IMService {
|
||||
im,
|
||||
ui_manager: None,
|
||||
state_manager,
|
||||
pending: IMProtocolState::default(),
|
||||
current: IMProtocolState::default(),
|
||||
preedit_string: String::new(),
|
||||
serial: Wrapping(0u32),
|
||||
});
|
||||
unsafe {
|
||||
c::imservice_connect_listeners(
|
||||
im,
|
||||
imservice.as_ref() as *const IMService,
|
||||
);
|
||||
}
|
||||
imservice
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +244,7 @@ pub mod c {
|
||||
pub mod procedures {
|
||||
use super::*;
|
||||
|
||||
use ::submission::c::ZwpVirtualKeyboardV1;
|
||||
use ::vkeyboard::c::ZwpVirtualKeyboardV1;
|
||||
|
||||
// This is constructed only in C, no need for warnings
|
||||
#[allow(dead_code)]
|
||||
|
||||
@ -28,8 +28,8 @@
|
||||
#include "eek/eek.h"
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
#include "dbus.h"
|
||||
#include "imservice.h"
|
||||
#include "outputs.h"
|
||||
#include "submission.h"
|
||||
#include "server-context-service.h"
|
||||
#include "wayland.h"
|
||||
|
||||
@ -42,7 +42,7 @@ struct squeekboard {
|
||||
DBusHandler *dbus_handler;
|
||||
EekboardContextService *settings_context;
|
||||
ServerContextService *ui_context;
|
||||
struct imservice *imservice;
|
||||
struct submission *submission;
|
||||
};
|
||||
|
||||
|
||||
@ -261,16 +261,11 @@ main (int argc, char **argv)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
struct imservice *imservice = NULL;
|
||||
if (instance.wayland.input_method_manager) {
|
||||
imservice = get_imservice(instance.wayland.input_method_manager,
|
||||
// Cannot fail
|
||||
instance.submission = get_submission(instance.wayland.input_method_manager,
|
||||
instance.wayland.seat,
|
||||
instance.settings_context);
|
||||
if (imservice) {
|
||||
instance.imservice = imservice;
|
||||
} else {
|
||||
g_warning("Failed to register as an input method");
|
||||
}
|
||||
}
|
||||
|
||||
ServerContextService *ui_context = server_context_service_new(instance.settings_context);
|
||||
@ -279,8 +274,8 @@ main (int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
instance.ui_context = ui_context;
|
||||
if (instance.imservice) {
|
||||
imservice_set_ui(instance.imservice, instance.ui_context);
|
||||
if (instance.submission) {
|
||||
submission_set_ui(instance.submission, instance.ui_context);
|
||||
}
|
||||
if (instance.dbus_handler) {
|
||||
dbus_handler_set_ui_context(instance.dbus_handler, instance.ui_context);
|
||||
|
||||
19
src/submission.h
Normal file
19
src/submission.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef __SUBMISSION_H
|
||||
#define __SUBMISSION_H
|
||||
|
||||
#include "input-method-unstable-v2-client-protocol.h"
|
||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||
#include "eek/eek-types.h"
|
||||
|
||||
struct submission;
|
||||
|
||||
struct submission* get_submission(struct zwp_input_method_manager_v2 *immanager,
|
||||
struct zwp_virtual_keyboard_manager_v1 *vkmanager,
|
||||
struct wl_seat *seat,
|
||||
EekboardContextService *state);
|
||||
|
||||
// Defined in Rust
|
||||
struct submission* submission_new(struct zwp_input_method_v2 *im, struct zwp_virtual_keyboard_v1 *vk, EekboardContextService *state);
|
||||
void submission_set_ui(struct submission *self, ServerContextService *ui_context);
|
||||
void submission_set_keyboard(struct submission *self, LevelKeyboard *keyboard);
|
||||
#endif
|
||||
@ -20,3 +20,65 @@
|
||||
/// Temporary reexport to keep stuff based directly on virtual-keyboard working
|
||||
/// until a unified handler appears and prompts a rework.
|
||||
pub use vkeyboard::*;
|
||||
|
||||
use ::imservice::IMService;
|
||||
|
||||
/// Gathers stuff defined in C or called by C
|
||||
pub mod c {
|
||||
use super::*;
|
||||
|
||||
use std::os::raw::c_void;
|
||||
|
||||
use ::imservice::c::InputMethod;
|
||||
|
||||
// The following defined in C
|
||||
|
||||
/// ServerContextService*
|
||||
#[repr(transparent)]
|
||||
pub struct UIManager(*const c_void);
|
||||
|
||||
/// EekboardContextService*
|
||||
#[repr(transparent)]
|
||||
pub struct StateManager(*const c_void);
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn submission_new(
|
||||
im: *mut InputMethod,
|
||||
state_manager: *const StateManager
|
||||
) -> *mut Submission {
|
||||
let imservice = if im.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(IMService::new(im, state_manager))
|
||||
};
|
||||
// TODO: add vkeyboard too
|
||||
Box::<Submission>::into_raw(Box::new(
|
||||
Submission {
|
||||
imservice,
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn submission_set_ui(submission: *mut Submission, ui_manager: *const UIManager) {
|
||||
if submission.is_null() {
|
||||
panic!("Null submission pointer");
|
||||
}
|
||||
let submission: &mut Submission = unsafe { &mut *submission };
|
||||
if let Some(ref mut imservice) = &mut submission.imservice {
|
||||
imservice.ui_manager = if ui_manager.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(ui_manager)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Submission {
|
||||
// used by C callbacks internally, TODO: make use with virtual keyboard
|
||||
#[allow(dead_code)]
|
||||
imservice: Option<Box<IMService>>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user