commit 6dfd3cd

Michael Forney  ·  2013-07-13 02:21:28 +0000 UTC
parent 2ccabcc
Initial import
25 files changed,  +3610, -0
A TODO
A font.c
A wld.h
+30, -0
 1@@ -0,0 +1,30 @@
 2+*.o
 3+*.lo
 4+.*.swp
 5+
 6+.deps/
 7+.libs/
 8+
 9+Makefile
10+Makefile.in
11+
12+/aclocal.m4
13+/ar-lib
14+/autom4te.cache/
15+/config.guess
16+/config.log
17+/config.status
18+/config.sub
19+/configure
20+/depcomp
21+/install-sh
22+/libtool
23+/ltmain.sh
24+/m4/
25+/missing
26+
27+/libwld.la
28+/wld.pc
29+/protocol/wayland-drm-client-protocol.h
30+/protocol/wayland-drm-protocol.c
31+
+46, -0
 1@@ -0,0 +1,46 @@
 2+# wld: Makefile.am
 3+
 4+ACLOCAL_AMFLAGS = -I m4
 5+AM_CFLAGS = $(fontconfig_CFLAGS) $(freetype_CFLAGS) $(pixman_CFLAGS)
 6+
 7+lib_LTLIBRARIES = libwld.la
 8+pkginclude_HEADERS = wld.h
 9+
10+pkgconfigdir = $(libdir)/pkgconfig
11+pkgconfig_DATA = wld.pc
12+
13+libwld_la_SOURCES = color.c drawable.c font.c
14+libwld_la_LIBADD = $(fontconfig_LIBS) $(freetype_LIBS) $(pixman_LIBS)
15+
16+if WITH_WAYLAND
17+    AM_CFLAGS += $(wayland_client_CFLAGS)
18+    libwld_la_SOURCES += wayland.c
19+    libwld_la_LIBADD += $(wayland_client_LIBS)
20+    pkginclude_HEADERS += wayland.h
21+endif
22+
23+if ENABLE_WAYLAND_DRM
24+    AM_CPPFLAGS = -I$(top_builddir)/protocol
25+    libwld_la_SOURCES += wayland-drm.c protocol/wayland-drm-protocol.c
26+    pkginclude_HEADERS += wayland-drm.h
27+endif
28+
29+if ENABLE_WAYLAND_SHM
30+    libwld_la_SOURCES += wayland-shm.c
31+    pkginclude_HEADERS += wayland-shm.h
32+endif
33+
34+if ENABLE_INTEL
35+    AM_CFLAGS += $(drm_intel_CFLAGS) $(intelbatch_CFLAGS)
36+    libwld_la_SOURCES += intel.c
37+    libwld_la_LIBADD += $(drm_intel_LIBS) $(intelbatch_LIBS)
38+    pkginclude_HEADERS += intel.h
39+endif
40+
41+if ENABLE_PIXMAN
42+    libwld_la_SOURCES += pixman.c
43+    pkginclude_HEADERS += pixman.h
44+endif
45+
46+SUBDIRS = protocol
47+
A TODO
+7, -0
1@@ -0,0 +1,7 @@
2+TODO
3+====
4+- Non-monochrome text rendering
5+    - Probably requires 3d engine blending for intel backend
6+- Optional damage tracking and handling for Wayland drawables
7+- Add doxygen documentation
8+
+13, -0
 1@@ -0,0 +1,13 @@
 2+#!/bin/sh
 3+
 4+set -ex
 5+
 6+rm -rf autom4te.cache
 7+
 8+libtoolize
 9+aclocal -I m4 --force
