@@ -69,7 +69,9 @@ trait ModeObject: Send + Sync + Downcastable {
6969trait DrmDevice : Send + Sync {
7070 /// Returns weather the DRM device supports creating dumb buffers.
7171 fn can_dumb_create ( & self ) -> bool ;
72+
7273 fn dumb_create ( & self , width : u32 , height : u32 , bpp : u32 ) -> BufferObject ;
74+ fn framebuffer_create ( & self , buffer_object : & BufferObject , width : u32 , height : u32 , pitch : u32 ) ;
7375
7476 /// Returns tuple containing the minumum dimensions (`xmin`, `ymin`).
7577 fn min_dim ( & self ) -> ( usize , usize ) ;
@@ -82,6 +84,7 @@ trait DrmDevice: Send + Sync {
8284 fn driver_info ( & self ) -> ( & ' static str , & ' static str , & ' static str ) ;
8385}
8486
87+ #[ derive( Clone ) ]
8588struct BufferObject {
8689 width : u32 ,
8790 height : u32 ,
@@ -251,6 +254,15 @@ struct Framebuffer {
251254 object_id : u32 ,
252255}
253256
257+ impl Framebuffer {
258+ pub fn new ( object_id : u32 ) -> Arc < Self > {
259+ Arc :: new_cyclic ( |sref| Self {
260+ sref : sref. clone ( ) ,
261+ object_id,
262+ } )
263+ }
264+ }
265+
254266impl ModeObject for Framebuffer {
255267 fn id ( & self ) -> u32 {
256268 self . object_id
@@ -360,6 +372,12 @@ impl Drm {
360372 self . install_object ( encoder)
361373 }
362374
375+ /// Installs and initializes the framebuffer identifier.
376+ pub fn install_framebuffer ( & self , fb : Arc < Framebuffer > ) {
377+ self . framebuffers . lock ( ) . push ( fb. clone ( ) ) ;
378+ self . install_object ( fb)
379+ }
380+
363381 pub fn allocate_object_id ( & self ) -> u32 {
364382 self . id_alloc . alloc ( ) as _
365383 }
@@ -369,7 +387,11 @@ impl Drm {
369387 }
370388
371389 fn find_object ( & self , id : u32 ) -> Option < Arc < dyn ModeObject > > {
372- self . mode_objs . lock ( ) . get ( & id) . map ( |obj| obj. clone ( ) )
390+ self . mode_objs . lock ( ) . get ( & id) . cloned ( )
391+ }
392+
393+ fn find_handle ( & self , handle : u32 ) -> Option < BufferObject > {
394+ self . buffers . lock ( ) . get ( & handle) . cloned ( )
373395 }
374396
375397 fn create_handle ( & self , buffer : BufferObject ) -> u32 {
@@ -556,6 +578,22 @@ impl INodeInterface for Drm {
556578 Ok ( 0 )
557579 }
558580
581+ DRM_IOCTL_MODE_ADDFB => {
582+ let struc = VirtAddr :: new ( arg as u64 )
583+ . read_mut :: < DrmModeFbCmd > ( )
584+ . unwrap ( ) ;
585+
586+ let handle = self . find_handle ( struc. handle ) . unwrap ( ) ;
587+ self . device
588+ . framebuffer_create ( & handle, struc. width , struc. height , struc. pitch ) ;
589+
590+ let fb = Framebuffer :: new ( self . allocate_object_id ( ) ) ;
591+ self . install_framebuffer ( fb. clone ( ) ) ;
592+
593+ struc. fb_id = fb. id ( ) ;
594+ Ok ( 0 )
595+ }
596+
559597 _ => {
560598 // command[8..16] is the ASCII character supposedly unique to each driver.
561599 if command. get_bits ( 8 ..16 ) == DRM_IOCTL_BASE {
0 commit comments