@@ -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,16 @@ 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- } ;
232- #[ cfg( not( feature = "opengl" ) ) ]
233- let ( depth, visual) = create_default_config ( ) ;
209+ let visual_info =
210+ WindowVisualConfig :: find_best_visual_config_for_gl ( & xcb_connection, options. gl_config ) ?;
234211
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) ?;
212+ #[ cfg( not( feature = "opengl" ) ) ]
213+ let visual_info = WindowVisualConfig :: find_best_visual_config ( & xcb_connection) ?;
239214
240215 let window_id = xcb_connection. conn . generate_id ( ) ?;
241216 xcb_connection. conn . create_window (
242- depth ,
217+ visual_info . visual_depth ,
243218 window_id,
244219 parent_id,
245220 0 , // x coordinate of the new window
@@ -248,7 +223,7 @@ impl<'a> Window<'a> {
248223 window_info. physical_size ( ) . height as u16 , // window height
249224 0 , // window border
250225 WindowClass :: INPUT_OUTPUT ,
251- visual ,
226+ visual_info . visual_id ,
252227 & CreateWindowAux :: new ( )
253228 . event_mask (
254229 EventMask :: EXPOSURE
@@ -263,7 +238,7 @@ impl<'a> Window<'a> {
263238 )
264239 // As mentioned above, these two values are needed to be able to create a window
265240 // with a depth of 32-bits when the parent window has a different depth
266- . colormap ( colormap )
241+ . colormap ( visual_info . color_map )
267242 . border_pixel ( 0 ) ,
268243 ) ?;
269244 xcb_connection. conn . map_window ( window_id) ?;
@@ -292,7 +267,7 @@ impl<'a> Window<'a> {
292267 // no error handling anymore at this point. Everything is more or less unchanged
293268 // compared to when raw-gl-context was a separate crate.
294269 #[ cfg( feature = "opengl" ) ]
295- let gl_context = fb_config. map ( |fb_config| {
270+ let gl_context = visual_info . fb_config . map ( |fb_config| {
296271 use std:: ffi:: c_ulong;
297272
298273 let window = window_id as c_ulong ;
@@ -308,7 +283,7 @@ impl<'a> Window<'a> {
308283 xcb_connection,
309284 window_id,
310285 window_info,
311- visual_id : visual ,
286+ visual_id : visual_info . visual_id ,
312287 mouse_cursor : MouseCursor :: default ( ) ,
313288
314289 frame_interval : Duration :: from_millis ( 15 ) ,
@@ -387,22 +362,6 @@ impl<'a> Window<'a> {
387362 pub fn gl_context ( & self ) -> Option < & crate :: gl:: GlContext > {
388363 self . inner . gl_context . as_ref ( )
389364 }
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- }
406365}
407366
408367impl WindowInner {
0 commit comments