ilut_x11.c
Upload User: wmy0603
Upload Date: 2022-05-02
Package Size: 1808k
Code Size: 7k
Development Platform:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. //
  3. // ImageLib Sources
  4. // Copyright (C) 2002 by Denton Woods
  5. // Copyright (C) 2002 Nelson Rush.
  6. // Last modified: 05/18/2002
  7. //
  8. // Filename: src-ILUT/src/ilut_x11.c
  9. //
  10. // Description: X11 Pixmap and XImage binding functions (with XShm)
  11. //
  12. //-----------------------------------------------------------------------------
  13. /*
  14. ** This file was created by Jesse Maurais Wed April 4, 2007
  15. ** Contact: www.jessemaurais@gmail.com
  16. **
  17. **
  18. ** This patch to the Devil Tookit binds to the X Windows System Version 11,
  19. ** using client-side XImages and server-side Pixmaps, with support for both
  20. ** ZPixmaps and the insane XYPixmap format. (Depends on the X server)
  21. **
  22. ** If the XShm extension to X11 is present at the time of ./configure then
  23. ** support for shared memory XImages and Pixmaps is also compiled in. Note
  24. ** that "shared" does not mean Devil and X are sharing the same memory space.
  25. ** This is not possible, because both libraries make byte-for-byte copies
  26. ** of their data. It means that memory is part of an inter-process memory
  27. ** segment (see XShm spec).
  28. **
  29. ** TODO
  30. ** 1) Assumed the display depth is 24 bits (the most common) but there should
  31. ** be a check, and iXConvertImage should handle this properly. I don't think
  32. ** this should be difficult to modify from whats here.
  33. ** 2) It would be nice to convert from an XImage back to a Devil image for
  34. ** saving changes. Would be seful for an interactive image editor.
  35. ** 3) Possibly some additional OpenGL bindings for GLX Pbuffers.
  36. **
  37. ** FYI
  38. ** It was a long night figuring out the under-documented XYPixmap format.
  39. */
  40. #include "ilut_internal.h"
  41. #ifdef ILUT_USE_X11
  42. int bits; // bits per pixel
  43. int field; // bits per channel
  44. int bytes; // bytes per pixel
  45. int grain; // bytes per line
  46. int width; // pixels per line
  47. int height; // number of lines
  48. ILpal* palette; // for indexed colors
  49. char* data; // pointer to pixels
  50. void iXGrabImage( ILimage * img )
  51. {
  52. bits     = img->Bpp*8; // bits per pixel
  53. field    = img->Bpc; // bits per channel
  54. bytes    = img->Bpp; // bytes per pixel
  55. grain    = img->Bps; // bytes per line
  56. width    = img->Width;
  57. height   = img->Height;
  58. palette  = &img->Pal;
  59. data     = (char*)img->Data;
  60. }
  61. Bool iXGrabCurrentImage(void)
  62. {
  63. ilutCurImage = ilGetCurImage();
  64. if (!ilutCurImage) {
  65. return False;
  66. }
  67. iXGrabImage(ilutCurImage);
  68. return True;
  69. }
  70. void iXConvertImage( Display * dpy, XImage * img )
  71. {
  72. int x,y,z;
  73. int sX,dX;
  74. int sY,dY;
  75.   int sZ,dZ;
  76. int plane;
  77. ILimage * tmp;
  78. switch ( img->byte_order )
  79. {
  80.  case LSBFirst:
  81. tmp = iConvertImage( ilutCurImage,IL_BGR,IL_UNSIGNED_BYTE );
  82. break;
  83.  case MSBFirst:
  84. tmp = iConvertImage( ilutCurImage,IL_RGB,IL_UNSIGNED_BYTE );
  85. break;
  86.  default:
  87. return;
  88. }
  89. if ( !tmp ) return;
  90. iXGrabImage( tmp );
  91. switch ( img->format )
  92. {
  93.  case ZPixmap:
  94. for ( y = 0; y < height; y ++ )
  95. {
  96.  dY = y * img->bytes_per_line;
  97.  sY = y * grain;
  98.  for ( x = 0; x < width; x ++ )
  99.  {
  100.   dX = x * img->bits_per_pixel / 8;
  101.   sX = x * bytes;
  102.   for ( z = 0; z < bytes; z ++ )
  103.   {
  104.    img->data[dX+dY+z] = data[sX+sY+z];
  105.   }
  106.  }
  107. }
  108.  break;
  109.  case XYPixmap:
  110. for ( y = 0; y < height; y ++ )
  111. {
  112.  sY = y * grain;
  113.  for ( x = 0; x < width; x ++ )
  114.  {
  115.   sX = x * bytes;
  116.   for ( z = 0; z < bits; z ++ )
  117.   {
  118.    sZ = z / 8;
  119.    dZ = z % 8;
  120.    if ( data[sY+sX+sZ] & ( 1 << dZ ) )
  121.    {
  122.     plane = bits - z - 1;
  123.     sZ = x % 8;
  124.     dX = x / 8;
  125.     dY = y * img->bytes_per_line;
  126.     dZ = plane * img->bytes_per_line * height;
  127.     img->data[dZ+dY+dX] |= 1 << sZ;
  128.    }
  129.   }
  130.  }
  131. }
  132.  break;
  133.  default:
  134. ilSetError( ILUT_NOT_SUPPORTED );
  135. }
  136. ilCloseImage( tmp );
  137. }
  138. ILboolean ilutXInit(void) {
  139. return IL_TRUE;
  140. }
  141. XImage * ILAPIENTRY ilutXCreateImage( Display * dpy )
  142. {
  143. Visual * vis;
  144. XImage * img;
  145. char * buffer;
  146. if (!iXGrabCurrentImage()) {
  147. return NULL;
  148. }
  149. buffer = malloc( width * height * 4 );
  150. if (!buffer) {
  151. return NULL;
  152. }
  153. vis = CopyFromParent;
  154. img = XCreateImage( dpy,vis, 24,ZPixmap,0,buffer,width,height,8,0 );
  155. if (!img) {
  156. free(buffer);
  157. return NULL;
  158. }
  159. iXConvertImage( dpy,img );
  160. return img;
  161. }
  162. Pixmap ILAPIENTRY ilutXCreatePixmap( Display * dpy, Drawable draw )
  163. {
  164. XImage * img;
  165. GC gc;
  166. Pixmap pix;
  167. img = ilutXCreateImage( dpy );
  168. if (!img) {
  169. return None;
  170. }
  171. gc = DefaultGC(dpy,DefaultScreen(dpy));
  172. if (!gc) {
  173. XDestroyImage( img );
  174. return None;
  175. }
  176. pix = XCreatePixmap( dpy,draw, width,height,24 );
  177. if (!pix ) {
  178. XDestroyImage( img );
  179. return None;
  180. }
  181. XPutImage( dpy,pix,gc,img, 0,0,0,0,width,height );
  182. XDestroyImage( img );
  183. return pix;
  184. }
  185. XImage * ILAPIENTRY ilutXLoadImage( Display * dpy, char * filename )
  186. {
  187. iBindImageTemp();
  188. if (!ilLoadImage(filename)) {
  189. return NULL;
  190. }
  191. return ilutXCreateImage( dpy );
  192. }
  193. Pixmap ILAPIENTRY ilutXLoadPixmap( Display * dpy, Drawable draw, char * filename )
  194. {
  195. iBindImageTemp();
  196. if (!ilLoadImage(filename)) {
  197. return None;
  198. }
  199. return ilutXCreatePixmap( dpy,draw );
  200. }
  201. #ifdef ILUT_USE_XSHM
  202. #include <sys/ipc.h>
  203. #include <sys/shm.h>
  204. #include <X11/extensions/XShm.h>
  205. XImage * ILAPIENTRY ilutXShmCreateImage( Display * dpy, XShmSegmentInfo * info )
  206. {
  207. Visual * vis;
  208. XImage * img;
  209. // Get server supported format
  210. int size,format = XShmPixmapFormat( dpy );
  211. // Grab the current image
  212. if (!iXGrabCurrentImage()) {
  213. return NULL;
  214. }
  215. // Create a shared image
  216. vis = CopyFromParent;
  217. img = XShmCreateImage( dpy,vis, 24,format,NULL,info,width,height );
  218. if (!img) {
  219. return NULL;
  220. }
  221. // Create shared memory
  222. size = img->bytes_per_line * img->height;
  223. info->shmid = shmget( IPC_PRIVATE, size, IPC_CREAT | 0666 );
  224. info->shmaddr = img->data = shmat( info->shmid, 0, 0 );
  225. info->readOnly = False;
  226. // Attach to server
  227. XShmAttach( dpy,info );
  228. // Copy image pixels to shared memory
  229. iXConvertImage( dpy,img );
  230. return img;
  231. }
  232. void ILAPIENTRY ilutXShmDestroyImage( Display * dpy, XImage * img, XShmSegmentInfo * info )
  233. {
  234. XShmDetach( dpy,info );
  235. XDestroyImage( img );
  236. XFlush( dpy );
  237. shmdt( info->shmaddr );
  238. shmctl( info->shmid, IPC_RMID, 0 );
  239. }
  240. Pixmap ILAPIENTRY ilutXShmCreatePixmap( Display * dpy, Drawable draw, XShmSegmentInfo * info )
  241. {
  242. Pixmap pix;
  243. XImage*img;
  244. // Create a dumby image
  245. img = ilutXShmCreateImage( dpy,info );
  246. if (!img) {
  247. return None;
  248. }
  249. // Use the same memory segment in the pixmap
  250. pix = XShmCreatePixmap( dpy,draw, info->shmaddr,info,width,height,24 );
  251. if (!pix) {
  252. ilutXShmDestroyImage( dpy,img,info );
  253. return None;
  254. }
  255. // Riddance to the image
  256. XDestroyImage( img );
  257. return pix;
  258. }
  259. void ILAPIENTRY ilutXShmFreePixmap( Display * dpy, Pixmap pix, XShmSegmentInfo * info )
  260. {
  261. XShmDetach( dpy,info );
  262. XFreePixmap( dpy,pix );
  263. XFlush( dpy );
  264. shmdt( info->shmaddr );
  265. shmctl( info->shmid, IPC_RMID, 0 );
  266. }
  267. XImage * ILAPIENTRY ilutXShmLoadImage( Display * dpy, char* filename, XShmSegmentInfo * info )
  268. {
  269. iBindImageTemp();
  270. if (!ilLoadImage(filename)) {
  271. return NULL;
  272. }
  273. return ilutXShmCreateImage( dpy,info );
  274. }
  275. Pixmap ILAPIENTRY ilutXShmLoadPixmap( Display * dpy, Drawable draw, char* filename, XShmSegmentInfo * info )
  276. {
  277. iBindImageTemp();
  278. if (!ilLoadImage(filename)) {
  279. return None;
  280. }
  281. return ilutXShmCreatePixmap( dpy,draw,info );
  282. }
  283. #endif//ILUT_USE_XSHM
  284. #endif//ILUT_USE_X11