1 module wayland.cursor;
2 
3 import wayland.native.cursor;
4 import wayland.client;
5 import wayland.util;
6 
7 import std..string;
8 
9 
10 class WlCursorImage : Native!wl_cursor_image
11 {
12     mixin nativeImpl!(wl_cursor_image);
13 
14     this(wl_cursor_image* native)
15     {
16         _native = native;
17     }
18 
19     @property uint width()
20     {
21         return native.width;
22     }
23 
24     @property uint height()
25     {
26         return native.height;
27     }
28 
29     @property uint hotspotX()
30     {
31         return native.hotspot_x;
32     }
33 
34     @property uint hotspotY()
35     {
36         return native.hotspot_y;
37     }
38 
39     @property uint delay()
40     {
41         return native.delay;
42     }
43 
44     @property WlBuffer buffer()
45     {
46         auto nb = wl_cursor_image_get_buffer(native);
47         if (!nb) return null;
48         auto buf = cast(WlBuffer)WlProxy.get(nb);
49         if (!buf) buf = cast(WlBuffer)WlBuffer.iface.makeProxy(nb);
50         return buf;
51     }
52 }
53 
54 class WlCursor : Native!wl_cursor
55 {
56     mixin nativeImpl!(wl_cursor);
57 
58     private WlCursorImage[] _images;
59 
60     this(wl_cursor* native)
61     {
62         _native = native;
63     }
64 
65     @property string name()
66     {
67         return fromStringz(native.name).idup;
68     }
69 
70     @property WlCursorImage[] images()
71     {
72         import std.array : uninitializedArray;
73 
74         if (_images) return _images;
75 
76         _images = uninitializedArray!(WlCursorImage[])(native.image_count);
77         foreach (i; 0 .. native.image_count)
78         {
79             _images[i] = new WlCursorImage(native.images[i]);
80         }
81         return _images;
82     }
83 
84     int frame(uint time)
85     {
86         return wl_cursor_frame(native, time);
87     }
88 
89     int frameAndDuration(uint time, out uint duration)
90     {
91         return wl_cursor_frame_and_duration(native, time, &duration);
92     }
93 }
94 
95 class WlCursorTheme : Native!wl_cursor_theme
96 {
97     mixin nativeImpl!(wl_cursor_theme);
98 
99     this(wl_cursor_theme* native)
100     {
101         _native = native;
102     }
103 
104     static WlCursorTheme load(string name, size_t size, WlShm shm)
105     {
106         auto nn = name.length ? toStringz(name) : null;
107         auto ct = wl_cursor_theme_load(nn, cast(int)size, shm.proxy);
108         return ct ? new WlCursorTheme(ct) : null;
109     }
110 
111     void destroy()
112     {
113         wl_cursor_theme_destroy(native);
114     }
115 
116     WlCursor cursor(string name)
117     {
118         auto cp = wl_cursor_theme_get_cursor(native, toStringz(name));
119         return cp ? new WlCursor(cp) : null;
120     }
121 
122 }
123 
124 version(WlDynamic)
125 {
126     import derelict.util.loader : SharedLibLoader;
127 
128     private class WlCursorLoader : SharedLibLoader
129     {
130         this()
131         {
132             super("libwayland-cursor.so");
133         }
134 
135         protected override void loadSymbols()
136         {
137             bindFunc( cast( void** )&wl_cursor_theme_load, "wl_cursor_theme_load" );
138             bindFunc( cast( void** )&wl_cursor_theme_destroy, "wl_cursor_theme_destroy" );
139             bindFunc( cast( void** )&wl_cursor_theme_get_cursor, "wl_cursor_theme_get_cursor" );
140             bindFunc( cast( void** )&wl_cursor_image_get_buffer, "wl_cursor_image_get_buffer" );
141             bindFunc( cast( void** )&wl_cursor_frame, "wl_cursor_frame" );
142             bindFunc( cast( void** )&wl_cursor_frame_and_duration, "wl_cursor_frame_and_duration" );
143         }
144     }
145 
146     private __gshared WlCursorLoader _loader;
147 
148     shared static this()
149     {
150         _loader = new WlCursorLoader;
151     }
152 
153     public @property SharedLibLoader wlCursorDynLib()
154     {
155         return _loader;
156     }
157 }
158