aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Paul2016-02-03 09:52:15 -0600
committerSean Paul2016-02-03 09:52:15 -0600
commit870942e56aac024da5e0a621275f6561a4ddab1b (patch)
treef50e065f5088a40e2a34ae83e2e3ff6ab2e6f625 /xf86drmMode.c
parentbd4d0d244019a72be9ca51ac3e8f35201b271f1b (diff)
parentb38a4b2326c1be5702f5cb73a53c0ed74c12d510 (diff)
downloadexternal-libdrm-870942e56aac024da5e0a621275f6561a4ddab1b.tar.gz
external-libdrm-870942e56aac024da5e0a621275f6561a4ddab1b.tar.xz
external-libdrm-870942e56aac024da5e0a621275f6561a4ddab1b.zip
Merge tag 'tags/libdrm-2.4.66' into master
Tag libdrm-2.4.66 from git://anongit.freedesktop.org/mesa/drm Signed-off-by: Sean Paul <seanpaul@chromium.org> Conflicts: Android.mk Makefile.am configure.ac freedreno/Android.mk include/drm/drm_mode.h intel/Android.mk libkms/Android.mk nouveau/Android.mk radeon/Android.mk tegra/tegra.c tests/Makefile.am xf86drmMode.c xf86drmMode.h Change-Id: I3186bde7f196d2f3438c4334591ee2a0c1371c96
Diffstat (limited to 'xf86drmMode.c')
-rw-r--r--xf86drmMode.c429
1 files changed, 372 insertions, 57 deletions
diff --git a/xf86drmMode.c b/xf86drmMode.c
index e373c4cd..b341f382 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -37,15 +37,21 @@
37 * TODO the types we are after are defined in diffrent headers on diffrent 37 * TODO the types we are after are defined in diffrent headers on diffrent
38 * platforms find which headers to include to get uint32_t 38 * platforms find which headers to include to get uint32_t
39 */ 39 */
40#include <stdint.h>
41#include <sys/ioctl.h>
42#include <stdio.h>
43#include <stdbool.h>
44 40
45#ifdef HAVE_CONFIG_H 41#ifdef HAVE_CONFIG_H
46#include "config.h" 42#include "config.h"
47#endif 43#endif
48 44
45#include <limits.h>
46#include <stdint.h>
47#include <stdlib.h>
48#include <sys/ioctl.h>
49#ifdef HAVE_SYS_SYSCTL_H
50#include <sys/sysctl.h>
51#endif
52#include <stdio.h>
53#include <stdbool.h>
54
49#include "xf86drmMode.h" 55#include "xf86drmMode.h"
50#include "xf86drm.h" 56#include "xf86drm.h"
51#include <drm.h> 57#include <drm.h>
@@ -54,15 +60,7 @@
54#include <unistd.h> 60#include <unistd.h>
55#include <errno.h> 61#include <errno.h>
56 62
57#ifdef HAVE_VALGRIND 63#define memclear(s) memset(&s, 0, sizeof(s))
58#include <valgrind.h>
59#include <memcheck.h>
60#define VG(x) x
61#else
62#define VG(x)
63#endif
64
65#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s)))
66 64
67#define U642VOID(x) ((void *)(unsigned long)(x)) 65#define U642VOID(x) ((void *)(unsigned long)(x))
68#define VOID2U64(x) ((uint64_t)(unsigned long)(x)) 66#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
@@ -77,7 +75,7 @@ static inline int DRM_IOCTL(int fd, unsigned long cmd, void *arg)
77 * Util functions 75 * Util functions
78 */ 76 */
79 77
80void* drmAllocCpy(void *array, int count, int entry_size) 78static void* drmAllocCpy(char *array, int count, int entry_size)
81{ 79{
82 char *r; 80 char *r;
83 int i; 81 int i;
@@ -116,7 +114,6 @@ void drmModeFreeResources(drmModeResPtr ptr)
116 drmFree(ptr->connectors); 114 drmFree(ptr->connectors);
117 drmFree(ptr->encoders); 115 drmFree(ptr->encoders);
118 drmFree(ptr); 116 drmFree(ptr);
119
120} 117}
121 118
122void drmModeFreeFB(drmModeFBPtr ptr) 119void drmModeFreeFB(drmModeFBPtr ptr)
@@ -134,7 +131,6 @@ void drmModeFreeCrtc(drmModeCrtcPtr ptr)
134 return; 131 return;
135 132
136 drmFree(ptr); 133 drmFree(ptr);
137
138} 134}
139 135
140void drmModeFreeConnector(drmModeConnectorPtr ptr) 136void drmModeFreeConnector(drmModeConnectorPtr ptr)
@@ -147,7 +143,6 @@ void drmModeFreeConnector(drmModeConnectorPtr ptr)
147 drmFree(ptr->props); 143 drmFree(ptr->props);
148 drmFree(ptr->modes); 144 drmFree(ptr->modes);
149 drmFree(ptr); 145 drmFree(ptr);
150
151} 146}
152 147
153void drmModeFreeEncoder(drmModeEncoderPtr ptr) 148void drmModeFreeEncoder(drmModeEncoderPtr ptr)
@@ -165,7 +160,7 @@ drmModeResPtr drmModeGetResources(int fd)
165 drmModeResPtr r = 0; 160 drmModeResPtr r = 0;
166 161
167retry: 162retry:
168 memset(&res, 0, sizeof(struct drm_mode_card_res)); 163 memclear(res);
169 if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) 164 if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
170 return 0; 165 return 0;
171 166
@@ -254,13 +249,13 @@ err_allocs:
254} 249}
255 250
256int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, 251int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
257 uint8_t bpp, uint32_t pitch, uint32_t bo_handle, 252 uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
258 uint32_t *buf_id) 253 uint32_t *buf_id)
259{ 254{
260 struct drm_mode_fb_cmd f; 255 struct drm_mode_fb_cmd f;
261 int ret; 256 int ret;
262 257
263 VG_CLEAR(f); 258 memclear(f);
264 f.width = width; 259 f.width = width;
265 f.height = height; 260 f.height = height;
266 f.pitch = pitch; 261 f.pitch = pitch;
@@ -283,6 +278,7 @@ int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
283 struct drm_mode_fb_cmd2 f; 278 struct drm_mode_fb_cmd2 f;
284 int ret; 279 int ret;
285 280
281 memclear(f);
286 f.width = width; 282 f.width = width;
287 f.height = height; 283 f.height = height;
288 f.pixel_format = pixel_format; 284 f.pixel_format = pixel_format;
@@ -301,8 +297,6 @@ int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
301int drmModeRmFB(int fd, uint32_t bufferId) 297int drmModeRmFB(int fd, uint32_t bufferId)
302{ 298{
303 return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId); 299 return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
304
305
306} 300}
307 301
308drmModeFBPtr drmModeGetFB(int fd, uint32_t buf) 302drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
@@ -310,6 +304,7 @@ drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
310 struct drm_mode_fb_cmd info; 304 struct drm_mode_fb_cmd info;
311 drmModeFBPtr r; 305 drmModeFBPtr r;
312 306
307 memclear(info);
313 info.fb_id = buf; 308 info.fb_id = buf;
314 309
315 if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info)) 310 if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info))
@@ -332,8 +327,9 @@ drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
332int drmModeDirtyFB(int fd, uint32_t bufferId, 327int drmModeDirtyFB(int fd, uint32_t bufferId,
333 drmModeClipPtr clips, uint32_t num_clips) 328 drmModeClipPtr clips, uint32_t num_clips)
334{ 329{
335 struct drm_mode_fb_dirty_cmd dirty = { 0 }; 330 struct drm_mode_fb_dirty_cmd dirty;
336 331
332 memclear(dirty);
337 dirty.fb_id = bufferId; 333 dirty.fb_id = bufferId;
338 dirty.clips_ptr = VOID2U64(clips); 334 dirty.clips_ptr = VOID2U64(clips);
339 dirty.num_clips = num_clips; 335 dirty.num_clips = num_clips;
@@ -341,7 +337,6 @@ int drmModeDirtyFB(int fd, uint32_t bufferId,
341 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty); 337 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty);
342} 338}
343 339
344
345/* 340/*
346 * Crtc functions 341 * Crtc functions
347 */ 342 */
@@ -351,7 +346,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
351 struct drm_mode_crtc crtc; 346 struct drm_mode_crtc crtc;
352 drmModeCrtcPtr r; 347 drmModeCrtcPtr r;
353 348
354 VG_CLEAR(crtc); 349 memclear(crtc);
355 crtc.crtc_id = crtcId; 350 crtc.crtc_id = crtcId;
356 351
357 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc)) 352 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
@@ -378,14 +373,13 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
378 return r; 373 return r;
379} 374}
380 375
381
382int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, 376int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
383 uint32_t x, uint32_t y, uint32_t *connectors, int count, 377 uint32_t x, uint32_t y, uint32_t *connectors, int count,
384 drmModeModeInfoPtr mode) 378 drmModeModeInfoPtr mode)
385{ 379{
386 struct drm_mode_crtc crtc; 380 struct drm_mode_crtc crtc;
387 381
388 VG_CLEAR(crtc); 382 memclear(crtc);
389 crtc.x = x; 383 crtc.x = x;
390 crtc.y = y; 384 crtc.y = y;
391 crtc.crtc_id = crtcId; 385 crtc.crtc_id = crtcId;
@@ -395,8 +389,7 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
395 if (mode) { 389 if (mode) {
396 memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo)); 390 memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo));
397 crtc.mode_valid = 1; 391 crtc.mode_valid = 1;
398 } else 392 }
399 crtc.mode_valid = 0;
400 393
401 return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); 394 return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
402} 395}
@@ -409,6 +402,7 @@ int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width
409{ 402{
410 struct drm_mode_cursor arg; 403 struct drm_mode_cursor arg;
411 404
405 memclear(arg);
412 arg.flags = DRM_MODE_CURSOR_BO; 406 arg.flags = DRM_MODE_CURSOR_BO;
413 arg.crtc_id = crtcId; 407 arg.crtc_id = crtcId;
414 arg.width = width; 408 arg.width = width;
@@ -422,6 +416,7 @@ int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t widt
422{ 416{
423 struct drm_mode_cursor2 arg; 417 struct drm_mode_cursor2 arg;
424 418
419 memclear(arg);
425 arg.flags = DRM_MODE_CURSOR_BO; 420 arg.flags = DRM_MODE_CURSOR_BO;
426 arg.crtc_id = crtcId; 421 arg.crtc_id = crtcId;
427 arg.width = width; 422 arg.width = width;
@@ -437,6 +432,7 @@ int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
437{ 432{
438 struct drm_mode_cursor arg; 433 struct drm_mode_cursor arg;
439 434
435 memclear(arg);
440 arg.flags = DRM_MODE_CURSOR_MOVE; 436 arg.flags = DRM_MODE_CURSOR_MOVE;
441 arg.crtc_id = crtcId; 437 arg.crtc_id = crtcId;
442 arg.x = x; 438 arg.x = x;
@@ -453,11 +449,8 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
453 struct drm_mode_get_encoder enc; 449 struct drm_mode_get_encoder enc;
454 drmModeEncoderPtr r = NULL; 450 drmModeEncoderPtr r = NULL;
455 451
452 memclear(enc);
456 enc.encoder_id = encoder_id; 453 enc.encoder_id = encoder_id;
457 enc.crtc_id = 0;
458 enc.encoder_type = 0;
459 enc.possible_crtcs = 0;
460 enc.possible_clones = 0;
461 454
462 if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc)) 455 if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc))
463 return 0; 456 return 0;
@@ -477,19 +470,23 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
477/* 470/*
478 * Connector manipulation 471 * Connector manipulation
479 */ 472 */
480 473static drmModeConnectorPtr
481drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) 474_drmModeGetConnector(int fd, uint32_t connector_id, int probe)
482{ 475{
483 struct drm_mode_get_connector conn, counts; 476 struct drm_mode_get_connector conn, counts;
484 drmModeConnectorPtr r = NULL; 477 drmModeConnectorPtr r = NULL;
485 478
486retry: 479 memclear(conn);
487 memset(&conn, 0, sizeof(struct drm_mode_get_connector));
488 conn.connector_id = connector_id; 480 conn.connector_id = connector_id;
481 if (!probe) {
482 conn.count_modes = 1;
483 conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo)));
484 }
489 485
490 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) 486 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
491 return 0; 487 return 0;
492 488
489retry:
493 counts = conn; 490 counts = conn;
494 491
495 if (conn.count_props) { 492 if (conn.count_props) {
@@ -505,6 +502,9 @@ retry:
505 conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo))); 502 conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
506 if (!conn.modes_ptr) 503 if (!conn.modes_ptr)
507 goto err_allocs; 504 goto err_allocs;
505 } else {
506 conn.count_modes = 1;
507 conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo)));
508 } 508 }
509 509
510 if (conn.count_encoders) { 510 if (conn.count_encoders) {
@@ -573,10 +573,21 @@ err_allocs:
573 return r; 573 return r;
574} 574}
575 575
576drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
577{
578 return _drmModeGetConnector(fd, connector_id, 1);
579}
580
581drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id)
582{
583 return _drmModeGetConnector(fd, connector_id, 0);
584}
585
576int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info) 586int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
577{ 587{
578 struct drm_mode_mode_cmd res; 588 struct drm_mode_mode_cmd res;
579 589
590 memclear(res);
580 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); 591 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
581 res.connector_id = connector_id; 592 res.connector_id = connector_id;
582 593
@@ -587,25 +598,20 @@ int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf
587{ 598{
588 struct drm_mode_mode_cmd res; 599 struct drm_mode_mode_cmd res;
589 600
601 memclear(res);
590 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); 602 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
591 res.connector_id = connector_id; 603 res.connector_id = connector_id;
592 604
593 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res); 605 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
594} 606}
595 607
596
597drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) 608drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
598{ 609{
599 struct drm_mode_get_property prop; 610 struct drm_mode_get_property prop;
600 drmModePropertyPtr r; 611 drmModePropertyPtr r;
601 612
602 VG_CLEAR(prop); 613 memclear(prop);
603 prop.prop_id = property_id; 614 prop.prop_id = property_id;
604 prop.count_enum_blobs = 0;
605 prop.count_values = 0;
606 prop.flags = 0;
607 prop.enum_blob_ptr = 0;
608 prop.values_ptr = 0;
609 615
610 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) 616 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
611 return 0; 617 return 0;
@@ -668,8 +674,7 @@ drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id)
668 struct drm_mode_get_blob blob; 674 struct drm_mode_get_blob blob;
669 drmModePropertyBlobPtr r; 675 drmModePropertyBlobPtr r;
670 676
671 blob.length = 0; 677 memclear(blob);
672 blob.data = 0;
673 blob.blob_id = blob_id; 678 blob.blob_id = blob_id;
674 679
675 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) 680 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
@@ -709,6 +714,7 @@ int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property
709{ 714{
710 struct drm_mode_connector_set_property osp; 715 struct drm_mode_connector_set_property osp;
711 716
717 memclear(osp);
712 osp.connector_id = connector_id; 718 osp.connector_id = connector_id;
713 osp.prop_id = property_id; 719 osp.prop_id = property_id;
714 osp.value = value; 720 osp.value = value;
@@ -810,8 +816,25 @@ int drmCheckModesettingSupported(const char *busid)
810#elif defined(__DragonFly__) 816#elif defined(__DragonFly__)
811 return 0; 817 return 0;
812#endif 818#endif
813 return -ENOSYS; 819#ifdef __OpenBSD__
820 int fd;
821 struct drm_mode_card_res res;
822 drmModeResPtr r = 0;
814 823
824 if ((fd = drmOpen(NULL, busid)) < 0)
825 return -EINVAL;
826
827 memset(&res, 0, sizeof(struct drm_mode_card_res));
828
829 if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) {
830 drmClose(fd);
831 return -errno;
832 }
833
834 drmClose(fd);
835 return 0;
836#endif
837 return -ENOSYS;
815} 838}
816 839
817int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, 840int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
@@ -819,6 +842,7 @@ int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
819{ 842{
820 struct drm_mode_crtc_lut l; 843 struct drm_mode_crtc_lut l;
821 844
845 memclear(l);
822 l.crtc_id = crtc_id; 846 l.crtc_id = crtc_id;
823 l.gamma_size = size; 847 l.gamma_size = size;
824 l.red = VOID2U64(red); 848 l.red = VOID2U64(red);
@@ -833,6 +857,7 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
833{ 857{
834 struct drm_mode_crtc_lut l; 858 struct drm_mode_crtc_lut l;
835 859
860 memclear(l);
836 l.crtc_id = crtc_id; 861 l.crtc_id = crtc_id;
837 l.gamma_size = size; 862 l.gamma_size = size;
838 l.red = VOID2U64(red); 863 l.red = VOID2U64(red);
@@ -848,14 +873,14 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
848 int len, i; 873 int len, i;
849 struct drm_event *e; 874 struct drm_event *e;
850 struct drm_event_vblank *vblank; 875 struct drm_event_vblank *vblank;
851 876
852 /* The DRM read semantics guarantees that we always get only 877 /* The DRM read semantics guarantees that we always get only
853 * complete events. */ 878 * complete events. */
854 879
855 len = read(fd, buffer, sizeof buffer); 880 len = read(fd, buffer, sizeof buffer);
856 if (len == 0) 881 if (len == 0)
857 return 0; 882 return 0;
858 if (len < sizeof *e) 883 if (len < (int)sizeof *e)
859 return -1; 884 return -1;
860 885
861 i = 0; 886 i = 0;
@@ -868,7 +893,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
868 break; 893 break;
869 vblank = (struct drm_event_vblank *) e; 894 vblank = (struct drm_event_vblank *) e;
870 evctx->vblank_handler(fd, 895 evctx->vblank_handler(fd,
871 vblank->sequence, 896 vblank->sequence,
872 vblank->tv_sec, 897 vblank->tv_sec,
873 vblank->tv_usec, 898 vblank->tv_usec,
874 U642VOID (vblank->user_data)); 899 U642VOID (vblank->user_data));
@@ -898,11 +923,11 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
898{ 923{
899 struct drm_mode_crtc_page_flip flip; 924 struct drm_mode_crtc_page_flip flip;
900 925
926 memclear(flip);
901 flip.fb_id = fb_id; 927 flip.fb_id = fb_id;
902 flip.crtc_id = crtc_id; 928 flip.crtc_id = crtc_id;
903 flip.user_data = VOID2U64(user_data); 929 flip.user_data = VOID2U64(user_data);
904 flip.flags = flags; 930 flip.flags = flags;
905 flip.reserved = 0;
906 931
907 return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); 932 return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
908} 933}
@@ -913,10 +938,10 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
913 uint32_t crtc_w, uint32_t crtc_h, 938 uint32_t crtc_w, uint32_t crtc_h,
914 uint32_t src_x, uint32_t src_y, 939 uint32_t src_x, uint32_t src_y,
915 uint32_t src_w, uint32_t src_h) 940 uint32_t src_w, uint32_t src_h)
916
917{ 941{
918 struct drm_mode_set_plane s; 942 struct drm_mode_set_plane s;
919 943
944 memclear(s);
920 s.plane_id = plane_id; 945 s.plane_id = plane_id;
921 s.crtc_id = crtc_id; 946 s.crtc_id = crtc_id;
922 s.fb_id = fb_id; 947 s.fb_id = fb_id;
@@ -933,14 +958,13 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
933 return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s); 958 return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s);
934} 959}
935 960
936
937drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) 961drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
938{ 962{
939 struct drm_mode_get_plane ovr, counts; 963 struct drm_mode_get_plane ovr, counts;
940 drmModePlanePtr r = 0; 964 drmModePlanePtr r = 0;
941 965
942retry: 966retry:
943 memset(&ovr, 0, sizeof(struct drm_mode_get_plane)); 967 memclear(ovr);
944 ovr.plane_id = plane_id; 968 ovr.plane_id = plane_id;
945 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) 969 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr))
946 return 0; 970 return 0;
@@ -1000,7 +1024,7 @@ drmModePlaneResPtr drmModeGetPlaneResources(int fd)
1000 drmModePlaneResPtr r = 0; 1024 drmModePlaneResPtr r = 0;
1001 1025
1002retry: 1026retry:
1003 memset(&res, 0, sizeof(struct drm_mode_get_plane_res)); 1027 memclear(res);
1004 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res)) 1028 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res))
1005 return 0; 1029 return 0;
1006 1030
@@ -1057,7 +1081,7 @@ drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd,
1057 uint32_t count; 1081 uint32_t count;
1058 1082
1059retry: 1083retry:
1060 memset(&properties, 0, sizeof(struct drm_mode_obj_get_properties)); 1084 memclear(properties);
1061 properties.obj_id = object_id; 1085 properties.obj_id = object_id;
1062 properties.obj_type = object_type; 1086 properties.obj_type = object_type;
1063 1087
@@ -1123,6 +1147,7 @@ int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type,
1123{ 1147{
1124 struct drm_mode_obj_set_property prop; 1148 struct drm_mode_obj_set_property prop;
1125 1149
1150 memclear(prop);
1126 prop.value = value; 1151 prop.value = value;
1127 prop.prop_id = property_id; 1152 prop.prop_id = property_id;
1128 prop.obj_id = object_id; 1153 prop.obj_id = object_id;
@@ -1399,3 +1424,293 @@ out:
1399 1424
1400 return ret; 1425 return ret;
1401} 1426}
1427
1428typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem, *drmModeAtomicReqItemPtr;
1429
1430struct _drmModeAtomicReqItem {
1431 uint32_t object_id;
1432 uint32_t property_id;
1433 uint64_t value;
1434};
1435
1436struct _drmModeAtomicReq {
1437 uint32_t cursor;
1438 uint32_t size_items;
1439 drmModeAtomicReqItemPtr items;
1440};
1441
1442drmModeAtomicReqPtr drmModeAtomicAlloc(void)
1443{
1444 drmModeAtomicReqPtr req;
1445
1446 req = drmMalloc(sizeof *req);
1447 if (!req)
1448 return NULL;
1449
1450 req->items = NULL;
1451 req->cursor = 0;
1452 req->size_items = 0;
1453
1454 return req;
1455}
1456
1457drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
1458{
1459 drmModeAtomicReqPtr new;
1460
1461 if (!old)
1462 return NULL;
1463
1464 new = drmMalloc(sizeof *new);
1465 if (!new)
1466 return NULL;
1467
1468 new->cursor = old->cursor;
1469 new->size_items = old->size_items;
1470
1471 if (old->size_items) {
1472 new->items = drmMalloc(old->size_items * sizeof(*new->items));
1473 if (!new->items) {
1474 free(new);
1475 return NULL;
1476 }
1477 memcpy(new->items, old->items,
1478 old->size_items * sizeof(*new->items));
1479 } else {
1480 new->items = NULL;
1481 }
1482
1483 return new;
1484}
1485
1486int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment)
1487{
1488 if (!base)
1489 return -EINVAL;
1490
1491 if (!augment || augment->cursor == 0)
1492 return 0;
1493
1494 if (base->cursor + augment->cursor >= base->size_items) {
1495 drmModeAtomicReqItemPtr new;
1496 int saved_size = base->size_items;
1497
1498 base->size_items = base->cursor + augment->cursor;
1499 new = realloc(base->items,
1500 base->size_items * sizeof(*base->items));
1501 if (!new) {
1502 base->size_items = saved_size;
1503 return -ENOMEM;
1504 }
1505 base->items = new;
1506 }
1507
1508 memcpy(&base->items[base->cursor], augment->items,
1509 augment->cursor * sizeof(*augment->items));
1510 base->cursor += augment->cursor;
1511
1512 return 0;
1513}
1514
1515int drmModeAtomicGetCursor(drmModeAtomicReqPtr req)
1516{
1517 if (!req)
1518 return -EINVAL;
1519 return req->cursor;
1520}
1521
1522void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor)
1523{
1524 if (req)
1525 req->cursor = cursor;
1526}
1527
1528int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
1529 uint32_t object_id,
1530 uint32_t property_id,
1531 uint64_t value)
1532{
1533 if (!req)
1534 return -EINVAL;
1535
1536 if (req->cursor >= req->size_items) {
1537 drmModeAtomicReqItemPtr new;
1538
1539 req->size_items += 16;
1540 new = realloc(req->items, req->size_items * sizeof(*req->items));
1541 if (!new) {
1542 req->size_items -= 16;
1543 return -ENOMEM;
1544 }
1545 req->items = new;
1546 }
1547
1548 req->items[req->cursor].object_id = object_id;
1549 req->items[req->cursor].property_id = property_id;
1550 req->items[req->cursor].value = value;
1551 req->cursor++;
1552
1553 return req->cursor;
1554}
1555
1556void drmModeAtomicFree(drmModeAtomicReqPtr req)
1557{
1558 if (!req)
1559 return;
1560
1561 if (req->items)
1562 drmFree(req->items);
1563 drmFree(req);
1564}
1565
1566static int sort_req_list(const void *misc, const void *other)
1567{
1568 const drmModeAtomicReqItem *first = misc;
1569 const drmModeAtomicReqItem *second = other;
1570
1571 if (first->object_id < second->object_id)
1572 return -1;
1573 else if (first->object_id > second->object_id)
1574 return 1;
1575 else
1576 return second->property_id - first->property_id;
1577}
1578
1579int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags,
1580 void *user_data)
1581{
1582 drmModeAtomicReqPtr sorted;
1583 struct drm_mode_atomic atomic;
1584 uint32_t *objs_ptr = NULL;
1585 uint32_t *count_props_ptr = NULL;
1586 uint32_t *props_ptr = NULL;
1587 uint64_t *prop_values_ptr = NULL;
1588 uint32_t last_obj_id = 0;
1589 uint32_t i;
1590 int obj_idx = -1;
1591 int ret = -1;
1592
1593 if (!req)
1594 return -EINVAL;
1595
1596 if (req->cursor == 0)
1597 return 0;
1598
1599 sorted = drmModeAtomicDuplicate(req);
1600 if (sorted == NULL)
1601 return -ENOMEM;
1602
1603 memclear(atomic);
1604
1605 /* Sort the list by object ID, then by property ID. */
1606 qsort(sorted->items, sorted->cursor, sizeof(*sorted->items),
1607 sort_req_list);
1608
1609 /* Now the list is sorted, eliminate duplicate property sets. */
1610 for (i = 0; i < sorted->cursor; i++) {
1611 if (sorted->items[i].object_id != last_obj_id) {
1612 atomic.count_objs++;
1613 last_obj_id = sorted->items[i].object_id;
1614 }
1615
1616 if (i == sorted->cursor - 1)
1617 continue;
1618
1619 if (sorted->items[i].object_id != sorted->items[i + 1].object_id ||
1620 sorted->items[i].property_id != sorted->items[i + 1].property_id)
1621 continue;
1622
1623 memmove(&sorted->items[i], &sorted->items[i + 1],
1624 (sorted->cursor - i - 1) * sizeof(*sorted->items));
1625 sorted->cursor--;
1626 }
1627
1628 objs_ptr = drmMalloc(atomic.count_objs * sizeof objs_ptr[0]);
1629 if (!objs_ptr) {
1630 errno = ENOMEM;
1631 goto out;
1632 }
1633
1634 count_props_ptr = drmMalloc(atomic.count_objs * sizeof count_props_ptr[0]);
1635 if (!count_props_ptr) {
1636 errno = ENOMEM;
1637 goto out;
1638 }
1639
1640 props_ptr = drmMalloc(sorted->cursor * sizeof props_ptr[0]);
1641 if (!props_ptr) {
1642 errno = ENOMEM;
1643 goto out;
1644 }
1645
1646 prop_values_ptr = drmMalloc(sorted->cursor * sizeof prop_values_ptr[0]);
1647 if (!prop_values_ptr) {
1648 errno = ENOMEM;
1649 goto out;
1650 }
1651
1652 for (i = 0, last_obj_id = 0; i < sorted->cursor; i++) {
1653 if (sorted->items[i].object_id != last_obj_id) {
1654 obj_idx++;
1655 objs_ptr[obj_idx] = sorted->items[i].object_id;
1656 last_obj_id = objs_ptr[obj_idx];
1657 }
1658
1659 count_props_ptr[obj_idx]++;
1660 props_ptr[i] = sorted->items[i].property_id;
1661 prop_values_ptr[i] = sorted->items[i].value;
1662
1663 }
1664
1665 atomic.flags = flags;
1666 atomic.objs_ptr = VOID2U64(objs_ptr);
1667 atomic.count_props_ptr = VOID2U64(count_props_ptr);
1668 atomic.props_ptr = VOID2U64(props_ptr);
1669 atomic.prop_values_ptr = VOID2U64(prop_values_ptr);
1670 atomic.user_data = VOID2U64(user_data);
1671
1672 ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic);
1673
1674out:
1675 drmFree(objs_ptr);
1676 drmFree(count_props_ptr);
1677 drmFree(props_ptr);
1678 drmFree(prop_values_ptr);
1679 drmModeAtomicFree(sorted);
1680
1681 return ret;
1682}
1683
1684int
1685drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id)
1686{
1687 struct drm_mode_create_blob create;
1688 int ret;
1689
1690 if (length >= 0xffffffff)
1691 return -ERANGE;
1692
1693 memclear(create);
1694
1695 create.length = length;
1696 create.data = (uintptr_t) data;
1697 create.blob_id = 0;
1698 *id = 0;
1699
1700 ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create);
1701 if (ret != 0)
1702 return ret;
1703
1704 *id = create.blob_id;
1705 return 0;
1706}
1707
1708int
1709drmModeDestroyPropertyBlob(int fd, uint32_t id)
1710{
1711 struct drm_mode_destroy_blob destroy;
1712
1713 memclear(destroy);
1714 destroy.blob_id = id;
1715 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy);
1716}