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
//! This file contains the C-facing functions that are registered directly
//! with Hexchat when a client plugin registers a Rust-facing callback.
//! The callbacks in this file wrap the Rust-facing callbacks, marshal
//! the parameters (word, word_eol, etc) for the Rust callbacks.
use libc::{c_int, c_char, c_void};
use std::panic::catch_unwind;
use crate::callback_data::CallbackData;
use crate::hexchat::Eat;
use crate::hexchat::EventAttrs;
use crate::hexchat_entry_points::PHEXCHAT;
use crate::utils::*;
/// An actual callback registered with Hexchat, which proxies for client plugin
/// callbacks. It builds the `String` vectors passed to client callbacks.
/// See [Hexchat API](https://hexchat.readthedocs.io/en/latest/plugins.html)
pub (crate)
extern "C" fn c_callback(word : *const *const c_char,
word_eol : *const *const c_char,
user_data : *mut c_void)
-> c_int
{
catch_unwind(|| {
let word = argv2svec(word, 1);
let word_eol = argv2svec(word_eol, 1);
unsafe {
let cd = user_data as *mut CallbackData;
let hc = &*PHEXCHAT;
(*cd).command_cb(hc, &word, &word_eol, (*cd).get_user_data()) as _
}
}).unwrap_or(Eat::None as i32)
}
/// An actual callback registered with Hexchat, which proxies for client plugin
/// callbacks. It builds the `String` vector and invokes the client plugin's
/// callbacks. The client plugin callback and data is placed within the
/// `user_data`.
pub (crate)
extern "C" fn c_print_callback(word : *const *const c_char,
user_data : *mut c_void)
-> c_int
{
catch_unwind(|| {
let word = argv2svec(word, 1);
unsafe {
let cd = user_data as *mut CallbackData;
let hc = &*PHEXCHAT;
(*cd).print_cb(hc, &word, (*cd).get_user_data()) as _
}
}).unwrap_or(Eat::None as i32)
}
/// An actual callback registered with Hexchat, which proxies for client plugin
/// callbacks.
/// See [Hexchat API](https://hexchat.readthedocs.io/en/latest/plugins.html)
pub (crate)
extern "C" fn c_print_attrs_callback(word : *const *const c_char,
attrs : *const EventAttrs,
user_data : *mut c_void)
-> c_int
{
catch_unwind(|| {
let word = argv2svec(word, 1);
unsafe {
let cd = user_data as *mut CallbackData;
let hc = &*PHEXCHAT;
(*cd).print_attrs_cb(hc, &word, &*attrs, (*cd).get_user_data()) as _
}
}).unwrap_or(Eat::None as i32)
}
/// An actual callback registered with Hexchat, which proxies for client plugin
/// callbacks.
pub (crate)
extern "C" fn c_timer_callback(user_data: *mut c_void) -> c_int {
catch_unwind(|| {
unsafe {
let cd = user_data as *mut CallbackData;
let hc = &*PHEXCHAT;
(*cd).timer_cb(hc, (*cd).get_user_data())
}
}).unwrap_or(0)
}
/// A special case callback. This is used by the multi threading support to
/// put code on the main thread from code running on an independent thread.
/// The `CallbackData` object will ensure that this callback gets unhooked
/// after a one-time callback is executed.
#[allow(dead_code)]
pub (crate)
extern "C" fn c_timer_callback_once(user_data: *mut c_void) -> c_int {
catch_unwind(|| {
unsafe {
let cd = user_data as *mut CallbackData;
let hc = &*PHEXCHAT;
(*cd).timer_once_cb(hc, (*cd).get_user_data())
}
}).unwrap_or(0)
}
/// An actual callback registered with Hexchat, which proxies for client plugin
/// callbacks.
pub (crate)
extern "C" fn c_fd_callback(fd: c_int, flags: c_int, user_data: *mut c_void)
-> c_int
{
catch_unwind(|| {
unsafe {
let cd = user_data as *mut CallbackData;
let hc = &*PHEXCHAT;
(*cd).fd_cb(hc, fd, flags, (*cd).get_user_data()) as i32
}
}).unwrap_or(Eat::None as i32)
}