extern "C" fn preedit_draw_callback(
    _xim: ffi::XIM,
    client_data: ffi::XPointer,
    call_data: ffi::XPointer,
) {
    let client_data = unsafe { &mut *(client_data as *mut ImeContextClientData) };
    let call_data = unsafe { &mut *(call_data as *mut XIMPreeditDrawCallbackStruct) };
    client_data.cursor_pos = call_data.caret as usize;

    let chg_range =
        call_data.chg_first as usize..(call_data.chg_first + call_data.chg_length) as usize;
    if chg_range.start > client_data.text.len() || chg_range.end > client_data.text.len() {
        warn!(
            "invalid chg range: buffer length={}, but chg_first={} chg_lengthg={}",
            client_data.text.len(),
            call_data.chg_first,
            call_data.chg_length
        );
        return;
    }

    // NULL indicate text deletion
    let mut new_chars = if call_data.text.is_null() {
        Vec::new()
    } else {
        let xim_text = unsafe { &mut *(call_data.text) };
        if xim_text.encoding_is_wchar > 0 {
            return;
        }

        let new_text = unsafe { xim_text.string.multi_byte };

        if new_text.is_null() {
            return;
        }

        let new_text = unsafe { CStr::from_ptr(new_text) };

        String::from(new_text.to_str().expect("Invalid UTF-8 String from IME"))
            .chars()
            .collect()
    };
    let mut old_text_tail = client_data.text.split_off(chg_range.end);
    client_data.text.truncate(chg_range.start);
    client_data.text.append(&mut new_chars);
    client_data.text.append(&mut old_text_tail);
    let cursor_byte_pos = calc_byte_position(&client_data.text, client_data.cursor_pos);

    client_data
        .event_sender
        .send((
            client_data.window,
            ImeEvent::Update(client_data.text.iter().collect(), cursor_byte_pos),
        ))
        .expect("failed to send preedit update event");
}
/// Preedit text information to be drawn inline by the client.
Preedit text information to be drawn inline by the client.
Preedit text information to be drawn inline by the client .
extern "C" fn preedit_draw_callback(
    _xim: ffi::XIM,
    client_data: ffi::XPointer,
    call_data: ffi::XPointer,
) {
    let client_data = unsafe { &mut *(client_data as *mut ImeContextClientData) };
    let call_data = unsafe { &mut *(call_data as *mut XIMPreeditDrawCallbackStruct) };
    client_data.cursor_pos = call_data.caret as usize;
    let chg_range =
        call_data.chg_first as usize..(call_data.chg_first + call_data.chg_length) as usize;
    if chg_range.start > client_data.text.len() || chg_range.end > client_data.text.len() {
        warn!(
            "invalid chg range: buffer length={}, but chg_first={} chg_lengthg={}",
            client_data.text.len(),
            call_data.chg_first,
            call_data.chg_length
        );
        return;
    }
    // NULL indicate text deletion
    let mut new_chars = if call_data.text.is_null() {
        Vec::new()
    } else {
        let xim_text = unsafe { &mut *(call_data.text) };
        if xim_text.encoding_is_wchar > 0 {
            return;
        }
        let new_text = unsafe { xim_text.string.multi_byte };
        if new_text.is_null() {
            return;
        }
        let new_text = unsafe { CStr::from_ptr(new_text) };
        String::from(new_text.to_str().expect("Invalid UTF-8 String from IME"))
            .chars()
            .collect()
    };
    let mut old_text_tail = client_data.text.split_off(chg_range.end);
    client_data.text.truncate(chg_range.start);
    client_data.text.append(&mut new_chars);
    client_data.text.append(&mut old_text_tail);
    let cursor_byte_pos = calc_byte_position(&client_data.text, client_data.cursor_pos);
    client_data
        .event_sender
        .send((
            client_data.window,
            ImeEvent::Update(client_data.text.iter().collect(), cursor_byte_pos),
        ))
        .expect("failed to send preedit update event");
}
extern " " fn preedit_draw_callback ( _xim : ffi :: XIM , client_data : ffi :: XPointer , call_data : ffi :: XPointer , ) { let client_data = unsafe { & mut * ( client_data as * mut ImeContextClientData ) } ; let call_data = unsafe { & mut * ( call_data as * mut XIMPreeditDrawCallbackStruct ) } ; client_data . cursor_pos = call_data . caret as usize ; let chg_range = call_data . chg_first as usize .. ( call_data . chg_first + call_data . chg_length ) as usize ; if chg_range . start > client_data . text . len ( ) || chg_range . end > client_data . text . len ( ) { warn ! ( " " client_data text len ( ) call_data chg_first call_data chg_length ) ; return ; } // NULL indicate text deletion let mut new_chars = if call_data . text . is_null ( ) { Vec :: new ( ) } else { let xim_text = unsafe { & mut * ( call_data . text ) } ; if xim_text . encoding_is_wchar > 0 { return ; } let new_text = unsafe { xim_text . string . multi_byte } ; if new_text . is_null ( ) { return ; } let new_text = unsafe { CStr :: from_ptr ( new_text ) } ; String :: from ( new_text . to_str ( ) . expect ( " " ) ) . chars ( ) . collect ( ) } ; let mut old_text_tail = client_data . text . split_off ( chg_range . end ) ; client_data . text . truncate ( chg_range . start ) ; client_data . text . append ( & mut new_chars ) ; client_data . text . append ( & mut old_text_tail ) ; let cursor_byte_pos = calc_byte_position ( & client_data . text , client_data . cursor_pos ) ; client_data . event_sender . send ( ( client_data . window , ImeEvent :: Update ( client_data . text . iter ( ) . collect ( ) , cursor_byte_pos ) , ) ) . expect ( " " ) ; }
Preedit text information to be drawn inline by the client.
Preedit text information to be drawn inline by the client .
_xim
ffi::XIM
client_data
ffi::XPointer
call_data
ffi::XPointer