use std::cell::UnsafeCell;
use std::ops::DerefMut;
use glk_sys;
use glk_sys::{
event_t, frefid_t, giblorb_err_t, giblorb_map_t, gidispatch_rock_t, glkdate_t, glktimeval_t,
glsi32, glui32, gluniversal_t, schanid_t, stream_result_t, strid_t, winid_t,
};
mod dummy;
pub mod ext;
pub mod filename;
pub mod garglk;
pub mod giblorb;
pub mod gidispatch;
pub mod helpers;
pub mod latin1;
pub mod traits;
pub mod types;
pub mod unicode;
mod util;
thread_local! {
static H: UnsafeCell<Box<dyn traits::Api>> = UnsafeCell::new(Box::new(dummy::Dummy {}));
}
static mut DUMMY: dummy::Dummy = dummy::Dummy {};
fn dummy() -> &'static mut dummy::Dummy {
unsafe { &mut DUMMY }
}
fn ctx() -> &'static mut dyn traits::Api {
unsafe { &mut (**H.with(|h| h.get())) }
}
fn ctx_base() -> impl DerefMut<Target = dyn traits::Base + 'static> {
ctx().base()
}
fn ctx_line_echo() -> impl DerefMut<Target = dyn traits::LineEcho + 'static> {
ctx().line_echo().unwrap_or(dummy())
}
fn ctx_line_terminators() -> impl DerefMut<Target = dyn traits::LineTerminators + 'static> {
ctx().line_terminators().unwrap_or(dummy())
}
fn ctx_unicode() -> impl DerefMut<Target = dyn traits::Unicode + 'static> {
ctx().unicode().unwrap_or(dummy())
}
fn ctx_unicode_norm() -> impl DerefMut<Target = dyn traits::UnicodeNorm + 'static> {
ctx().unicode_norm().unwrap_or(dummy())
}
fn ctx_image() -> impl DerefMut<Target = dyn traits::Image + 'static> {
ctx().image().unwrap_or(dummy())
}
fn ctx_sound() -> impl DerefMut<Target = dyn traits::Sound + 'static> {
ctx().sound().unwrap_or(dummy())
}
fn ctx_sound2() -> impl DerefMut<Target = dyn traits::Sound2 + 'static> {
ctx().sound2().unwrap_or(dummy())
}
fn ctx_hyperlinks() -> impl DerefMut<Target = dyn traits::Hyperlinks + 'static> {
ctx().hyperlinks().unwrap_or(dummy())
}
fn ctx_date_time() -> impl DerefMut<Target = dyn traits::Datetime + 'static> {
ctx().date_time().unwrap_or(dummy())
}
fn ctx_resource_stream() -> impl DerefMut<Target = dyn traits::ResourceStream + 'static> {
ctx().resource_stream().unwrap_or(dummy())
}
fn ctx_garglk_text() -> impl DerefMut<Target = dyn garglk::GarGlkText + 'static> {
ctx().garglk_text().unwrap_or(dummy())
}
fn ctx_giblorb() -> impl DerefMut<Target = dyn giblorb::Handlers + 'static> {
ctx().giblorb().unwrap_or(dummy())
}
fn ctx_gidispatch() -> impl DerefMut<Target = dyn gidispatch::Handlers + 'static> {
ctx().gidispatch().unwrap_or(dummy())
}
fn ctx_ext() -> impl DerefMut<Target = dyn ext::Handlers + 'static> {
ctx().ext().unwrap_or(dummy())
}
fn strlen<T: Copy + PartialEq + Default>(s: *const T) -> usize {
let mut rv = 0;
while unsafe { *s.add(rv) } != T::default() {
rv += 1;
}
rv
}
#[no_mangle]
pub extern "C" fn glk_set_interrupt_handler(func: ::std::option::Option<unsafe extern "C" fn()>) {
ctx_base().set_interrupt_handler(func)
}
#[no_mangle]
pub extern "C" fn glk_tick() {
ctx_base().tick()
}
#[no_mangle]
pub extern "C" fn glk_gestalt(sel: glui32, val: glui32) -> glui32 {
ctx_base().gestalt(types::gestalt(sel), val, &mut [])
}
#[no_mangle]
pub unsafe extern "C" fn glk_gestalt_ext(
sel: glui32,
val: glui32,
arr: *mut glui32,
arrlen: glui32,
) -> glui32 {
ctx_base().gestalt(
types::gestalt(sel),
val,
util::from_raw_parts_mut(arr, arrlen as usize),
)
}
#[no_mangle]
pub extern "C" fn glk_char_to_lower(ch: ::std::os::raw::c_uchar) -> ::std::os::raw::c_uchar {
ctx_base().char_to_lower(ch)
}
#[no_mangle]
pub extern "C" fn glk_char_to_upper(ch: ::std::os::raw::c_uchar) -> ::std::os::raw::c_uchar {
ctx_base().char_to_upper(ch)
}
#[no_mangle]
pub extern "C" fn glk_window_get_root() -> winid_t {
ctx_base().window_get_root()
}
#[no_mangle]
pub extern "C" fn glk_window_open(
split: winid_t,
method: glui32,
size: glui32,
wintype: glui32,
rock: glui32,
) -> winid_t {
ctx_base().window_open(
split,
types::winmethod(method),
size,
types::wintype(wintype),
rock,
)
}
#[no_mangle]
pub unsafe extern "C" fn glk_window_close(win: winid_t, result: *mut stream_result_t) {
let rv = ctx_base().window_close(win);
if !result.is_null() {
result.write(rv);
}
}
#[no_mangle]
pub unsafe extern "C" fn glk_window_get_size(
win: winid_t,
widthptr: *mut glui32,
heightptr: *mut glui32,
) {
let (width, height) = ctx_base().window_get_size(win);
if !widthptr.is_null() {
widthptr.write(width);
}
if !heightptr.is_null() {
heightptr.write(height);
}
}
#[no_mangle]
pub extern "C" fn glk_window_set_arrangement(
win: winid_t,
method: glui32,
size: glui32,
keywin: winid_t,
) {
ctx_base().window_set_arrangement(win, types::winmethod(method), size, keywin);
}
#[no_mangle]
pub unsafe extern "C" fn glk_window_get_arrangement(
win: winid_t,
methodptr: *mut glui32,
sizeptr: *mut glui32,
keywinptr: *mut winid_t,
) {
let (method, size, keywin) = ctx_base().window_get_arrangement(win);
if !methodptr.is_null() {
methodptr.write(method);
}
if !sizeptr.is_null() {
sizeptr.write(size);
}
if !keywinptr.is_null() {
keywinptr.write(keywin);
}
}
#[no_mangle]
pub unsafe extern "C" fn glk_window_iterate(win: winid_t, rockptr: *mut glui32) -> winid_t {
let (win, rock) = ctx_base().window_iterate(win);
if !rockptr.is_null() {
rockptr.write(rock);
}
win
}
#[no_mangle]
pub extern "C" fn glk_window_get_rock(win: winid_t) -> glui32 {
ctx_base().window_get_rock(win)
}
#[no_mangle]
pub extern "C" fn glk_window_get_type(win: winid_t) -> glui32 {
ctx_base().window_get_type(win).0
}
#[no_mangle]
pub extern "C" fn glk_window_get_parent(win: winid_t) -> winid_t {
ctx_base().window_get_parent(win)
}
#[no_mangle]
pub extern "C" fn glk_window_get_sibling(win: winid_t) -> winid_t {
ctx_base().window_get_sibling(win)
}
#[no_mangle]
pub extern "C" fn glk_window_clear(win: winid_t) {
ctx_base().window_clear(win)
}
#[no_mangle]
pub extern "C" fn glk_window_move_cursor(win: winid_t, xpos: glui32, ypos: glui32) {
ctx_base().window_move_cursor(win, xpos, ypos)
}
#[no_mangle]
pub extern "C" fn glk_window_get_stream(win: winid_t) -> strid_t {
ctx_base().window_get_stream(win)
}
#[no_mangle]
pub extern "C" fn glk_window_set_echo_stream(win: winid_t, str: strid_t) {
ctx_base().window_set_echo_stream(win, str)
}
#[no_mangle]
pub extern "C" fn glk_window_get_echo_stream(win: winid_t) -> strid_t {
ctx_base().window_get_echo_stream(win)
}
#[no_mangle]
pub extern "C" fn glk_set_window(win: winid_t) {
ctx_base().set_window(win)
}
#[no_mangle]
pub extern "C" fn glk_stream_open_file(fileref: frefid_t, fmode: glui32, rock: glui32) -> strid_t {
ctx_base().stream_open_file(fileref, types::filemode(fmode), rock)
}
#[no_mangle]
pub unsafe extern "C" fn glk_stream_open_memory(
buf: *mut ::std::os::raw::c_char,
buflen: glui32,
fmode: glui32,
rock: glui32,
) -> strid_t {
ctx_base().stream_open_memory(
&mut gidispatch::RetainableBuffer::new(
buf as *mut u8,
buflen as usize,
gidispatch::TYPECODE_U8_ARRAY,
),
types::filemode(fmode),
rock,
)
}
#[no_mangle]
pub unsafe extern "C" fn glk_stream_close(str: strid_t, result: *mut stream_result_t) {
let rv = ctx_base().stream_close(str);
if !result.is_null() {
result.write(rv);
}
}
#[no_mangle]
pub unsafe extern "C" fn glk_stream_iterate(strid: strid_t, rockptr: *mut glui32) -> strid_t {
let (strid, rock) = ctx_base().stream_iterate(strid);
if !rockptr.is_null() {
rockptr.write(rock);
}
strid
}
#[no_mangle]
pub extern "C" fn glk_stream_get_rock(str: strid_t) -> glui32 {
ctx_base().stream_get_rock(str)
}
#[no_mangle]
pub extern "C" fn glk_stream_set_position(str: strid_t, pos: glsi32, seekmode: glui32) {
ctx_base().stream_set_position(str, pos, types::seekmode(seekmode))
}
#[no_mangle]
pub extern "C" fn glk_stream_get_position(str: strid_t) -> glui32 {
ctx_base().stream_get_position(str)
}
#[no_mangle]
pub extern "C" fn glk_stream_set_current(str: strid_t) {
ctx_base().stream_set_current(str)
}
#[no_mangle]
pub extern "C" fn glk_stream_get_current() -> strid_t {
ctx_base().stream_get_current()
}
#[no_mangle]
pub extern "C" fn glk_put_char(ch: ::std::os::raw::c_uchar) {
ctx_base().put_char(ch)
}
#[no_mangle]
pub extern "C" fn glk_put_char_stream(str: strid_t, ch: ::std::os::raw::c_uchar) {
ctx_base().put_char_stream(str, ch)
}
#[no_mangle]
pub unsafe extern "C" fn glk_put_string(s: *const ::std::os::raw::c_char) {
assert!(!s.is_null());
let len = strlen(s);
ctx_base().put_buffer(util::from_raw_parts(s as *const u8, len))
}
#[no_mangle]
pub unsafe extern "C" fn glk_put_string_stream(str: strid_t, s: *const ::std::os::raw::c_char) {
assert!(!s.is_null());
let len = strlen(s);
ctx_base().put_buffer_stream(str, util::from_raw_parts(s as *const u8, len));
}
#[no_mangle]
pub unsafe extern "C" fn glk_put_buffer(buf: *const ::std::os::raw::c_char, len: glui32) {
ctx_base().put_buffer(util::from_raw_parts(buf as *const u8, len as usize))
}
#[no_mangle]
pub unsafe extern "C" fn glk_put_buffer_stream(
str: strid_t,
buf: *const ::std::os::raw::c_char,
len: glui32,
) {
ctx_base().put_buffer_stream(str, util::from_raw_parts(buf as *const u8, len as usize))
}
#[no_mangle]
pub extern "C" fn glk_set_style(styl: glui32) {
ctx_base().set_style(types::style(styl))
}
#[no_mangle]
pub extern "C" fn glk_set_style_stream(str: strid_t, styl: glui32) {
ctx_base().set_style_stream(str, types::style(styl))
}
#[no_mangle]
pub extern "C" fn glk_get_char_stream(str: strid_t) -> glsi32 {
ctx_base().get_char_stream(str)
}
#[no_mangle]
pub unsafe extern "C" fn glk_get_line_stream(
str: strid_t,
buf: *mut ::std::os::raw::c_char,
len: glui32,
) -> glui32 {
ctx_base().get_line_stream(str, util::from_raw_parts_mut(buf as *mut u8, len as usize))
}
#[no_mangle]
pub unsafe extern "C" fn glk_get_buffer_stream(
str: strid_t,
buf: *mut ::std::os::raw::c_char,
len: glui32,
) -> glui32 {
ctx_base().get_buffer_stream(str, util::from_raw_parts_mut(buf as *mut u8, len as usize))
}
#[no_mangle]
pub extern "C" fn glk_stylehint_set(wintype: glui32, styl: glui32, hint: glui32, val: glsi32) {
ctx_base().stylehint_set(
types::wintype(wintype),
types::style(styl),
types::stylehint(hint),
val,
)
}
#[no_mangle]
pub extern "C" fn glk_stylehint_clear(wintype: glui32, styl: glui32, hint: glui32) {
ctx_base().stylehint_clear(
types::wintype(wintype),
types::style(styl),
types::stylehint(hint),
)
}
#[no_mangle]
pub extern "C" fn glk_style_distinguish(win: winid_t, styl1: glui32, styl2: glui32) -> glui32 {
ctx_base().style_distinguish(win, types::style(styl1), types::style(styl2))
}
#[no_mangle]
pub unsafe extern "C" fn glk_style_measure(
win: winid_t,
styl: glui32,
hint: glui32,
result_ptr: *mut glui32,
) -> glui32 {
if let Some(result) = ctx_base().style_measure(win, types::style(styl), types::stylehint(hint))
{
if !result_ptr.is_null() {
result_ptr.write(result);
}
1
} else {
0
}
}
#[no_mangle]
pub extern "C" fn glk_fileref_create_temp(usage: glui32, rock: glui32) -> frefid_t {
ctx_base().fileref_create_temp(types::fileusage(usage), rock)
}
#[no_mangle]
pub unsafe extern "C" fn glk_fileref_create_by_name(
usage: glui32,
name: *const ::std::os::raw::c_char,
rock: glui32,
) -> frefid_t {
assert!(!name.is_null());
let len = strlen(name);
ctx_base().fileref_create_by_name(
types::fileusage(usage),
util::from_raw_parts(name as *const u8, len),
rock,
)
}
#[no_mangle]
pub extern "C" fn glk_fileref_create_by_prompt(
usage: glui32,
fmode: glui32,
rock: glui32,
) -> frefid_t {
ctx_base().fileref_create_by_prompt(types::fileusage(usage), types::filemode(fmode), rock)
}
#[no_mangle]
pub extern "C" fn glk_fileref_create_from_fileref(
usage: glui32,
fref: frefid_t,
rock: glui32,
) -> frefid_t {
ctx_base().fileref_create_from_fileref(types::fileusage(usage), fref, rock)
}
#[no_mangle]
pub extern "C" fn glk_fileref_destroy(fref: frefid_t) {
ctx_base().fileref_destroy(fref)
}
#[no_mangle]
pub unsafe extern "C" fn glk_fileref_iterate(fref: frefid_t, rockptr: *mut glui32) -> frefid_t {
let (fref, rock) = ctx_base().fileref_iterate(fref);
if !rockptr.is_null() {
rockptr.write(rock);
}
fref
}
#[no_mangle]
pub extern "C" fn glk_fileref_get_rock(fref: frefid_t) -> glui32 {
ctx_base().fileref_get_rock(fref)
}
#[no_mangle]
pub extern "C" fn glk_fileref_delete_file(fref: frefid_t) {
ctx_base().fileref_delete_file(fref)
}
#[no_mangle]
pub extern "C" fn glk_fileref_does_file_exist(fref: frefid_t) -> glui32 {
ctx_base().fileref_does_file_exist(fref)
}
#[no_mangle]
pub unsafe extern "C" fn glk_select(event_ptr: *mut event_t) {
let event = ctx_base().select();
assert!(!event_ptr.is_null());
event_ptr.write(event);
}
#[no_mangle]
pub unsafe extern "C" fn glk_select_poll(event_ptr: *mut event_t) {
let event = ctx_base().select_poll();
assert!(!event_ptr.is_null());
event_ptr.write(event);
}
#[no_mangle]
pub extern "C" fn glk_request_timer_events(millisecs: glui32) {
ctx_base().request_timer_events(millisecs)
}
#[no_mangle]
pub unsafe extern "C" fn glk_request_line_event(
win: winid_t,
buf: *mut ::std::os::raw::c_char,
maxlen: glui32,
initlen: glui32,
) {
ctx_base().request_line_event(
win,
&mut gidispatch::RetainableBuffer::new(
buf as *mut u8,
maxlen as usize,
gidispatch::TYPECODE_U8_ARRAY,
),
initlen,
)
}
#[no_mangle]
pub extern "C" fn glk_request_char_event(win: winid_t) {
ctx_base().request_char_event(win)
}
#[no_mangle]
pub extern "C" fn glk_request_mouse_event(win: winid_t) {
ctx_base().request_mouse_event(win)
}
#[no_mangle]
pub unsafe extern "C" fn glk_cancel_line_event(win: winid_t, event_ptr: *mut event_t) {
let event = ctx_base().cancel_line_event(win);
if !event_ptr.is_null() {
event_ptr.write(event);
}
}
#[no_mangle]
pub extern "C" fn glk_cancel_char_event(win: winid_t) {
ctx_base().cancel_char_event(win)
}
#[no_mangle]
pub extern "C" fn glk_cancel_mouse_event(win: winid_t) {
ctx_base().cancel_mouse_event(win)
}
#[no_mangle]
pub extern "C" fn glk_set_echo_line_event(win: winid_t, val: glui32) {
ctx_line_echo().set_echo_line_event(win, val)
}
#[no_mangle]
pub unsafe extern "C" fn glk_set_terminators_line_event(
win: winid_t,
keycodes: *const glui32,
count: glui32,
) {
ctx_line_terminators()
.set_terminators_line_event(win, util::from_raw_parts(keycodes, count as usize))
}
#[no_mangle]
pub unsafe extern "C" fn glk_buffer_to_lower_case_uni(
buf: *mut glui32,
len: glui32,
numchars: glui32,
) -> glui32 {
ctx_unicode().buffer_to_lower_case_uni(util::from_raw_parts_mut(buf, len as usize), numchars)
}
#[no_mangle]
pub unsafe extern "C" fn glk_buffer_to_upper_case_uni(
buf: *mut glui32,
len: glui32,
numchars: glui32,
) -> glui32 {
ctx_unicode().buffer_to_upper_case_uni(util::from_raw_parts_mut(buf, len as usize), numchars)
}
#[no_mangle]
pub unsafe extern "C" fn glk_buffer_to_title_case_uni(
buf: *mut glui32,
len: glui32,
numchars: glui32,
lowerrest: glui32,
) -> glui32 {
ctx_unicode().buffer_to_title_case_uni(
util::from_raw_parts_mut(buf, len as usize),
numchars,
lowerrest,
)
}
#[no_mangle]
pub extern "C" fn glk_put_char_uni(ch: glui32) {
ctx_unicode().put_char_uni(ch)
}
#[no_mangle]
pub unsafe extern "C" fn glk_put_string_uni(s: *const glui32) {
assert!(!s.is_null());
let len = strlen(s);
ctx_unicode().put_buffer_uni(util::from_raw_parts(s, len))
}
#[no_mangle]
pub unsafe extern "C" fn glk_put_buffer_uni(buf: *const glui32, len: glui32) {
ctx_unicode().put_buffer_uni(util::from_raw_parts(buf, len as usize))
}
#[no_mangle]
pub extern "C" fn glk_put_char_stream_uni(str: strid_t, ch: glui32) {
ctx_unicode().put_char_stream_uni(str, ch)
}
#[no_mangle]
pub unsafe extern "C" fn glk_put_string_stream_uni(str: strid_t, s: *const glui32) {
assert!(!s.is_null());
let len = strlen(s);
ctx_unicode().put_buffer_stream_uni(str, util::from_raw_parts(s, len))
}
#[no_mangle]
pub unsafe extern "C" fn glk_put_buffer_stream_uni(str: strid_t, buf: *const glui32, len: glui32) {
ctx_unicode().put_buffer_stream_uni(str, util::from_raw_parts(buf, len as usize))
}
#[no_mangle]
pub extern "C" fn glk_get_char_stream_uni(str: strid_t) -> glsi32 {
ctx_unicode().get_char_stream_uni(str)
}
#[no_mangle]
pub unsafe extern "C" fn glk_get_buffer_stream_uni(
str: strid_t,
buf: *mut glui32,
len: glui32,
) -> glui32 {
ctx_unicode().get_buffer_stream_uni(str, util::from_raw_parts_mut(buf, len as usize))
}
#[no_mangle]
pub unsafe extern "C" fn glk_get_line_stream_uni(
str: strid_t,
buf: *mut glui32,
len: glui32,
) -> glui32 {
ctx_unicode().get_line_stream_uni(str, util::from_raw_parts_mut(buf, len as usize))
}
#[no_mangle]
pub extern "C" fn glk_stream_open_file_uni(
fileref: frefid_t,
fmode: glui32,
rock: glui32,
) -> strid_t {
ctx_unicode().stream_open_file_uni(fileref, types::filemode(fmode), rock)
}
#[no_mangle]
pub unsafe extern "C" fn glk_stream_open_memory_uni(
buf: *mut glui32,
buflen: glui32,
fmode: glui32,
rock: glui32,
) -> strid_t {
ctx_unicode().stream_open_memory_uni(
&mut gidispatch::RetainableBuffer::new(
buf,
buflen as usize,
gidispatch::TYPECODE_U32_ARRAY,
),
types::filemode(fmode),
rock,
)
}
#[no_mangle]
pub extern "C" fn glk_request_char_event_uni(win: winid_t) {
ctx_unicode().request_char_event_uni(win)
}
#[no_mangle]
pub unsafe extern "C" fn glk_request_line_event_uni(
win: winid_t,
buf: *mut glui32,
maxlen: glui32,
initlen: glui32,
) {
ctx_unicode().request_line_event_uni(
win,
&mut gidispatch::RetainableBuffer::new(
buf,
maxlen as usize,
gidispatch::TYPECODE_U32_ARRAY,
),
initlen,
)
}
#[no_mangle]
pub unsafe extern "C" fn glk_buffer_canon_decompose_uni(
buf: *mut glui32,
len: glui32,
numchars: glui32,
) -> glui32 {
ctx_unicode_norm()
.buffer_canon_decompose_uni(util::from_raw_parts_mut(buf, len as usize), numchars)
}
#[no_mangle]
pub unsafe extern "C" fn glk_buffer_canon_normalize_uni(
buf: *mut glui32,
len: glui32,
numchars: glui32,
) -> glui32 {
ctx_unicode_norm()
.buffer_canon_normalize_uni(util::from_raw_parts_mut(buf, len as usize), numchars)
}
#[no_mangle]
pub extern "C" fn glk_image_draw(
win: winid_t,
image: glui32,
val1: glsi32,
val2: glsi32,
) -> glui32 {
ctx_image().image_draw(win, image, val1, val2)
}
#[no_mangle]
pub extern "C" fn glk_image_draw_scaled(
win: winid_t,
image: glui32,
val1: glsi32,
val2: glsi32,
width: glui32,
height: glui32,
) -> glui32 {
ctx_image().image_draw_scaled(win, image, val1, val2, width, height)
}
#[no_mangle]
pub unsafe extern "C" fn glk_image_get_info(
image: glui32,
width: *mut glui32,
height: *mut glui32,
) -> glui32 {
if let Some((w, h)) = ctx_image().image_get_info(image) {
if !width.is_null() {
width.write(w);
}
if !height.is_null() {
height.write(h);
}
1
} else {
0
}
}
#[no_mangle]
pub extern "C" fn glk_window_flow_break(win: winid_t) {
ctx_image().window_flow_break(win)
}
#[no_mangle]
pub extern "C" fn glk_window_erase_rect(
win: winid_t,
left: glsi32,
top: glsi32,
width: glui32,
height: glui32,
) {
ctx_image().window_erase_rect(win, left, top, width, height)
}
#[no_mangle]
pub extern "C" fn glk_window_fill_rect(
win: winid_t,
color: glui32,
left: glsi32,
top: glsi32,
width: glui32,
height: glui32,
) {
ctx_image().window_fill_rect(win, color, left, top, width, height)
}
#[no_mangle]
pub extern "C" fn glk_window_set_background_color(win: winid_t, color: glui32) {
ctx_image().window_set_background_color(win, color)
}
#[no_mangle]
pub extern "C" fn glk_schannel_create(rock: glui32) -> schanid_t {
ctx_sound().schannel_create(rock)
}
#[no_mangle]
pub extern "C" fn glk_schannel_destroy(chan: schanid_t) {
ctx_sound().schannel_destroy(chan)
}
#[no_mangle]
pub unsafe extern "C" fn glk_schannel_iterate(chan: schanid_t, rockptr: *mut glui32) -> schanid_t {
let (chan, rock) = ctx_sound().schannel_iterate(chan);
if !rockptr.is_null() {
rockptr.write(rock);
}
chan
}
#[no_mangle]
pub extern "C" fn glk_schannel_get_rock(chan: schanid_t) -> glui32 {
ctx_sound().schannel_get_rock(chan)
}
#[no_mangle]
pub extern "C" fn glk_schannel_play(chan: schanid_t, snd: glui32) -> glui32 {
ctx_sound().schannel_play(chan, snd)
}
#[no_mangle]
pub extern "C" fn glk_schannel_play_ext(
chan: schanid_t,
snd: glui32,
repeats: glui32,
notify: glui32,
) -> glui32 {
ctx_sound().schannel_play_ext(chan, snd, repeats, notify)
}
#[no_mangle]
pub extern "C" fn glk_schannel_stop(chan: schanid_t) {
ctx_sound().schannel_stop(chan)
}
#[no_mangle]
pub extern "C" fn glk_schannel_set_volume(chan: schanid_t, vol: glui32) {
ctx_sound().schannel_set_volume(chan, vol)
}
#[no_mangle]
pub extern "C" fn glk_sound_load_hint(snd: glui32, flag: glui32) {
ctx_sound().sound_load_hint(snd, flag)
}
#[no_mangle]
pub extern "C" fn glk_schannel_create_ext(rock: glui32, volume: glui32) -> schanid_t {
ctx_sound2().schannel_create_ext(rock, volume)
}
#[no_mangle]
pub unsafe extern "C" fn glk_schannel_play_multi(
chanarray: *mut schanid_t,
chancount: glui32,
sndarray: *mut glui32,
soundcount: glui32,
notify: glui32,
) -> glui32 {
assert!(!chanarray.is_null() && !sndarray.is_null());
ctx_sound2().schannel_play_multi(
util::from_raw_parts(chanarray, chancount as usize),
util::from_raw_parts(sndarray, soundcount as usize),
notify,
)
}
#[no_mangle]
pub extern "C" fn glk_schannel_pause(chan: schanid_t) {
ctx_sound2().schannel_pause(chan)
}
#[no_mangle]
pub extern "C" fn glk_schannel_unpause(chan: schanid_t) {
ctx_sound2().schannel_unpause(chan)
}
#[no_mangle]
pub extern "C" fn glk_schannel_set_volume_ext(
chan: schanid_t,
vol: glui32,
duration: glui32,
notify: glui32,
) {
ctx_sound2().schannel_set_volume_ext(chan, vol, duration, notify)
}
#[no_mangle]
pub extern "C" fn glk_set_hyperlink(linkval: glui32) {
ctx_hyperlinks().set_hyperlink(linkval)
}
#[no_mangle]
pub extern "C" fn glk_set_hyperlink_stream(str: strid_t, linkval: glui32) {
ctx_hyperlinks().set_hyperlink_stream(str, linkval)
}
#[no_mangle]
pub extern "C" fn glk_request_hyperlink_event(win: winid_t) {
ctx_hyperlinks().request_hyperlink_event(win)
}
#[no_mangle]
pub extern "C" fn glk_cancel_hyperlink_event(win: winid_t) {
ctx_hyperlinks().cancel_hyperlink_event(win)
}
#[no_mangle]
pub unsafe extern "C" fn glk_current_time(time: *mut glktimeval_t) {
assert!(!time.is_null());
time.write(ctx_date_time().current_time())
}
#[no_mangle]
pub extern "C" fn glk_current_simple_time(factor: glui32) -> glsi32 {
ctx_date_time().current_simple_time(factor)
}
#[no_mangle]
pub unsafe extern "C" fn glk_time_to_date_utc(time: *mut glktimeval_t, date: *mut glkdate_t) {
assert!(!time.is_null() && !date.is_null());
date.write(ctx_date_time().time_to_date_utc(time.read()))
}
#[no_mangle]
pub unsafe extern "C" fn glk_time_to_date_local(time: *mut glktimeval_t, date: *mut glkdate_t) {
assert!(!time.is_null() && !date.is_null());
date.write(ctx_date_time().time_to_date_local(time.read()))
}
#[no_mangle]
pub unsafe extern "C" fn glk_simple_time_to_date_utc(
time: glsi32,
factor: glui32,
date: *mut glkdate_t,
) {
assert!(!date.is_null());
date.write(ctx_date_time().simple_time_to_date_utc(time, factor))
}
#[no_mangle]
pub unsafe extern "C" fn glk_simple_time_to_date_local(
time: glsi32,
factor: glui32,
date: *mut glkdate_t,
) {
assert!(!date.is_null());
date.write(ctx_date_time().simple_time_to_date_local(time, factor))
}
#[no_mangle]
pub unsafe extern "C" fn glk_date_to_time_utc(date: *mut glkdate_t, time: *mut glktimeval_t) {
assert!(!date.is_null() && !time.is_null());
time.write(ctx_date_time().date_to_time_utc(date.read()));
}
#[no_mangle]
pub unsafe extern "C" fn glk_date_to_time_local(date: *mut glkdate_t, time: *mut glktimeval_t) {
assert!(!date.is_null() && !time.is_null());
time.write(ctx_date_time().date_to_time_local(date.read()));
}
#[no_mangle]
pub unsafe extern "C" fn glk_date_to_simple_time_utc(
date: *mut glkdate_t,
factor: glui32,
) -> glsi32 {
assert!(date.is_null());
ctx_date_time().date_to_simple_time_utc(date.read(), factor)
}
#[no_mangle]
pub unsafe extern "C" fn glk_date_to_simple_time_local(
date: *mut glkdate_t,
factor: glui32,
) -> glsi32 {
assert!(date.is_null());
ctx_date_time().date_to_simple_time_local(date.read(), factor)
}
#[no_mangle]
pub extern "C" fn glk_stream_open_resource(filenum: glui32, rock: glui32) -> strid_t {
ctx_resource_stream().stream_open_resource(filenum, rock)
}
#[no_mangle]
pub extern "C" fn glk_stream_open_resource_uni(filenum: glui32, rock: glui32) -> strid_t {
ctx_resource_stream().stream_open_resource_uni(filenum, rock)
}
#[no_mangle]
pub extern "C" fn giblorb_set_resource_map(file: strid_t) -> giblorb_err_t {
ctx_giblorb().giblorb_set_resource_map(file).0
}
#[no_mangle]
pub extern "C" fn giblorb_get_resource_map() -> *mut giblorb_map_t {
ctx_giblorb().giblorb_get_resource_map()
}
#[no_mangle]
pub extern "C" fn gidispatch_set_object_registry(
regi: ::std::option::Option<
unsafe extern "C" fn(
obj: *mut ::std::os::raw::c_void,
objclass: glui32,
) -> gidispatch_rock_t,
>,
unregi: ::std::option::Option<
unsafe extern "C" fn(
obj: *mut ::std::os::raw::c_void,
objclass: glui32,
objrock: gidispatch_rock_t,
),
>,
) {
ctx_gidispatch()
.gidispatch_set_object_registry(gidispatch::ObjRegistry::new_with_funcs(regi, unregi))
}
#[no_mangle]
pub extern "C" fn gidispatch_get_objrock(
obj: *mut ::std::os::raw::c_void,
objclass: glui32,
) -> gidispatch_rock_t {
ctx_gidispatch().gidispatch_get_objrock(obj, objclass)
}
#[no_mangle]
pub extern "C" fn gidispatch_set_retained_registry(
regi: ::std::option::Option<
unsafe extern "C" fn(
array: *mut ::std::os::raw::c_void,
len: glui32,
typecode: *const ::std::os::raw::c_char,
) -> gidispatch_rock_t,
>,
unregi: ::std::option::Option<
unsafe extern "C" fn(
array: *mut ::std::os::raw::c_void,
len: glui32,
typecode: *const ::std::os::raw::c_char,
objrock: gidispatch_rock_t,
),
>,
) {
ctx_gidispatch().gidispatch_set_retained_registry(gidispatch::RetainedRegistry::new_with_funcs(
regi, unregi,
))
}
#[no_mangle]
pub extern "C" fn gidispatch_set_autorestore_registry(
locatearr: ::std::option::Option<
unsafe extern "C" fn(
array: *mut ::std::os::raw::c_void,
len: glui32,
typecode: *const ::std::os::raw::c_char,
objrock: gidispatch_rock_t,
elemsizeref: *mut ::std::os::raw::c_int,
) -> ::std::os::raw::c_long,
>,
restorearr: ::std::option::Option<
unsafe extern "C" fn(
bufkey: ::std::os::raw::c_long,
len: glui32,
typecode: *const ::std::os::raw::c_char,
arrayref: *mut *mut ::std::os::raw::c_void,
) -> gidispatch_rock_t,
>,
) {
ctx_gidispatch().gidispatch_set_autorestore_registry(locatearr, restorearr)
}
#[no_mangle]
pub extern "C" fn garglk_set_zcolors(fg: glui32, bg: glui32) {
ctx_garglk_text().garglk_set_zcolors(garglk::zcolor(fg), garglk::zcolor(bg))
}
#[no_mangle]
pub extern "C" fn garglk_set_zcolors_stream(str: strid_t, fg: glui32, bg: glui32) {
ctx_garglk_text().garglk_set_zcolors_stream(str, garglk::zcolor(fg), garglk::zcolor(bg))
}
#[no_mangle]
pub extern "C" fn garglk_set_reversevideo(reverse: glui32) {
ctx_garglk_text().garglk_set_reversevideo(reverse)
}
#[no_mangle]
pub extern "C" fn garglk_set_reversevideo_stream(str: strid_t, reverse: glui32) {
ctx_garglk_text().garglk_set_reversevideo_stream(str, reverse)
}
#[no_mangle]
pub extern "C" fn rustglk_ext_prototype(funcnum: glui32) -> *const ::std::os::raw::c_char {
if let Some(s) = ctx_ext().ext_prototype(funcnum) {
assert!(s[s.len() - 1] == 0);
s.as_ptr() as *const ::std::os::raw::c_char
} else {
0 as *const ::std::os::raw::c_char
}
}
#[no_mangle]
pub extern "C" fn rustglk_ext_call(funcnum: glui32, numargs: glui32, arglist: *mut gluniversal_t) {
ctx_ext().ext_call(funcnum, unsafe {
util::from_raw_parts_mut(arglist, numargs as usize)
});
}
pub fn init(glk: Box<dyn traits::Api>) {
H.with(|h| unsafe {
*(h.get()) = glk;
});
}
pub fn reset() {
init(Box::new(dummy::Dummy {}));
}