- Main Page
- Data Structures
- Files

- File List

# E:/DevIL/src-ILUT/src/ilut_x11.c

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Sources
    00004 // Copyright (C) 2002 by Denton Woods
    00005 // Copyright (C) 2002 Nelson Rush.
    00006 // Last modified: 05/18/2002
    00007 //
    00008 // Filename: src-ILUT/src/ilut_x11.c
    00009 //
    00010 // Description: X11 Pixmap and XImage binding functions (with XShm)
    00011 //
    00012 //-----------------------------------------------------------------------------
    00013
    00014 /*
    00015 ** This file was created by Jesse Maurais Wed April 4, 2007
    00016 ** Contact: www.jessemaurais@gmail.com
    00017 **
    00018 **
    00019 ** This patch to the Devil Tookit binds to the X Windows System Version 11,
    00020 ** using client-side XImages and server-side Pixmaps, with support for both
    00021 ** ZPixmaps and the insane XYPixmap format. (Depends on the X server)
    00022 **
    00023 ** If the XShm extension to X11 is present at the time of ./configure then
    00024 ** support for shared memory XImages and Pixmaps is also compiled in. Note
    00025 ** that "shared" does not mean Devil and X are sharing the same memory space.
    00026 ** This is not possible, because both libraries make byte-for-byte copies
    00027 ** of their data. It means that memory is part of an inter-process memory
    00028 ** segment (see XShm spec).
    00029 **
    00030 ** TODO
    00031 ** 1) Assumed the display depth is 24 bits (the most common) but there should
    00032 ** be a check, and iXConvertImage should handle this properly. I don't think
    00033 ** this should be difficult to modify from whats here.
    00034 ** 2) It would be nice to convert from an XImage back to a Devil image for
    00035 ** saving changes. Would be seful for an interactive image editor.
    00036 ** 3) Possibly some additional OpenGL bindings for GLX Pbuffers.
    00037 **
    00038 ** FYI
    00039 ** It was a long night figuring out the under-documented XYPixmap format.
    00040 */
    00041
    00042
    00043 #include "ilut_internal.h"
    00044 #ifdef ILUT_USE_X11
    00045
    00046
    00047 int bits;       // bits per pixel
    00048 int field;      // bits per channel
    00049 int bytes;      // bytes per pixel
    00050 int grain;      // bytes per line
    00051 int width;      // pixels per line
    00052 int height;     // number of lines
    00053 ILpal* palette; // for indexed colors
    00054 char* data;     // pointer to pixels
    00055
    00056
    00057
    00058 void iXGrabImage( ILimage * img )
    00059 {
    00060         bits     = img->Bpp*8;  // bits per pixel
    00061         field    = img->Bpc;    // bits per channel
    00062         bytes    = img->Bpp;    // bytes per pixel
    00063         grain    = img->Bps;    // bytes per line
    00064         width    = img->Width;
    00065         height   = img->Height;
    00066         palette  = &img->Pal;
    00067         data     = (char*)img->Data;
    00068 }
    00069
    00070
    00071 Bool iXGrabCurrentImage(void)
    00072 {
    00073         ilutCurImage = ilGetCurImage();
    00074         if (!ilutCurImage) {
    00075                 return False;
    00076         }
    00077         iXGrabImage(ilutCurImage);
    00078         return True;
    00079 }
    00080
    00081
    00082 void iXConvertImage( Display * dpy, XImage * img )
    00083 {
    00084         int x,y,z;
    00085         int sX,dX;
    00086         int sY,dY;
    00087         int sZ,dZ;
    00088         int plane;
    00089
    00090
    00091         ILimage * tmp;
    00092
    00093         switch ( img->byte_order )
    00094         {
    00095          case LSBFirst:
    00096                 tmp = iConvertImage( ilutCurImage,IL_BGR,IL_UNSIGNED_BYTE );
    00097                 break;
    00098          case MSBFirst:
    00099                 tmp = iConvertImage( ilutCurImage,IL_RGB,IL_UNSIGNED_BYTE );
    00100                 break;
    00101          default:
    00102                 return;
    00103         }
    00104
    00105         if ( !tmp ) return;
    00106         iXGrabImage( tmp );
    00107
    00108
    00109         switch ( img->format )
    00110         {
    00111          case ZPixmap:
    00112
    00113                 for ( y = 0; y < height; y ++ )
    00114                 {
    00115                  dY = y * img->bytes_per_line;
    00116                  sY = y * grain;
    00117
    00118                  for ( x = 0; x < width; x ++ )
    00119                  {
    00120                   dX = x * img->bits_per_pixel / 8;
    00121                   sX = x * bytes;
    00122
    00123                   for ( z = 0; z < bytes; z ++ )
    00124                   {
    00125                    img->data[dX+dY+z] = data[sX+sY+z];
    00126                   }
    00127                  }
    00128                 }
    00129
    00130          break;
    00131
    00132          case XYPixmap:
    00133
    00134                 for ( y = 0; y < height; y ++ )
    00135                 {
    00136                  sY = y * grain;
    00137
    00138                  for ( x = 0; x < width; x ++ )
    00139                  {
    00140                   sX = x * bytes;
    00141
    00142                   for ( z = 0; z < bits; z ++ )
    00143                   {
    00144                    sZ = z / 8;
    00145                    dZ = z % 8;
    00146
    00147                    if ( data[sY+sX+sZ] & ( 1 << dZ ) )
    00148                    {
    00149                     plane = bits - z - 1;
    00150
    00151                     sZ = x % 8;
    00152                     dX = x / 8;
    00153                     dY = y * img->bytes_per_line;
    00154                     dZ = plane * img->bytes_per_line * height;
    00155
    00156                     img->data[dZ+dY+dX] |= 1 << sZ;
    00157                    }
    00158                   }
    00159                  }
    00160                 }
    00161
    00162          break;
    00163
    00164          default:
    00165                 ilSetError( ILUT_NOT_SUPPORTED );
    00166         }
    00167
    00168         ilCloseImage( tmp );
    00169 }
    00170
    00171 ILboolean ilutXInit(void) {
    00172         return IL_TRUE;
    00173 }
    00174
    00175
    00176
    00177
    00178
    00179
    00180
    00181 XImage * ILAPIENTRY ilutXCreateImage( Display * dpy )
    00182 {
    00183         Visual * vis;
    00184         XImage * img;
    00185         char * buffer;
    00186
    00187         if (!iXGrabCurrentImage()) {
    00188                 return NULL;
    00189         }
    00190
    00191         buffer = malloc( width * height * 4 );
    00192         if (!buffer) {
    00193                 return NULL;
    00194         }
    00195
    00196         vis = CopyFromParent;
    00197         img = XCreateImage( dpy,vis, 24,ZPixmap,0,buffer,width,height,8,0 );
    00198         if (!img) {
    00199                 free(buffer);
    00200                 return NULL;
    00201         }
    00202
    00203         iXConvertImage( dpy,img );
    00204
    00205         return img;
    00206 }
    00207
    00208
    00209
    00210 Pixmap ILAPIENTRY ilutXCreatePixmap( Display * dpy, Drawable draw )
    00211 {
    00212         XImage * img;
    00213         GC gc;
    00214         Pixmap pix;
    00215
    00216         img = ilutXCreateImage( dpy );
    00217         if (!img) {
    00218                 return None;
    00219         }
    00220
    00221         gc = DefaultGC(dpy,DefaultScreen(dpy));
    00222         if (!gc) {
    00223                 XDestroyImage( img );
    00224                 return None;
    00225         }
    00226
    00227         pix = XCreatePixmap( dpy,draw, width,height,24 );
    00228         if (!pix ) {
    00229                 XDestroyImage( img );
    00230                 return None;
    00231         }
    00232
    00233         XPutImage( dpy,pix,gc,img, 0,0,0,0,width,height );
    00234
    00235         XDestroyImage( img );
    00236
    00237         return pix;
    00238 }
    00239
    00240
    00241
    00242 XImage * ILAPIENTRY ilutXLoadImage( Display * dpy, char * filename )
    00243 {
    00244         iBindImageTemp();
    00245         if (!ilLoadImage(filename)) {
    00246                 return NULL;
    00247         }
    00248         return ilutXCreateImage( dpy );
    00249 }
    00250
    00251
    00252
    00253 Pixmap ILAPIENTRY ilutXLoadPixmap( Display * dpy, Drawable draw, char * filename )
    00254 {
    00255         iBindImageTemp();
    00256         if (!ilLoadImage(filename)) {
    00257                 return None;
    00258         }
    00259         return ilutXCreatePixmap( dpy,draw );
    00260 }
    00261
    00262
    00263
    00264
    00265
    00266
    00267 #ifdef ILUT_USE_XSHM
    00268 #include <sys/ipc.h>
    00269 #include <sys/shm.h>
    00270 #include <X11/extensions/XShm.h>
    00271
    00272
    00273 XImage * ILAPIENTRY ilutXShmCreateImage( Display * dpy, XShmSegmentInfo * info )
    00274 {
    00275         Visual * vis;
    00276         XImage * img;
    00277
    00278         // Get server supported format
    00279
    00280         int size,format = XShmPixmapFormat( dpy );
    00281
    00282         // Grab the current image
    00283
    00284         if (!iXGrabCurrentImage()) {
    00285                 return NULL;
    00286         }
    00287
    00288         // Create a shared image
    00289
    00290         vis = CopyFromParent;
    00291         img = XShmCreateImage( dpy,vis, 24,format,NULL,info,width,height );
    00292
    00293         if (!img) {
    00294                 return NULL;
    00295         }
    00296
    00297         // Create shared memory
    00298
    00299         size = img->bytes_per_line * img->height;
    00300
    00301         info->shmid = shmget( IPC_PRIVATE, size, IPC_CREAT | 0666 );
    00302         info->shmaddr = img->data = shmat( info->shmid, 0, 0 );
    00303         info->readOnly = False;
    00304
    00305         // Attach to server
    00306
    00307         XShmAttach( dpy,info );
    00308
    00309         // Copy image pixels to shared memory
    00310
    00311         iXConvertImage( dpy,img );
    00312
    00313         return img;
    00314 }
    00315
    00316
    00317
    00318 void ILAPIENTRY ilutXShmDestroyImage( Display * dpy, XImage * img, XShmSegmentInfo * info )
    00319 {
    00320         XShmDetach( dpy,info );
    00321         XDestroyImage( img );
    00322         XFlush( dpy );
    00323
    00324         shmdt( info->shmaddr );
    00325         shmctl( info->shmid, IPC_RMID, 0 );
    00326 }
    00327
    00328
    00329
    00330 Pixmap ILAPIENTRY ilutXShmCreatePixmap( Display * dpy, Drawable draw, XShmSegmentInfo * info )
    00331 {
    00332         Pixmap pix;
    00333         XImage*img;
    00334
    00335         // Create a dumby image
    00336
    00337         img = ilutXShmCreateImage( dpy,info );
    00338         if (!img) {
    00339                 return None;
    00340         }
    00341
    00342         // Use the same memory segment in the pixmap
    00343
    00344         pix = XShmCreatePixmap( dpy,draw, info->shmaddr,info,width,height,24 );
    00345         if (!pix) {
    00346                 ilutXShmDestroyImage( dpy,img,info );
    00347                 return None;
    00348         }
    00349
    00350         // Riddance to the image
    00351
    00352         XDestroyImage( img );
    00353
    00354         return pix;
    00355 }
    00356
    00357
    00358
    00359 void ILAPIENTRY ilutXShmFreePixmap( Display * dpy, Pixmap pix, XShmSegmentInfo * info )
    00360 {
    00361         XShmDetach( dpy,info );
    00362         XFreePixmap( dpy,pix );
    00363         XFlush( dpy );
    00364
    00365         shmdt( info->shmaddr );
    00366         shmctl( info->shmid, IPC_RMID, 0 );
    00367 }
    00368
    00369
    00370
    00371 XImage * ILAPIENTRY ilutXShmLoadImage( Display * dpy, char* filename, XShmSegmentInfo * info )
    00372 {
    00373         iBindImageTemp();
    00374         if (!ilLoadImage(filename)) {
    00375                 return NULL;
    00376         }
    00377         return ilutXShmCreateImage( dpy,info );
    00378 }
    00379
    00380
    00381
    00382 Pixmap ILAPIENTRY ilutXShmLoadPixmap( Display * dpy, Drawable draw, char* filename, XShmSegmentInfo * info )
    00383 {
    00384         iBindImageTemp();
    00385         if (!ilLoadImage(filename)) {
    00386                 return None;
    00387         }
    00388         return ilutXShmCreatePixmap( dpy,draw,info );
    00389 }
    00390
    00391
    00392
    00393
    00394
    00395 #endif//ILUT_USE_XSHM
    00396
    00397
    00398 #endif//ILUT_USE_X11
    00399