1
2pub use super::*;
3
4impl RenderBack for CWin {
6 fn init(&mut self) {
7 if self.rep.init_flag {
8 return;
9 }
10 unsafe {
12 match x11_dl::xlib::Xlib::open() {
13 Ok(the_lib) => {
14 ptr::write(&mut (self.rep.xlib_dl_obj), the_lib);
16 }
17 Err(_e) => {
18 println!("[ CGUI ] Fatal Error: we expect to be able to open XLib but cannot. You have uninitialized memory and cannot continue.");
19 return;
20 }
21 }
22
23 self.rep.x11_disp_ptr = (self.rep.xlib_dl_obj.XOpenDisplay)(null_mut());
24 let screen = (self.rep.xlib_dl_obj.XDefaultScreen)(self.rep.x11_disp_ptr);
25 self.rep.x11_window_ptr = (self.rep.xlib_dl_obj.XCreateSimpleWindow)(
26 self.rep.x11_disp_ptr, (self.rep.xlib_dl_obj.XRootWindow)(self.rep.x11_disp_ptr, screen),
27 0, 0, self.rep.width as u32, self.rep.height as u32,
29 0 , (self.rep.xlib_dl_obj.XBlackPixel)(self.rep.x11_disp_ptr, screen) , (self.rep.xlib_dl_obj.XWhitePixel)(self.rep.x11_disp_ptr, screen) );
31 let root_win_ptr = (self.rep.xlib_dl_obj.XDefaultRootWindow)(self.rep.x11_disp_ptr);
32
33 (self.rep.xlib_dl_obj.XSelectInput)(self.rep.x11_disp_ptr, self.rep.x11_window_ptr,
34 x11_dl::xlib::ExposureMask | x11_dl::xlib::KeyPressMask | x11_dl::xlib::PointerMotionMask | x11_dl::xlib::ButtonPressMask | x11_dl::xlib::ButtonReleaseMask | x11_dl::xlib::ButtonReleaseMask
35 );
36 (self.rep.xlib_dl_obj.XMapWindow)(self.rep.x11_disp_ptr, self.rep.x11_window_ptr);
37
38 let title_ffi_content = CString::new(self.rep.title.clone()).expect("CString::new failed");
39 (self.rep.xlib_dl_obj.XSetWMName)(self.rep.x11_disp_ptr, self.rep.x11_window_ptr, &mut x11_dl::xlib::XTextProperty {
40 value: title_ffi_content.into_raw() as *mut _ as *mut u8,
41 encoding: x11_dl::xlib::XA_STRING,
42 format: 8, nitems: self.rep.title.len() as u64,
44 });
45
46 self.rep.x11_gc_ptr = (self.rep.xlib_dl_obj.XCreateGC)(self.rep.x11_disp_ptr, root_win_ptr, 0, null_mut() );
47
48 }
49 self.rep.init_flag = true;
50 self.call_callbacks("WinShown".to_string());
52 self.redraw_dirty();
54 }
55
56 fn redraw_dirty(&mut self) {
57 let x1 = self.rep.dirty_extents[0];
58 let y1 = self.rep.dirty_extents[1];
59 let x2 = self.rep.dirty_extents[2];
60 let y2 = self.rep.dirty_extents[3];
61 self.redraw_box(x1, y1, x2, y2);
62 self.rep.dirty_extents = [self.rep.width, self.rep.height, 0, 0]; }
64
65 fn redraw_box(&mut self, x1: usize, y1: usize, x2: usize, y2: usize) {
66 self.rep.redraw_box(x1, y1, x2, y2);
67 }
68
69 fn event_tick(&self) -> String {
72 unsafe {
73 let mut event: x11_dl::xlib::XEvent = mem::zeroed(); (self.rep.xlib_dl_obj.XNextEvent)(self.rep.x11_disp_ptr, &mut event);
75
76 let evt_str: String = match event.get_type() {
77 x11_dl::xlib::Expose => {
78 "WinShown".to_string()
79 }
80 x11_dl::xlib::KeyPress => {
81 match get_alpha_char_from_x11_evt(&self.rep, event) {
82 Some(c) => {
83 format!("KeyPress,{}", c)
84 }
85 None => {
86 "KeyPress,UNKNOWN".to_string()
87 }
88 }
89 }
90 6 => { format!("MouseMove,{},{}", event.motion.x, event.motion.y)
92 }
93 5 => { format!("MouseUp,{},{}", event.motion.x, event.motion.y)
95 }
96 num => {
97 format!("UNKNOWN: {}", num)
98 }
99 };
100
101 return evt_str;
105 }
106 }
107
108 fn event_loop(&mut self) {
109 if ! self.rep.init_flag {
110 self.init();
111 }
112 while ! self.rep.exit_flag {
113 let evt_mess = self.event_tick();
114 self.call_callbacks(evt_mess);
115 }
116 }
117}
118
119fn get_alpha_char_from_x11_evt(self_cwin_rep: &CWinRep, mut event: x11_dl::xlib::XEvent) -> Option<char> {
120 unsafe {
121 let key_pressed_buff = CString::new("buff-buff-buff-buff").expect("CString::new failed");
122 let mut key_sym : x11_dl::xlib::KeySym = mem::zeroed();
123 let c_str_ptr = key_pressed_buff.into_raw();
124 (self_cwin_rep.xlib_dl_obj.XLookupString)(&mut event.key, c_str_ptr, 8 , &mut key_sym, null_mut());
125 let returned_data = CStr::from_ptr(c_str_ptr);
127 if returned_data.to_bytes().len() < 1 {
128 println!("TODO: handle an empty character (I think this happens on arrow keys)");
129 return None;
130 }
131 let first_char : char = (returned_data.to_bytes()[0] as u8) as char;
133 return Some(first_char);
134 }
141}
142
143impl RenderBack for CWinRep {
144 fn init(&mut self) {
145 if self.init_flag {
146 return;
147 }
148 unsafe {
150 match x11_dl::xlib::Xlib::open() {
151 Ok(the_lib) => {
152 ptr::write(&mut (self.xlib_dl_obj), the_lib);
154 }
155 Err(_e) => {
156 println!("[ CGUI ] Fatal Error: we expect to be able to open XLib but cannot. You have uninitialized memory and cannot continue.");
157 return;
158 }
159 }
160
161 self.x11_disp_ptr = (self.xlib_dl_obj.XOpenDisplay)(null_mut());
162 let screen = (self.xlib_dl_obj.XDefaultScreen)(self.x11_disp_ptr);
163 self.x11_window_ptr = (self.xlib_dl_obj.XCreateSimpleWindow)(
164 self.x11_disp_ptr, (self.xlib_dl_obj.XRootWindow)(self.x11_disp_ptr, screen),
165 0, 0, self.width as u32, self.height as u32,
167 0 , (self.xlib_dl_obj.XBlackPixel)(self.x11_disp_ptr, screen) , (self.xlib_dl_obj.XWhitePixel)(self.x11_disp_ptr, screen) );
169 let root_win_ptr = (self.xlib_dl_obj.XDefaultRootWindow)(self.x11_disp_ptr);
170
171 (self.xlib_dl_obj.XSelectInput)(self.x11_disp_ptr, self.x11_window_ptr, x11_dl::xlib::ExposureMask | x11_dl::xlib::KeyPressMask);
172 (self.xlib_dl_obj.XMapWindow)(self.x11_disp_ptr, self.x11_window_ptr);
173
174 let title_ffi_content = CString::new(self.title.clone()).expect("CString::new failed");
175 (self.xlib_dl_obj.XSetWMName)(self.x11_disp_ptr, self.x11_window_ptr, &mut x11_dl::xlib::XTextProperty {
176 value: title_ffi_content.into_raw() as *mut _ as *mut u8,
177 encoding: x11_dl::xlib::XA_STRING,
178 format: 8, nitems: self.title.len() as u64,
180 });
181
182 self.x11_gc_ptr = (self.xlib_dl_obj.XCreateGC)(self.x11_disp_ptr, root_win_ptr, 0, null_mut() );
183
184 }
185 self.init_flag = true;
186 }
187
188 fn redraw_dirty(&mut self) {
189 let x1 = self.dirty_extents[0];
190 let y1 = self.dirty_extents[1];
191 let x2 = self.dirty_extents[2];
192 let y2 = self.dirty_extents[3];
193 self.redraw_box(x1, y1, x2, y2);
194 self.dirty_extents = [self.width, self.height, 0, 0]; }
196
197 fn redraw_box(&mut self, x1: usize, y1: usize, x2: usize, y2: usize) {
198
199 if x1 == x2 || y1 == y2 {
200 return;
202 }
203 if x1 > x2 || y1 > y2 {
204 return;
206 }
207
208 unsafe {
209 for x in x1..x2 {
211 for y in y1..y2 {
212 let color = self.pixels.get_pixel(x as u32, y as u32).to_rgb().data;
213 let color_int: u64 = ((color[0] as u64) << 16) |
215 ((color[1] as u64) << 8) |
216 ((color[2] as u64) << 0)
217 ;
218 (self.xlib_dl_obj.XSetForeground)(self.x11_disp_ptr, self.x11_gc_ptr, color_int as u64);
221 (self.xlib_dl_obj.XDrawPoint)(self.x11_disp_ptr, self.x11_window_ptr, self.x11_gc_ptr, x as i32, y as i32);
222 }
223 }
224
225 let pixmap = (self.xlib_dl_obj.XCreatePixmap)(
226 self.x11_disp_ptr, self.x11_window_ptr, self.width as u32, self.height as u32, 8 );
228 (self.xlib_dl_obj.XFreePixmap)(self.x11_disp_ptr, pixmap);
229
230
231 (self.xlib_dl_obj.XFlush)(self.x11_disp_ptr);
232 }
233 }
234
235 fn event_tick(&self) -> String {
240 unsafe {
241 let mut event: x11_dl::xlib::XEvent = mem::zeroed(); (self.xlib_dl_obj.XNextEvent)(self.x11_disp_ptr, &mut event);
243
244 let evt_str: String = match event.get_type() {
245 x11_dl::xlib::Expose => {
246 "WinShown".to_string()
247 }
248 x11_dl::xlib::KeyPress => {
249 match get_alpha_char_from_x11_evt(self, event) {
250 Some(c) => {
251 format!("KeyPress,{}", c)
252 }
253 None => {
254 "KeyPress,UNKNOWN".to_string()
255 }
256 }
257 }
258 _ => {
259 "UNKNOWN".to_string()
260 }
261 };
262
263 let safe_cstr : CString = CString::new(evt_str).unwrap();
264 return format!("{}", safe_cstr.to_string_lossy().to_owned() );
265 }
266 }
267
268 fn event_loop(&mut self) {
269 println!("Warning: event_loop on a CWinRep is a no-op.");
271 }
272}
273