10+autoconf -f -W all
11+automake -f -a -c -W all
12+
13+rm -rf autom4te.cache
14+
+849, -0
  1@@ -0,0 +1,849 @@
  2+/* Adapted from xorg-server */
  3+
  4+/***********************************************************
  5+
  6+Copyright 1987, 1998  The Open Group
  7+
  8+Permission to use, copy, modify, distribute, and sell this software and its
  9+documentation for any purpose is hereby granted without fee, provided that
 10+the above copyright notice appear in all copies and that both that
 11+copyright notice and this permission notice appear in supporting
 12+documentation.
 13+
 14+The above copyright notice and this permission notice shall be included in
 15+all copies or substantial portions of the Software.
 16+
 17+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 20+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 21+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 22+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 23+
 24+Except as contained in this notice, the name of The Open Group shall not be
 25+used in advertising or otherwise to promote the sale, use or other dealings
 26+in this Software without prior written authorization from The Open Group.
 27+
 28+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 29+
 30+                        All Rights Reserved
 31+
 32+Permission to use, copy, modify, and distribute this software and its 
 33+documentation for any purpose and without fee is hereby granted, 
 34+provided that the above copyright notice appear in all copies and that
 35+both that copyright notice and this permission notice appear in 
 36+supporting documentation, and that the name of Digital not be
 37+used in advertising or publicity pertaining to distribution of the
 38+software without specific, written prior permission.  
 39+
 40+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 41+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 42+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 43+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 44+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 45+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 46+SOFTWARE.
 47+
 48+******************************************************************/
 49+
 50+#include "wld-private.h"
 51+
 52+#include <strings.h>
 53+
 54+struct named_color
 55+{
 56+    const char * name;
 57+    uint32_t color;
 58+};
 59+
 60+static const struct named_color named_colors[] = {
 61+    { "alice blue",             0xfff0f8ff },
 62+    { "AliceBlue",              0xfff0f8ff },
 63+    { "antique white",          0xfffaebd7 },
 64+    { "AntiqueWhite",           0xfffaebd7 },
 65+    { "AntiqueWhite1",          0xffffefdb },
 66+    { "AntiqueWhite2",          0xffeedfcc },
 67+    { "AntiqueWhite3",          0xffcdc0b0 },
 68+    { "AntiqueWhite4",          0xff8b8378 },
 69+    { "aquamarine",             0xff7fffd4 },
 70+    { "aquamarine1",            0xff7fffd4 },
 71+    { "aquamarine2",            0xff76eec6 },
 72+    { "aquamarine3",            0xff66cdaa },
 73+    { "aquamarine4",            0xff458b74 },
 74+    { "azure",                  0xfff0ffff },
 75+    { "azure1",                 0xfff0ffff },
 76+    { "azure2",                 0xffe0eeee },
 77+    { "azure3",                 0xffc1cdcd },
 78+    { "azure4",                 0xff838b8b },
 79+    { "beige",                  0xfff5f5dc },
 80+    { "bisque",                 0xffffe4c4 },
 81+    { "bisque1",                0xffffe4c4 },
 82+    { "bisque2",                0xffeed5b7 },
 83+    { "bisque3",                0xffcdb79e },
 84+    { "bisque4",                0xff8b7d6b },
 85+    { "black",                  0xff000000 },
 86+    { "blanched almond",        0xffffebcd },
 87+    { "BlanchedAlmond",         0xffffebcd },
 88+    { "blue",                   0xff0000ff },
 89+    { "blue violet",            0xff8a2be2 },
 90+    { "blue1",                  0xff0000ff },
 91+    { "blue2",                  0xff0000ee },
 92+    { "blue3",                  0xff0000cd },
 93+    { "blue4",                  0xff00008b },
 94+    { "BlueViolet",             0xff8a2be2 },
 95+    { "brown",                  0xffa52a2a },
 96+    { "brown1",                 0xffff4040 },
 97+    { "brown2",                 0xffee3b3b },
 98+    { "brown3",                 0xffcd3333 },
 99+    { "brown4",                 0xff8b2323 },
100+    { "burlywood",              0xffdeb887 },
101+    { "burlywood1",             0xffffd39b },
102+    { "burlywood2",             0xffeec591 },
103+    { "burlywood3",             0xffcdaa7d },
104+    { "burlywood4",             0xff8b7355 },
105+    { "cadet blue",             0xff5f9ea0 },
106+    { "CadetBlue",              0xff5f9ea0 },
107+    { "CadetBlue1",             0xff98f5ff },
108+    { "CadetBlue2",             0xff8ee5ee },
109+    { "CadetBlue3",             0xff7ac5cd },
110+    { "CadetBlue4",             0xff53868b },
111+    { "chartreuse",             0xff7fff00 },
112+    { "chartreuse1",            0xff7fff00 },
113+    { "chartreuse2",            0xff76ee00 },
114+    { "chartreuse3",            0xff66cd00 },
115+    { "chartreuse4",            0xff458b00 },
116+    { "chocolate",              0xffd2691e },
117+    { "chocolate1",             0xffff7f24 },
118+    { "chocolate2",             0xffee7621 },
119+    { "chocolate3",             0xffcd661d },
120+    { "chocolate4",             0xff8b4513 },
121+    { "coral",                  0xffff7f50 },
122+    { "coral1",                 0xffff7256 },
123+    { "coral2",                 0xffee6a50 },
124+    { "coral3",                 0xffcd5b45 },
125+    { "coral4",                 0xff8b3e2f },
126+    { "cornflower blue",        0xff6495ed },
127+    { "CornflowerBlue",         0xff6495ed },
128+    { "cornsilk",               0xfffff8dc },
129+    { "cornsilk1",              0xfffff8dc },
130+    { "cornsilk2",              0xffeee8cd },
131+    { "cornsilk3",              0xffcdc8b1 },
132+    { "cornsilk4",              0xff8b8878 },
133+    { "cyan",                   0xff00ffff },
134+    { "cyan1",                  0xff00ffff },
135+    { "cyan2",                  0xff00eeee },
136+    { "cyan3",                  0xff00cdcd },
137+    { "cyan4",                  0xff008b8b },
138+    { "dark blue",              0xff00008b },
139+    { "dark cyan",              0xff008b8b },
140+    { "dark goldenrod",         0xffb8860b },
141+    { "dark gray",              0xffa9a9a9 },
142+    { "dark green",             0xff006400 },
143+    { "dark grey",              0xffa9a9a9 },
144+    { "dark khaki",             0xffbdb76b },
145+    { "dark magenta",           0xff8b008b },
146+    { "dark olive green",       0xff556b2f },
147+    { "dark orange",            0xffff8c00 },
148+    { "dark orchid",            0xff9932cc },
149+    { "dark red",               0xff8b0000 },
150+    { "dark salmon",            0xffe9967a },
151+    { "dark sea green",         0xff8fbc8f },
152+    { "dark slate blue",        0xff483d8b },
153+    { "dark slate gray",        0xff2f4f4f },
154+    { "dark slate grey",        0xff2f4f4f },
155+    { "dark turquoise",         0xff00ced1 },
156+    { "dark violet",            0xff9400d3 },
157+    { "DarkBlue",               0xff00008b },
158+    { "DarkCyan",               0xff008b8b },
159+    { "DarkGoldenrod",          0xffb8860b },
160+    { "DarkGoldenrod1",         0xffffb90f },
161+    { "DarkGoldenrod2",         0xffeead0e },
162+    { "DarkGoldenrod3",         0xffcd950c },
163+    { "DarkGoldenrod4",         0xff8b6508 },
164+    { "DarkGray",               0xffa9a9a9 },
165+    { "DarkGreen",              0xff006400 },
166+    { "DarkGrey",               0xffa9a9a9 },
167+    { "DarkKhaki",              0xffbdb76b },
168+    { "DarkMagenta",            0xff8b008b },
169+    { "DarkOliveGreen",         0xff556b2f },
170+    { "DarkOliveGreen1",        0xffcaff70 },
171+    { "DarkOliveGreen2",        0xffbcee68 },
172+    { "DarkOliveGreen3",        0xffa2cd5a },
173+    { "DarkOliveGreen4",        0xff6e8b3d },
174+    { "DarkOrange",             0xffff8c00 },
175+    { "DarkOrange1",            0xffff7f00 },
176+    { "DarkOrange2",            0xffee7600 },
177+    { "DarkOrange3",            0xffcd6600 },
178+    { "DarkOrange4",            0xff8b4500 },
179+    { "DarkOrchid",             0xff9932cc },
180+    { "DarkOrchid1",            0xffbf3eff },
181+    { "DarkOrchid2",            0xffb23aee },
182+    { "DarkOrchid3",            0xff9a32cd },
183+    { "DarkOrchid4",            0xff68228b },
184+    { "DarkRed",                0xff8b0000 },
185+    { "DarkSalmon",             0xffe9967a },
186+    { "DarkSeaGreen",           0xff8fbc8f },
187+    { "DarkSeaGreen1",          0xffc1ffc1 },
188+    { "DarkSeaGreen2",          0xffb4eeb4 },
189+    { "DarkSeaGreen3",          0xff9bcd9b },
190+    { "DarkSeaGreen4",          0xff698b69 },
191+    { "DarkSlateBlue",          0xff483d8b },
192+    { "DarkSlateGray",          0xff2f4f4f },
193+    { "DarkSlateGray1",         0xff97ffff },
194+    { "DarkSlateGray2",         0xff8deeee },
195+    { "DarkSlateGray3",         0xff79cdcd },
196+    { "DarkSlateGray4",         0xff528b8b },
197+    { "DarkSlateGrey",          0xff2f4f4f },
198+    { "DarkTurquoise",          0xff00ced1 },
199+    { "DarkViolet",             0xff9400d3 },
200+    { "deep pink",              0xffff1493 },
201+    { "deep sky blue",          0xff00bfff },
202+    { "DeepPink",               0xffff1493 },
203+    { "DeepPink1",              0xffff1493 },
204+    { "DeepPink2",              0xffee1289 },
205+    { "DeepPink3",              0xffcd1076 },
206+    { "DeepPink4",              0xff8b0a50 },
207+    { "DeepSkyBlue",            0xff00bfff },
208+    { "DeepSkyBlue1",           0xff00bfff },
209+    { "DeepSkyBlue2",           0xff00b2ee },
210+    { "DeepSkyBlue3",           0xff009acd },
211+    { "DeepSkyBlue4",           0xff00688b },
212+    { "dim gray",               0xff696969 },
213+    { "dim grey",               0xff696969 },
214+    { "DimGray",                0xff696969 },
215+    { "DimGrey",                0xff696969 },
216+    { "dodger blue",            0xff1e90ff },
217+    { "DodgerBlue",             0xff1e90ff },
218+    { "DodgerBlue1",            0xff1e90ff },
219+    { "DodgerBlue2",            0xff1c86ee },
220+    { "DodgerBlue3",            0xff1874cd },
221+    { "DodgerBlue4",            0xff104e8b },
222+    { "firebrick",              0xffb22222 },
223+    { "firebrick1",             0xffff3030 },
224+    { "firebrick2",             0xffee2c2c },
225+    { "firebrick3",             0xffcd2626 },
226+    { "firebrick4",             0xff8b1a1a },
227+    { "floral white",           0xfffffaf0 },
228+    { "FloralWhite",            0xfffffaf0 },
229+    { "forest green",           0xff228b22 },
230+    { "ForestGreen",            0xff228b22 },
231+    { "gainsboro",              0xffdcdcdc },
232+    { "ghost white",            0xfff8f8ff },
233+    { "GhostWhite",             0xfff8f8ff },
234+    { "gold",                   0xffffd700 },
235+    { "gold1",                  0xffffd700 },
236+    { "gold2",                  0xffeec900 },
237+    { "gold3",                  0xffcdad00 },
238+    { "gold4",                  0xff8b7500 },
239+    { "goldenrod",              0xffdaa520 },
240+    { "goldenrod1",             0xffffc125 },
241+    { "goldenrod2",             0xffeeb422 },
242+    { "goldenrod3",             0xffcd9b1d },
243+    { "goldenrod4",             0xff8b6914 },
244+    { "gray",                   0xffbebebe },
245+    { "gray0",                  0xff000000 },
246+    { "gray1",                  0xff030303 },
247+    { "gray10",                 0xff1a1a1a },
248+    { "gray100",                0xffffffff },
249+    { "gray11",                 0xff1c1c1c },
250+    { "gray12",                 0xff1f1f1f },
251+    { "gray13",                 0xff212121 },
252+    { "gray14",                 0xff242424 },
253+    { "gray15",                 0xff262626 },
254+    { "gray16",                 0xff292929 },
255+    { "gray17",                 0xff2b2b2b },
256+    { "gray18",                 0xff2e2e2e },
257+    { "gray19",                 0xff303030 },
258+    { "gray2",                  0xff050505 },
259+    { "gray20",                 0xff333333 },
260+    { "gray21",                 0xff363636 },
261+    { "gray22",                 0xff383838 },
262+    { "gray23",                 0xff3b3b3b },
263+    { "gray24",                 0xff3d3d3d },
264+    { "gray25",                 0xff404040 },
265+    { "gray26",                 0xff424242 },
266+    { "gray27",                 0xff454545 },
267+    { "gray28",                 0xff474747 },
268+    { "gray29",                 0xff4a4a4a },
269+    { "gray3",                  0xff080808 },
270+    { "gray30",                 0xff4d4d4d },
271+    { "gray31",                 0xff4f4f4f },
272+    { "gray32",                 0xff525252 },
273+    { "gray33",                 0xff545454 },
274+    { "gray34",                 0xff575757 },
275+    { "gray35",                 0xff595959 },
276+    { "gray36",                 0xff5c5c5c },
277+    { "gray37",                 0xff5e5e5e },
278+    { "gray38",                 0xff616161 },
279+    { "gray39",                 0xff636363 },
280+    { "gray4",                  0xff0a0a0a },
281+    { "gray40",                 0xff666666 },
282+    { "gray41",                 0xff696969 },
283+    { "gray42",                 0xff6b6b6b },
284+    { "gray43",                 0xff6e6e6e },
285+    { "gray44",                 0xff707070 },
286+    { "gray45",                 0xff737373 },
287+    { "gray46",                 0xff757575 },
288+    { "gray47",                 0xff787878 },
289+    { "gray48",                 0xff7a7a7a },
290+    { "gray49",                 0xff7d7d7d },
291+    { "gray5",                  0xff0d0d0d },
292+    { "gray50",                 0xff7f7f7f },
293+    { "gray51",                 0xff828282 },
294+    { "gray52",                 0xff858585 },
295+    { "gray53",                 0xff878787 },
296+    { "gray54",                 0xff8a8a8a },
297+    { "gray55",                 0xff8c8c8c },
298+    { "gray56",                 0xff8f8f8f },
299+    { "gray57",                 0xff919191 },
300+    { "gray58",                 0xff949494 },
301+    { "gray59",                 0xff969696 },
302+    { "gray6",                  0xff0f0f0f },
303+    { "gray60",                 0xff999999 },
304+    { "gray61",                 0xff9c9c9c },
305+    { "gray62",                 0xff9e9e9e },
306+    { "gray63",                 0xffa1a1a1 },
307+    { "gray64",                 0xffa3a3a3 },
308+    { "gray65",                 0xffa6a6a6 },
309+    { "gray66",                 0xffa8a8a8 },
310+    { "gray67",                 0xffababab },
311+    { "gray68",                 0xffadadad },
312+    { "gray69",                 0xffb0b0b0 },
313+    { "gray7",                  0xff121212 },
314+    { "gray70",                 0xffb3b3b3 },
315+    { "gray71",                 0xffb5b5b5 },
316+    { "gray72",                 0xffb8b8b8 },
317+    { "gray73",                 0xffbababa },
318+    { "gray74",                 0xffbdbdbd },
319+    { "gray75",                 0xffbfbfbf },
320+    { "gray76",                 0xffc2c2c2 },
321+    { "gray77",                 0xffc4c4c4 },
322+    { "gray78",                 0xffc7c7c7 },
323+    { "gray79",                 0xffc9c9c9 },
324+    { "gray8",                  0xff141414 },
325+    { "gray80",                 0xffcccccc },
326+    { "gray81",                 0xffcfcfcf },
327+    { "gray82",                 0xffd1d1d1 },
328+    { "gray83",                 0xffd4d4d4 },
329+    { "gray84",                 0xffd6d6d6 },
330+    { "gray85",                 0xffd9d9d9 },
331+    { "gray86",                 0xffdbdbdb },
332+    { "gray87",                 0xffdedede },
333+    { "gray88",                 0xffe0e0e0 },
334+    { "gray89",                 0xffe3e3e3 },
335+    { "gray9",                  0xff171717 },
336+    { "gray90",                 0xffe5e5e5 },
337+    { "gray91",                 0xffe8e8e8 },
338+    { "gray92",                 0xffebebeb },
339+    { "gray93",                 0xffededed },
340+    { "gray94",                 0xfff0f0f0 },
341+    { "gray95",                 0xfff2f2f2 },
342+    { "gray96",                 0xfff5f5f5 },
343+    { "gray97",                 0xfff7f7f7 },
344+    { "gray98",                 0xfffafafa },
345+    { "gray99",                 0xfffcfcfc },
346+    { "green",                  0xff00ff00 },
347+    { "green yellow",           0xffadff2f },
348+    { "green1",                 0xff00ff00 },
349+    { "green2",                 0xff00ee00 },
350+    { "green3",                 0xff00cd00 },
351+    { "green4",                 0xff008b00 },
352+    { "GreenYellow",            0xffadff2f },
353+    { "grey",                   0xffbebebe },
354+    { "grey0",                  0xff000000 },
355+    { "grey1",                  0xff030303 },
356+    { "grey10",                 0xff1a1a1a },
357+    { "grey100",                0xffffffff },
358+    { "grey11",                 0xff1c1c1c },
359+    { "grey12",                 0xff1f1f1f },
360+    { "grey13",                 0xff212121 },
361+    { "grey14",                 0xff242424 },
362+    { "grey15",                 0xff262626 },
363+    { "grey16",                 0xff292929 },
364+    { "grey17",                 0xff2b2b2b },
365+    { "grey18",                 0xff2e2e2e },
366+    { "grey19",                 0xff303030 },
367+    { "grey2",                  0xff050505 },
368+    { "grey20",                 0xff333333 },
369+    { "grey21",                 0xff363636 },
370+    { "grey22",                 0xff383838 },
371+    { "grey23",                 0xff3b3b3b },
372+    { "grey24",                 0xff3d3d3d },
373+    { "grey25",                 0xff404040 },
374+    { "grey26",                 0xff424242 },
375+    { "grey27",                 0xff454545 },
376+    { "grey28",                 0xff474747 },
377+    { "grey29",                 0xff4a4a4a },
378+    { "grey3",                  0xff080808 },
379+    { "grey30",                 0xff4d4d4d },
380+    { "grey31",                 0xff4f4f4f },
381+    { "grey32",                 0xff525252 },
382+    { "grey33",                 0xff545454 },
383+    { "grey34",                 0xff575757 },
384+    { "grey35",                 0xff595959 },
385+    { "grey36",                 0xff5c5c5c },
386+    { "grey37",                 0xff5e5e5e },
387+    { "grey38",                 0xff616161 },
388+    { "grey39",                 0xff636363 },
389+    { "grey4",                  0xff0a0a0a },
390+    { "grey40",                 0xff666666 },
391+    { "grey41",                 0xff696969 },
392+    { "grey42",                 0xff6b6b6b },
393+    { "grey43",                 0xff6e6e6e },
394+    { "grey44",                 0xff707070 },
395+    { "grey45",                 0xff737373 },
396+    { "grey46",                 0xff757575 },
397+    { "grey47",                 0xff787878 },
398+    { "grey48",                 0xff7a7a7a },
399+    { "grey49",                 0xff7d7d7d },
400+    { "grey5",                  0xff0d0d0d },
401+    { "grey50",                 0xff7f7f7f },
402+    { "grey51",                 0xff828282 },
403+    { "grey52",                 0xff858585 },
404+    { "grey53",                 0xff878787 },
405+    { "grey54",                 0xff8a8a8a },
406+    { "grey55",                 0xff8c8c8c },
407+    { "grey56",                 0xff8f8f8f },
408+    { "grey57",                 0xff919191 },
409+    { "grey58",                 0xff949494 },
410+    { "grey59",                 0xff969696 },
411+    { "grey6",                  0xff0f0f0f },
412+    { "grey60",                 0xff999999 },
413+    { "grey61",                 0xff9c9c9c },
414+    { "grey62",                 0xff9e9e9e },
415+    { "grey63",                 0xffa1a1a1 },
416+    { "grey64",                 0xffa3a3a3 },
417+    { "grey65",                 0xffa6a6a6 },
418+    { "grey66",                 0xffa8a8a8 },
419+    { "grey67",                 0xffababab },
420+    { "grey68",                 0xffadadad },
421+    { "grey69",                 0xffb0b0b0 },
422+    { "grey7",                  0xff121212 },
423+    { "grey70",                 0xffb3b3b3 },
424+    { "grey71",                 0xffb5b5b5 },
425+    { "grey72",                 0xffb8b8b8 },
426+    { "grey73",                 0xffbababa },
427+    { "grey74",                 0xffbdbdbd },
428+    { "grey75",                 0xffbfbfbf },
429+    { "grey76",                 0xffc2c2c2 },
430+    { "grey77",                 0xffc4c4c4 },
431+    { "grey78",                 0xffc7c7c7 },
432+    { "grey79",                 0xffc9c9c9 },
433+    { "grey8",                  0xff141414 },
434+    { "grey80",                 0xffcccccc },
435+    { "grey81",                 0xffcfcfcf },
436+    { "grey82",                 0xffd1d1d1 },
437+    { "grey83",                 0xffd4d4d4 },
438+    { "grey84",                 0xffd6d6d6 },
439+    { "grey85",                 0xffd9d9d9 },
440+    { "grey86",                 0xffdbdbdb },
441+    { "grey87",                 0xffdedede },
442+    { "grey88",                 0xffe0e0e0 },
443+    { "grey89",                 0xffe3e3e3 },
444+    { "grey9",                  0xff171717 },
445+    { "grey90",                 0xffe5e5e5 },
446+    { "grey91",                 0xffe8e8e8 },
447+    { "grey92",                 0xffebebeb },
448+    { "grey93",                 0xffededed },
449+    { "grey94",                 0xfff0f0f0 },
450+    { "grey95",                 0xfff2f2f2 },
451+    { "grey96",                 0xfff5f5f5 },
452+    { "grey97",                 0xfff7f7f7 },
453+    { "grey98",                 0xfffafafa },
454+    { "grey99",                 0xfffcfcfc },
455+    { "honeydew",               0xfff0fff0 },
456+    { "honeydew1",              0xfff0fff0 },
457+    { "honeydew2",              0xffe0eee0 },
458+    { "honeydew3",              0xffc1cdc1 },
459+    { "honeydew4",              0xff838b83 },
460+    { "hot pink",               0xffff69b4 },
461+    { "HotPink",                0xffff69b4 },
462+    { "HotPink1",               0xffff6eb4 },
463+    { "HotPink2",               0xffee6aa7 },
464+    { "HotPink3",               0xffcd6090 },
465+    { "HotPink4",               0xff8b3a62 },
466+    { "indian red",             0xffcd5c5c },
467+    { "IndianRed",              0xffcd5c5c },
468+    { "IndianRed1",             0xffff6a6a },
469+    { "IndianRed2",             0xffee6363 },
470+    { "IndianRed3",             0xffcd5555 },
471+    { "IndianRed4",             0xff8b3a3a },
472+    { "ivory",                  0xfffffff0 },
473+    { "ivory1",                 0xfffffff0 },
474+    { "ivory2",                 0xffeeeee0 },
475+    { "ivory3",                 0xffcdcdc1 },
476+    { "ivory4",                 0xff8b8b83 },
477+    { "khaki",                  0xfff0e68c },
478+    { "khaki1",                 0xfffff68f },
479+    { "khaki2",                 0xffeee685 },
480+    { "khaki3",                 0xffcdc673 },
481+    { "khaki4",                 0xff8b864e },
482+    { "lavender",               0xffe6e6fa },
483+    { "lavender blush",         0xfffff0f5 },
484+    { "LavenderBlush",          0xfffff0f5 },
485+    { "LavenderBlush1",         0xfffff0f5 },
486+    { "LavenderBlush2",         0xffeee0e5 },
487+    { "LavenderBlush3",         0xffcdc1c5 },
488+    { "LavenderBlush4",         0xff8b8386 },
489+    { "lawn green",             0xff7cfc00 },
490+    { "LawnGreen",              0xff7cfc00 },
491+    { "lemon chiffon",          0xfffffacd },
492+    { "LemonChiffon",           0xfffffacd },
493+    { "LemonChiffon1",          0xfffffacd },
494+    { "LemonChiffon2",          0xffeee9bf },
495+    { "LemonChiffon3",          0xffcdc9a5 },
496+    { "LemonChiffon4",          0xff8b8970 },
497+    { "light blue",             0xffadd8e6 },
498+    { "light coral",            0xfff08080 },
499+    { "light cyan",             0xffe0ffff },
500+    { "light goldenrod",        0xffeedd82 },
501+    { "light goldenrod yellow", 0xfffafad2 },
502+    { "light gray",             0xffd3d3d3 },
503+    { "light green",            0xff90ee90 },
504+    { "light grey",             0xffd3d3d3 },
505+    { "light pink",             0xffffb6c1 },
506+    { "light salmon",           0xffffa07a },
507+    { "light sea green",        0xff20b2aa },
508+    { "light sky blue",         0xff87cefa },
509+    { "light slate blue",       0xff8470ff },
510+    { "light slate gray",       0xff778899 },
511+    { "light slate grey",       0xff778899 },
512+    { "light steel blue",       0xffb0c4de },
513+    { "light yellow",           0xffffffe0 },
514+    { "LightBlue",              0xffadd8e6 },
515+    { "LightBlue1",             0xffbfefff },
516+    { "LightBlue2",             0xffb2dfee },
517+    { "LightBlue3",             0xff9ac0cd },
518+    { "LightBlue4",             0xff68838b },
519+    { "LightCoral",             0xfff08080 },
520+    { "LightCyan",              0xffe0ffff },
521+    { "LightCyan1",             0xffe0ffff },
522+    { "LightCyan2",             0xffd1eeee },
523+    { "LightCyan3",             0xffb4cdcd },
524+    { "LightCyan4",             0xff7a8b8b },
525+    { "LightGoldenrod",         0xffeedd82 },
526+    { "LightGoldenrod1",        0xffffec8b },
527+    { "LightGoldenrod2",        0xffeedc82 },
528+    { "LightGoldenrod3",        0xffcdbe70 },
529+    { "LightGoldenrod4",        0xff8b814c },
530+    { "LightGoldenrodYellow",   0xfffafad2 },
531+    { "LightGray",              0xffd3d3d3 },
532+    { "LightGreen",             0xff90ee90 },
533+    { "LightGrey",              0xffd3d3d3 },
534+    { "LightPink",              0xffffb6c1 },
535+    { "LightPink1",             0xffffaeb9 },
536+    { "LightPink2",             0xffeea2ad },
537+    { "LightPink3",             0xffcd8c95 },
538+    { "LightPink4",             0xff8b5f65 },
539+    { "LightSalmon",            0xffffa07a },
540+    { "LightSalmon1",           0xffffa07a },
541+    { "LightSalmon2",           0xffee9572 },
542+    { "LightSalmon3",           0xffcd8162 },
543+    { "LightSalmon4",           0xff8b5742 },
544+    { "LightSeaGreen",          0xff20b2aa },
545+    { "LightSkyBlue",           0xff87cefa },
546+    { "LightSkyBlue1",          0xffb0e2ff },
547+    { "LightSkyBlue2",          0xffa4d3ee },
548+    { "LightSkyBlue3",          0xff8db6cd },
549+    { "LightSkyBlue4",          0xff607b8b },
550+    { "LightSlateBlue",         0xff8470ff },
551+    { "LightSlateGray",         0xff778899 },
552+    { "LightSlateGrey",         0xff778899 },
553+    { "LightSteelBlue",         0xffb0c4de },
554+    { "LightSteelBlue1",        0xffcae1ff },
555+    { "LightSteelBlue2",        0xffbcd2ee },
556+    { "LightSteelBlue3",        0xffa2b5cd },
557+    { "LightSteelBlue4",        0xff6e7b8b },
558+    { "LightYellow",            0xffffffe0 },
559+    { "LightYellow1",           0xffffffe0 },
560+    { "LightYellow2",           0xffeeeed1 },
561+    { "LightYellow3",           0xffcdcdb4 },
562+    { "LightYellow4",           0xff8b8b7a },
563+    { "lime green",             0xff32cd32 },
564+    { "LimeGreen",              0xff32cd32 },
565+    { "linen",                  0xfffaf0e6 },
566+    { "magenta",                0xffff00ff },
567+    { "magenta1",               0xffff00ff },
568+    { "magenta2",               0xffee00ee },
569+    { "magenta3",               0xffcd00cd },
570+    { "magenta4",               0xff8b008b },
571+    { "maroon",                 0xffb03060 },
572+    { "maroon1",                0xffff34b3 },
573+    { "maroon2",                0xffee30a7 },
574+    { "maroon3",                0xffcd2990 },
575+    { "maroon4",                0xff8b1c62 },
576+    { "medium aquamarine",      0xff66cdaa },
577+    { "medium blue",            0xff0000cd },
578+    { "medium orchid",          0xffba55d3 },
579+    { "medium purple",          0xff9370db },
580+    { "medium sea green",       0xff3cb371 },
581+    { "medium slate blue",      0xff7b68ee },
582+    { "medium spring green",    0xff00fa9a },
583+    { "medium turquoise",       0xff48d1cc },
584+    { "medium violet red",      0xffc71585 },
585+    { "MediumAquamarine",       0xff66cdaa },
586+    { "MediumBlue",             0xff0000cd },
587+    { "MediumOrchid",           0xffba55d3 },
588+    { "MediumOrchid1",          0xffe066ff },
589+    { "MediumOrchid2",          0xffd15fee },
590+    { "MediumOrchid3",          0xffb452cd },
591+    { "MediumOrchid4",          0xff7a378b },
592+    { "MediumPurple",           0xff9370db },
593+    { "MediumPurple1",          0xffab82ff },
594+    { "MediumPurple2",          0xff9f79ee },
595+    { "MediumPurple3",          0xff8968cd },
596+    { "MediumPurple4",          0xff5d478b },
597+    { "MediumSeaGreen",         0xff3cb371 },
598+    { "MediumSlateBlue",        0xff7b68ee },
599+    { "MediumSpringGreen",      0xff00fa9a },
600+    { "MediumTurquoise",        0xff48d1cc },
601+    { "MediumVioletRed",        0xffc71585 },
602+    { "midnight blue",          0xff191970 },
603+    { "MidnightBlue",           0xff191970 },
604+    { "mint cream",             0xfff5fffa },
605+    { "MintCream",              0xfff5fffa },
606+    { "misty rose",             0xffffe4e1 },
607+    { "MistyRose",              0xffffe4e1 },
608+    { "MistyRose1",             0xffffe4e1 },
609+    { "MistyRose2",             0xffeed5d2 },
610+    { "MistyRose3",             0xffcdb7b5 },
611+    { "MistyRose4",             0xff8b7d7b },
612+    { "moccasin",               0xffffe4b5 },
613+    { "navajo white",           0xffffdead },
614+    { "NavajoWhite",            0xffffdead },
615+    { "NavajoWhite1",           0xffffdead },
616+    { "NavajoWhite2",           0xffeecfa1 },
617+    { "NavajoWhite3",           0xffcdb38b },
618+    { "NavajoWhite4",           0xff8b795e },
619+    { "navy",                   0xff000080 },
620+    { "navy blue",              0xff000080 },
621+    { "NavyBlue",               0xff000080 },
622+    { "old lace",               0xfffdf5e6 },
623+    { "OldLace",                0xfffdf5e6 },
624+    { "olive drab",             0xff6b8e23 },
625+    { "OliveDrab",              0xff6b8e23 },
626+    { "OliveDrab1",             0xffc0ff3e },
627+    { "OliveDrab2",             0xffb3ee3a },
628+    { "OliveDrab3",             0xff9acd32 },
629+    { "OliveDrab4",             0xff698b22 },
630+    { "orange",                 0xffffa500 },
631+    { "orange red",             0xffff4500 },
632+    { "orange1",                0xffffa500 },
633+    { "orange2",                0xffee9a00 },
634+    { "orange3",                0xffcd8500 },
635+    { "orange4",                0xff8b5a00 },
636+    { "OrangeRed",              0xffff4500 },
637+    { "OrangeRed1",             0xffff4500 },
638+    { "OrangeRed2",             0xffee4000 },
639+    { "OrangeRed3",             0xffcd3700 },
640+    { "OrangeRed4",             0xff8b2500 },
641+    { "orchid",                 0xffda70d6 },
642+    { "orchid1",                0xffff83fa },
643+    { "orchid2",                0xffee7ae9 },
644+    { "orchid3",                0xffcd69c9 },
645+    { "orchid4",                0xff8b4789 },
646+    { "pale goldenrod",         0xffeee8aa },
647+    { "pale green",             0xff98fb98 },
648+    { "pale turquoise",         0xffafeeee },
649+    { "pale violet red",        0xffdb7093 },
650+    { "PaleGoldenrod",          0xffeee8aa },
651+    { "PaleGreen",              0xff98fb98 },
652+    { "PaleGreen1",             0xff9aff9a },
653+    { "PaleGreen2",             0xff90ee90 },
654+    { "PaleGreen3",             0xff7ccd7c },
655+    { "PaleGreen4",             0xff548b54 },
656+    { "PaleTurquoise",          0xffafeeee },
657+    { "PaleTurquoise1",         0xffbbffff },
658+    { "PaleTurquoise2",         0xffaeeeee },
659+    { "PaleTurquoise3",         0xff96cdcd },
660+    { "PaleTurquoise4",         0xff668b8b },
661+    { "PaleVioletRed",          0xffdb7093 },
662+    { "PaleVioletRed1",         0xffff82ab },
663+    { "PaleVioletRed2",         0xffee799f },
664+    { "PaleVioletRed3",         0xffcd6889 },
665+    { "PaleVioletRed4",         0xff8b475d },
666+    { "papaya whip",            0xffffefd5 },
667+    { "PapayaWhip",             0xffffefd5 },
668+    { "peach puff",             0xffffdab9 },
669+    { "PeachPuff",              0xffffdab9 },
670+    { "PeachPuff1",             0xffffdab9 },
671+    { "PeachPuff2",             0xffeecbad },
672+    { "PeachPuff3",             0xffcdaf95 },
673+    { "PeachPuff4",             0xff8b7765 },
674+    { "peru",                   0xffcd853f },
675+    { "pink",                   0xffffc0cb },
676+    { "pink1",                  0xffffb5c5 },
677+    { "pink2",                  0xffeea9b8 },
678+    { "pink3",                  0xffcd919e },
679+    { "pink4",                  0xff8b636c },
680+    { "plum",                   0xffdda0dd },
681+    { "plum1",                  0xffffbbff },
682+    { "plum2",                  0xffeeaeee },
683+    { "plum3",                  0xffcd96cd },
684+    { "plum4",                  0xff8b668b },
685+    { "powder blue",            0xffb0e0e6 },
686+    { "PowderBlue",             0xffb0e0e6 },
687+    { "purple",                 0xffa020f0 },
688+    { "purple1",                0xff9b30ff },
689+    { "purple2",                0xff912cee },
690+    { "purple3",                0xff7d26cd },
691+    { "purple4",                0xff551a8b },
692+    { "red",                    0xffff0000 },
693+    { "red1",                   0xffff0000 },
694+    { "red2",                   0xffee0000 },
695+    { "red3",                   0xffcd0000 },
696+    { "red4",                   0xff8b0000 },
697+    { "rosy brown",             0xffbc8f8f },
698+    { "RosyBrown",              0xffbc8f8f },
699+    { "RosyBrown1",             0xffffc1c1 },
700+    { "RosyBrown2",             0xffeeb4b4 },
701+    { "RosyBrown3",             0xffcd9b9b },
702+    { "RosyBrown4",             0xff8b6969 },
703+    { "royal blue",             0xff4169e1 },
704+    { "RoyalBlue",              0xff4169e1 },
705+    { "RoyalBlue1",             0xff4876ff },
706+    { "RoyalBlue2",             0xff436eee },
707+    { "RoyalBlue3",             0xff3a5fcd },
708+    { "RoyalBlue4",             0xff27408b },
709+    { "saddle brown",           0xff8b4513 },
710+    { "SaddleBrown",            0xff8b4513 },
711+    { "salmon",                 0xfffa8072 },
712+    { "salmon1",                0xffff8c69 },
713+    { "salmon2",                0xffee8262 },
714+    { "salmon3",                0xffcd7054 },
715+    { "salmon4",                0xff8b4c39 },
716+    { "sandy brown",            0xfff4a460 },
717+    { "SandyBrown",             0xfff4a460 },
718+    { "sea green",              0xff2e8b57 },
719+    { "SeaGreen",               0xff2e8b57 },
720+    { "SeaGreen1",              0xff54ff9f },
721+    { "SeaGreen2",              0xff4eee94 },
722+    { "SeaGreen3",              0xff43cd80 },
723+    { "SeaGreen4",              0xff2e8b57 },
724+    { "seashell",               0xfffff5ee },
725+    { "seashell1",              0xfffff5ee },
726+    { "seashell2",              0xffeee5de },
727+    { "seashell3",              0xffcdc5bf },
728+    { "seashell4",              0xff8b8682 },
729+    { "sienna",                 0xffa0522d },
730+    { "sienna1",                0xffff8247 },
731+    { "sienna2",                0xffee7942 },
732+    { "sienna3",                0xffcd6839 },
733+    { "sienna4",                0xff8b4726 },
734+    { "sky blue",               0xff87ceeb },
735+    { "SkyBlue",                0xff87ceeb },
736+    { "SkyBlue1",               0xff87ceff },
737+    { "SkyBlue2",               0xff7ec0ee },
738+    { "SkyBlue3",               0xff6ca6cd },
739+    { "SkyBlue4",               0xff4a708b },
740+    { "slate blue",             0xff6a5acd },
741+    { "slate gray",             0xff708090 },
742+    { "slate grey",             0xff708090 },
743+    { "SlateBlue",              0xff6a5acd },
744+    { "SlateBlue1",             0xff836fff },
745+    { "SlateBlue2",             0xff7a67ee },
746+    { "SlateBlue3",             0xff6959cd },
747+    { "SlateBlue4",             0xff473c8b },
748+    { "SlateGray",              0xff708090 },
749+    { "SlateGray1",             0xffc6e2ff },
750+    { "SlateGray2",             0xffb9d3ee },
751+    { "SlateGray3",             0xff9fb6cd },
752+    { "SlateGray4",             0xff6c7b8b },
753+    { "SlateGrey",              0xff708090 },
754+    { "snow",                   0xfffffafa },
755+    { "snow1",                  0xfffffafa },
756+    { "snow2",                  0xffeee9e9 },
757+    { "snow3",                  0xffcdc9c9 },
758+    { "snow4",                  0xff8b8989 },
759+    { "spring green",           0xff00ff7f },
760+    { "SpringGreen",            0xff00ff7f },
761+    { "SpringGreen1",           0xff00ff7f },
762+    { "SpringGreen2",           0xff00ee76 },
763+    { "SpringGreen3",           0xff00cd66 },
764+    { "SpringGreen4",           0xff008b45 },
765+    { "steel blue",             0xff4682b4 },
766+    { "SteelBlue",              0xff4682b4 },
767+    { "SteelBlue1",             0xff63b8ff },
768+    { "SteelBlue2",             0xff5cacee },
769+    { "SteelBlue3",             0xff4f94cd },
770+    { "SteelBlue4",             0xff36648b },
771+    { "tan",                    0xffd2b48c },
772+    { "tan1",                   0xffffa54f },
773+    { "tan2",                   0xffee9a49 },
774+    { "tan3",                   0xffcd853f },
775+    { "tan4",                   0xff8b5a2b },
776+    { "thistle",                0xffd8bfd8 },
777+    { "thistle1",               0xffffe1ff },
778+    { "thistle2",               0xffeed2ee },
779+    { "thistle3",               0xffcdb5cd },
780+    { "thistle4",               0xff8b7b8b },
781+    { "tomato",                 0xffff6347 },
782+    { "tomato1",                0xffff6347 },
783+    { "tomato2",                0xffee5c42 },
784+    { "tomato3",                0xffcd4f39 },
785+    { "tomato4",                0xff8b3626 },
786+    { "turquoise",              0xff40e0d0 },
787+    { "turquoise1",             0xff00f5ff },
788+    { "turquoise2",             0xff00e5ee },
789+    { "turquoise3",             0xff00c5cd },
790+    { "turquoise4",             0xff00868b },
791+    { "violet",                 0xffee82ee },
792+    { "violet red",             0xffd02090 },
793+    { "VioletRed",              0xffd02090 },
794+    { "VioletRed1",             0xffff3e96 },
795+    { "VioletRed2",             0xffee3a8c },
796+    { "VioletRed3",             0xffcd3278 },
797+    { "VioletRed4",             0xff8b2252 },
798+    { "wheat",                  0xfff5deb3 },
799+    { "wheat1",                 0xffffe7ba },
800+    { "wheat2",                 0xffeed8ae },
801+    { "wheat3",                 0xffcdba96 },
802+    { "wheat4",                 0xff8b7e66 },
803+    { "white",                  0xffffffff },
804+    { "white smoke",            0xfff5f5f5 },
805+    { "WhiteSmoke",             0xfff5f5f5 },
806+    { "yellow",                 0xffffff00 },
807+    { "yellow green",           0xff9acd32 },
808+    { "yellow1",                0xffffff00 },
809+    { "yellow2",                0xffeeee00 },
810+    { "yellow3",                0xffcdcd00 },
811+    { "yellow4",                0xff8b8b00 },
812+    { "YellowGreen",            0xff9acd32 }
813+};
814+
815+bool wld_lookup_named_color(const char * name, uint32_t * color)
816+{
817+    char * end;
818+    int low = 0, mid, high = ARRAY_LENGTH(named_colors);
819+    int r;
820+
821+    if (name[0] == '#' && name[1] != '\0')
822+    {
823+        *color = strtoul(name + 1, &end, 16);
824+
825+        /* Set alpha channel to opaque. */
826+        *color |= 0xff << 24;
827+
828+        if (*end == '\0')
829+            return true;
830+    }
831+
832+    while (low <= high)
833+    {
834+        mid = (low + high) / 2;
835+        r = strcasecmp(named_colors[mid].name, name);
836+
837+        if (r == 0)
838+        {
839+            *color = named_colors[mid].color;
840+            return true;
841+        }
842+        if (r < 0)
843+            low = mid + 1;
844+        else
845+            high = mid - 1;
846+    }
847+
848+    return false;
849+}
850+
+136, -0
  1@@ -0,0 +1,136 @@
  2+dnl wld: configure.ac
  3+
  4+AC_PREREQ([2.59])
  5+
  6+AC_INIT([wld], [0.0.1], [mforney@mforney.org])
  7+AM_INIT_AUTOMAKE([foreign nostdinc -Wall -Werror])
  8+AC_LANG([C])
  9+
 10+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 11+
 12+AC_PROG_CC_C99
 13+AC_USE_SYSTEM_EXTENSIONS
 14+
 15+AM_PROG_AR
 16+LT_INIT
 17+
 18+AC_CONFIG_SRCDIR([wld.h])
 19+AC_CONFIG_MACRO_DIR([m4])
 20+
 21+PKG_PROG_PKG_CONFIG([0.9.0])
 22+
 23+dnl Options {{{
 24+# Debugging
 25+AC_ARG_ENABLE([debug],
 26+              AS_HELP_STRING([--enable-debug],
 27+                             [Enable debugging messages]),
 28+              enable_debug=$enableval,
 29+              enable_debug=no)
 30+if test "x$enable_debug" = "xyes" ; then
 31+    AC_DEFINE([ENABLE_DEBUG], [1], [Enable debug messages])
 32+fi
 33+
 34+# Wayland
 35+AC_ARG_WITH([wayland],
 36+            AS_HELP_STRING([--without-wayland],
 37+                           [Disable Wayland support]),
 38+            with_wayland=$withval,
 39+            with_wayland=yes)
 40+if test "x$with_wayland" = "xyes" ; then
 41+    PKG_CHECK_MODULES([wayland_client], [wayland-client],,
 42+                      AC_MSG_ERROR([Wayland client libraries not found. Specify
 43+                                    --without-wayland to build without wayland
 44+                                    support]))
 45+    AC_DEFINE([WITH_WAYLAND], [1], [Build Wayland support])
 46+    PKGCONFIG_EXTRA_REQUIRES="wayland-client $PKGCONFIG_EXTRA_REQUIRES"
 47+
 48+fi
 49+AM_CONDITIONAL([WITH_WAYLAND], test "x$with_wayland" = "xyes")
 50+
 51+# Wayland DRM
 52+AC_ARG_ENABLE([drm],
 53+              AS_HELP_STRING([--disable-drm],
 54+                             [Disable Wayland DRM support]),
 55+              enable_drm=$enableval,
 56+              enable_drm=$with_wayland)
 57+if test "x$enable_drm" = "xyes" ; then
 58+    if test "x$with_wayland" != "xyes" ; then
 59+        AC_MSG_ERROR([--enable-drm requires --with-wayland])
 60+    fi
 61+    AC_DEFINE([ENABLE_WAYLAND_DRM], [1], [Enable Wayland DRM support])
 62+fi
 63+AM_CONDITIONAL([ENABLE_WAYLAND_DRM], test "x$enable_drm" = "xyes")
 64+
 65+# Wayland SHM
 66+AC_ARG_ENABLE([shm],
 67+              AS_HELP_STRING([--disable-shm],
 68+                             [Disable Wayland SHM support]),
 69+              enable_shm=$enableval,
 70+              enable_shm=$with_wayland)
 71+if test "x$enable_shm" = "xyes" ; then
 72+    if test "x$with_wayland" != "xyes" ; then
 73+        AC_MSG_ERROR([--enable-shm requires --with-wayland])
 74+    fi
 75+    AC_DEFINE([ENABLE_WAYLAND_SHM], [1], [Enable Wayland SHM support])
 76+fi
 77+AM_CONDITIONAL([ENABLE_WAYLAND_SHM], test "x$enable_shm" = "xyes")
 78+
 79+# Intel
 80+AC_ARG_ENABLE([intel],
 81+              AS_HELP_STRING([--disable-intel],
 82+                             [Disable Intel drawable support]),
 83+              enable_intel=$enableval,
 84+              enable_intel=auto)
 85+if test "x$enable_intel" = "xyes" -o "x$enable_intel" = "xauto" ; then
 86+    PKG_CHECK_MODULES([drm_intel], [libdrm_intel], have_drm_intel=yes,
 87+        if test "x$enable_intel" = "xyes" ; then
 88+            AC_MSG_ERROR([--enable-intel requires libdrm_intel])
 89+        fi
 90+    )
 91+    PKG_CHECK_MODULES([intelbatch], [intelbatch], have_intelbatch=yes,
 92+        if test "x$enable_intel" = "xyes" ; then
 93+            AC_MSG_ERROR([--enable-intel requires libintelbatch])
 94+        fi
 95+    )
 96+
 97+    if test "x$enable_intel" = "xauto" \
 98+         -a "x$have_drm_intel" = "xyes" -a "x$have_intelbatch" = "xyes"
 99+    then
100+        enable_intel=yes
101+    fi
102+
103+    if test "x$enable_intel" = "xyes" ; then
104+        AC_DEFINE([ENABLE_INTEL], [1], [Enable Intel DRM support])
105+        PKGCONFIG_REQUIRES_PRIVATE="libdrm_intel $PKGCONFIG_REQUIRES_PRIVATE"
106+        PKGCONFIG_REQUIRES_PRIVATE="intelbatch $PKGCONFIG_REQUIRES_PRIVATE"
107+    fi
108+fi
109+AM_CONDITIONAL([ENABLE_INTEL], test "x$enable_intel" = "xyes")
110+
111+# Pixman
112+AC_ARG_ENABLE([pixman],
113+              AS_HELP_STRING([--disable-pixman],
114+                             [Disable pixman drawable support]),
115+              enable_pixman=$enableval,
116+              enable_pixman=yes)
117+if test "x$enable_pixman" = "xyes" ; then
118+    AC_DEFINE([ENABLE_PIXMAN], [1], [Enable Pixman support])
119+fi
120+AM_CONDITIONAL([ENABLE_PIXMAN], test "x$enable_pixman" = "xyes")
121+dnl }}}
122+
123+dnl Check for libraries {{{
124+PKG_CHECK_MODULES([pixman], [pixman-1])
125+PKG_CHECK_MODULES([fontconfig], [fontconfig])
126+PKG_CHECK_MODULES([freetype], [freetype2])
127+dnl }}}
128+
129+dnl Wayland protocol
130+WAYLAND_SCANNER_RULES(['$(top_srcdir)/protocol'])
131+
132+dnl pkgconfig
133+AC_SUBST([PKGCONFIG_REQUIRES_PRIVATE])
134+
135+AC_CONFIG_FILES([Makefile protocol/Makefile wld.pc])
136+AC_OUTPUT
137+
+78, -0
 1@@ -0,0 +1,78 @@
 2+/* wld: drawable.c
 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+#include "wld-private.h"
26+
27+void default_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
28+                            pixman_rectangle16_t * rectangle)
29+{
30+    wld_fill_rectangles(drawable, color, rectangle, 1);
31+}
32+
33+void default_fill_rectangles(struct wld_drawable * drawable, uint32_t color,
34+                             pixman_rectangle16_t * rectangles,
35+                             uint32_t num_rectangles)
36+{
37+    while (num_rectangles--)
38+        wld_fill_rectangle(drawable, color, &rectangles[num_rectangles]);
39+}
40+
41+void default_flush(struct wld_drawable * drawable)
42+{
43+}
44+
45+void wld_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
46+                        pixman_rectangle16_t * rectangle)
47+{
48+    drawable->interface->fill_rectangle(drawable, color, rectangle);
49+}
50+
51+void wld_fill_rectangles(struct wld_drawable * drawable, uint32_t color,
52+                         pixman_rectangle16_t * rectangles,
53+                         uint32_t num_rectangles)
54+{
55+    drawable->interface->fill_rectangles(drawable, color, rectangles,
56+                                         num_rectangles);
57+}
58+
59+void wld_draw_text_utf8_n(struct wld_drawable * drawable,
60+                          struct wld_font * font_base, uint32_t color,
61+                          int32_t x, int32_t y,
62+                          const char * text, int32_t length)
63+{
64+    struct font * font = container_of(font_base, typeof(*font), base);
65+
66+    drawable->interface->draw_text_utf8(drawable, font, color, x, y,
67+                                        text, length);
68+}
69+
70+void wld_destroy_drawable(struct wld_drawable * drawable)
71+{
72+    drawable->interface->destroy(drawable);
73+}
74+
75+void wld_flush(struct wld_drawable * drawable)
76+{
77+    drawable->interface->flush(drawable);
78+}
79+
+50, -0
 1@@ -0,0 +1,50 @@
 2+/* wld: drm-private.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 WLD_DRM_PRIVATE_H
26+#define WLD_DRM_PRIVATE_H 1
27+
28+typedef bool (* drm_device_supported_func_t)(uint32_t vendor_id,
29+                                             uint32_t device_id);
30+typedef void * (* drm_create_context_func_t)(int drm_fd);
31+typedef void (* drm_destroy_context_func_t)(void * context);
32+typedef struct wld_drawable * (* drm_create_drawable_func_t)
33+    (void * context, uint32_t width, uint32_t height, uint32_t format);
34+typedef void (* drm_get_drawable_info_func_t)
35+    (struct wld_drawable * drawable, uint32_t * name, uint32_t * pitch);
36+
37+struct wld_drm_interface
38+{
39+    drm_device_supported_func_t device_supported;
40+    drm_create_context_func_t create_context;
41+    drm_destroy_context_func_t destroy_context;
42+    drm_create_drawable_func_t create_drawable;
43+    drm_get_drawable_info_func_t get_drawable_info;
44+};
45+
46+#if ENABLE_INTEL
47+extern const struct wld_drm_interface intel_drm;
48+#endif
49+
50+#endif
51+
A font.c
+222, -0
  1@@ -0,0 +1,222 @@
  2+/* wld: font.c
  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+#include "wld-private.h"
 26+
 27+#include <fontconfig/fcfreetype.h>
 28+
 29+struct wld_font_context * wld_font_create_context()
 30+{
 31+    struct wld_font_context * context;
 32+
 33+    context = malloc(sizeof *context);
 34+
 35+    if (!context)
 36+        goto error0;
 37+
 38+    if (FT_Init_FreeType(&context->library) != 0)
 39+    {
 40+        printf("failed to initialize ft library\n");
 41+
 42+        goto error1;
 43+    }
 44+
 45+    return context;
 46+
 47+  error1:
 48+    free(context);
 49+  error0:
 50+    return NULL;
 51+}
 52+
 53+struct wld_font * wld_font_open_name(struct wld_font_context * context,
 54+                                     const char * name)
 55+{
 56+    FcPattern * pattern, * match;
 57+    FcResult result;
 58+
 59+    printf("name: %s\n", name);
 60+
 61+    pattern = FcNameParse((const FcChar8 *) name);
 62+    FcConfigSubstitute(NULL, pattern, FcMatchPattern);
 63+    FcDefaultSubstitute(pattern);
 64+
 65+    match = FcFontMatch(NULL, pattern, &result);
 66+
 67+    if (!match)
 68+        return NULL;
 69+
 70+    return wld_font_open_pattern(context, match);
 71+}
 72+
 73+struct wld_font * wld_font_open_pattern(struct wld_font_context * context,
 74+                                        FcPattern * match)
 75+{
 76+    char * filename;
 77+    struct font * font;
 78+    FcResult result;
 79+    double pixel_size, aspect;
 80+
 81+    font = malloc(sizeof *font);
 82+
 83+    if (!font)
 84+        goto error0;
 85+
 86+    font->context = context;
 87+
 88+    result = FcPatternGetString(match, FC_FILE, 0, (FcChar8 **) &filename);
 89+
 90+    if (result == FcResultMatch)
 91+    {
 92+        FT_Error error;
 93+
 94+        DEBUG("Loading font file: %s\n", filename);
 95+
 96+        error = FT_New_Face(context->library, filename, 0, &font->face);
 97+
 98+        if (error == 0)
 99+            goto load_face;
100+    }
101+
102+    result = FcPatternGetFTFace(match, FC_FT_FACE, 0, &font->face);
103+
104+    if (result != FcResultMatch)
105+    {
106+        DEBUG("Couldn't determine font filename or FreeType face\n");
107+        goto error1;
108+    }
109+
110+  load_face:
111+    result = FcPatternGetDouble(match, FC_PIXEL_SIZE, 0, &pixel_size);
112+
113+    result = FcPatternGetDouble(match, FC_ASPECT, 0, &aspect);
114+
115+    if (result == FcResultNoMatch)
116+        aspect = 1.0;
117+
118+    if (font->face->face_flags & FT_FACE_FLAG_SCALABLE)
119+    {
120+        FT_F26Dot6 width, height;
121+
122+        width = ((unsigned int) pixel_size) << 6;
123+        height = ((unsigned int) (pixel_size * aspect)) << 6;
124+
125+        FT_Set_Char_Size(font->face, width, height, 0, 0);
126+    }
127+    else
128+    {
129+        FT_Set_Pixel_Sizes(font->face, (unsigned int) pixel_size,
130+                           (unsigned int) (pixel_size * aspect));
131+    }
132+
133+    font->base.ascent = font->face->size->metrics.ascender >> 6;
134+    font->base.descent = -font->face->size->metrics.descender >> 6;
135+    font->base.height = font->base.ascent + font->base.descent;
136+    font->base.max_advance = font->face->size->metrics.max_advance >> 6;
137+
138+    font->glyphs = calloc(font->face->num_glyphs, sizeof(struct glyph *));
139+
140+    return &font->base;
141+
142+  error1:
143+    free(font);
144+  error0:
145+    return NULL;
146+}
147+
148+void wld_font_close(struct wld_font * font_base)
149+{
150+    struct font * font = container_of(font_base, typeof(*font), base);
151+
152+    FT_Done_Face(font->face);
153+    free(font);
154+}
155+
156+bool font_ensure_glyph(struct font * font, FT_UInt glyph_index)
157+{
158+    if (glyph_index)
159+    {
160+        if (!font->glyphs[glyph_index])
161+        {
162+            struct glyph * glyph;
163+
164+            glyph = malloc(sizeof *glyph);
165+
166+            if (!glyph)
167+                return false;
168+
169+            FT_Load_Glyph(font->face, glyph_index, FT_LOAD_RENDER
170+                          | FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO);
171+
172+            FT_Bitmap_New(&glyph->bitmap);
173+
174+            FT_Bitmap_Copy(font->context->library,
175+                           &font->face->glyph->bitmap, &glyph->bitmap);
176+
177+            glyph->advance = font->face->glyph->metrics.horiAdvance >> 6;
178+            glyph->x = font->face->glyph->bitmap_left;
179+            glyph->y = -font->face->glyph->bitmap_top;
180+
181+            font->glyphs[glyph_index] = glyph;
182+        }
183+
184+        return true;
185+    }
186+
187+    return false;
188+}
189+
190+bool wld_font_ensure_char(struct wld_font * font_base, uint32_t character)
191+{
192+    struct font * font = container_of(font_base, typeof(*font), base);
193+    FT_UInt glyph_index;
194+
195+    glyph_index = FT_Get_Char_Index(font->face, character);
196+
197+    return font_ensure_glyph(font, glyph_index);
198+}
199+
200+void wld_font_text_extents_utf8_n(struct wld_font * font_base,
201+                                  const char * text, int32_t length,
202+                                  struct wld_extents * extents)
203+{
204+    struct font * font = container_of(font_base, typeof(*font), base);
205+    int ret;
206+    uint32_t c;
207+    FT_UInt glyph_index;
208+
209+    extents->advance = 0;
210+
211+    while ((ret = FcUtf8ToUcs4((FcChar8 *) text, &c, length) > 0))
212+    {
213+        length -= ret;
214+        text += ret;
215+        glyph_index = FT_Get_Char_Index(font->face, c);
216+
217+        if (!font_ensure_glyph(font, glyph_index))
218+            continue;
219+
220+        extents->advance += font->glyphs[glyph_index]->advance;
221+    }
222+}
223+
+226, -0
  1@@ -0,0 +1,226 @@
  2+/* wld: intel.c
  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+#include "intel.h"
 26+#include "drm-private.h"
 27+#include "wld-private.h"
 28+
 29+#include <intelbatch/batch.h>
 30+#include <intelbatch/blt.h>
 31+#include <intelbatch/mi.h>
 32+#include <intel_bufmgr.h>
 33+#include <i915_drm.h>
 34+
 35+struct wld_intel_context
 36+{
 37+    drm_intel_bufmgr * bufmgr;
 38+    struct intel_batch batch;
 39+};
 40+
 41+struct intel_drawable
 42+{
 43+    struct wld_drawable base;
 44+
 45+    struct wld_intel_context * context;
 46+    uint32_t name;
 47+    unsigned long pitch;
 48+
 49+    drm_intel_bo * bo;
 50+};
 51+
 52+static void intel_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
 53+                          pixman_rectangle16_t * rectangle);
 54+static void intel_draw_text_utf8(struct wld_drawable * drawable,
 55+                                 struct font * font, uint32_t color,
 56+                                 int32_t x, int32_t y,
 57+                                 const char * text, int32_t length);
 58+static void intel_flush(struct wld_drawable * drawable);
 59+static void intel_destroy(struct wld_drawable * drawable);
 60+
 61+const static struct wld_draw_interface intel_draw = {
 62+    .fill_rectangle = &intel_fill_rectangle,
 63+    .fill_rectangles = &default_fill_rectangles,
 64+    .draw_text_utf8 = &intel_draw_text_utf8,
 65+    .flush = &intel_flush,
 66+    .destroy = &intel_destroy
 67+};
 68+
 69+const struct wld_drm_interface intel_drm = {
 70+    .device_supported = &wld_intel_device_supported,
 71+    .create_context = (drm_create_context_func_t) &wld_intel_create_context,
 72+    .destroy_context = (drm_destroy_context_func_t) &wld_intel_destroy_context,
 73+    .create_drawable = (drm_create_drawable_func_t) &wld_intel_create_drawable,
 74+    .get_drawable_info = &wld_intel_get_drawable_info
 75+};
 76+
 77+bool wld_intel_device_supported(uint32_t vendor_id, uint32_t device_id)
 78+{
 79+    return vendor_id == 0x8086;
 80+}
 81+
 82+struct wld_intel_context * wld_intel_create_context(int drm_fd)
 83+{
 84+    struct wld_intel_context * context;
 85+
 86+    context = malloc(sizeof *context);
 87+
 88+    if (!context)
 89+        return NULL;
 90+
 91+    context->bufmgr = drm_intel_bufmgr_gem_init(drm_fd, INTEL_BATCH_SIZE);
 92+    intel_batch_initialize(&context->batch, context->bufmgr);
 93+
 94+    return context;
 95+}
 96+
 97+void wld_intel_destroy_context(struct wld_intel_context * context)
 98+{
 99+    drm_intel_bufmgr_destroy(context->bufmgr);
100+    free(context);
101+}
102+
103+struct wld_drawable * wld_intel_create_drawable
104+    (struct wld_intel_context * context, uint32_t width, uint32_t height,
105+     uint32_t format)
106+{
107+    struct intel_drawable * intel;
108+    uint32_t tiling_mode = I915_TILING_X, pitch;
109+
110+    intel = malloc(sizeof *intel);
111+
112+    if (!intel)
113+        return NULL;
114+
115+    intel->base.interface = &intel_draw;
116+    intel->base.width = width;
117+    intel->base.height = height;
118+
119+    intel->context = context;
120+    intel->bo = drm_intel_bo_alloc_tiled(context->bufmgr, "drawable",
121+                                         width, height, 4,
122+                                         &tiling_mode, &intel->pitch, 0);
123+
124+    drm_intel_bo_flink(intel->bo, &intel->name);
125+
126+    return &intel->base;
127+}
128+
129+void wld_intel_get_drawable_info(struct wld_drawable * drawable,
130+                                 uint32_t * name, uint32_t * pitch)
131+{
132+    struct intel_drawable * intel;
133+
134+    intel = container_of(drawable, typeof(*intel), base);
135+    *name = intel->name;
136+    *pitch = intel->pitch;
137+}
138+
139+void intel_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
140+                          pixman_rectangle16_t * rectangle)
141+{
142+    struct intel_drawable * intel;
143+
144+    intel = container_of(drawable, typeof(*intel), base);
145+    xy_color_blt(&intel->context->batch, intel->bo, intel->pitch,
146+                 rectangle->x, rectangle->y,
147+                 rectangle->x + rectangle->width,
148+                 rectangle->y + rectangle->height, color);
149+}
150+
151+void intel_draw_text_utf8(struct wld_drawable * drawable,
152+                          struct font * font, uint32_t color,
153+                          int32_t x, int32_t y,
154+                          const char * text, int32_t length)
155+{
156+    struct intel_drawable * intel;
157+    int ret;
158+    struct glyph * glyph;
159+    uint32_t row;
160+    FT_UInt glyph_index;
161+    uint32_t c;
162+    uint8_t immediate[512];
163+    uint8_t * byte;
164+    uint8_t byte_index;
165+
166+    intel = container_of(drawable, typeof(*intel), base);
167+
168+    /* For some reason the text doesn't render if we don't flush the command
169+     * buffer first. */
170+    intel_batch_flush(&intel->context->batch);
171+
172+    xy_setup_blt(&intel->context->batch, true, INTEL_BLT_RASTER_OPERATION_SRC,
173+                 0, color, intel->bo, intel->pitch);
174+
175+    while ((ret = FcUtf8ToUcs4((FcChar8 *) text, &c, length)) > 0 && c != '\0')
176+    {
177+        text += ret;
178+        length -= ret;
179+        glyph_index = FT_Get_Char_Index(font->face, c);
180+
181+        if (!font_ensure_glyph(font, glyph_index))
182+            continue;
183+
184+        glyph = font->glyphs[glyph_index];
185+
186+        if (glyph->bitmap.width == 0 || glyph->bitmap.rows == 0)
187+            goto advance;
188+
189+        byte = immediate;
190+
191+        /* XY_TEXT_IMMEDIATE requires a pitch with no extra bytes */
192+        for (row = 0; row < glyph->bitmap.rows; ++row)
193+        {
194+            memcpy(byte, glyph->bitmap.buffer + (row * glyph->bitmap.pitch),
195+                   (glyph->bitmap.width + 7) / 8);
196+            byte += (glyph->bitmap.width + 7) / 8;
197+        }
198+
199+        xy_text_immediate_blt(&intel->context->batch, intel->bo,
200+                              x + glyph->x, y + glyph->y,
201+                              x + glyph->x + glyph->bitmap.width,
202+                              y + glyph->y + glyph->bitmap.rows,
203+                              (byte - immediate + 3) / 4,
204+                              (uint32_t *) immediate);
205+
206+      advance:
207+        x += glyph->advance;
208+    }
209+}
210+
211+void intel_flush(struct wld_drawable * drawable)
212+{
213+    struct intel_drawable * intel;
214+
215+    intel = container_of(drawable, typeof(*intel), base);
216+    intel_batch_flush(&intel->context->batch);
217+}
218+
219+void intel_destroy(struct wld_drawable * drawable)
220+{
221+    struct intel_drawable * intel;
222+
223+    intel = container_of(drawable, typeof(*intel), base);
224+    drm_intel_bo_unreference(intel->bo);
225+    free(intel);
226+}
227+
+65, -0
 1@@ -0,0 +1,65 @@
 2+/* wld: intel.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 WLD_INTEL_H
26+#define WLD_INTEL_H 1
27+
28+#include <stdbool.h>
29+#include <stdint.h>
30+
31+struct wld_intel_context;
32+struct wld_drawable;
33+enum wld_format;
34+
35+/**
36+ * Create a new drawing context which uses Intel Graphics hardware accelerated
37+ * operations.
38+ */
39+struct wld_intel_context * wld_intel_create_context(int drm_fd);
40+
41+/**
42+ * Destroy an Intel context
43+ */
44+void wld_intel_destroy_context(struct wld_intel_context * context);
45+
46+/**
47+ * Check if the device with the given vendor and device ID is supported by the
48+ * Intel drawing backend.
49+ */
50+bool wld_intel_device_supported(uint32_t vendor_id, uint32_t device_id);
51+
52+/**
53+ * Create a new Intel drawable with the specified dimensions.
54+ */
55+struct wld_drawable * wld_intel_create_drawable
56+    (struct wld_intel_context * context, uint32_t width, uint32_t height,
57+     enum wld_format format);
58+
59+/**
60+ * Get the name and pitch of the underlying BO for this Intel drawable.
61+ */
62+void wld_intel_get_drawable_info(struct wld_drawable * drawable,
63+                                 uint32_t * name, uint32_t * pitch);
64+
65+#endif
66+
+248, -0
  1@@ -0,0 +1,248 @@
  2+/* wld: pixman.c
  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+#include "pixman.h"
 26+#include "wld-private.h"
 27+
 28+#define PIXMAN_COLOR(c) {                   \
 29+    .alpha  = ((c >> 24) & 0xff) * 0x101,   \
 30+    .red    = ((c >> 16) & 0xff) * 0x101,   \
 31+    .green  = ((c >>  8) & 0xff) * 0x101,   \
 32+    .blue   = ((c >>  0) & 0xff) * 0x101,   \
 33+}
 34+
 35+struct wld_pixman_context
 36+{
 37+    pixman_glyph_cache_t * glyph_cache;
 38+};
 39+
 40+struct pixman_drawable
 41+{
 42+    struct wld_drawable base;
 43+    pixman_image_t * image;
 44+    struct wld_pixman_context * context;
 45+};
 46+
 47+static void pixman_fill_rectangles(struct wld_drawable * drawable,
 48+                                   uint32_t color,
 49+                                   pixman_rectangle16_t * rectangles,
 50+                                   uint32_t num_rectangles);
 51+static void pixman_draw_text_utf8(struct wld_drawable * drawable,
 52+                                  struct font * font, uint32_t color,
 53+                                  int32_t x, int32_t y,
 54+                                  const char * text, int32_t length);
 55+static void pixman_destroy(struct wld_drawable * drawable);
 56+
 57+const static struct wld_draw_interface pixman_draw = {
 58+    .fill_rectangle = &default_fill_rectangle,
 59+    .fill_rectangles = &pixman_fill_rectangles,
 60+    .draw_text_utf8 = &pixman_draw_text_utf8,
 61+    .flush = &default_flush,
 62+    .destroy = &pixman_destroy
 63+};
 64+
 65+static inline pixman_format_code_t pixman_format(uint32_t format)
 66+{
 67+    switch (format)
 68+    {
 69+        case WLD_FORMAT_ARGB8888:
 70+            return PIXMAN_a8r8g8b8;
 71+        case WLD_FORMAT_XRGB8888:
 72+            return PIXMAN_x8r8g8b8;
 73+        default:
 74+            return 0;
 75+    }
 76+}
 77+
 78+struct wld_pixman_context * wld_pixman_create_context()
 79+{
 80+    struct wld_pixman_context * context;
 81+
 82+    context = malloc(sizeof *context);
 83+
 84+    if (!context)
 85+        return NULL;
 86+
 87+    context->glyph_cache = pixman_glyph_cache_create();
 88+
 89+    return context;
 90+}
 91+
 92+void wld_pixman_destroy_context(struct wld_pixman_context * context)
 93+{
 94+    pixman_glyph_cache_destroy(context->glyph_cache);
 95+    free(context);
 96+}
 97+
 98+struct wld_drawable * wld_pixman_create_drawable
 99+    (struct wld_pixman_context * context, uint32_t width, uint32_t height,
100+     void * data, uint32_t pitch, enum wld_format format)
101+{
102+    struct pixman_drawable * pixman;
103+
104+    pixman = malloc(sizeof *pixman);
105+
106+    if (!pixman)
107+        goto error0;
108+
109+    pixman->base.interface = &pixman_draw;
110+    pixman->base.width = width;
111+    pixman->base.height = height;
112+
113+    pixman->context = context;
114+    pixman->image = pixman_image_create_bits(pixman_format(format),
115+                                             width, height,
116+                                             (uint32_t *) data, pitch);
117+
118+    if (!pixman->image)
119+        goto error1;
120+
121+    return &pixman->base;
122+
123+  error1:
124+    free(pixman);
125+  error0:
126+    return NULL;
127+}
128+
129+static void pixman_fill_rectangles(struct wld_drawable * drawable,
130+                                   uint32_t color,
131+                                   pixman_rectangle16_t * rectangles,
132+                                   uint32_t num_rectangles)
133+{
134+    struct pixman_drawable * pixman;
135+    pixman_color_t pixman_color = PIXMAN_COLOR(color);
136+
137+    pixman = container_of(drawable, typeof(*pixman), base);
138+    pixman_image_fill_rectangles(PIXMAN_OP_SRC, pixman->image, &pixman_color,
139+                                 num_rectangles, rectangles);
140+}
141+
142+static inline uint8_t reverse(uint8_t byte)
143+{
144+    byte = ((byte << 1) & 0xaa) | ((byte >> 1) & 0x55);
145+    byte = ((byte << 2) & 0xcc) | ((byte >> 2) & 0x33);
146+    byte = ((byte << 4) & 0xf0) | ((byte >> 4) & 0x0f);
147+
148+    return byte;
149+}
150+
151+static void pixman_draw_text_utf8(struct wld_drawable * drawable,
152+                                  struct font * font, uint32_t color,
153+                                  int32_t x, int32_t y,
154+                                  const char * text, int32_t length)
155+{
156+    struct pixman_drawable * pixman;
157+    int ret;
158+    uint32_t c;
159+    struct glyph * glyph;
160+    FT_UInt glyph_index;
161+    pixman_glyph_t glyphs[strlen(text)];
162+    uint32_t index = 0, glyph_x = 0;
163+    pixman_color_t pixman_color = PIXMAN_COLOR(color);
164+    pixman_image_t * solid;
165+
166+    pixman = container_of(drawable, typeof(*pixman), base);
167+    solid = pixman_image_create_solid_fill(&pixman_color);
168+
169+    while ((ret = FcUtf8ToUcs4((FcChar8 *) text, &c, length)) > 0 && c != '\0')
170+    {
171+        text += ret;
172+        length -= ret;
173+        glyph_index = FT_Get_Char_Index(font->face, c);
174+
175+        if (!font_ensure_glyph(font, glyph_index))
176+            continue;
177+
178+        glyph = font->glyphs[glyph_index];
179+
180+        glyphs[index].x = glyph_x;
181+        glyphs[index].y = 0;
182+        glyphs[index].glyph = pixman_glyph_cache_lookup
183+            (pixman->context->glyph_cache, font, glyph);
184+
185+        /* If we don't have the glyph in our cache, do some conversions to make
186+         * pixman happy, and then insert it. */
187+        if (!glyphs[index].glyph)
188+        {
189+            uint8_t * src, * dst;
190+            uint32_t row, byte_index, bytes_per_row, pitch;
191+            pixman_image_t * image;
192+            FT_Bitmap * bitmap;
193+
194+            bitmap = &glyph->bitmap;
195+            image = pixman_image_create_bits
196+                (PIXMAN_a1, bitmap->width, bitmap->rows, NULL, bitmap->pitch);
197+
198+            if (!image)
199+                goto advance;
200+
201+            pitch = pixman_image_get_stride(image);
202+            bytes_per_row = (bitmap->width + 7) / 8;
203+            src = bitmap->buffer;
204+            dst = (uint8_t *) pixman_image_get_data(image);
205+
206+            for (row = 0; row < bitmap->rows; ++row)
207+            {
208+                /* Pixman's A1 format expects the bits in the opposite order
209+                 * that Freetype gives us. Sigh... */
210+                for (byte_index = 0; byte_index < bytes_per_row; ++byte_index)
211+                    dst[byte_index] = reverse(src[byte_index]);
212+
213+                dst += pitch;
214+                src += bitmap->pitch;
215+            }
216+
217+            /* Insert the glyph into the cache. */
218+            pixman_glyph_cache_freeze(pixman->context->glyph_cache);
219+            glyphs[index].glyph = pixman_glyph_cache_insert
220+                (pixman->context->glyph_cache, font, glyph,
221+                 -glyph->x, -glyph->y, image);
222+            pixman_glyph_cache_thaw(pixman->context->glyph_cache);
223+
224+            /* The glyph cache copies the contents of the glyph bitmap. */
225+            pixman_image_unref(image);
226+        }
227+
228+        ++index;
229+
230+      advance:
231+        glyph_x += glyph->advance;
232+    }
233+
234+    pixman_composite_glyphs_no_mask(PIXMAN_OP_OVER, solid, pixman->image, 0, 0,
235+                                    x, y, pixman->context->glyph_cache,
236+                                    index, glyphs);
237+
238+    pixman_image_unref(solid);
239+}
240+
241+void pixman_destroy(struct wld_drawable * drawable)
242+{
243+    struct pixman_drawable * pixman;
244+
245+    pixman = container_of(drawable, typeof(*pixman), base);
246+    pixman_image_unref(pixman->image);
247+    free(pixman);
248+}
249+
+54, -0
 1@@ -0,0 +1,54 @@
 2+/* wld: pixman.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 WLD_PIXMAN_H
26+#define WLD_PIXMAN_H 1
27+
28+#include <stdint.h>
29+
30+struct wld_pixman_context;
31+struct wld_drawable;
32+enum wld_format;
33+
34+/**
35+ * Create a new drawing context which uses Pixman to do software rendering on
36+ * buffers in memory.
37+ */
38+struct wld_pixman_context * wld_pixman_create_context();
39+
40+/**
41+ * Destroy a Pixman context.
42+ */
43+void wld_pixman_destroy_context(struct wld_pixman_context * context);
44+
45+/**
46+ * Create a new Pixman drawable with the specified dimensions.
47+ *
48+ * If data is NULL, new backing memory will be allocated.
49+ */
50+struct wld_drawable * wld_pixman_create_drawable
51+    (struct wld_pixman_context * context, uint32_t width, uint32_t height,
52+     void * data, uint32_t pitch, enum wld_format format);
53+
54+#endif
55+
+7, -0
1@@ -0,0 +1,7 @@
2+# wld: protocol/Makefile.am
3+
4+BUILT_SOURCES = wayland-drm-protocol.c wayland-drm-client-protocol.h
5+CLEANFILES = $(BUILT_SOURCES)
6+
7+@wayland_scanner_rules@
8+
+182, -0
  1@@ -0,0 +1,182 @@
  2+<?xml version="1.0" encoding="UTF-8"?>
  3+<protocol name="drm">
  4+
  5+  <copyright>
  6+    Copyright © 2008-2011 Kristian Høgsberg
  7+    Copyright © 2010-2011 Intel Corporation
  8+
  9+    Permission to use, copy, modify, distribute, and sell this
 10+    software and its documentation for any purpose is hereby granted
 11+    without fee, provided that\n the above copyright notice appear in
 12+    all copies and that both that copyright notice and this permission
 13+    notice appear in supporting documentation, and that the name of
 14+    the copyright holders not be used in advertising or publicity
 15+    pertaining to distribution of the software without specific,
 16+    written prior permission.  The copyright holders make no
 17+    representations about the suitability of this software for any
 18+    purpose.  It is provided "as is" without express or implied
 19+    warranty.
 20+
 21+    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 22+    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 23+    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24+    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 25+    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 26+    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 27+    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 28+    THIS SOFTWARE.
 29+  </copyright>
 30+
 31+  <!-- drm support. This object is created by the server and published
 32+       using the display's global event. -->
 33+  <interface name="wl_drm" version="2">
 34+    <enum name="error">
 35+      <entry name="authenticate_fail" value="0"/>
 36+      <entry name="invalid_format" value="1"/>
 37+      <entry name="invalid_name" value="2"/>
 38+    </enum>
 39+
 40+    <enum name="format">
 41+      <!-- The drm format codes match the #defines in drm_fourcc.h.
 42+           The formats actually supported by the compositor will be
 43+           reported by the format event. -->
 44+      <entry name="c8" value="0x20203843"/>
 45+      <entry name="rgb332" value="0x38424752"/>
 46+      <entry name="bgr233" value="0x38524742"/>
 47+      <entry name="xrgb4444" value="0x32315258"/>
 48+      <entry name="xbgr4444" value="0x32314258"/>
 49+      <entry name="rgbx4444" value="0x32315852"/>
 50+      <entry name="bgrx4444" value="0x32315842"/>
 51+      <entry name="argb4444" value="0x32315241"/>
 52+      <entry name="abgr4444" value="0x32314241"/>
 53+      <entry name="rgba4444" value="0x32314152"/>
 54+      <entry name="bgra4444" value="0x32314142"/>
 55+      <entry name="xrgb1555" value="0x35315258"/>
 56+      <entry name="xbgr1555" value="0x35314258"/>
 57+      <entry name="rgbx5551" value="0x35315852"/>
 58+      <entry name="bgrx5551" value="0x35315842"/>
 59+      <entry name="argb1555" value="0x35315241"/>
 60+      <entry name="abgr1555" value="0x35314241"/>
 61+      <entry name="rgba5551" value="0x35314152"/>
 62+      <entry name="bgra5551" value="0x35314142"/>
 63+      <entry name="rgb565" value="0x36314752"/>
 64+      <entry name="bgr565" value="0x36314742"/>
 65+      <entry name="rgb888" value="0x34324752"/>
 66+      <entry name="bgr888" value="0x34324742"/>
 67+      <entry name="xrgb8888" value="0x34325258"/>
 68+      <entry name="xbgr8888" value="0x34324258"/>
 69+      <entry name="rgbx8888" value="0x34325852"/>
 70+      <entry name="bgrx8888" value="0x34325842"/>
 71+      <entry name="argb8888" value="0x34325241"/>
 72+      <entry name="abgr8888" value="0x34324241"/>
 73+      <entry name="rgba8888" value="0x34324152"/>
 74+      <entry name="bgra8888" value="0x34324142"/>
 75+      <entry name="xrgb2101010" value="0x30335258"/>
 76+      <entry name="xbgr2101010" value="0x30334258"/>
 77+      <entry name="rgbx1010102" value="0x30335852"/>
 78+      <entry name="bgrx1010102" value="0x30335842"/>
 79+      <entry name="argb2101010" value="0x30335241"/>
 80+      <entry name="abgr2101010" value="0x30334241"/>
 81+      <entry name="rgba1010102" value="0x30334152"/>
 82+      <entry name="bgra1010102" value="0x30334142"/>
 83+      <entry name="yuyv" value="0x56595559"/>
 84+      <entry name="yvyu" value="0x55595659"/>
 85+      <entry name="uyvy" value="0x59565955"/>
 86+      <entry name="vyuy" value="0x59555956"/>
 87+      <entry name="ayuv" value="0x56555941"/>
 88+      <entry name="nv12" value="0x3231564e"/>
 89+      <entry name="nv21" value="0x3132564e"/>
 90+      <entry name="nv16" value="0x3631564e"/>
 91+      <entry name="nv61" value="0x3136564e"/>
 92+      <entry name="yuv410" value="0x39565559"/>
 93+      <entry name="yvu410" value="0x39555659"/>
 94+      <entry name="yuv411" value="0x31315559"/>
 95+      <entry name="yvu411" value="0x31315659"/>
 96+      <entry name="yuv420" value="0x32315559"/>
 97+      <entry name="yvu420" value="0x32315659"/>
 98+      <entry name="yuv422" value="0x36315559"/>
 99+      <entry name="yvu422" value="0x36315659"/>
