1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// external functions

pub use super::*;

/**
 * Allocates heap space for a CWin structure and passes a pointer back.
 */
#[no_mangle]
pub extern fn alloc_win() -> *mut CWin {
  return CWin::new().to_ffi_ptr();
}

#[no_mangle]
pub extern fn alloc_win_detail(title: *const c_char, width: u32, height: u32) -> *mut CWin {
  let title_owned: String = unsafe { // may get null pointer for 'title'
    CStr::from_ptr(title).to_str().unwrap().to_owned()
  };
  return CWin::new_detail(title_owned, width, height).to_ffi_ptr();
}

/**
 * Takes a raw CWin pointer and deallocates it.
 * Deallocation happens when the 'data' variable goes out of scope.
 */
#[no_mangle]
pub extern fn dealloc_win(win_ptr: *mut CWin) {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return;
    }
    let _data = Box::from_raw(win_ptr);
  }
}

#[no_mangle]
pub extern fn add_callback(win_ptr: *mut CWin, ffi_fun: extern fn(*mut CWinRep, *const c_char /* event string */)) {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return;
    }
    (*win_ptr).add_callback(ffi_fun);
  }
}

#[no_mangle]
pub extern fn call_callbacks(win_ptr: *mut CWin, evt_str: *const c_char /* event string */) {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return;
    }
    (*win_ptr).call_callbacks(evt_str);
  }
}

#[no_mangle]
pub extern fn event_loop(win_ptr: *mut CWin, ) {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return;
    }
    (*win_ptr).event_loop();
  }
}

#[no_mangle]
pub extern fn event_tick(win_ptr: *mut CWin, ) -> *const c_char {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return null_mut();
    }
    return (*win_ptr).event_tick();
  }
}

#[no_mangle]
pub extern fn init(win_ptr: *mut CWin, ) {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return;
    }
    (*win_ptr).init();
  }
}

#[no_mangle]
pub extern fn set_rep_exit_flag(win_ptr: *mut CWin, val: libc::c_uchar) {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return;
    }
    println!("set_rep_exit_flag = {}", val != 0);
    (*win_ptr).rep.exit_flag = val != 0;
    // 0 is false, non-zero becomes true.
  }
}

#[no_mangle]
pub extern fn redraw_dirty(win_ptr: *mut CWin) {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return;
    }
    (*win_ptr).redraw_dirty();
  }
}

#[no_mangle]
pub extern fn redraw_box(win_ptr: *mut CWin, x1: u32, y1: u32, x2: u32, y2: u32, ) {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return;
    }
    (*win_ptr).redraw_box(x1 as usize, y1 as usize, x2 as usize, y2 as usize);
  }
}

#[no_mangle]
pub extern fn write_px(win_ptr: *mut CWin, x: u32, y: u32, red: libc::c_uchar, green: libc::c_uchar, blue: libc::c_uchar) {
  unsafe { // unsafe b/c we may get a null pointer for 'win_ptr'
    if win_ptr.is_null() {
      return;
    }
    (*win_ptr).write_px(x, y, [red as u8, green as u8, blue as u8]);
  }
}