1 // Manually created
2 module std.c.linux.X11.xcb.image;
3 version(USE_XCB):
4 
5 import std.c.linux.X11.xcb.xcb;
6 import std.c.linux.X11.xcb.shm;
7 import std.c.linux.X11.xcb.xproto;
8 import std.c.stdlib;
9 import std.conv;
10 
11 struct xcb_image_t
12 {
13 	ushort           width;
14 	ushort           height;
15 	xcb_image_format_t format;
16 	ubyte            scanline_pad;
17 	ubyte            depth;
18 	ubyte            bpp;
19 	ubyte          unit;
20 	uint           plane_mask;
21 	xcb_image_order_t  byte_order;
22 	xcb_image_order_t  bit_order;
23 	uint           stride;
24 	uint           size;
25 	void *             base;
26 	ubyte *          data;
27 }
28 
29 xcb_format_t *
30 find_format_by_depth (xcb_setup_t *setup, ubyte depth)
31 {
32   xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
33   xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
34   for(; fmt != fmtend; ++fmt)
35       if(fmt.depth == depth)
36 	  return fmt;
37   return null;
38 }
39 
40 
41 xcb_image_format_t
42 effective_format(xcb_image_format_t format, ubyte bpp)
43 {
44     if (format == XCB_IMAGE_FORMAT_Z_PIXMAP && bpp != 1)
45 	    return format;
46     return XCB_IMAGE_FORMAT_XY_PIXMAP;
47 }
48 
49 
50 int
51 format_valid (ubyte depth, ubyte bpp, ubyte unit,
52 	      xcb_image_format_t format, ubyte xpad)
53 {
54   xcb_image_format_t  ef = effective_format(format, bpp);
55   if (depth > bpp)
56       return 0;
57   switch(ef) {
58   case XCB_IMAGE_FORMAT_XY_PIXMAP:
59       switch(unit) {
60       case 8:
61       case 16:
62       case 32:
63 	  break;
64       default:
65 	  return 0;
66       }
67       if (xpad < bpp)
68 	  return 0;
69       switch (xpad) {
70       case 8:
71       case 16:
72       case 32:
73 	  break;
74       default:
75 	  return 0;
76       }
77       break;
78   case XCB_IMAGE_FORMAT_Z_PIXMAP:
79       switch (bpp) {
80       case 4:
81 	  if (unit != 8)
82 	      return 0;
83 	  break;
84       case 8:
85       case 16:
86       case 24:
87       case 32:
88 	  if (unit != bpp)
89 	      return 0;
90 	  break;
91       default:
92 	  return 0;
93       }
94       break;
95   default:
96       return 0;
97   }
98   return 1;
99 }
100 
101 
102 int
103 image_format_valid (xcb_image_t *image) {
104     return format_valid(image.depth,
105 			image.bpp,
106 			image.unit,
107 			image.format,
108 			image.scanline_pad);
109 }
110 
111 uint xcb_roundup(uint  	base,
112 		uint	pad
113 )
114 {
115     uint b = base + pad - 1;
116     /* faster if pad is a power of two */
117     if (((pad - 1) & pad) == 0)
118        return b & -pad;
119     return b - b % pad;
120 }
121 
122 void
123 xcb_image_annotate (xcb_image_t *image)
124 {
125   xcb_image_format_t  ef = effective_format(image.format, image.bpp);
126   switch (ef) {
127   case XCB_IMAGE_FORMAT_XY_PIXMAP:
128       image.stride = xcb_roundup(image.width, image.scanline_pad) >> 3;
129       image.size = image.height * image.stride * image.depth;
130       break;
131   case XCB_IMAGE_FORMAT_Z_PIXMAP:
132       image.stride = xcb_roundup(cast(uint)image.width *
133 				  cast(uint)image.bpp,
134 				  image.scanline_pad) >> 3;
135       image.size = image.height * image.stride;
136       break;
137   default:
138       assert(0);
139   }
140 }
141 
142 xcb_image_t *
143 xcb_image_create_native (xcb_connection_t *  c,
144 			 ushort            width,
145 			 ushort            height,
146 			 xcb_image_format_t  format,
147 			 ubyte             depth,
148 			 void *              base,
149 			 uint            bytes,
150 			 ubyte *           data)
151 {
152   xcb_setup_t *  setup = xcb_get_setup(c);
153   xcb_format_t *       fmt;
154   xcb_image_format_t   ef = format;
155 
156   if (ef == XCB_IMAGE_FORMAT_Z_PIXMAP && depth == 1)
157       ef = XCB_IMAGE_FORMAT_XY_PIXMAP;
158   switch (ef) {
159   case XCB_IMAGE_FORMAT_XY_BITMAP:
160       if (depth != 1)
161 	  return null;
162       /* fall through */
163         goto case;
164   case XCB_IMAGE_FORMAT_XY_PIXMAP:
165       if (depth > 1) {
166 	  fmt = find_format_by_depth(setup, depth);
167 	  if (!fmt)
168 	      return null;
169       }
170       return xcb_image_create(width, height, format,
171 			      setup.bitmap_format_scanline_pad,
172 			      depth, depth, setup.bitmap_format_scanline_unit,
173 			      setup.image_byte_order,
174 			      setup.bitmap_format_bit_order,
175 			      base, bytes, data);
176   case XCB_IMAGE_FORMAT_Z_PIXMAP:
177       fmt = find_format_by_depth(setup, depth);
178       if (!fmt)
179 	  		return null;
180       return xcb_image_create(width, height, format,
181 			      fmt.scanline_pad,
182 			      fmt.depth, fmt.bits_per_pixel, 0,
183 			      setup.image_byte_order,
184 			      XCB_IMAGE_ORDER_MSB_FIRST,
185 			      base, bytes, data);
186   default:
187       assert(0);
188   }
189   assert(0);
190 }
191 
192 uint xcb_mask(uint n)
193 {
194     return n == 32 ? ~0 : (1 << n) - 1;
195 }
196 
197 xcb_image_t *
198 xcb_image_create (ushort           width,
199 		  ushort           height,
200 		  xcb_image_format_t format,
201 		  ubyte            xpad,
202 		  ubyte            depth,
203 		  ubyte            bpp,
204 		  ubyte            unit,
205 		  xcb_image_order_t  byte_order,
206 		  xcb_image_order_t  bit_order,
207 		  void *             base,
208 		  uint           bytes,
209 		  ubyte *          data)
210 {
211   xcb_image_t *  image;
212 
213   if (unit == 0) {
214       switch (format) {
215 	      case XCB_IMAGE_FORMAT_XY_BITMAP:
216 	      case XCB_IMAGE_FORMAT_XY_PIXMAP:
217 			  unit = 32;
218 			  break;
219 	      case XCB_IMAGE_FORMAT_Z_PIXMAP:
220 			  if (bpp == 1) {
221 			      unit = 32;
222 			      break;
223 			  }
224 			  if (bpp < 8) {
225 			      unit = 8;
226 			      break;
227 			  }
228 			  unit = bpp;
229 			  break;
230 		default:
231 			break;
232 
233       }
234   }
235   if (!format_valid(depth, bpp, unit, format, xpad))
236       return null;
237   import std.c.stdlib;
238   image = cast(xcb_image_t*)malloc(xcb_image_t.sizeof);
239   if (image is null)
240       return null;
241   image.width = width;
242   image.height = height;
243   image.format = format;
244   image.scanline_pad = xpad;
245   image.depth = depth;
246   image.bpp = bpp;
247   image.unit = unit;
248   image.plane_mask = xcb_mask(depth);
249   image.byte_order = byte_order;
250   image.bit_order = bit_order;
251   xcb_image_annotate(image);
252 
253   /*
254    * Ways this function can be called:
255    *   * with data: we fail if bytes isn't
256    *     large enough, else leave well enough alone.
257    *   * with base and !data: if bytes is zero, we
258    *     default; otherwise we fail if bytes isn't
259    *     large enough, else fill in data
260    *   * with !base and !data: we malloc storage
261    *     for the data, save that address as the base,
262    *     and fail if malloc does.
263    *
264    * When successful, we establish the invariant that data
265    * points at sufficient storage that may have been
266    * supplied, and base is set iff it should be
267    * auto-freed when the image is destroyed.
268    *
269    * Except as a special case when base = 0 && data == 0 &&
270    * bytes == ~0 we just return the image structure and let
271    * the caller deal with getting the allocation right.
272    */
273   if (!base && !data && bytes == ~0) {
274       image.base = null;
275       image.data = null;
276       return image;
277   }
278   if (!base && data && bytes == 0)
279       bytes = image.size;
280   image.base = base;
281   image.data = data;
282   if (!image.data) {
283       if (image.base) {
284   	  	  image.data = cast(ubyte*)image.base;
285       } else {
286 		  bytes = image.size;
287 		  image.base = malloc(bytes);
288 		  image.data = cast(ubyte*)image.base;
289       }
290   }
291   if (!image.data || bytes < image.size) {
292       free(image);
293       return null;
294   }
295   return image;
296 }
297 
298 
299 void
300 xcb_image_destroy (xcb_image_t *image)
301 {
302   if (image.base)
303       free (image.base);
304   free (image);
305 }
306 
307 ubyte
308 xcb_aux_get_depth(xcb_connection_t *c,
309                    xcb_screen_t     *screen)
310 {
311   xcb_drawable_t            drawable;
312   xcb_get_geometry_reply_t *geom;
313   ubyte                       depth;
314 
315   drawable = screen.root;
316   geom = xcb_get_geometry_reply (c, xcb_get_geometry(c, drawable), null);
317 
318   if (!geom) {
319 	  //Log.e("GetGeometry(root) failed");
320     	exit (0);
321   }
322 
323   depth = geom.depth;
324   free (geom);
325 
326   return depth;
327 }
328 
329 extern (C) int xcb_image_shm_get(xcb_connection_t * conn,
330 	       xcb_drawable_t          draw,
331 	       xcb_image_t *           image,
332 	       xcb_shm_segment_info_t  shminfo,
333 	       ushort                 x,
334 	       ushort                 y,
335 	       uint                plane_mask);
336 const XCB_ALL_PLANES = ~0;
337 
338 extern (C) xcb_image_t *
339 xcb_image_shm_put (xcb_connection_t *      conn,
340 		   xcb_drawable_t          draw,
341 		   xcb_gcontext_t          gc,
342 		   xcb_image_t *           image,
343 		   xcb_shm_segment_info_t  shminfo,
344 		   short                 src_x,
345 		   short                 src_y,
346 		   short                 dest_x,
347 		   short                 dest_y,
348 		   ushort                src_width,
349 		   ushort                src_height,
350 		   ubyte                 send_event);
351 
352 /**
353  * @struct xcb_shm_segment_info_t
354  * A structure that stores the informations needed by the MIT Shm
355  * Extension.
356  */
357 struct xcb_shm_segment_info_t
358 {
359   xcb_shm_seg_t shmseg;
360   uint    shmid;
361   ubyte   *shmaddr;
362 }
363 
364 alias int key_t;
365 extern (C) int shmget(key_t key, size_t size, int shmflg);
366 extern (C) int getpagesize();
367 extern (C) ubyte *shmat(int shmid, ubyte *shmaddr, int shmflg);
368 extern (C) int shmctl(int shmid, int cmd, void *buf);
369 const IPC_CREAT = octal!1000;
370 const IPC_PRIVATE = (cast(key_t) 0);
371 const IPC_RMID = 0;