100+      <entry name="yuv444" value="0x34325559"/>
101+      <entry name="yvu444" value="0x34325659"/>
102+    </enum>
103+
104+    <!-- Call this request with the magic received from drmGetMagic().
105+         It will be passed on to the drmAuthMagic() or
106+         DRIAuthConnection() call.  This authentication must be
107+         completed before create_buffer could be used. -->
108+    <request name="authenticate">
109+      <arg name="id" type="uint"/>
110+    </request>
111+
112+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
113+         surface must have a name using the flink ioctl -->
114+    <request name="create_buffer">
115+      <arg name="id" type="new_id" interface="wl_buffer"/>
116+      <arg name="name" type="uint"/>
117+      <arg name="width" type="int"/>
118+      <arg name="height" type="int"/>
119+      <arg name="stride" type="uint"/>
120+      <arg name="format" type="uint"/>
121+    </request>
122+
123+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
124+         surface must have a name using the flink ioctl -->
125+    <request name="create_planar_buffer">
126+      <arg name="id" type="new_id" interface="wl_buffer"/>
127+      <arg name="name" type="uint"/>
128+      <arg name="width" type="int"/>
129+      <arg name="height" type="int"/>
130+      <arg name="format" type="uint"/>
131+      <arg name="offset0" type="int"/>
132+      <arg name="stride0" type="int"/>
133+      <arg name="offset1" type="int"/>
134+      <arg name="stride1" type="int"/>
135+      <arg name="offset2" type="int"/>
136+      <arg name="stride2" type="int"/>
137+    </request>
138+
139+    <!-- Create a wayland buffer for the prime fd.  Use for regular and planar
140+         buffers.  Pass 0 for offset and stride for unused planes. -->
141+    <request name="create_prime_buffer" since="2">
142+      <arg name="id" type="new_id" interface="wl_buffer"/>
143+      <arg name="name" type="fd"/>
144+      <arg name="width" type="int"/>
145+      <arg name="height" type="int"/>
146+      <arg name="format" type="uint"/>
147+      <arg name="offset0" type="int"/>
148+      <arg name="stride0" type="int"/>
149+      <arg name="offset1" type="int"/>
150+      <arg name="stride1" type="int"/>
151+      <arg name="offset2" type="int"/>
152+      <arg name="stride2" type="int"/>
153+    </request>
154+
155+    <!-- Notification of the path of the drm device which is used by
156+         the server.  The client should use this device for creating
157+         local buffers.  Only buffers created from this device should
158+         be be passed to the server using this drm object's
159+         create_buffer request. -->
160+    <event name="device">
161+      <arg name="name" type="string"/>
162+    </event>
163+
164+    <event name="format">
165+      <arg name="format" type="uint"/>
166+    </event>
167+
168+    <!-- Raised if the authenticate request succeeded -->
169+    <event name="authenticated"/>
170+
171+    <enum name="capability" since="2">
172+      <description summary="wl_drm capability bitmask">
173+        Bitmask of capabilities.
174+      </description>
175+      <entry name="prime" value="1" summary="wl_drm prime available"/>
176+    </enum>
177+
178+    <event name="capabilities">
179+      <arg name="value" type="uint"/>
180+    </event>
181+  </interface>
182+
183+</protocol>
+312, -0
  1@@ -0,0 +1,312 @@
  2+/* wld: wayland-drm.c
  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+#include "wayland-drm.h"
 26+#include "wayland-drm-client-protocol.h"
 27+#include "wayland.h"
 28+#include "wayland-private.h"
 29+#include "wld-private.h"
 30+#include "drm-private.h"
 31+
 32+#include <stdlib.h>
 33+#include <string.h>
 34+#include <unistd.h>
 35+#include <fcntl.h>
 36+#include <xf86drm.h>
 37+
 38+#include <stdio.h>
 39+
 40+struct wld_drm_context
 41+{
 42+    struct wl_drm * wl;
 43+    struct wl_registry * registry;
 44+    struct wl_event_queue * queue;
 45+    struct wl_array formats;
 46+    int fd;
 47+    bool authenticated;
 48+
 49+    const struct wld_drm_interface * interface;
 50+    void * context;
 51+};
 52+
 53+static void registry_global(void * data, struct wl_registry * registry,
 54+                            uint32_t name, const char * interface,
 55+                            uint32_t version);
 56+
 57+static void drm_device(void * data, struct wl_drm * wl, const char * name);
 58+static void drm_format(void * data, struct wl_drm * wl, uint32_t format);
 59+static void drm_authenticated(void * data, struct wl_drm * wl);
 60+
 61+const struct wld_wayland_interface wayland_drm_interface = {
 62+    .create_context = (wayland_create_context_func_t) &wld_drm_create_context,
 63+    .destroy_context
 64+        = (wayland_destroy_context_func_t) &wld_drm_destroy_context,
 65+    .create_drawable = (wayland_create_drawable_func_t) &wld_drm_create_drawable
 66+};
 67+
 68+const static struct wl_registry_listener registry_listener = {
 69+    .global = &registry_global
 70+};
 71+
 72+const static struct wl_drm_listener drm_listener = {
 73+    .device = &drm_device,
 74+    .format = &drm_format,
 75+    .authenticated = &drm_authenticated
 76+};
 77+
 78+const static struct wld_drm_interface * drm_interfaces[] = {
 79+#if ENABLE_INTEL
 80+    &intel_drm
 81+#endif
 82+};
 83+
 84+static const struct wld_drm_interface * find_drm_interface(int fd)
 85+{
 86+    char path[64], id[32];
 87+    uint32_t vendor_id, device_id;
 88+    char * path_part;
 89+    struct stat st;
 90+    FILE * file;
 91+    uint32_t index;
 92+
 93+    if (fstat(fd, &st) == -1)
 94+        return NULL;
 95+
 96+    snprintf(path, sizeof path, "/sys/dev/char/%u:%u/",
 97+             major(st.st_rdev), minor(st.st_rdev));
 98+    path_part = path + strlen(path);
 99+
100+    strcpy(path_part, "device/vendor");
101+    puts(path);
102+    file = fopen(path, "r");
103+    fgets(id, sizeof id, file);
104+    fclose(file);
105+    vendor_id = strtoul(id, NULL, 0);
106+
107+    strcpy(path_part, "device/device");
108+    puts(path);
109+    file = fopen(path, "r");
110+    fgets(id, sizeof id, file);
111+    fclose(file);
112+    device_id = strtoul(id, NULL, 0);
113+
114+    for (index = 0; index < ARRAY_LENGTH(drm_interfaces); ++index)
115+    {
116+        if (drm_interfaces[index]->device_supported(vendor_id, device_id))
117+            return drm_interfaces[index];
118+    }
119+
120+    return NULL;
121+}
122+
123+struct wld_drm_context * wld_drm_create_context(struct wl_display * display)
124+{
125+    struct wld_drm_context * drm;
126+
127+    drm = malloc(sizeof *drm);
128+
129+    if (!drm)
130+        return 0;
131+
132+    drm->wl = NULL;
133+    drm->fd = -1;
134+    wl_array_init(&drm->formats);
135+
136+    drm->queue = wl_display_create_queue(display);
137+
138+    if (!drm->queue)
139+        goto error2;
140+
141+    drm->registry = wl_display_get_registry(display);
142+
143+    if (!drm->registry)
144+        goto error3;
145+
146+    wl_registry_add_listener(drm->registry, &registry_listener, drm);
147+    wl_proxy_set_queue((struct wl_proxy *) drm->registry, drm->queue);
148+
149+    /* Wait for wl_drm global. */
150+    wayland_roundtrip(display, drm->queue);
151+
152+    if (!drm->wl)
153+    {
154+        DEBUG("No wl_drm global\n");
155+        goto error3;
156+    }
157+
158+    wl_drm_add_listener(drm->wl, &drm_listener, drm);
159+
160+    /* Wait for DRM device. */
161+    wayland_roundtrip(display, drm->queue);
162+
163+    if (drm->fd == -1)
164+    {
165+        DEBUG("No DRM device\n");
166+        goto error4;
167+    }
168+
169+    /* Wait for DRM authentication. */
170+    wayland_roundtrip(display, drm->queue);
171+
172+    if (!drm->authenticated)
173+    {
174+        DEBUG("DRM authentication failed\n");
175+        goto error5;
176+    }
177+
178+    drm->interface = find_drm_interface(drm->fd);
179+
180+    if (!drm->interface)
181+    {
182+        DEBUG("Couldn't find drawable implementation for DRM device\n");
183+        goto error5;
184+    }
185+
186+    drm->context = drm->interface->create_context(drm->fd);
187+
188+    if (!drm->context)
189+    {
190+        DEBUG("Couldn't create context for DRM drawable implementation\n");
191+        goto error5;
192+    }
193+
194+    return drm;
195+
196+  error5:
197+    close(drm->fd);
198+  error4:
199+    wl_drm_destroy(drm->wl);
200+  error3:
201+    wl_registry_destroy(drm->registry);
202+  error2:
203+    wl_event_queue_destroy(drm->queue);
204+  error1:
205+    wl_array_release(&drm->formats);
206+    free(drm);
207+  error0:
208+    return NULL;
209+}
210+
211+void wld_drm_destroy_context(struct wld_drm_context * drm)
212+{
213+    drm->interface->destroy_context(drm->context);
214+    close(drm->fd);
215+    wl_drm_destroy(drm->wl);
216+    wl_registry_destroy(drm->registry);
217+    wl_event_queue_destroy(drm->queue);
218+    wl_array_release(&drm->formats);
219+
220+    free(drm);
221+}
222+
223+bool wld_drm_has_format(struct wld_drm_context * drm, uint32_t format)
224+{
225+    uint32_t * supported_format;
226+
227+    wl_array_for_each(supported_format, &drm->formats)
228+    {
229+        if (*supported_format == format)
230+            return true;
231+    }
232+
233+    return false;
234+}
235+
236+int wld_drm_get_fd(struct wld_drm_context * drm)
237+{
238+    return drm->authenticated ? drm->fd : -1;
239+}
240+
241+struct wld_drawable * wld_drm_create_drawable(struct wld_drm_context * drm,
242+                                              struct wl_surface * surface,
243+                                              uint32_t width, uint32_t height,
244+                                              uint32_t format)
245+{
246+    struct wld_drawable * drawable0, * drawable1;
247+    uint32_t name0, name1, pitch0, pitch1;
248+    struct wl_buffer * buffer0, * buffer1;
249+
250+    if (!wld_drm_has_format(drm, format))
251+        return NULL;
252+
253+    drawable0 = drm->interface->create_drawable(drm->context, width, height,
254+                                                format);
255+    drawable1 = drm->interface->create_drawable(drm->context, width, height,
256+                                                format);
257+
258+    drm->interface->get_drawable_info(drawable0, &name0, &pitch0);
259+    drm->interface->get_drawable_info(drawable1, &name1, &pitch1);
260+
261+    buffer0 = wl_drm_create_buffer(drm->wl, name0, width, height,
262+                                   pitch0, format);
263+    buffer1 = wl_drm_create_buffer(drm->wl, name1, width, height,
264+                                   pitch1, format);
265+
266+    return wld_wayland_create_drawable_from_buffers(surface,
267+                                                    buffer0, drawable0,
268+                                                    buffer1, drawable1);
269+}
270+
271+void registry_global(void * data, struct wl_registry * registry, uint32_t name,
272+                     const char * interface, uint32_t version)
273+{
274+    struct wld_drm_context * drm = data;
275+
276+    if (strcmp(interface, "wl_drm") == 0)
277+    {
278+        drm->wl = wl_registry_bind(registry, name, &wl_drm_interface, 1);
279+        wl_proxy_set_queue((struct wl_proxy *) drm->wl, drm->queue);
280+    }
281+}
282+
283+void drm_device(void * data, struct wl_drm * wl, const char * name)
284+{
285+    struct wld_drm_context * drm = data;
286+    drm_magic_t magic;
287+
288+    drm->fd = open(name, O_RDWR);
289+
290+    if (drm->fd == -1)
291+    {
292+        DEBUG("Couldn't open DRM device '%s'\n", name);
293+        return;
294+    }
295+
296+    drmGetMagic(drm->fd, &magic);
297+    wl_drm_authenticate(wl, magic);
298+}
299+
300+void drm_format(void * data, struct wl_drm * wl, uint32_t format)
301+{
302+    struct wld_drm_context * drm = data;
303+
304+    *((uint32_t *) wl_array_add(&drm->formats, sizeof format)) = format;
305+}
306+
307+void drm_authenticated(void * data, struct wl_drm * wl)
308+{
309+    struct wld_drm_context * drm = data;
310+
311+    drm->authenticated = true;
312+}
313+
+70, -0
 1@@ -0,0 +1,70 @@
 2+/* wld: wayland-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 WLD_WAYLAND_DRM_H
26+#define WLD_WAYLAND_DRM_H 1
27+
28+#include <stdbool.h>
29+#include <stdint.h>
30+
31+struct wld_context;
32+struct wld_drawable;
33+enum wld_format;
34+
35+struct wl_display;
36+struct wl_surface;
37+
38+/**
39+ * Create a new drawable context which creates Wayland buffers through the
40+ * wl_drm interface, backed by hardware specific drawable implementations.
41+ */
42+struct wld_drm_context * wld_drm_create_context(struct wl_display * display);
43+
44+/**
45+ * Destroy a DRM context.
46+ */
47+void wld_drm_destroy_context(struct wld_drm_context * context);
48+
49+/**
50+ * Check if the wl_drm global has the specified pixel format.
51+ *
52+ * @see enum wld_format
53+ */
54+bool wld_drm_has_format(struct wld_drm_context * context,
55+                        enum wld_format format);
56+
57+/**
58+ * Get the opened file descriptor for the DRM device.
59+ */
60+int wld_drm_get_fd(struct wld_drm_context * context);
61+
62+/**
63+ * Create a new DRM drawable with the specified dimensions.
64+ */
65+struct wld_drawable * wld_drm_create_drawable(struct wld_drm_context * context,
66+                                              struct wl_surface * surface,
67+                                              uint32_t width, uint32_t height,
68+                                              enum wld_format format);
69+
70+#endif
71+
+60, -0
 1@@ -0,0 +1,60 @@
 2+/* wld: wayland-private.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 WLD_WAYLAND_PRIVATE_H
26+#define WLD_WAYLAND_PRIVATE_H 1
27+
28+#include <stdint.h>
29+
30+struct wld_drawable;
31+enum wld_format format;
32+
33+struct wl_display;
34+struct wl_event_queue;
35+
36+typedef void * (* wayland_create_context_func_t)(struct wl_display * display);
37+typedef void (* wayland_destroy_context_func_t)(void * context);
38+typedef struct wld_drawable * (* wayland_create_drawable_func_t)
39+    (void * context, struct wl_surface * surface,
40+     uint32_t width, uint32_t height, enum wld_format format);
41+
42+struct wld_wayland_interface
43+{
44+    wayland_create_context_func_t create_context;
45+    wayland_destroy_context_func_t destroy_context;
46+    wayland_create_drawable_func_t create_drawable;
47+};
48+
49+#if ENABLE_WAYLAND_DRM
50+extern const struct wld_wayland_interface wayland_drm_interface;
51+#endif
52+
53+#if ENABLE_WAYLAND_SHM
54+extern const struct wld_wayland_interface wayland_shm_interface;
55+#endif
56+
57+int wayland_roundtrip(struct wl_display * display,
58+                      struct wl_event_queue * queue);
59+
60+#endif
61+
+221, -0
  1@@ -0,0 +1,221 @@
  2+/* wld: wayland-shm.c
  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+#include "wayland-shm.h"
 26+#include "wayland.h"
 27+#include "wayland-private.h"
 28+#include "wld-private.h"
 29+#include "pixman.h"
 30+
 31+#include <stdlib.h>
 32+#include <string.h>
 33+#include <unistd.h>
 34+#include <fcntl.h>
 35+#include <sys/mman.h>
 36+#include <wayland-client.h>
 37+
 38+struct wld_shm_context
 39+{
 40+    struct wl_registry * registry;
 41+    struct wl_event_queue * queue;
 42+    struct wl_shm * wl;
 43+    struct wl_array formats;
 44+
 45+    struct wld_pixman_context * pixman_context;
 46+};
 47+
 48+static void registry_global(void * data, struct wl_registry * registry,
 49+                            uint32_t name, const char * interface,
 50+                            uint32_t version);
 51+
 52+static void shm_format(void * data, struct wl_shm * wl, uint32_t format);
 53+
 54+const struct wld_wayland_interface wayland_shm_interface = {
 55+    .create_context = (wayland_create_context_func_t) &wld_shm_create_context,
 56+    .destroy_context
 57+        = (wayland_destroy_context_func_t) &wld_shm_destroy_context,
 58+    .create_drawable = (wayland_create_drawable_func_t) &wld_shm_create_drawable
 59+};
 60+
 61+const static struct wl_registry_listener registry_listener = {
 62+    .global = &registry_global
 63+};
 64+
 65+const static struct wl_shm_listener shm_listener = {
 66+    .format = &shm_format,
 67+};
 68+
 69+static inline uint32_t wayland_format(enum wld_format format)
 70+{
 71+    switch (format)
 72+    {
 73+        case WLD_FORMAT_ARGB8888:
 74+            return WL_SHM_FORMAT_ARGB8888;
 75+        case WLD_FORMAT_XRGB8888:
 76+            return WL_SHM_FORMAT_XRGB8888;
 77+        default:
 78+            return 0;
 79+    }
 80+}
 81+
 82+struct wld_shm_context * wld_shm_create_context(struct wl_display * display)
 83+{
 84+    struct wld_shm_context * shm;
 85+
 86+    shm = malloc(sizeof *shm);
 87+
 88+    if (!shm)
 89+        return 0;
 90+
 91+    shm->wl = NULL;
 92+    wl_array_init(&shm->formats);
 93+
 94+    shm->queue = wl_display_create_queue(display);
 95+    shm->registry = wl_display_get_registry(display);
 96+    wl_registry_add_listener(shm->registry, &registry_listener, shm);
 97+    wl_proxy_set_queue((struct wl_proxy *) shm->registry, shm->queue);
 98+
 99+    shm->pixman_context = wld_pixman_create_context();
100+
101+    /* Wait for wl_shm global. */
102+    wayland_roundtrip(display, shm->queue);
103+
104+    if (!shm->wl)
105+    {
106+        DEBUG("No wl_shm global\n");
107+        goto error2;
108+    }
109+
110+    wl_shm_add_listener(shm->wl, &shm_listener, shm);
111+
112+    /* Wait for SHM formats. */
113+    wayland_roundtrip(display, shm->queue);
114+
115+    return shm;
116+
117+  error2:
118+    wl_registry_destroy(shm->registry);
119+    wl_event_queue_destroy(shm->queue);
120+  error1:
121+    wl_array_release(&shm->formats);
122+    free(shm);
123+  error0:
124+    return NULL;
125+}
126+
127+void wld_shm_destroy_context(struct wld_shm_context * shm)
128+{
129+    wld_pixman_destroy_context(shm->pixman_context);
130+    wl_shm_destroy(shm->wl);
131+    wl_registry_destroy(shm->registry);
132+    wl_event_queue_destroy(shm->queue);
133+    wl_array_release(&shm->formats);
134+
135+    free(shm);
136+}
137+
138+bool wld_shm_has_format(struct wld_shm_context * shm, uint32_t format)
139+{
140+    uint32_t * supported_format;
141+
142+    wl_array_for_each(supported_format, &shm->formats)
143+    {
144+        if (*supported_format == format)
145+            return true;
146+    }
147+
148+    return false;
149+}
150+
151+struct wld_drawable * wld_shm_create_drawable(struct wld_shm_context * shm,
152+                                              struct wl_surface * surface,
153+                                              uint32_t width, uint32_t height,
154+                                              uint32_t format)
155+{
156+    char name[] = "/tmp/wld-XXXXXX";
157+    uint32_t pitch = width * format_bytes_per_pixel(format);
158+    uint32_t size = height * pitch;
159+    int fd;
160+    void * data;
161+    struct wl_shm_pool * pool;
162+    struct wl_buffer * buffer0, * buffer1;
163+    struct wld_drawable * drawable0, * drawable1;
164+    uint32_t shm_format = wayland_format(format);
165+
166+    fd = mkostemp(name, O_CLOEXEC);
167+
168+    if (fd < 0)
169+        goto error0;
170+
171+    unlink(name);
172+
173+    if (ftruncate(fd, size * 2) < 0)
174+        goto error1;
175+
176+    data = mmap(NULL, size * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
177+
178+    if (data == MAP_FAILED)
179+        goto error1;
180+
181+    pool = wl_shm_create_pool(shm->wl, fd, size * 2);
182+    buffer0 = wl_shm_pool_create_buffer(pool, 0, width, height, pitch,
183+                                        shm_format);
184+    buffer1 = wl_shm_pool_create_buffer(pool, size, width, height, pitch,
185+                                        shm_format);
186+    wl_shm_pool_destroy(pool);
187+    close(fd);
188+
189+    drawable0 = wld_pixman_create_drawable(shm->pixman_context, width, height,
190+                                           data, pitch, format);
191+    drawable1 = wld_pixman_create_drawable(shm->pixman_context, width, height,
192+                                           data + size, pitch, format);
193+
194+    return wld_wayland_create_drawable_from_buffers(surface,
195+                                                    buffer0, drawable0,
196+                                                    buffer1, drawable1);
197+
198+  error1:
199+    close(fd);
200+  error0:
201+    return NULL;
202+}
203+
204+void registry_global(void * data, struct wl_registry * registry, uint32_t name,
205+                     const char * interface, uint32_t version)
206+{
207+    struct wld_shm_context * shm = data;
208+
209+    if (strcmp(interface, "wl_shm") == 0)
210+    {
211+        shm->wl = wl_registry_bind(registry, name, &wl_shm_interface, 1);
212+        wl_proxy_set_queue((struct wl_proxy *) shm->wl, shm->queue);
213+    }
214+}
215+
216+void shm_format(void * data, struct wl_shm * wl, uint32_t format)
217+{
218+    struct wld_shm_context * shm = data;
219+
220+    *((uint32_t *) wl_array_add(&shm->formats, sizeof format)) = format;
221+}
222+
+65, -0
 1@@ -0,0 +1,65 @@
 2+/* wld: wayland-shm.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 WLD_WAYLAND_SHM_H
26+#define WLD_WAYLAND_SHM_H 1
27+
28+#include <stdbool.h>
29+#include <stdint.h>
30+
31+struct wld_shm_context;
32+struct wld_drawable;
33+enum wld_format;
34+
35+struct wl_display;
36+struct wl_surface;
37+
38+/**
39+ * Create a new drawable context which creates Wayland buffers through the
40+ * wl_shm interface, back by Pixman drawables.
41+ */
42+struct wld_shm_context * wld_shm_create_context(struct wl_display * display);
43+
44+/**
45+ * Destroy an SHM context.
46+ */
47+void wld_shm_destroy_context(struct wld_shm_context * context);
48+
49+/**
50+ * Check if the wl_shm global has the specified pixel format.
51+ *
52+ * @see enum wld_format
53+ */
54+bool wld_shm_has_format(struct wld_shm_context * context,
55+                        enum wld_format format);
56+
57+/**
58+ * Create a new SHM drawable with the specified dimensions.
59+ */
60+struct wld_drawable * wld_shm_create_drawable(struct wld_shm_context * context,
61+                                              struct wl_surface * surface,
62+                                              uint32_t width, uint32_t height,
63+                                              enum wld_format format);
64+
65+#endif
66+
+283, -0
  1@@ -0,0 +1,283 @@
  2+/* wld: wayland.c
  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+#include "wayland.h"
 26+#include "wayland-private.h"
 27+#include "wld-private.h"
 28+
 29+#include <stdlib.h>
 30+#include <wayland-client.h>
 31+
 32+#define BACKBUF(drawable) (drawable)->buffers[(drawable)->front_buffer ^ 1]
 33+#define FRONTBUF(drawable) (drawable)->buffers[(drawable)->front_buffer]
 34+
 35+struct wld_wayland_context
 36+{
 37+    const struct wld_wayland_interface * interface;
 38+    void * context;
 39+};
 40+
 41+struct wayland_drawable
 42+{
 43+    struct wld_drawable base;
 44+    struct wl_surface * surface;
 45+    struct
 46+    {
 47+        struct wl_buffer * buffer;
 48+        struct wld_drawable * drawable;
 49+    } buffers[2];
 50+    uint8_t front_buffer;
 51+};
 52+
 53+static void callback_done(void * data, struct wl_callback * callback,
 54+                          uint32_t msecs);
 55+
 56+static void wayland_fill_rectangle(struct wld_drawable * drawable,
 57+                                   uint32_t color,
 58+                                   pixman_rectangle16_t * rectangles);
 59+static void wayland_fill_rectangles(struct wld_drawable * drawable,
 60+                                    uint32_t color,
 61+                                    pixman_rectangle16_t * rectangles,
 62+                                    uint32_t num_rectangles);
 63+static void wayland_draw_text_utf8(struct wld_drawable * drawable,
 64+                                   struct font * font, uint32_t color,
 65+                                   int32_t x, int32_t y,
 66+                                   const char * text, int32_t length);
 67+static void wayland_flush(struct wld_drawable * drawable);
 68+static void wayland_destroy(struct wld_drawable * drawable);
 69+
 70+const struct wl_callback_listener callback_listener = {
 71+    .done = &callback_done
 72+};
 73+
 74+const struct wld_draw_interface wayland_draw = {
 75+    .fill_rectangle = &wayland_fill_rectangle,
 76+    .fill_rectangles = &wayland_fill_rectangles,
 77+    .draw_text_utf8 = &wayland_draw_text_utf8,
 78+    .flush = &wayland_flush,
 79+    .destroy = &wayland_destroy
 80+};
 81+
 82+const static struct wld_wayland_interface * interfaces[] = {
 83+#if ENABLE_WAYLAND_DRM
 84+    [WLD_DRM] = &wayland_drm_interface,
 85+#endif
 86+
 87+#if ENABLE_WAYLAND_SHM
 88+    [WLD_SHM] = &wayland_shm_interface
 89+#endif
 90+};
 91+
 92+struct wld_wayland_context * wld_wayland_create_context
 93+    (struct wl_display * display, enum wld_wayland_interface_id id, ...)
 94+{
 95+    struct wld_wayland_context * wayland;
 96+    va_list requested_interfaces;
 97+    bool interfaces_tried[ARRAY_LENGTH(interfaces)] = {};
 98+
 99+    wayland = malloc(sizeof *wayland);
100+
101+    if (!wayland)
102+        goto error0;
103+
104+    wayland->context = NULL;
105+    wayland->interface = NULL;
106+
107+    va_start(requested_interfaces, id);
108+
109+    while (id >= 0)
110+    {
111+        if (interfaces_tried[id] || !interfaces[id])
112+            continue;
113+
114+        if ((wayland->context = interfaces[id]->create_context(display)))
115+        {
116+            wayland->interface = interfaces[id];
117+            break;
118+        }
119+
120+        interfaces_tried[id] = true;
121+        id = va_arg(requested_interfaces, enum wld_wayland_interface_id);
122+    }
123+
124+    va_end(requested_interfaces);
125+
126+    /* If the user specified WLD_ANY, try any remaining interfaces. */
127+    if (!wayland->context && id == WLD_ANY)
128+    {
129+        for (id = 0; id < ARRAY_LENGTH(interfaces); ++id)
130+        {
131+            if (interfaces_tried[id] || !interfaces[id])
132+                continue;
133+
134+            if ((wayland->context = interfaces[id]->create_context(display)))
135+            {
136+                wayland->interface = interfaces[id];
137+                break;
138+            }
139+        }
140+    }
141+
142+    if (!wayland->context)
143+    {
144+        DEBUG("Could not initialize any of the specified interfaces");
145+        goto error1;
146+    }
147+
148+    return wayland;
149+
150+  error1:
151+    free(wayland);
152+  error0:
153+    return NULL;
154+}
155+
156+void wld_wayland_destroy_context(struct wld_wayland_context * wayland)
157+{
158+    wayland->interface->destroy_context(wayland->context);
159+    free(wayland);
160+}
161+
162+struct wld_drawable * wld_wayland_create_drawable
163+    (struct wld_wayland_context * context, struct wl_surface * surface,
164+     uint32_t width, uint32_t height, enum wld_format format)
165+{
166+    return context->interface->create_drawable(context->context, surface,
167+                                               width, height, format);
168+}
169+
170+struct wld_drawable * wld_wayland_create_drawable_from_buffers
171+    (struct wl_surface * surface,
172+     struct wl_buffer * buffer0, struct wld_drawable * drawable0,
173+     struct wl_buffer * buffer1, struct wld_drawable * drawable1)
174+{
175+    struct wayland_drawable * wayland;
176+    uint32_t * data;
177+
178+    if (drawable0->width != drawable1->width
179+        || drawable0->height != drawable1->height)
180+    {
181+        DEBUG("Drawables aren't the same dimensions\n");
182+        return NULL;
183+    }
184+
185+    wayland = malloc(sizeof *wayland);
186+
187+    if (!wayland)
188+        return NULL;
189+
190+    wayland->buffers[0].buffer = buffer0;
191+    wayland->buffers[1].buffer = buffer1;
192+    wayland->buffers[0].drawable = drawable0;
193+    wayland->buffers[1].drawable = drawable1;
194+    wayland->front_buffer = 0;
195+    wayland->surface = surface;
196+
197+    wayland->base.interface = &wayland_draw;
198+    wayland->base.width = drawable0->width;
199+    wayland->base.height = drawable0->height;
200+
201+    return &wayland->base;
202+}
203+
204+int wayland_roundtrip(struct wl_display * display,
205+                      struct wl_event_queue * queue)
206+{
207+    struct wl_callback * callback;
208+    bool done = false;
209+    int ret = 0;
210+
211+    callback = wl_display_sync(display);
212+    wl_callback_add_listener(callback, &callback_listener, &done);
213+    wl_proxy_set_queue((struct wl_proxy *) callback, queue);
214+
215+    while (!done && ret >= 0)
216+        ret = wl_display_dispatch_queue(display, queue);
217+
218+    if (ret == -1 && !done)
219+        wl_callback_destroy(callback);
220+
221+    return ret;
222+}
223+
224+void callback_done(void * data, struct wl_callback * callback, uint32_t msecs)
225+{
226+    bool * done = data;
227+
228+    *done = true;
229+}
230+void wayland_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
231+                            pixman_rectangle16_t * rectangle)
232+{
233+    struct wayland_drawable * wayland;
234+
235+    wayland = container_of(drawable, typeof(*wayland), base);
236+    wld_fill_rectangle(BACKBUF(wayland).drawable, color, rectangle);
237+}
238+
239+void wayland_fill_rectangles(struct wld_drawable * drawable, uint32_t color,
240+                             pixman_rectangle16_t * rectangles,
241+                             uint32_t num_rectangles)
242+{
243+    struct wayland_drawable * wayland;
244+
245+    wayland = container_of(drawable, typeof(*wayland), base);
246+    wld_fill_rectangles(BACKBUF(wayland).drawable, color,
247+                        rectangles, num_rectangles);
248+}
249+
250+void wayland_draw_text_utf8(struct wld_drawable * drawable,
251+                            struct font * font, uint32_t color,
252+                            int32_t x, int32_t y,
253+                            const char * text, int32_t length)
254+{
255+    struct wayland_drawable * wayland;
256+
257+    wayland = container_of(drawable, typeof(*wayland), base);
258+    wld_draw_text_utf8_n(BACKBUF(wayland).drawable, &font->base, color,
259+                         x, y, text, length);
260+}
261+
262+void wayland_flush(struct wld_drawable * drawable)
263+{
264+    struct wayland_drawable * wayland;
265+
266+    wayland = container_of(drawable, typeof(*wayland), base);
267+
268+    wld_flush(BACKBUF(wayland).drawable);
269+    wl_surface_attach(wayland->surface, BACKBUF(wayland).buffer, 0, 0);
270+    wl_surface_commit(wayland->surface);
271+    wayland->front_buffer ^= 1;
272+}
273+
274+void wayland_destroy(struct wld_drawable * drawable)
275+{
276+    struct wayland_drawable * wayland;
277+
278+    wayland = container_of(drawable, typeof(*wayland), base);
279+    wl_buffer_destroy(wayland->buffers[0].buffer);
280+    wl_buffer_destroy(wayland->buffers[1].buffer);
281+    wld_destroy_drawable(wayland->buffers[0].drawable);
282+    wld_destroy_drawable(wayland->buffers[1].drawable);
283+}
284+
+93, -0
 1@@ -0,0 +1,93 @@
 2+/* wld: wayland.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 WLD_WAYLAND_H
26+#define WLD_WAYLAND_H 1
27+
28+#include <stdint.h>
29+
30+struct wl_display;
31+struct wl_surface;
32+struct wl_buffer;
33+
34+struct wld_wayland_context;
35+enum wld_format;
36+
37+enum wld_wayland_interface_id
38+{
39+    /**
40+     * Give up on trying any new interfaces. This can be considered as a
41+     * sentinel for wld_wayland_create_context.
42+     */
43+    WLD_NONE = -2,
44+
45+    /**
46+     * Try any available interface.
47+     */
48+    WLD_ANY = -1,
49+    WLD_DRM,
50+    WLD_SHM
51+};
52+
53+/**
54+ * Create a new drawing context which uses various available Wayland interfaces
55+ * (such as wl_shm and wl_drm) to create buffers backed by drawables specific
56+ * to the interface.
57+ *
58+ * You can specify the particular interface you want to use by specifying them
59+ * as arguments. Interfaces will be tried in the order they are given.
60+ *
61+ * The last argument must be either WLD_NONE or WLD_ANY.
62+ *
63+ * @see enum wld_wayland_interface_id
64+ */
65+struct wld_wayland_context * wld_wayland_create_context
66+    (struct wl_display * display, enum wld_wayland_interface_id id, ...);
67+
68+/**
69+ * Destroy a Wayland context.
70+ */
71+void wld_wayland_destroy_context(struct wld_wayland_context * context);
72+
73+/**
74+ * Create a new Wayland drawable for the given surface with a particular pixel
75+ * format.
76+ */
77+struct wld_drawable * wld_wayland_create_drawable
78+    (struct wld_wayland_context * context, struct wl_surface * surface,
79+     uint32_t width, uint32_t height, enum wld_format format);
80+
81+/**
82+ * Create a new Wayland drawable for the given surface, using the given buffers
83+ * and drawables as backing for the surface.
84+ *
85+ * This method does not require a Wayland context to be created because buffers
86+ * and drawables are passed to it explicitly.
87+ */
88+struct wld_drawable * wld_wayland_create_drawable_from_buffers
89+    (struct wl_surface * surface,
90+     struct wl_buffer * buffer0, struct wld_drawable * drawable0,
91+     struct wl_buffer * buffer1, struct wld_drawable * drawable1);
92+
93+#endif
94+
+135, -0
  1@@ -0,0 +1,135 @@
  2+/* wld: wld-private.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 WLD_PRIVATE_H
 26+#define WLD_PRIVATE_H 1
 27+
 28+#include "wld.h"
 29+
 30+#include <stdbool.h>
 31+#include <stdint.h>
 32+#include <ft2build.h>
 33+#include FT_FREETYPE_H
 34+#include FT_BITMAP_H
 35+
 36+#ifndef offsetof
 37+#   define offsetof __builtin_offsetof
 38+#endif
 39+
 40+#define container_of(ptr, type, member) ({                                  \
 41+    const typeof(((type *) 0)->member) *__mptr = (ptr);                     \
 42+    ((type *) ((uintptr_t) __mptr - offsetof(type, member)));               \
 43+})
 44+
 45+#define ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0])
 46+#if ENABLE_DEBUG
 47+#   define DEBUG(format, args...) \
 48+        fprintf(stderr, "# %s: " format, __func__, ## args)
 49+#else
 50+#   define DEBUG(format, args...)
 51+#endif
 52+
 53+struct wld_font_context
 54+{
 55+    FT_Library library;
 56+};
 57+
 58+struct glyph
 59+{
 60+    FT_Bitmap bitmap;
 61+
 62+    /**
 63+     * The offset from the origin to the top left corner of the bitmap.
 64+     */
 65+    int16_t x, y;
 66+
 67+    /**
 68+     * The width to advance to the origin of the next character.
 69+     */
 70+    uint16_t advance;
 71+};
 72+
 73+struct font
 74+{
 75+    struct wld_font base;
 76+
 77+    struct wld_font_context * context;
 78+    FT_Face face;
 79+    struct glyph ** glyphs;
 80+};
 81+
 82+struct wld_draw_interface
 83+{
 84+    void (* fill_rectangle)(struct wld_drawable * drawable, uint32_t color,
 85+                            pixman_rectangle16_t * rectangle);
 86+    void (* fill_rectangles)(struct wld_drawable * drawable, uint32_t color,
 87+                             pixman_rectangle16_t * rectangle,
 88+                             uint32_t num_rectangles);
 89+    void (* draw_text_utf8)(struct wld_drawable * drawable,
 90+                            struct font * font, uint32_t color,
 91+                            int32_t x, int32_t y,
 92+                            const char * text, int32_t length);
 93+    void (* flush)(struct wld_drawable * drawable);
 94+    void (* destroy)(struct wld_drawable * drawable);
 95+};
 96+
 97+
 98+bool font_ensure_glyph(struct font * font, FT_UInt glyph_index);
 99+
