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>
 | 
					#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 = {
 | 
					static const struct zwp_input_method_v2_listener input_method_listener = {
 | 
				
			||||||
    .activate = imservice_handle_input_method_activate,
 | 
					    .activate = imservice_handle_input_method_activate,
 | 
				
			||||||
    .deactivate = imservice_handle_input_method_deactivate,
 | 
					    .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,
 | 
					    .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,
 | 
					                                  struct wl_seat *seat,
 | 
				
			||||||
                                EekboardContextService *state) {
 | 
					                                  EekboardContextService *state) {
 | 
				
			||||||
    struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat);
 | 
					    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
 | 
					/// Un-inlined
 | 
				
			||||||
       callbacks. */
 | 
					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);
 | 
					    zwp_input_method_v2_add_listener(im, &input_method_listener, imservice);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return imservice;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Declared explicitly because _destroy is inline,
 | 
					/// 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};
 | 
					    use std::os::raw::{c_char, c_void};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub use ::submission::c::UIManager;
 | 
				
			||||||
 | 
					    pub use ::submission::c::StateManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The following defined in C
 | 
					    // The following defined in C
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    /// struct zwp_input_method_v2*
 | 
					    /// struct zwp_input_method_v2*
 | 
				
			||||||
    #[repr(transparent)]
 | 
					    #[repr(transparent)]
 | 
				
			||||||
    pub struct InputMethod(*const c_void);
 | 
					    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]
 | 
					    #[no_mangle]
 | 
				
			||||||
    extern "C" {
 | 
					    extern "C" {
 | 
				
			||||||
        fn imservice_destroy_im(im: *mut c::InputMethod);
 | 
					        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 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_show_keyboard(imservice: *const UIManager);
 | 
				
			||||||
        fn server_context_service_hide_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
 | 
					    // 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?
 | 
					    // TODO: is unsafe needed here?
 | 
				
			||||||
    #[no_mangle]
 | 
					    #[no_mangle]
 | 
				
			||||||
    pub unsafe extern "C"
 | 
					    pub unsafe extern "C"
 | 
				
			||||||
@ -349,12 +313,38 @@ pub struct IMService {
 | 
				
			|||||||
    /// Owned reference (still created and destroyed in C)
 | 
					    /// Owned reference (still created and destroyed in C)
 | 
				
			||||||
    pub im: *const c::InputMethod,
 | 
					    pub im: *const c::InputMethod,
 | 
				
			||||||
    /// Unowned reference. Be careful, it's shared with C at large
 | 
					    /// 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,
 | 
					    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,
 | 
					    pending: IMProtocolState,
 | 
				
			||||||
    current: IMProtocolState, // turn current into an idiomatic representation?
 | 
					    current: IMProtocolState, // turn current into an idiomatic representation?
 | 
				
			||||||
    preedit_string: String,
 | 
					    preedit_string: String,
 | 
				
			||||||
    serial: Wrapping<u32>,
 | 
					    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 {
 | 
					    pub mod procedures {
 | 
				
			||||||
        use super::*;
 | 
					        use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        use ::submission::c::ZwpVirtualKeyboardV1;
 | 
					        use ::vkeyboard::c::ZwpVirtualKeyboardV1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // This is constructed only in C, no need for warnings
 | 
					        // This is constructed only in C, no need for warnings
 | 
				
			||||||
        #[allow(dead_code)]
 | 
					        #[allow(dead_code)]
 | 
				
			||||||
 | 
				
			|||||||
@ -28,8 +28,8 @@
 | 
				
			|||||||
#include "eek/eek.h"
 | 
					#include "eek/eek.h"
 | 
				
			||||||
#include "eekboard/eekboard-context-service.h"
 | 
					#include "eekboard/eekboard-context-service.h"
 | 
				
			||||||
#include "dbus.h"
 | 
					#include "dbus.h"
 | 
				
			||||||
#include "imservice.h"
 | 
					 | 
				
			||||||
#include "outputs.h"
 | 
					#include "outputs.h"
 | 
				
			||||||
 | 
					#include "submission.h"
 | 
				
			||||||
#include "server-context-service.h"
 | 
					#include "server-context-service.h"
 | 
				
			||||||
#include "wayland.h"
 | 
					#include "wayland.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -42,7 +42,7 @@ struct squeekboard {
 | 
				
			|||||||
    DBusHandler *dbus_handler;
 | 
					    DBusHandler *dbus_handler;
 | 
				
			||||||
    EekboardContextService *settings_context;
 | 
					    EekboardContextService *settings_context;
 | 
				
			||||||
    ServerContextService *ui_context;
 | 
					    ServerContextService *ui_context;
 | 
				
			||||||
    struct imservice *imservice;
 | 
					    struct submission *submission;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -261,16 +261,11 @@ main (int argc, char **argv)
 | 
				
			|||||||
        exit (1);
 | 
					        exit (1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct imservice *imservice = NULL;
 | 
					 | 
				
			||||||
    if (instance.wayland.input_method_manager) {
 | 
					    if (instance.wayland.input_method_manager) {
 | 
				
			||||||
        imservice = get_imservice(instance.wayland.input_method_manager,
 | 
					        // Cannot fail
 | 
				
			||||||
                                  instance.wayland.seat,
 | 
					        instance.submission = get_submission(instance.wayland.input_method_manager,
 | 
				
			||||||
                                  instance.settings_context);
 | 
					                                             instance.wayland.seat,
 | 
				
			||||||
        if (imservice) {
 | 
					                                             instance.settings_context);
 | 
				
			||||||
            instance.imservice = imservice;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            g_warning("Failed to register as an input method");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ServerContextService *ui_context = server_context_service_new(instance.settings_context);
 | 
					    ServerContextService *ui_context = server_context_service_new(instance.settings_context);
 | 
				
			||||||
@ -279,8 +274,8 @@ main (int argc, char **argv)
 | 
				
			|||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    instance.ui_context = ui_context;
 | 
					    instance.ui_context = ui_context;
 | 
				
			||||||
    if (instance.imservice) {
 | 
					    if (instance.submission) {
 | 
				
			||||||
        imservice_set_ui(instance.imservice, instance.ui_context);
 | 
					        submission_set_ui(instance.submission, instance.ui_context);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (instance.dbus_handler) {
 | 
					    if (instance.dbus_handler) {
 | 
				
			||||||
        dbus_handler_set_ui_context(instance.dbus_handler, instance.ui_context);
 | 
					        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
 | 
					/// Temporary reexport to keep stuff based directly on virtual-keyboard working
 | 
				
			||||||
/// until a unified handler appears and prompts a rework.
 | 
					/// until a unified handler appears and prompts a rework.
 | 
				
			||||||
pub use vkeyboard::*;
 | 
					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