Skip to content

Commit

Permalink
Remove some uses of static mut
Browse files Browse the repository at this point in the history
  • Loading branch information
declantsien committed Apr 13, 2024
1 parent 2b770d9 commit df8b8fc
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 41 deletions.
1 change: 1 addition & 0 deletions crates/emacs-sys/src/lisp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ impl LispObject {
pub struct ExternalPtr<T>(*mut T);

impl<T> Copy for ExternalPtr<T> {}
unsafe impl<T> Send for ExternalPtr<T> {}

// Derive fails for this type so do it manually
impl<T> Clone for ExternalPtr<T> {
Expand Down
49 changes: 38 additions & 11 deletions crates/winit/src/fns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use font::register_swash_font_driver;
use raw_window_handle::RawWindowHandle;
use std::ffi::CString;
use std::ptr;
use std::sync::Mutex;
use webrender_api::*;
use winit::dpi::LogicalSize;

Expand Down Expand Up @@ -75,7 +76,33 @@ pub type DisplayRef = ExternalPtr<Display>;
pub static tip_frame: LispObject = Qnil;

#[no_mangle]
pub static mut winit_display_list: DisplayInfoRef = DisplayInfoRef::new(ptr::null_mut());
pub static WINIT_DISPLAY_LIST: Mutex<DisplayInfoRef> =
Mutex::new(DisplayInfoRef::new(ptr::null_mut()));

fn winit_display_list() -> DisplayInfoRef {
let v = WINIT_DISPLAY_LIST.lock().map_or_else(
|e| {
log::error!("failed to read winit_display_list: {e:?}");
DisplayInfoRef::new(ptr::null_mut())
},
|v| v.clone(),
);
v
}

fn set_winit_display_list(dpyinfo: DisplayInfoRef) {
match WINIT_DISPLAY_LIST.lock().and_then(|mut v| Ok(*v = dpyinfo)) {
Err(e) => log::error!("failed to update winit_display_list: {e:?}"),
_ => {}
}
}

#[allow(unused_variables)]
#[no_mangle]
pub extern "C" fn winit_display_available() -> bool {
let display = winit_display_list();
!display.is_null()
}

#[allow(unused_variables)]
#[no_mangle]
Expand Down Expand Up @@ -148,11 +175,12 @@ pub extern "C" fn check_x_display_info(obj: LispObject) -> DisplayInfoRef {
return frame.display_info();
}

if !unsafe { winit_display_list.is_null() } {
return unsafe { winit_display_list };
let winit_display_list = winit_display_list();
if !winit_display_list.is_null() {
return winit_display_list;
}

error!("Webrender windows are not in use or not initialized");
error!("Winit frames are not in use or not initialized");
}

if let Some(terminal) = obj.as_terminal() {
Expand All @@ -167,7 +195,7 @@ pub extern "C" fn check_x_display_info(obj: LispObject) -> DisplayInfoRef {

if let Some(display_name) = obj.as_string() {
let display_name = display_name.to_string();
let mut dpyinfo = unsafe { winit_display_list };
let mut dpyinfo = winit_display_list();

while !dpyinfo.is_null() {
if dpyinfo
Expand All @@ -186,8 +214,9 @@ pub extern "C" fn check_x_display_info(obj: LispObject) -> DisplayInfoRef {

x_open_connection(obj, Qnil, Qnil);

if !unsafe { winit_display_list.is_null() } {
return unsafe { winit_display_list };
let winit_display_list = winit_display_list();
if !winit_display_list.is_null() {
return winit_display_list;
}

error!("Display on {} not responding.", display_name);
Expand Down Expand Up @@ -517,10 +546,8 @@ pub fn x_open_connection(
let mut display_info = winit_term_init(display);

// Put this display on the chain.
unsafe {
display_info.next = winit_display_list.as_mut();
winit_display_list = display_info;
}
display_info.next = winit_display_list().as_mut();
set_winit_display_list(display_info);
Qnil
}

Expand Down
56 changes: 29 additions & 27 deletions crates/winit/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use emacs_sys::globals::Qt;
use emacs_sys::lisp::LispObject;
use emacs_sys::sys::EmacsModifiers::down_modifier;
use emacs_sys::sys::EmacsModifiers::up_modifier;
use std::sync::OnceLock;
use std::sync::LazyLock;
use std::sync::Mutex;
use winit::dpi::PhysicalPosition;
use winit::event::ElementState;
use winit::event::MouseButton;
Expand All @@ -23,22 +24,17 @@ use winit::keyboard::KeyCode;
use winit::keyboard::ModifiersState;
use winit::keyboard::PhysicalKey;

static mut INPUT_STATE: OnceLock<InputProcessor> = OnceLock::new();
static INPUT_STATE: LazyLock<Mutex<InputProcessor>> =
LazyLock::new(|| Mutex::new(InputProcessor::default()));
impl InputProcessor {
pub fn global() -> &'static InputProcessor {
unsafe {
INPUT_STATE.get_or_init(|| {
log::trace!("INPUT_STATE is being created...");
InputProcessor {
modifiers: ModifiersState::default(),
total_delta: PhysicalPosition::new(0.0, 0.9),
}
})
}
}

pub fn snapshot() -> InputProcessor {
Self::global().clone()
INPUT_STATE.lock().map_or_else(
|e| {
log::error!("Failed to snapshot INPUT_STATE {e:?}");
InputProcessor::default()
},
|s| s.clone(),
)
}

fn update(new_state: InputProcessor) {
Expand All @@ -47,13 +43,9 @@ impl InputProcessor {
new_state.modifiers,
new_state.total_delta
);
unsafe {
let _ = INPUT_STATE.take();
};
if let Ok(_) = unsafe { INPUT_STATE.set(new_state) } {
log::debug!("Global input state changed");
} else {
log::error!("Failed to update input state");
match INPUT_STATE.lock().and_then(|mut s| Ok(*s = new_state)) {
Err(e) => log::error!("Failed to update INPUT_STATE: {e:?}"),
_ => {}
}
}
}
Expand All @@ -64,6 +56,16 @@ pub struct InputProcessor {
total_delta: PhysicalPosition<f64>,
}

impl Default for InputProcessor {
#[inline]
fn default() -> Self {
InputProcessor {
modifiers: ModifiersState::default(),
total_delta: PhysicalPosition::new(0.0, 0.9),
}
}
}

impl InputProcessor {
pub fn handle_modifiers_changed(new_state: ModifiersState) {
let snapshot = Self::snapshot();
Expand Down Expand Up @@ -96,14 +98,14 @@ impl InputProcessor {
}

fn get_modifiers() -> ModifiersState {
let InputProcessor { modifiers, .. } = Self::global();
let InputProcessor { modifiers, .. } = Self::snapshot();
modifiers.clone()
}
}

impl InputProcessor {
pub fn handle_receive_char(c: char, top_frame: LispObject) -> Option<input_event> {
let state = Self::global();
let state = Self::snapshot();

let iev: input_event = InputEvent {
kind: event_kind::ASCII_KEYSTROKE_EVENT,
Expand Down Expand Up @@ -132,7 +134,7 @@ impl InputProcessor {
None
}
PhysicalKey::Code(key_code) => {
let InputProcessor { modifiers, .. } = Self::global().clone();
let InputProcessor { modifiers, .. } = Self::snapshot();
if keycode_to_emacs_key_name(key_code).is_null() {
return None;
}
Expand Down Expand Up @@ -184,7 +186,7 @@ impl InputProcessor {
pos = frame.cursor_position();
}

let InputProcessor { modifiers, .. } = Self::global();
let InputProcessor { modifiers, .. } = Self::snapshot();
let iev: input_event = InputEvent {
kind: event_kind::MOUSE_CLICK_EVENT,
part: scroll_bar_part::scroll_bar_nowhere,
Expand Down Expand Up @@ -226,7 +228,7 @@ impl InputProcessor {
}
}
MouseScrollDelta::PixelDelta(pos) => {
let mut total_delta = Self::global().total_delta.clone();
let mut total_delta = Self::snapshot().total_delta.clone();
if phase != TouchPhase::Moved {
total_delta = PhysicalPosition::new(0.0, 0.0);
}
Expand Down
1 change: 1 addition & 0 deletions crates/winit/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
#![feature(concat_idents)]
#![feature(lazy_cell)]
#![allow(non_upper_case_globals)]

#[macro_use]
Expand Down
4 changes: 4 additions & 0 deletions src/frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ decode_any_frame (register Lisp_Object frame)
bool
display_available (void)
{
#ifdef HAVE_WINIT
return winit_display_available();
#else
return x_display_list != NULL;
#endif
}
#endif

Expand Down
4 changes: 1 addition & 3 deletions src/winitterm.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,6 @@ struct winit_display_info
void *gl_renderer_data;
};

extern struct winit_display_info *winit_display_list;
#define x_display_list winit_display_list

struct winit_output
{

Expand Down Expand Up @@ -172,6 +169,7 @@ extern const char *app_bundle_relocate (const char *);

/* Symbol initializations implemented in each pgtk sources. */
extern void syms_of_winit_term(void);
extern bool winit_display_available(void);

#include "webrender_ffi.h"

Expand Down

0 comments on commit df8b8fc

Please sign in to comment.