@@ -14,9 +14,8 @@ use raw_window_handle::{
1414
1515use x11rb:: connection:: Connection ;
1616use x11rb:: protocol:: xproto:: {
17- AtomEnum , ChangeWindowAttributesAux , ColormapAlloc , ConfigureWindowAux , ConnectionExt as _,
18- CreateGCAux , CreateWindowAux , EventMask , PropMode , Screen , VisualClass , Visualid ,
19- Window as XWindow , WindowClass ,
17+ AtomEnum , ChangeWindowAttributesAux , ConfigureWindowAux , ConnectionExt as _, CreateGCAux ,
18+ CreateWindowAux , EventMask , PropMode , Visualid , Window as XWindow , WindowClass ,
2019} ;
2120use x11rb:: protocol:: Event as XEvent ;
2221use x11rb:: wrapper:: ConnectionExt as _;
@@ -31,6 +30,7 @@ use super::keyboard::{convert_key_press_event, convert_key_release_event, key_mo
3130
3231#[ cfg( feature = "opengl" ) ]
3332use crate :: gl:: { platform, GlContext } ;
33+ use crate :: x11:: visual_info:: WindowVisualConfig ;
3434
3535pub struct WindowHandle {
3636 raw_window_handle : Option < RawWindowHandle > ,
@@ -187,11 +187,9 @@ impl<'a> Window<'a> {
187187 // FIXME: baseview error type instead of unwrap()
188188 let xcb_connection = XcbConnection :: new ( ) ?;
189189
190- // Get screen information (?)
191- let setup = xcb_connection. conn . setup ( ) ;
192- let screen = & setup. roots [ xcb_connection. screen ] ;
193-
194- let parent_id = parent. unwrap_or_else ( || screen. root ) ;
190+ // Get screen information
191+ let screen = xcb_connection. screen ( ) ;
192+ let parent_id = parent. unwrap_or ( screen. root ) ;
195193
196194 let gc_id = xcb_connection. conn . generate_id ( ) ?;
197195 xcb_connection. conn . create_gc (
@@ -207,39 +205,18 @@ impl<'a> Window<'a> {
207205
208206 let window_info = WindowInfo :: from_logical_size ( options. size , scaling) ;
209207
210- // Now it starts becoming fun. If we're creating an OpenGL context, then we need to create
211- // the window with a visual that matches the framebuffer used for the OpenGL context. So the
212- // idea is that we first retrieve a framebuffer config that matches our wanted OpenGL
213- // configuration, find the visual that matches that framebuffer config, create the window
214- // with that visual, and then finally create an OpenGL context for the window. If we don't
215- // use OpenGL, then we'll just take a random visual with a 32-bit depth.
216- let create_default_config = || {
217- Self :: find_visual_for_depth ( screen, 32 )
218- . map ( |visual| ( 32 , visual) )
219- . unwrap_or ( ( x11rb:: COPY_FROM_PARENT as u8 , x11rb:: COPY_FROM_PARENT as u32 ) )
220- } ;
221208 #[ cfg( feature = "opengl" ) ]
222- let ( fb_config, ( depth, visual) ) = match options. gl_config {
223- Some ( gl_config) => unsafe {
224- platform:: GlContext :: get_fb_config_and_visual ( xcb_connection. dpy , gl_config)
225- . map ( |( fb_config, window_config) | {
226- ( Some ( fb_config) , ( window_config. depth , window_config. visual ) )
227- } )
228- . expect ( "Could not fetch framebuffer config" )
229- } ,
230- None => ( None , create_default_config ( ) ) ,
231- } ;
209+ let visual_info =
210+ WindowVisualConfig :: find_best_visual_config_for_gl ( & xcb_connection, options. gl_config ) ;
211+
232212 #[ cfg( not( feature = "opengl" ) ) ]
233- let ( depth , visual ) = create_default_config ( ) ;
213+ let visual_info = WindowVisualConfig :: find_best_visual_config ( & xcb_connection ) ;
234214
235- // For this 32-bith depth to work, you also need to define a color map and set a border
236- // pixel: https://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c#n818
237- let colormap = xcb_connection. conn . generate_id ( ) ?;
238- xcb_connection. conn . create_colormap ( ColormapAlloc :: NONE , colormap, screen. root , visual) ?;
215+ let color_map = visual_info. create_color_map ( & xcb_connection) ?;
239216
240217 let window_id = xcb_connection. conn . generate_id ( ) ?;
241218 xcb_connection. conn . create_window (
242- depth ,
219+ visual_info . visual_depth ,
243220 window_id,
244221 parent_id,
245222 0 , // x coordinate of the new window
@@ -248,7 +225,7 @@ impl<'a> Window<'a> {
248225 window_info. physical_size ( ) . height as u16 , // window height
249226 0 , // window border
250227 WindowClass :: INPUT_OUTPUT ,
251- visual ,
228+ visual_info . visual_id ,
252229 & CreateWindowAux :: new ( )
253230 . event_mask (
254231 EventMask :: EXPOSURE
@@ -263,7 +240,7 @@ impl<'a> Window<'a> {
263240 )
264241 // As mentioned above, these two values are needed to be able to create a window
265242 // with a depth of 32-bits when the parent window has a different depth
266- . colormap ( colormap )
243+ . colormap ( color_map )
267244 . border_pixel ( 0 ) ,
268245 ) ?;
269246 xcb_connection. conn . map_window ( window_id) ?;
@@ -292,7 +269,7 @@ impl<'a> Window<'a> {
292269 // no error handling anymore at this point. Everything is more or less unchanged
293270 // compared to when raw-gl-context was a separate crate.
294271 #[ cfg( feature = "opengl" ) ]
295- let gl_context = fb_config. map ( |fb_config| {
272+ let gl_context = visual_info . fb_config . map ( |fb_config| {
296273 use std:: ffi:: c_ulong;
297274
298275 let window = window_id as c_ulong ;
@@ -308,7 +285,7 @@ impl<'a> Window<'a> {
308285 xcb_connection,
309286 window_id,
310287 window_info,
311- visual_id : visual ,
288+ visual_id : visual_info . visual_id ,
312289 mouse_cursor : MouseCursor :: default ( ) ,
313290
314291 frame_interval : Duration :: from_millis ( 15 ) ,
@@ -387,22 +364,6 @@ impl<'a> Window<'a> {
387364 pub fn gl_context ( & self ) -> Option < & crate :: gl:: GlContext > {
388365 self . inner . gl_context . as_ref ( )
389366 }
390-
391- fn find_visual_for_depth ( screen : & Screen , depth : u8 ) -> Option < Visualid > {
392- for candidate_depth in & screen. allowed_depths {
393- if candidate_depth. depth != depth {
394- continue ;
395- }
396-
397- for candidate_visual in & candidate_depth. visuals {
398- if candidate_visual. class == VisualClass :: TRUE_COLOR {
399- return Some ( candidate_visual. visual_id ) ;
400- }
401- }
402- }
403-
404- None
405- }
406367}
407368
408369impl WindowInner {
0 commit comments