services: Split out layout management from EekboardContextService

Layout management was pointlessly bound with the EekboardContextService with inheritance. Splitting it out will make it easier to further break apart layout state management, settings, and input method in the future.
This commit is contained in:
Dorota Czaplejewicz
2020-01-09 20:49:27 +00:00
parent 58b087e35a
commit 92c9572ac2
10 changed files with 116 additions and 68 deletions

View File

@ -21,14 +21,18 @@ 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_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);
}
@ -36,12 +40,16 @@ pub mod c {
// 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 {
server_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 {
server_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;
server_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?