19
19
* https://raw.githubusercontent.com/dvdhrm/docs/master/drm-howto/modeset.c
20
20
*/
21
21
22
+ #define _GNU_SOURCE
23
+
22
24
#include <assert.h>
23
25
#include <ctype.h>
24
26
#include <errno.h>
25
27
#include <getopt.h>
26
28
#include <libgen.h>
27
- #include <stdarg.h>
28
29
#include <stdbool.h>
29
30
#include <stdio.h>
30
31
#include <stdlib.h>
@@ -111,29 +112,28 @@ struct modeset_dev {
111
112
uint32_t crtc_id ;
112
113
};
113
114
114
- void draw_buffer (struct modeset_dev * dev , char * dir , char * base )
115
+ void draw_buffer (struct modeset_dev * dev , const char * dir , const char * base )
115
116
{
116
117
int fd_src ;
117
- char filename [ 128 ] ;
118
+ char * filename ;
118
119
ssize_t size ;
119
120
int ret ;
120
121
121
122
/*
122
123
* make it easy and load a raw file in the right format instead of
123
124
* opening an (say) PNG and convert the image data to the right format.
124
125
*/
125
- ret = snprintf (filename , sizeof (filename ),
126
- "%s/%s-%ux%u-%s.bin" ,
126
+ ret = asprintf (& filename , "%s/%s-%ux%u-%s.bin" ,
127
127
dir , base , dev -> width , dev -> height , dev -> format -> name );
128
- if (ret >= sizeof ( filename ) ) {
129
- error ("Failed to fit filename into buffer\n" );
128
+ if (ret < 0 ) {
129
+ error ("Failed to allocate filename buffer\n" );
130
130
return ;
131
131
}
132
132
133
133
fd_src = open (filename , O_RDONLY | O_CLOEXEC );
134
134
if (fd_src < 0 ) {
135
135
error ("Failed to open %s: %m\n" , filename );
136
- return ;
136
+ goto out ;
137
137
}
138
138
139
139
size = readfull (fd_src , dev -> map , dev -> size );
@@ -151,6 +151,9 @@ void draw_buffer(struct modeset_dev *dev, char *dir, char *base)
151
151
error ("Failed to close image file\n" );
152
152
}
153
153
154
+ out :
155
+ free (filename );
156
+
154
157
return ;
155
158
}
156
159
@@ -160,8 +163,8 @@ static int drmprepare_crtc(int fd, drmModeRes *res, drmModeConnector *conn,
160
163
struct modeset_dev * dev )
161
164
{
162
165
drmModeEncoder * enc ;
163
- unsigned int i , j ;
164
- int32_t crtc_id ;
166
+ int i , j ;
167
+ uint32_t crtc_id ;
165
168
struct modeset_dev * iter ;
166
169
167
170
/* first try the currently connected encoder+crtc */
@@ -181,16 +184,16 @@ static int drmprepare_crtc(int fd, drmModeRes *res, drmModeConnector *conn,
181
184
if (enc ) {
182
185
if (enc -> crtc_id ) {
183
186
crtc_id = enc -> crtc_id ;
184
- assert ( crtc_id >= 0 ) ;
187
+ bool in_use = false ;
185
188
186
189
for (iter = modeset_list ; iter ; iter = iter -> next ) {
187
190
if (iter -> crtc_id == crtc_id ) {
188
- crtc_id = -1 ;
191
+ in_use = true ;
189
192
break ;
190
193
}
191
194
}
192
195
193
- if (crtc_id > 0 ) {
196
+ if (! in_use ) {
194
197
debug ("encoder #%d uses crtc #%d\n" ,
195
198
enc -> encoder_id , enc -> crtc_id );
196
199
drmModeFreeEncoder (enc );
@@ -223,6 +226,8 @@ static int drmprepare_crtc(int fd, drmModeRes *res, drmModeConnector *conn,
223
226
224
227
/* iterate all global CRTCs */
225
228
for (j = 0 ; j < res -> count_crtcs ; ++ j ) {
229
+ bool in_use = false;
230
+
226
231
/* check whether this CRTC works with the encoder */
227
232
if (!(enc -> possible_crtcs & (1 << j )))
228
233
continue ;
@@ -231,13 +236,13 @@ static int drmprepare_crtc(int fd, drmModeRes *res, drmModeConnector *conn,
231
236
crtc_id = res -> crtcs [j ];
232
237
for (iter = modeset_list ; iter ; iter = iter -> next ) {
233
238
if (iter -> crtc_id == crtc_id ) {
234
- crtc_id = -1 ;
239
+ in_use = true ;
235
240
break ;
236
241
}
237
242
}
238
243
239
244
/* we have found a CRTC, so save it and return */
240
- if (crtc_id >= 0 ) {
245
+ if (! in_use ) {
241
246
debug ("encoder #%d will use crtc #%d\n" ,
242
247
enc -> encoder_id , crtc_id );
243
248
drmModeFreeEncoder (enc );
@@ -348,7 +353,7 @@ static char *get_normalized_conn_type_name(uint32_t connector_type)
348
353
349
354
static const struct platsch_format * platsch_format_find (const char * name )
350
355
{
351
- int i ;
356
+ unsigned i ;
352
357
353
358
for (i = 0 ; i < ARRAY_SIZE (platsch_formats ); i ++ )
354
359
if (!strcmp (platsch_formats [i ].name , name ))
@@ -363,7 +368,7 @@ static int set_env_connector_mode(drmModeConnector *conn,
363
368
int ret , i = 0 ;
364
369
u_int32_t width = 0 , height = 0 ;
365
370
const char * mode ;
366
- char * connector_type_name , mode_env_name [ 32 ] , fmt_specifier [32 ] = "" ;
371
+ char * connector_type_name , * mode_env_name = NULL , fmt_specifier [32 ] = "" ;
367
372
const struct platsch_format * format = NULL ;
368
373
369
374
connector_type_name = get_normalized_conn_type_name (conn -> connector_type );
@@ -373,12 +378,12 @@ static int set_env_connector_mode(drmModeConnector *conn,
373
378
goto fallback ;
374
379
}
375
380
376
- ret = snprintf ( mode_env_name , sizeof ( mode_env_name ) , "platsch_%s%u_mode" ,
381
+ ret = asprintf ( & mode_env_name , "platsch_%s%u_mode" ,
377
382
connector_type_name , conn -> connector_type_id );
378
383
free (connector_type_name );
379
- if (ret >= sizeof ( mode_env_name ) ) {
380
- error ("failed to fit platsch env mode variable name into buffer \n" );
381
- return - EFAULT ;
384
+ if (ret < 0 ) {
385
+ error ("failed to allocate platsch env mode variable\n" );
386
+ return - ENOMEM ;
382
387
}
383
388
384
389
/* check for connector mode configuration in environment */
@@ -391,7 +396,8 @@ static int set_env_connector_mode(drmModeConnector *conn,
391
396
ret = sscanf (mode , "%ux%u@%s" , & width , & height , fmt_specifier );
392
397
if (ret < 2 ) {
393
398
error ("error while scanning %s for mode\n" , mode_env_name );
394
- return - EFAULT ;
399
+ ret = - EFAULT ;
400
+ goto err_out ;
395
401
}
396
402
397
403
/* use first mode matching given resolution */
@@ -407,7 +413,8 @@ static int set_env_connector_mode(drmModeConnector *conn,
407
413
408
414
if (i == conn -> count_modes ) {
409
415
error ("no mode available matching %ux%u\n" , width , height );
410
- return - ENOENT ;
416
+ ret = - ENOENT ;
417
+ goto err_out ;
411
418
}
412
419
413
420
format = platsch_format_find (fmt_specifier );
@@ -419,6 +426,8 @@ static int set_env_connector_mode(drmModeConnector *conn,
419
426
420
427
dev -> format = format ;
421
428
429
+ free (mode_env_name );
430
+
422
431
return 0 ;
423
432
424
433
fallback :
@@ -432,7 +441,12 @@ static int set_env_connector_mode(drmModeConnector *conn,
432
441
debug ("using default format %s for connector #%u\n" , dev -> format -> name ,
433
442
conn -> connector_id );
434
443
435
- return 0 ;
444
+ ret = 0 ;
445
+
446
+ err_out :
447
+ free (mode_env_name );
448
+
449
+ return ret ;
436
450
}
437
451
438
452
static int drmprepare_connector (int fd , drmModeRes * res , drmModeConnector * conn ,
@@ -483,7 +497,7 @@ static int drmprepare(int fd)
483
497
{
484
498
drmModeRes * res ;
485
499
drmModeConnector * conn ;
486
- unsigned int i ;
500
+ int i ;
487
501
struct modeset_dev * dev ;
488
502
int ret ;
489
503
@@ -562,7 +576,6 @@ int main(int argc, char *argv[])
562
576
{
563
577
char * * initsargv ;
564
578
int drmfd ;
565
- char drmdev [128 ];
566
579
struct modeset_dev * iter ;
567
580
bool pid1 = getpid () == 1 ;
568
581
const char * dir = "/usr/share/platsch" ;
@@ -606,19 +619,21 @@ int main(int argc, char *argv[])
606
619
607
620
for (i = 0 ; i < 64 ; i ++ ) {
608
621
struct drm_mode_card_res res = {0 };
622
+ char * drmdev ;
609
623
610
624
/*
611
625
* XXX: Maybe use drmOpen instead?
612
626
* (Where should name/busid come from?)
613
627
* XXX: Loop through drm devices to find one with connectors.
614
628
*/
615
- ret = snprintf ( drmdev , sizeof ( drmdev ) , DRM_DEV_NAME , DRM_DIR_NAME , i );
616
- if (ret >= sizeof ( drmdev ) ) {
617
- error ("Huh, device name overflowed buffer\n" );
629
+ ret = asprintf ( & drmdev , DRM_DEV_NAME , DRM_DIR_NAME , i );
630
+ if (ret < 0 ) {
631
+ error ("Huh, failed to allocate device name buffer\n" );
618
632
goto execinit ;
619
633
}
620
634
621
635
drmfd = open (drmdev , O_RDWR | O_CLOEXEC , 0 );
636
+ free (drmdev );
622
637
if (drmfd < 0 ) {
623
638
error ("Failed to open drm device: %m\n" );
624
639
goto execinit ;
0 commit comments