commit 47c94eb

Michael Forney  ·  2013-12-31 20:04:39 +0000 UTC
parent 0aea280
Move interface prototypes and struct declarations to interface/
9 files changed,  +344, -257
M dumb.c
M dumb.c
+31, -48
  1@@ -44,45 +44,25 @@ struct dumb_drawable
  2     uint32_t handle;
  3 };
  4 
  5-/* DRM implementation */
  6-static bool dumb_device_supported(uint32_t vendor_id, uint32_t device_id);
  7-static struct dumb_context * dumb_create_context(int drm_fd);
  8-static void dumb_destroy_context(struct dumb_context * context);
  9-static struct wld_drawable * dumb_create_drawable
 10-    (struct dumb_context * context, uint32_t width, uint32_t height,
 11-     uint32_t format);
 12-static struct wld_drawable * dumb_import
 13-    (struct dumb_context * context, uint32_t width, uint32_t height,
 14-     uint32_t format, int prime_fd, unsigned long pitch);
 15-static struct wld_drawable * dumb_import_gem
 16-    (struct dumb_context * context, uint32_t width, uint32_t height,
 17-     uint32_t format, uint32_t gem_name, unsigned long pitch);
 18+#define DRM_DRIVER_NAME dumb
 19+#include "interface/drm.h"
 20 
 21 /* DRM drawable */
 22-static int dumb_export(struct wld_drawable * drawable);
 23-static uint32_t dumb_get_handle(struct wld_drawable * drawable);
 24+static int drawable_export(struct wld_drawable * drawable);
 25+static uint32_t drawable_get_handle(struct wld_drawable * drawable);
 26 
 27-static struct drm_draw_interface dumb_draw = {
 28-    .export = &dumb_export,
 29-    .get_handle = &dumb_get_handle
 30-};
 31-static bool dumb_draw_initialized;
 32-
 33-const struct wld_drm_interface dumb_drm = {
 34-    .device_supported = &dumb_device_supported,
 35-    .create_context = (drm_create_context_func_t) &dumb_create_context,
 36-    .destroy_context = (drm_destroy_context_func_t) &dumb_destroy_context,
 37-    .create_drawable = (drm_create_drawable_func_t) &dumb_create_drawable,
 38-    .import = (drm_import_func_t) &dumb_import,
 39-    .import_gem = (drm_import_gem_func_t) &dumb_import_gem,
 40+static struct drm_draw_interface draw_interface = {
 41+    .export = &drawable_export,
 42+    .get_handle = &drawable_get_handle
 43 };
 44+static bool draw_initialized;
 45 
 46-bool dumb_device_supported(uint32_t vendor_id, uint32_t device_id)
 47+bool drm_device_supported(uint32_t vendor_id, uint32_t device_id)
 48 {
 49     return true;
 50 }
 51 
 52-struct dumb_context * dumb_create_context(int drm_fd)
 53+void * drm_create_context(int drm_fd)
 54 {
 55     struct dumb_context * context;
 56 
 57@@ -94,10 +74,10 @@ struct dumb_context * dumb_create_context(int drm_fd)
 58 
 59     context->fd = drm_fd;
 60 
 61-    if (!dumb_draw_initialized)
 62+    if (!draw_initialized)
 63     {
 64-        dumb_draw.base = pixman_draw;
 65-        dumb_draw_initialized = true;
 66+        draw_interface.base = *pixman_draw;
 67+        draw_initialized = true;
 68     }
 69 
 70     return context;
 71@@ -108,8 +88,10 @@ struct dumb_context * dumb_create_context(int drm_fd)
 72     return NULL;
 73 }
 74 
 75-void dumb_destroy_context(struct dumb_context * context)
 76+void drm_destroy_context(void * base)
 77 {
 78+    struct dumb_context * context = base;
 79+
 80     wld_pixman_destroy_context(context->pixman);
 81     free(context);
 82 }
 83@@ -145,7 +127,7 @@ static struct wld_drawable * new_drawable(struct dumb_context * context,
 84         goto error2;
 85     }
 86 
 87-    drawable->pixman.base.interface = (struct wld_draw_interface *) &dumb_draw;
 88+    drawable->pixman.base.interface = &draw_interface.base;
 89     drawable->context = context;
 90     drawable->handle = handle;
 91 
 92@@ -159,10 +141,11 @@ static struct wld_drawable * new_drawable(struct dumb_context * context,
 93     return NULL;
 94 }
 95 
 96-struct wld_drawable * dumb_create_drawable
 97-    (struct dumb_context * context, uint32_t width, uint32_t height,
 98-     uint32_t format)
 99+struct wld_drawable * drm_create_drawable(void * base,
100+                                          uint32_t width, uint32_t height,
101+                                          uint32_t format)
102 {
103+    struct dumb_context * context = base;
104     struct wld_drawable * drawable;
105     struct drm_mode_create_dumb create_dumb_arg = {
106         .height = height, .width = width,
107@@ -195,11 +178,11 @@ struct wld_drawable * dumb_create_drawable
108     return NULL;
109 }
110 
111-struct wld_drawable * dumb_import(struct dumb_context * context,
112-                                  uint32_t width, uint32_t height,
113-                                  uint32_t format,
114-                                  int prime_fd, unsigned long pitch)
115+struct wld_drawable * drm_import(void * base, uint32_t width, uint32_t height,
116+                                 uint32_t format, int prime_fd,
117+                                 unsigned long pitch)
118 {
119+    struct dumb_context * context = base;
120     int ret;
121     uint32_t handle;
122 
123@@ -214,17 +197,17 @@ struct wld_drawable * dumb_import(struct dumb_context * context,
124     return NULL;
125 }
126 
127-struct wld_drawable * dumb_import_gem(struct dumb_context * context,
128-                                      uint32_t width, uint32_t height,
129-                                      uint32_t format,
130-                                      uint32_t gem_name, unsigned long pitch)
131+struct wld_drawable * drm_import_gem(void * context,
132+                                     uint32_t width, uint32_t height,
133+                                     uint32_t format,
134+                                     uint32_t gem_name, unsigned long pitch)
135 {
136     DEBUG("dumb: import_gem is not supported\n");
137 
138     return NULL;
139 }
140 
141-static int dumb_export(struct wld_drawable * drawable)
142+static int drawable_export(struct wld_drawable * drawable)
143 {
144     struct dumb_drawable * dumb = (void *) drawable;
145     int prime_fd, ret;
146@@ -238,7 +221,7 @@ static int dumb_export(struct wld_drawable * drawable)
147     return prime_fd;
148 }
149 
150-static uint32_t dumb_get_handle(struct wld_drawable * drawable)
151+static uint32_t drawable_get_handle(struct wld_drawable * drawable)
152 {
153     struct dumb_drawable * dumb = (void *) drawable;
154 
+42, -94
  1@@ -44,74 +44,16 @@ struct intel_drawable
  2     pixman_image_t * virtual;
  3 };
  4 
  5-/* Drawable implementation */
  6-static void intel_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
  7-                                 int32_t x, int32_t y,
  8-                                 uint32_t width, uint32_t height);
  9-static void intel_copy_rectangle(struct wld_drawable * src,
 10-                                 struct wld_drawable * dst,
 11-                                 int32_t src_x, int32_t src_y,
 12-                                 int32_t dst_x, int32_t dst_y,
 13-                                 uint32_t width, uint32_t height);
 14-static void intel_draw_text_utf8(struct wld_drawable * drawable,
 15-                                 struct font * font, uint32_t color,
 16-                                 int32_t x, int32_t y,
 17-                                 const char * text, int32_t length,
 18-                                 struct wld_extents * extents);
 19-static void intel_write(struct wld_drawable * drawable,
 20-                        const void * data, size_t size);
 21-static pixman_image_t * intel_map(struct wld_drawable * drawable);
 22-static void intel_flush(struct wld_drawable * drawable);
 23-static void intel_destroy(struct wld_drawable * drawable);
 24-
 25-static int intel_export(struct wld_drawable * drawable);
 26-static uint32_t intel_get_handle(struct wld_drawable * drawable);
 27-
 28-/* DRM implementation */
 29-static bool intel_device_supported(uint32_t vendor_id, uint32_t device_id);
 30-static struct intel_context * intel_create_context(int drm_fd);
 31-static void intel_destroy_context(struct intel_context * context);
 32-static struct wld_drawable * intel_create_drawable
 33-    (struct intel_context * context, uint32_t width, uint32_t height,
 34-     uint32_t format);
 35-static struct wld_drawable * intel_import
 36-    (struct intel_context * context, uint32_t width, uint32_t height,
 37-     uint32_t format, int prime_fd, unsigned long pitch);
 38-static struct wld_drawable * intel_import_gem
 39-    (struct intel_context * context, uint32_t width, uint32_t height,
 40-     uint32_t format, uint32_t gem_name, unsigned long pitch);
 41-
 42-const static struct drm_draw_interface intel_draw = {
 43-    .base = {
 44-        .fill_rectangle = &intel_fill_rectangle,
 45-        .fill_region = &default_fill_region,
 46-        .copy_rectangle = &intel_copy_rectangle,
 47-        .copy_region = &default_copy_region,
 48-        .draw_text_utf8 = &intel_draw_text_utf8,
 49-        .write = &intel_write,
 50-        .map = &intel_map,
 51-        .flush = &intel_flush,
 52-        .destroy = &intel_destroy
 53-    },
 54-    .export = &intel_export,
 55-    .get_handle = &intel_get_handle
 56-};
 57-
 58-const struct wld_drm_interface intel_drm = {
 59-    .device_supported = &intel_device_supported,
 60-    .create_context = (drm_create_context_func_t) &intel_create_context,
 61-    .destroy_context = (drm_destroy_context_func_t) &intel_destroy_context,
 62-    .create_drawable = (drm_create_drawable_func_t) &intel_create_drawable,
 63-    .import = (drm_import_func_t) &intel_import,
 64-    .import_gem = (drm_import_gem_func_t) &intel_import_gem,
 65-};
 66+#define DRM_DRIVER_NAME intel
 67+#include "interface/drm.h"
 68+#include "interface/drm_drawable.h"
 69 
 70-bool intel_device_supported(uint32_t vendor_id, uint32_t device_id)
 71+bool drm_device_supported(uint32_t vendor_id, uint32_t device_id)
 72 {
 73     return vendor_id == 0x8086;
 74 }
 75 
 76-struct intel_context * intel_create_context(int drm_fd)
 77+void * drm_create_context(int drm_fd)
 78 {
 79     struct intel_context * context;
 80 
 81@@ -140,8 +82,10 @@ struct intel_context * intel_create_context(int drm_fd)
 82     return NULL;
 83 }
 84 
 85-void intel_destroy_context(struct intel_context * context)
 86+void drm_destroy_context(void * base)
 87 {
 88+    struct intel_context * context = base;
 89+
 90     intel_batch_destroy(context->batch);
 91     drm_intel_bufmgr_destroy(context->bufmgr);
 92     free(context);
 93@@ -156,7 +100,7 @@ static struct intel_drawable * new_drawable(struct intel_context * context,
 94     if (!(intel = malloc(sizeof *intel)))
 95         return NULL;
 96 
 97-    intel->base.interface = (struct wld_draw_interface *) &intel_draw;
 98+    intel->base.interface = &draw_interface.base;
 99     intel->base.width = width;
100     intel->base.height = height;
101     intel->base.format = format;
102@@ -166,10 +110,11 @@ static struct intel_drawable * new_drawable(struct intel_context * context,
103     return intel;
104 }
105 
106-struct wld_drawable * intel_create_drawable
107-    (struct intel_context * context, uint32_t width, uint32_t height,
108-     uint32_t format)
109+struct wld_drawable * drm_create_drawable(void * base,
110+                                          uint32_t width, uint32_t height,
111+                                          uint32_t format)
112 {
113+    struct intel_context * context = base;
114     struct intel_drawable * intel;
115     uint32_t tiling_mode = width >= 128 ? I915_TILING_X : I915_TILING_NONE;
116 
117@@ -183,11 +128,12 @@ struct wld_drawable * intel_create_drawable
118     return &intel->base;
119 }
120 
121-struct wld_drawable * intel_import(struct intel_context * context,
122-                                   uint32_t width, uint32_t height,
123-                                   uint32_t format,
124-                                   int prime_fd, unsigned long pitch)
125+struct wld_drawable * drm_import(void * base,
126+                                 uint32_t width, uint32_t height,
127+                                 uint32_t format,
128+                                 int prime_fd, unsigned long pitch)
129 {
130+    struct intel_context * context = base;
131     struct intel_drawable * intel;
132     uint32_t size = width * height * 4;
133 
134@@ -201,11 +147,12 @@ struct wld_drawable * intel_import(struct intel_context * context,
135     return &intel->base;
136 }
137 
138-struct wld_drawable * intel_import_gem(struct intel_context * context,
139-                                       uint32_t width, uint32_t height,
140-                                       uint32_t format,
141-                                       uint32_t gem_name, unsigned long pitch)
142+struct wld_drawable * drm_import_gem(void * base,
143+                                     uint32_t width, uint32_t height,
144+                                     uint32_t format,
145+                                     uint32_t gem_name, unsigned long pitch)
146 {
147+    struct intel_context * context = base;
148     struct intel_drawable * intel;
149 
150     if (!(intel = new_drawable(context, width, height, format)))
151@@ -218,8 +165,9 @@ struct wld_drawable * intel_import_gem(struct intel_context * context,
152     return &intel->base;
153 }
154 
155-void intel_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
156-                          int32_t x, int32_t y, uint32_t width, uint32_t height)
157+void drawable_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
158+                             int32_t x, int32_t y,
159+                             uint32_t width, uint32_t height)
160 {
161     struct intel_drawable * intel = (void *) drawable;
162 
163@@ -227,11 +175,11 @@ void intel_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
164                  x, y, x + width, y + height, color);
165 }
166 
167-void intel_copy_rectangle(struct wld_drawable * src_drawable,
168-                          struct wld_drawable * dst_drawable,
169-                          int32_t src_x, int32_t src_y,
170-                          int32_t dst_x, int32_t dst_y,
171-                          uint32_t width, uint32_t height)
172+void drawable_copy_rectangle(struct wld_drawable * src_drawable,
173+                             struct wld_drawable * dst_drawable,
174+                             int32_t src_x, int32_t src_y,
175+                             int32_t dst_x, int32_t dst_y,
176+                             uint32_t width, uint32_t height)
177 {
178     struct intel_drawable * src = (void *) src_drawable;
179     struct intel_drawable * dst = (void *) dst_drawable;
180@@ -241,11 +189,11 @@ void intel_copy_rectangle(struct wld_drawable * src_drawable,
181                     dst->bo, dst->base.pitch, dst_x, dst_y, width, height);
182 }
183 
184-void intel_draw_text_utf8(struct wld_drawable * drawable,
185-                          struct font * font, uint32_t color,
186-                          int32_t x, int32_t y,
187-                          const char * text, int32_t length,
188-                          struct wld_extents * extents)
189+void drawable_draw_text_utf8(struct wld_drawable * drawable,
190+                             struct font * font, uint32_t color,
191+                             int32_t x, int32_t y,
192+                             const char * text, int32_t length,
193+                             struct wld_extents * extents)
194 {
195     struct intel_drawable * intel = (void *) drawable;
196     int ret;
197@@ -309,7 +257,7 @@ void intel_draw_text_utf8(struct wld_drawable * drawable,
198         extents->advance = origin_x - x;
199 }
200 
201-void intel_write(struct wld_drawable * drawable, const void * data, size_t size)
202+void drawable_write(struct wld_drawable * drawable, const void * data, size_t size)
203 {
204     struct intel_drawable * intel = (void *) drawable;
205 
206@@ -324,7 +272,7 @@ static void destroy_virtual(pixman_image_t * image, void * data)
207     intel->virtual = NULL;
208 }
209 
210-pixman_image_t * intel_map(struct wld_drawable * drawable)
211+pixman_image_t * drawable_map(struct wld_drawable * drawable)
212 {
213     struct intel_drawable * intel = (void *) drawable;
214 
215@@ -344,21 +292,21 @@ pixman_image_t * intel_map(struct wld_drawable * drawable)
216     return intel->virtual;
217 }
218 
219-void intel_flush(struct wld_drawable * drawable)
220+void drawable_flush(struct wld_drawable * drawable)
221 {
222     struct intel_drawable * intel = (void *) drawable;
223 
224     intel_batch_flush(intel->context->batch);
225 }
226 
227-void intel_destroy(struct wld_drawable * drawable)
228+void drawable_destroy(struct wld_drawable * drawable)
229 {
230     struct intel_drawable * intel = (void *) drawable;
231     drm_intel_bo_unreference(intel->bo);
232     free(intel);
233 }
234 
235-int intel_export(struct wld_drawable * drawable)
236+int drawable_export(struct wld_drawable * drawable)
237 {
238     struct intel_drawable * intel = (void *) drawable;
239     int prime_fd;
240@@ -368,7 +316,7 @@ int intel_export(struct wld_drawable * drawable)
241     return prime_fd;
242 }
243 
244-uint32_t intel_get_handle(struct wld_drawable * drawable)
245+uint32_t drawable_get_handle(struct wld_drawable * drawable)
246 {
247     struct intel_drawable * intel = (void *) drawable;
248 
+67, -0
 1@@ -0,0 +1,67 @@
 2+/* wld: interface/drawable.h
 3+ *
 4+ * Copyright (c) 2013 Michael Forney
 5+ *
 6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
 7+ * of this software and associated documentation files (the "Software"), to deal
 8+ * in the Software without restriction, including without limitation the rights
 9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+static void drawable_fill_rectangle(struct wld_drawable * drawable,
26+                                    uint32_t color, int32_t x, int32_t y,
27+                                    uint32_t width, uint32_t height);
28+static void drawable_copy_rectangle(struct wld_drawable * src,
29+                                    struct wld_drawable * dst,
30+                                    int32_t src_x, int32_t src_y,
31+                                    int32_t dst_x, int32_t dst_y,
32+                                    uint32_t width, uint32_t height);
33+#ifdef DRAWABLE_IMPLEMENTS_REGION
34+static void drawable_fill_region(struct wld_drawable * drawable, uint32_t color,
35+                                 pixman_region32_t * region);
36+static void drawable_copy_region(struct wld_drawable * src,
37+                                 struct wld_drawable * drawable,
38+                                 pixman_region32_t * region,
39+                                 int32_t dst_x, int32_t dst_y);
40+#endif
41+static void drawable_draw_text_utf8(struct wld_drawable * drawable,
42+                                    struct font * font, uint32_t color,
43+                                    int32_t x, int32_t y,
44+                                    const char * text, int32_t length,
45+                                    struct wld_extents * extents);
46+static void drawable_write(struct wld_drawable * drawable,
47+                           const void * data, size_t size);
48+static pixman_image_t * drawable_map(struct wld_drawable * drawable);
49+static void drawable_flush(struct wld_drawable * drawable);
50+static void drawable_destroy(struct wld_drawable * drawable);
51+
52+static const struct wld_draw_interface draw_interface = {
53+    .fill_rectangle = &drawable_fill_rectangle,
54+    .copy_rectangle = &drawable_copy_rectangle,
55+#ifdef DRAWABLE_IMPLEMENTS_REGION
56+    .fill_region = &drawable_fill_region,
57+    .copy_region = &drawable_copy_region,
58+#else
59+    .fill_region = &default_fill_region,
60+    .copy_region = &default_copy_region,
61+#endif
62+    .draw_text_utf8 = &drawable_draw_text_utf8,
63+    .write = &drawable_write,
64+    .map = &drawable_map,
65+    .flush = &drawable_flush,
66+    .destroy = &drawable_destroy
67+};
68+
+55, -0
 1@@ -0,0 +1,55 @@
 2+/* wld: interface/drm.h
 3+ *
 4+ * Copyright (c) 2013 Michael Forney
 5+ *
 6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
 7+ * of this software and associated documentation files (the "Software"), to deal
 8+ * in the Software without restriction, including without limitation the rights
 9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#ifndef DRM_DRIVER_NAME
26+#   error "You must define DRM_DRIVER_NAME before including interface/drm.h"
27+#endif
28+
29+/* DRM implementation */
30+static bool drm_device_supported(uint32_t vendor_id, uint32_t device_id);
31+static void * drm_create_context(int drm_fd);
32+static void drm_destroy_context(void * context);
33+static struct wld_drawable * drm_create_drawable
34+    (void * context, uint32_t width, uint32_t height, uint32_t format);
35+static struct wld_drawable * drm_import(void * context,
36+                                        uint32_t width, uint32_t height,
37+                                        uint32_t format, int prime_fd,
38+                                        unsigned long pitch);
39+static struct wld_drawable * drm_import_gem(void * context,
40+                                            uint32_t width, uint32_t height,
41+                                            uint32_t format, uint32_t gem_name,
42+                                            unsigned long pitch);
43+
44+#define EXPAND(f, x) f(x)
45+#define VAR(name) name ## _drm
46+const struct wld_drm_interface EXPAND(VAR, DRM_DRIVER_NAME) = {
47+    .device_supported = &drm_device_supported,
48+    .create_context = &drm_create_context,
49+    .destroy_context = &drm_destroy_context,
50+    .create_drawable = &drm_create_drawable,
51+    .import = &drm_import,
52+    .import_gem = &drm_import_gem,
53+};
54+#undef VAR
55+#undef EXPAND
56+
+74, -0
 1@@ -0,0 +1,74 @@
 2+/* wld: interface/drm_drawable.h
 3+ *
 4+ * Copyright (c) 2013 Michael Forney
 5+ *
 6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
 7+ * of this software and associated documentation files (the "Software"), to deal
 8+ * in the Software without restriction, including without limitation the rights
 9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+static void drawable_fill_rectangle(struct wld_drawable * drawable,
26+                                    uint32_t color, int32_t x, int32_t y,
27+                                    uint32_t width, uint32_t height);
28+static void drawable_copy_rectangle(struct wld_drawable * src,
29+                                    struct wld_drawable * dst,
30+                                    int32_t src_x, int32_t src_y,
31+                                    int32_t dst_x, int32_t dst_y,
32+                                    uint32_t width, uint32_t height);
33+#ifdef DRAWABLE_IMPLEMENTS_REGION
34+static void drawable_fill_region(struct wld_drawable * drawable, uint32_t color,
35+                                 pixman_region32_t * region);
36+static void drawable_copy_region(struct wld_drawable * src,
37+                                 struct wld_drawable * drawable,
38+                                 pixman_region32_t * region,
39+                                 int32_t dst_x, int32_t dst_y);
40+#endif
41+static void drawable_draw_text_utf8(struct wld_drawable * drawable,
42+                                    struct font * font, uint32_t color,
43+                                    int32_t x, int32_t y,
44+                                    const char * text, int32_t length,
45+                                    struct wld_extents * extents);
46+static void drawable_write(struct wld_drawable * drawable,
47+                           const void * data, size_t size);
48+static pixman_image_t * drawable_map(struct wld_drawable * drawable);
49+static void drawable_flush(struct wld_drawable * drawable);
50+static void drawable_destroy(struct wld_drawable * drawable);
51+
52+static int drawable_export(struct wld_drawable * drawable);
53+static uint32_t drawable_get_handle(struct wld_drawable * drawable);
54+
55+static const struct drm_draw_interface draw_interface = {
56+    .base = {
57+        .fill_rectangle = &drawable_fill_rectangle,
58+        .copy_rectangle = &drawable_copy_rectangle,
59+#ifdef DRAWABLE_IMPLEMENTS_REGION
60+        .fill_region = &drawable_fill_region,
61+        .copy_region = &drawable_copy_region,
62+#else
63+        .fill_region = &default_fill_region,
64+        .copy_region = &default_copy_region,
65+#endif
66+        .draw_text_utf8 = &drawable_draw_text_utf8,
67+        .write = &drawable_write,
68+        .map = &drawable_map,
69+        .flush = &drawable_flush,
70+        .destroy = &drawable_destroy
71+    },
72+    .export = &drawable_export,
73+    .get_handle = &drawable_get_handle
74+};
75+
+1, -1
1@@ -35,7 +35,7 @@ struct pixman_drawable
2     struct wld_pixman_context * context;
3 };
4 
5-extern const struct wld_draw_interface pixman_draw;
6+extern const struct wld_draw_interface * const pixman_draw;
7 
8 bool pixman_initialize_drawable
9     (struct wld_pixman_context * context, struct pixman_drawable * drawable,
+29, -61
  1@@ -37,42 +37,10 @@ struct wld_pixman_context
  2     pixman_glyph_cache_t * glyph_cache;
  3 };
  4 
  5-static void pixman_fill_rectangle(struct wld_drawable * drawable,
  6-                                  uint32_t color, int32_t x, int32_t y,
  7-                                  uint32_t width, uint32_t height);
  8-static void pixman_fill_region(struct wld_drawable * drawable, uint32_t color,
  9-                               pixman_region32_t * region);
 10-static void pixman_copy_rectangle(struct wld_drawable * src,
 11-                                  struct wld_drawable * dst,
 12-                                  int32_t src_x, int32_t src_y,
 13-                                  int32_t dst_x, int32_t dst_y,
 14-                                  uint32_t width, uint32_t height);
 15-static void pixman_copy_region(struct wld_drawable * src,
 16-                               struct wld_drawable * dst,
 17-                               pixman_region32_t * region,
 18-                               int32_t dst_x, int32_t dst_y);
 19-static void pixman_draw_text_utf8(struct wld_drawable * drawable,
 20-                                  struct font * font, uint32_t color,
 21-                                  int32_t x, int32_t y,
 22-                                  const char * text, int32_t length,
 23-                                  struct wld_extents * extents);
 24-static void pixman_write(struct wld_drawable * drawable,
 25-                         const void * data, size_t size);
 26-static pixman_image_t * pixman_map(struct wld_drawable * drawable);
 27-static void pixman_flush(struct wld_drawable * drawable);
 28-static void pixman_destroy(struct wld_drawable * drawable);
 29-
 30-const struct wld_draw_interface pixman_draw = {
 31-    .fill_rectangle = &pixman_fill_rectangle,
 32-    .fill_region = &pixman_fill_region,
 33-    .copy_rectangle = &pixman_copy_rectangle,
 34-    .copy_region = &pixman_copy_region,
 35-    .draw_text_utf8 = &pixman_draw_text_utf8,
 36-    .write = &pixman_write,
 37-    .map = &pixman_map,
 38-    .flush = &pixman_flush,
 39-    .destroy = &pixman_destroy
 40-};
 41+#define DRAWABLE_IMPLEMENTS_REGION
 42+#include "interface/drawable.h"
 43+
 44+const struct wld_draw_interface * const pixman_draw = &draw_interface;
 45 
 46 EXPORT
 47 struct wld_pixman_context * wld_pixman_create_context()
 48@@ -105,7 +73,7 @@ bool pixman_initialize_drawable
 49      uint32_t width, uint32_t height,
 50      void * data, uint32_t pitch, uint32_t format)
 51 {
 52-    drawable->base.interface = &pixman_draw;
 53+    drawable->base.interface = &draw_interface;
 54     drawable->base.width = width;
 55     drawable->base.height = height;
 56     drawable->base.format = format;
 57@@ -145,9 +113,9 @@ struct wld_drawable * wld_pixman_create_drawable
 58     return NULL;
 59 }
 60 
 61-void pixman_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
 62-                           int32_t x, int32_t y,
 63-                           uint32_t width, uint32_t height)
 64+void drawable_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
 65+                             int32_t x, int32_t y,
 66+                             uint32_t width, uint32_t height)
 67 {
 68     struct pixman_drawable * pixman = (void *) drawable;
 69     pixman_color_t pixman_color = PIXMAN_COLOR(color);
 70@@ -157,8 +125,8 @@ void pixman_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
 71                             1, &box);
 72 }
 73 
 74-void pixman_fill_region(struct wld_drawable * drawable, uint32_t color,
 75-                        pixman_region32_t * region)
 76+void drawable_fill_region(struct wld_drawable * drawable, uint32_t color,
 77+                          pixman_region32_t * region)
 78 {
 79     struct pixman_drawable * pixman = (void *) drawable;
 80     pixman_color_t pixman_color = PIXMAN_COLOR(color);
 81@@ -170,11 +138,11 @@ void pixman_fill_region(struct wld_drawable * drawable, uint32_t color,
 82                             num_boxes, boxes);
 83 }
 84 
 85-void pixman_copy_rectangle(struct wld_drawable * src_drawable,
 86-                           struct wld_drawable * dst_drawable,
 87-                           int32_t src_x, int32_t src_y,
 88-                           int32_t dst_x, int32_t dst_y,
 89-                           uint32_t width, uint32_t height)
 90+void drawable_copy_rectangle(struct wld_drawable * src_drawable,
 91+                             struct wld_drawable * dst_drawable,
 92+                             int32_t src_x, int32_t src_y,
 93+                             int32_t dst_x, int32_t dst_y,
 94+                             uint32_t width, uint32_t height)
 95 {
 96     struct pixman_drawable * src = (void *) src_drawable;
 97     struct pixman_drawable * dst = (void *) dst_drawable;
 98@@ -183,10 +151,10 @@ void pixman_copy_rectangle(struct wld_drawable * src_drawable,
 99                              src_x, src_y, 0, 0, dst_x, dst_y, width, height);
100 }
101 
102-void pixman_copy_region(struct wld_drawable * src_drawable,
103-                        struct wld_drawable * dst_drawable,
104-                        pixman_region32_t * region,
105-                        int32_t dst_x, int32_t dst_y)
106+void drawable_copy_region(struct wld_drawable * src_drawable,
107+                          struct wld_drawable * dst_drawable,
108+                          pixman_region32_t * region,
109+                          int32_t dst_x, int32_t dst_y)
110 {
111     struct pixman_drawable * src = (void *) src_drawable;
112     struct pixman_drawable * dst = (void *) dst_drawable;
113@@ -210,11 +178,11 @@ static inline uint8_t reverse(uint8_t byte)
114     return byte;
115 }
116 
117-void pixman_draw_text_utf8(struct wld_drawable * drawable,
118-                           struct font * font, uint32_t color,
119-                           int32_t x, int32_t y,
120-                           const char * text, int32_t length,
121-                           struct wld_extents * extents)
122+void drawable_draw_text_utf8(struct wld_drawable * drawable,
123+                             struct font * font, uint32_t color,
124+                             int32_t x, int32_t y,
125+                             const char * text, int32_t length,
126+                             struct wld_extents * extents)
127 {
128     struct pixman_drawable * pixman = (void *) drawable;
129     int ret;
130@@ -303,26 +271,26 @@ void pixman_draw_text_utf8(struct wld_drawable * drawable,
131         extents->advance = origin_x;
132 }
133 
134-void pixman_write(struct wld_drawable * drawable,
135-                  const void * data, size_t size)
136+void drawable_write(struct wld_drawable * drawable,
137+                    const void * data, size_t size)
138 {
139     struct pixman_drawable * pixman = (void *) drawable;
140 
141     memcpy(pixman_image_get_data(pixman->image), data, size);
142 }
143 
144-pixman_image_t * pixman_map(struct wld_drawable * drawable)
145+pixman_image_t * drawable_map(struct wld_drawable * drawable)
146 {
147     struct pixman_drawable * pixman = (void *) drawable;
148 
149     return pixman_image_ref(pixman->image);
150 }
151 
152-void pixman_flush(struct wld_drawable * drawable)
153+void drawable_flush(struct wld_drawable * drawable)
154 {
155 }
156 
157-void pixman_destroy(struct wld_drawable * drawable)
158+void drawable_destroy(struct wld_drawable * drawable)
159 {
160     struct pixman_drawable * pixman = (void *) drawable;
161 
+37, -53
  1@@ -61,27 +61,8 @@ static void sync_done(void * data, struct wl_callback * callback,
  2 
  3 static void buffer_release(void * data, struct wl_buffer * buffer);
  4 
  5-static void wayland_fill_rectangle(struct wld_drawable * drawable,
  6-                                   uint32_t color, int32_t x, int32_t y,
  7-                                   uint32_t width, uint32_t height);
  8-static void wayland_fill_region(struct wld_drawable * drawable, uint32_t color,
  9-                                pixman_region32_t * region);
 10-static void wayland_copy_rectangle(struct wld_drawable * src,
 11-                                   struct wld_drawable * dst,
 12-                                   int32_t src_x, int32_t src_y,
 13-                                   int32_t dst_x, int32_t dst_y,
 14-                                   uint32_t width, uint32_t height);
 15-static void wayland_copy_region(struct wld_drawable * src,
 16-                                struct wld_drawable * dst,
 17-                                pixman_region32_t * region,
 18-                                int32_t dst_x, int32_t dst_y);
 19-static void wayland_draw_text_utf8(struct wld_drawable * drawable,
 20-                                   struct font * font, uint32_t color,
 21-                                   int32_t x, int32_t y,
 22-                                   const char * text, int32_t length,
 23-                                   struct wld_extents * extents);
 24-static void wayland_flush(struct wld_drawable * drawable);
 25-static void wayland_destroy(struct wld_drawable * drawable);
 26+#define DRAWABLE_IMPLEMENTS_REGION
 27+#include "interface/drawable.h"
 28 
 29 const struct wl_callback_listener sync_listener = {
 30     .done = &sync_done
 31@@ -91,16 +72,6 @@ const struct wl_buffer_listener buffer_listener = {
 32     .release = &buffer_release
 33 };
 34 
 35-const struct wld_draw_interface wayland_draw = {
 36-    .fill_rectangle = &wayland_fill_rectangle,
 37-    .fill_region = &wayland_fill_region,
 38-    .copy_rectangle = &wayland_copy_rectangle,
 39-    .copy_region = &wayland_copy_region,
 40-    .draw_text_utf8 = &wayland_draw_text_utf8,
 41-    .flush = &wayland_flush,
 42-    .destroy = &wayland_destroy
 43-};
 44-
 45 const static struct wld_wayland_interface * interfaces[] = {
 46 #if WITH_WAYLAND_DRM
 47     [WLD_DRM] = &wayland_drm_interface,
 48@@ -228,7 +199,7 @@ struct wld_drawable * wld_wayland_create_drawable
 49     wayland->surface = surface;
 50     wayland->damage_tracking = damage_flags;
 51 
 52-    wayland->base.interface = &wayland_draw;
 53+    wayland->base.interface = &draw_interface;
 54     wayland->base.width = width;
 55     wayland->base.height = height;
 56 
 57@@ -326,9 +297,9 @@ static void begin(struct wayland_drawable * wayland)
 58     }
 59 }
 60 
 61-void wayland_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
 62-                            int32_t x, int32_t y,
 63-                            uint32_t width, uint32_t height)
 64+void drawable_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
 65+                             int32_t x, int32_t y,
 66+                             uint32_t width, uint32_t height)
 67 {
 68     struct wayland_drawable * wayland = (void *) drawable;
 69 
 70@@ -343,8 +314,8 @@ void wayland_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
 71     }
 72 }
 73 
 74-void wayland_fill_region(struct wld_drawable * drawable, uint32_t color,
 75-                         pixman_region32_t * region)
 76+void drawable_fill_region(struct wld_drawable * drawable, uint32_t color,
 77+                          pixman_region32_t * region)
 78 {
 79     struct wayland_drawable * wayland = (void *) drawable;
 80 
 81@@ -358,28 +329,28 @@ void wayland_fill_region(struct wld_drawable * drawable, uint32_t color,
 82     }
 83 }
 84 
 85-void wayland_copy_rectangle(struct wld_drawable * src_drawable,
 86-                            struct wld_drawable * dst_drawable,
 87-                            int32_t src_x, int32_t src_y,
 88-                            int32_t dst_x, int32_t dst_y,
 89-                            uint32_t width, uint32_t height)
 90+void drawable_copy_rectangle(struct wld_drawable * src_drawable,
 91+                             struct wld_drawable * dst_drawable,
 92+                             int32_t src_x, int32_t src_y,
 93+                             int32_t dst_x, int32_t dst_y,
 94+                             uint32_t width, uint32_t height)
 95 {
 96     fprintf(stderr, "wayland: Copy rectangle is not implemented\n");
 97 }
 98 
 99-void wayland_copy_region(struct wld_drawable * src_drawable,
100-                         struct wld_drawable * dst_drawable,
101-                         pixman_region32_t * region,
102-                         int32_t dst_x, int32_t dst_y)
103+void drawable_copy_region(struct wld_drawable * src_drawable,
104+                          struct wld_drawable * dst_drawable,
105+                          pixman_region32_t * region,
106+                          int32_t dst_x, int32_t dst_y)
107 {
108     fprintf(stderr, "wayland: Copy region is not implemented\n");
109 }
110 
111-void wayland_draw_text_utf8(struct wld_drawable * drawable,
112-                            struct font * font, uint32_t color,
113-                            int32_t x, int32_t y,
114-                            const char * text, int32_t length,
115-                            struct wld_extents * extents)
116+void drawable_draw_text_utf8(struct wld_drawable * drawable,
117+                             struct font * font, uint32_t color,
118+                             int32_t x, int32_t y,
119+                             const char * text, int32_t length,
120+                             struct wld_extents * extents)
121 {
122     struct wld_extents extents0;
123     struct wayland_drawable * wayland = (void *) drawable;
124@@ -400,7 +371,20 @@ void wayland_draw_text_utf8(struct wld_drawable * drawable,
125     }
126 }
127 
128-void wayland_flush(struct wld_drawable * drawable)
129+void drawable_write(struct wld_drawable * drawable,
130+                    const void * data, size_t size)
131+{
132+    fprintf(stderr, "wayland: Write is not implemented\n");
133+}
134+
135+pixman_image_t * drawable_map(struct wld_drawable * drawable)
136+{
137+    fprintf(stderr, "wayland: Map is not implemented\n");
138+
139+    return NULL;
140+}
141+
142+void drawable_flush(struct wld_drawable * drawable)
143 {
144     struct wayland_drawable * wayland = (void *) drawable;
145 
146@@ -431,7 +415,7 @@ void wayland_flush(struct wld_drawable * drawable)
147     wayland->front_buffer ^= 1;
148 }
149 
150-void wayland_destroy(struct wld_drawable * drawable)
151+void drawable_destroy(struct wld_drawable * drawable)
152 {
153     struct wayland_drawable * wayland = (void *) drawable;
154 
+8, -0
 1@@ -26,6 +26,7 @@
 2 
 3 #include "wld.h"
 4 
 5+#include <assert.h>
 6 #include <stdbool.h>
 7 #include <stdint.h>
 8 #include <ft2build.h>
 9@@ -45,6 +46,13 @@
10 #endif
11 
12 #define EXPORT __attribute__((visibility("default")))
13+#define IMPL(name, type)                                                    \
14+    static inline struct name ## _ ## type * name ## _ ## type              \
15+        (struct wld_ ## type * type)                                        \
16+    {                                                                       \
17+        assert(type->impl == &type ## _impl);                               \
18+        return (struct name ## _ ## type *) type;                           \
19+    }
20 
21 struct wld_font_context
22 {