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;