1 #include "ecore_drm2_private.h"
2
3 static int _ecore_drm2_init_count = 0;
4 static void *drm_lib = NULL;
5
6 int _ecore_drm2_log_dom = -1;
7
8 int (*sym_drmHandleEvent)(int fd, drmEventContext *evctx) = NULL;
9 void *(*sym_drmGetVersion)(int fd) = NULL;
10 void (*sym_drmFreeVersion)(void *drmver) = NULL;
11 void *(*sym_drmModeGetProperty)(int fd, uint32_t propertyId) = NULL;
12 void (*sym_drmModeFreeProperty)(drmModePropertyPtr ptr) = NULL;
13 void *(*sym_drmModeGetPropertyBlob)(int fd, uint32_t blob_id) = NULL;
14 void (*sym_drmModeFreePropertyBlob)(drmModePropertyBlobPtr ptr) = NULL;
15 int (*sym_drmModeDestroyPropertyBlob)(int fd, uint32_t id) = NULL;
16 int (*sym_drmIoctl)(int fd, unsigned long request, void *arg) = NULL;
17 void *(*sym_drmModeObjectGetProperties)(int fd, uint32_t object_id, uint32_t object_type) = NULL;
18 void (*sym_drmModeFreeObjectProperties)(drmModeObjectPropertiesPtr ptr) = NULL;
19 int (*sym_drmModeCreatePropertyBlob)(int fd, const void *data, size_t size, uint32_t *id) = NULL;
20 void *(*sym_drmModeAtomicAlloc)(void) = NULL;
21 void (*sym_drmModeAtomicFree)(drmModeAtomicReqPtr req) = NULL;
22 int (*sym_drmModeAtomicAddProperty)(drmModeAtomicReqPtr req, uint32_t object_id, uint32_t property_id, uint64_t value) = NULL;
23 int (*sym_drmModeAtomicCommit)(int fd, drmModeAtomicReqPtr req, uint32_t flags, void *user_data) = NULL;
24 void (*sym_drmModeAtomicSetCursor)(drmModeAtomicReqPtr req, int cursor) = NULL;
25 int (*sym_drmModeAtomicMerge)(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment);
26 void *(*sym_drmModeGetEncoder)(int fd, uint32_t encoder_id) = NULL;
27 void (*sym_drmModeFreeEncoder)(drmModeEncoderPtr ptr) = NULL;
28 void *(*sym_drmModeGetCrtc)(int fd, uint32_t crtcId) = NULL;
29 void (*sym_drmModeFreeCrtc)(drmModeCrtcPtr ptr) = NULL;
30 int (*sym_drmModeSetCrtc)(int fd, uint32_t crtcId, uint32_t bufferId, uint32_t x, uint32_t y, uint32_t *connectors, int count, drmModeModeInfoPtr mode) = NULL;
31 void *(*sym_drmModeGetResources)(int fd) = NULL;
32 void (*sym_drmModeFreeResources)(drmModeResPtr ptr) = NULL;
33 void *(*sym_drmModeGetConnector)(int fd, uint32_t connectorId) = NULL;
34 void (*sym_drmModeFreeConnector)(drmModeConnectorPtr ptr) = NULL;
35 int (*sym_drmModeConnectorSetProperty)(int fd, uint32_t connector_id, uint32_t property_id, uint64_t value) = NULL;
36 int (*sym_drmGetCap)(int fd, uint64_t capability, uint64_t *value) = NULL;
37 int (*sym_drmSetClientCap)(int fd, uint64_t capability, uint64_t value) = NULL;
38 void *(*sym_drmModeGetPlaneResources)(int fd) = NULL;
39 void (*sym_drmModeFreePlaneResources)(drmModePlaneResPtr ptr) = NULL;
40 void *(*sym_drmModeGetPlane)(int fd, uint32_t plane_id) = NULL;
41 void (*sym_drmModeFreePlane)(drmModePlanePtr ptr) = NULL;
42 int (*sym_drmModeAddFB)(int fd, uint32_t width, uint32_t height, uint8_t depth, uint8_t bpp, uint32_t pitch, uint32_t bo_handle, uint32_t *buf_id) = NULL;
43 int (*sym_drmModeAddFB2)(int fd, uint32_t width, uint32_t height, uint32_t pixel_format, uint32_t bo_handles[4], uint32_t pitches[4], uint32_t offsets[4], uint32_t *buf_id, uint32_t flags) = NULL;
44 int (*sym_drmModeRmFB)(int fd, uint32_t bufferId) = NULL;
45 int (*sym_drmModePageFlip)(int fd, uint32_t crtc_id, uint32_t fb_id, uint32_t flags, void *user_data) = NULL;
46 int (*sym_drmModeDirtyFB)(int fd, uint32_t bufferId, drmModeClipPtr clips, uint32_t num_clips) = NULL;
47 int (*sym_drmModeCrtcSetGamma)(int fd, uint32_t crtc_id, uint32_t size, uint16_t *red, uint16_t *green, uint16_t *blue) = NULL;
48 int (*sym_drmPrimeFDToHandle)(int fd, int prime_fd, uint32_t *handle) = NULL;
49 int (*sym_drmWaitVBlank)(int fd, drmVBlank *vbl) = NULL;
50
51 EAPI int ECORE_DRM2_EVENT_OUTPUT_CHANGED = -1;
52 EAPI int ECORE_DRM2_EVENT_ACTIVATE = -1;
53
54 static Eina_Bool
_ecore_drm2_link(void)55 _ecore_drm2_link(void)
56 {
57 int i, fail;
58 const char *drm_libs[] =
59 {
60 "libdrm.so.2",
61 "libdrm.so.1",
62 "libdrm.so.0",
63 "libdrm.so",
64 NULL,
65 };
66
67 #define SYM(lib, xx) \
68 do { \
69 sym_ ## xx = dlsym(lib, #xx); \
70 if (!(sym_ ## xx)) { \
71 fail = 1; \
72 } \
73 } while (0)
74
75 if (drm_lib) return EINA_TRUE;
76
77 for (i = 0; drm_libs[i]; i++)
78 {
79 drm_lib = dlopen(drm_libs[i], RTLD_LOCAL | RTLD_LAZY);
80 if (!drm_lib) continue;
81
82 fail = 0;
83
84 SYM(drm_lib, drmIoctl);
85 /* SYM(drm_lib, drmClose); */
86 SYM(drm_lib, drmWaitVBlank);
87 SYM(drm_lib, drmHandleEvent);
88 SYM(drm_lib, drmGetVersion);
89 SYM(drm_lib, drmFreeVersion);
90 SYM(drm_lib, drmModeGetProperty);
91 SYM(drm_lib, drmModeFreeProperty);
92 SYM(drm_lib, drmModeGetPropertyBlob);
93 SYM(drm_lib, drmModeFreePropertyBlob);
94 SYM(drm_lib, drmModeDestroyPropertyBlob);
95 SYM(drm_lib, drmModeObjectGetProperties);
96 SYM(drm_lib, drmModeFreeObjectProperties);
97 SYM(drm_lib, drmModeCreatePropertyBlob);
98 SYM(drm_lib, drmModeAtomicAlloc);
99 SYM(drm_lib, drmModeAtomicFree);
100 SYM(drm_lib, drmModeAtomicAddProperty);
101 SYM(drm_lib, drmModeAtomicCommit);
102 SYM(drm_lib, drmModeAtomicSetCursor);
103 SYM(drm_lib, drmModeAtomicMerge);
104 SYM(drm_lib, drmModeGetEncoder);
105 SYM(drm_lib, drmModeFreeEncoder);
106 SYM(drm_lib, drmModeGetCrtc);
107 SYM(drm_lib, drmModeFreeCrtc);
108 SYM(drm_lib, drmModeSetCrtc);
109 SYM(drm_lib, drmModeGetResources);
110 SYM(drm_lib, drmModeFreeResources);
111 SYM(drm_lib, drmModeGetConnector);
112 SYM(drm_lib, drmModeFreeConnector);
113 SYM(drm_lib, drmModeConnectorSetProperty);
114 SYM(drm_lib, drmGetCap);
115 SYM(drm_lib, drmSetClientCap);
116 SYM(drm_lib, drmModeGetPlaneResources);
117 SYM(drm_lib, drmModeFreePlaneResources);
118 SYM(drm_lib, drmModeGetPlane);
119 SYM(drm_lib, drmModeFreePlane);
120 SYM(drm_lib, drmModeAddFB);
121 SYM(drm_lib, drmModeAddFB2);
122 SYM(drm_lib, drmModeRmFB);
123 SYM(drm_lib, drmModePageFlip);
124 SYM(drm_lib, drmModeDirtyFB);
125 SYM(drm_lib, drmModeCrtcSetGamma);
126 SYM(drm_lib, drmPrimeFDToHandle);
127
128 if (fail)
129 {
130 dlclose(drm_lib);
131 drm_lib = NULL;
132 }
133 else
134 break;
135 }
136
137 if (!drm_lib) return EINA_FALSE;
138 return EINA_TRUE;
139 }
140
141 EAPI int
ecore_drm2_init(void)142 ecore_drm2_init(void)
143 {
144 if (++_ecore_drm2_init_count != 1) return _ecore_drm2_init_count;
145
146 if (!eina_init()) goto eina_err;
147
148 if (!ecore_init())
149 {
150 EINA_LOG_ERR("Could not initialize Ecore library");
151 goto ecore_err;
152 }
153
154 if (!eeze_init())
155 {
156 EINA_LOG_ERR("Could not initialize Eeze library");
157 goto eeze_err;
158 }
159
160 if (!elput_init())
161 {
162 EINA_LOG_ERR("Could not initialize Elput library");
163 goto elput_err;
164 }
165
166 _ecore_drm2_log_dom =
167 eina_log_domain_register("ecore_drm2", ECORE_DRM2_DEFAULT_LOG_COLOR);
168 if (!_ecore_drm2_log_dom)
169 {
170 EINA_LOG_ERR("Could not create logging domain for Ecore_Drm2");
171 goto log_err;
172 }
173
174 ECORE_DRM2_EVENT_OUTPUT_CHANGED = ecore_event_type_new();
175 ECORE_DRM2_EVENT_ACTIVATE = ecore_event_type_new();
176
177 if (!_ecore_drm2_link()) goto link_err;
178
179 return _ecore_drm2_init_count;
180
181 link_err:
182 eina_log_domain_unregister(_ecore_drm2_log_dom);
183 _ecore_drm2_log_dom = -1;
184 log_err:
185 elput_shutdown();
186 elput_err:
187 eeze_shutdown();
188 eeze_err:
189 ecore_shutdown();
190 ecore_err:
191 eina_shutdown();
192 eina_err:
193 return --_ecore_drm2_init_count;
194 }
195
196 EAPI int
ecore_drm2_shutdown(void)197 ecore_drm2_shutdown(void)
198 {
199 if (_ecore_drm2_init_count < 1)
200 {
201 ERR("Ecore_Drm2 shutdown called without init");
202 return 0;
203 }
204
205 if (--_ecore_drm2_init_count != 0) return _ecore_drm2_init_count;
206
207 ECORE_DRM2_EVENT_OUTPUT_CHANGED = -1;
208 ECORE_DRM2_EVENT_ACTIVATE = -1;
209
210 eina_log_domain_unregister(_ecore_drm2_log_dom);
211 _ecore_drm2_log_dom = -1;
212
213 elput_shutdown();
214 eeze_shutdown();
215 ecore_shutdown();
216 eina_shutdown();
217
218 return _ecore_drm2_init_count;
219 }
220
221 EAPI int
ecore_drm2_event_handle(Ecore_Drm2_Device * dev,Ecore_Drm2_Context * drmctx)222 ecore_drm2_event_handle(Ecore_Drm2_Device *dev, Ecore_Drm2_Context *drmctx)
223 {
224 drmEventContext ctx;
225
226 EINA_SAFETY_ON_NULL_RETURN_VAL(dev, -1);
227
228 memset(&ctx, 0, sizeof(ctx));
229 ctx.version = 2;
230 ctx.page_flip_handler = drmctx->page_flip_handler;
231 ctx.vblank_handler = drmctx->vblank_handler;
232
233 return sym_drmHandleEvent(dev->fd, &ctx);
234 }
235