100+/**
101+ * Returns the number of bytes per pixel for the given format.
102+ */
103+static inline uint8_t format_bytes_per_pixel(enum wld_format format)
104+{
105+    switch (format)
106+    {
107+        case WLD_FORMAT_ARGB8888:
108+        case WLD_FORMAT_XRGB8888:
109+            return 4;
110+        default:
111+            return 0;
112+    }
113+}
114+
115+/**
116+ * This default fill_rectangle method is implemented as fill_rectangles with a
117+ * length parameter of 1.
118+ */
119+void default_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
120+                            pixman_rectangle16_t * rectangle);
121+
122+/**
123+ * This default fill_rectangles method is implemented in terms of the singular
124+ * fill_rectangle.
125+ */
126+void default_fill_rectangles(struct wld_drawable * drawable, uint32_t color,
127+                             pixman_rectangle16_t * rectangles,
128+                             uint32_t num_rectangles);
129+
130+/**
131+ * This is a NO-OP for implementations that do not require flushing.
132+ */
133+void default_flush(struct wld_drawable * drawable);
134+
135+#endif
136+
A wld.h
+144, -0
  1@@ -0,0 +1,144 @@
  2+/* wld: wld.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 WLD_H
 26+#define WLD_H 1
 27+
 28+#include <stdbool.h>
 29+#include <stdint.h>
 30+#include <pixman.h>
 31+#include <fontconfig/fontconfig.h>
 32+
 33+#define __WLD_FOURCC(a, b, c, d) ( (a)          \
 34+                                 | ((b) << 8)   \
 35+                                 | ((c) << 16)  \
 36+                                 | ((d) << 24) )
 37+
 38+/**
 39+ * Supported pixel formats.
 40+ *
 41+ * These formats can safely be interchanged with GBM and wl_drm formats.
 42+ */
 43+enum wld_format
 44+{
 45+    WLD_FORMAT_XRGB8888 = __WLD_FOURCC('X', 'R', '2', '4'),
 46+    WLD_FORMAT_ARGB8888 = __WLD_FOURCC('A', 'R', '2', '4')
 47+};
 48+
 49+bool wld_lookup_named_color(const char * name, uint32_t * color);
 50+
 51+/* Font Handling */
 52+struct wld_extents
 53+{
 54+    uint32_t advance;
 55+};
 56+
 57+struct wld_font
 58+{
 59+    uint32_t ascent, descent;
 60+    uint32_t height;
 61+    uint32_t max_advance;
 62+};
 63+
 64+/**
 65+ * Create a new font context.
 66+ *
 67+ * This sets up the underlying FreeType library.
 68+ */
 69+struct wld_font_context * wld_font_create_context();
 70+
 71+/**
 72+ * Open a new font from the given fontconfig match.
 73+ */
 74+struct wld_font * wld_font_open_pattern(struct wld_font_context * context,
 75+                                        FcPattern * match);
 76+
 77+/**
 78+ * Open a new font from a fontconfig pattern string.
 79+ */
 80+struct wld_font * wld_font_open_name(struct wld_font_context * context,
 81+                                     const char * name);
 82+
 83+/**
 84+ * Close a font.
 85+ */
 86+void wld_font_close(struct wld_font * font);
 87+
 88+/**
 89+ * Check if the given font has a particular character (in UTF-32), and if so,
 90+ * load the glyph.
 91+ */
 92+bool wld_font_ensure_char(struct wld_font * font, uint32_t character);
 93+
 94+/**
 95+ * Calculate the text extents of the given UTF-8 string.
 96+ *
 97+ * @param length The maximum number of bytes in the string to process
 98+ */
 99+void wld_font_text_extents_utf8_n(struct wld_font * font,
100+                                  const char * text, int32_t length,
101+                                  struct wld_extents * extents);
102+
103+static inline void wld_font_text_extents_utf8(struct wld_font * font,
104+                                              const char * text,
105+                                              struct wld_extents * extents)
106+{
107+    wld_font_text_extents_utf8_n(font, text, INT32_MAX, extents);
108+}
109+
110+/* Drawables */
111+struct wld_drawable
112+{
113+    const struct wld_draw_interface * interface;
114+    uint32_t width, height;
115+};
116+
117+/**
118+ * Destroy a drawable (created with any context).
119+ */
120+void wld_destroy_drawable(struct wld_drawable * drawable);
121+
122+void wld_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
123+                        pixman_rectangle16_t * rectangle);
124+
125+void wld_fill_rectangles(struct wld_drawable * drawable, uint32_t color,
126+                         pixman_rectangle16_t * rectangles,
127+                         uint32_t num_rectangles);
128+
129+void wld_draw_text_utf8_n(struct wld_drawable * drawable,
130+                          struct wld_font * font, uint32_t color,
131+                          int32_t x, int32_t y,
132+                          const char * text, int32_t length);
133+
134+static inline void wld_draw_text_utf8(struct wld_drawable * drawable,
135+                        struct wld_font * font, uint32_t color,
136+                        int32_t x, int32_t y,
137+                        const char * text)
138+{
139+    wld_draw_text_utf8_n(drawable, font, color, x, y, text, INT32_MAX);
140+}
141+
142+void wld_flush(struct wld_drawable * drawable);
143+
144+#endif
145+
+14, -0
 1@@ -0,0 +1,14 @@
 2+prefix=@prefix@
 3+exec_prefix=@exec_prefix@
 4+libdir=@libdir@
 5+includedir=@includedir@
 6+
 7+Name: wld
 8+Description: A primitive drawing library library targeted at Wayland
 9+Version: @PACKAGE_VERSION@
10+Cflags: -I${includedir}
11+Libs: -L${libdir} -lwld
12+
13+Requires: fontconfig pixman-1
14+Requires.private: freetype2 @PKGCONFIG_REQUIRES_PRIVATE@
15+