Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

target_ximage_shm.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: target_ximage_shm.cpp,v 1.1 2001/03/06 15:09:17 mbn Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 */
00014 
00015 #include "Core/precomp.h"
00016 
00017 #include "API/Core/System/cl_assert.h"
00018 #include <API/Core/System/error.h>
00019 #include <API/Display/Display/palette.h>
00020 #include <Display/Display/X11/target_ximage_shm.h>
00021 #include <API/Core/Math/rect.h>
00022 
00023 #include <iostream>
00024 #include <string.h>
00025 
00026 static int (*cl_shm_oldhandler)(Display *, XErrorEvent *);
00027 static bool cl_shm_error = false;
00028 static int cl_shm_errorhandler(Display *disp,XErrorEvent *xev)
00029 {
00030         if (xev->error_code == BadAccess)
00031         {
00032                 cl_shm_error = true;
00033                 return 0;
00034         }
00035         else
00036         {
00037                 return ((*cl_shm_oldhandler)(disp,xev));
00038         }
00039 }
00040 
00041 CL_Target_XImage_Shm::CL_Target_XImage_Shm(
00042         XVisualInfo visual_info,
00043         Display *dpy,
00044         unsigned int width,
00045         unsigned int height)
00046 {
00047         m_visual_info = visual_info;
00048         m_dpy = dpy;
00049         m_width = width;
00050         m_height = height;
00051         
00052         if (XShmQueryExtension(dpy) == False)
00053         // does we have the extension at all?
00054         {
00055                 throw CL_Error("Cannot use shared memory ximage backbuffer");
00056         }
00057         
00058         // Figure out what the depth and pitch is:
00059         int num_formats;
00060         XPixmapFormatValues *formats = XListPixmapFormats(m_dpy, &num_formats);
00061         for (int i=0; i<num_formats; i++)
00062         {
00063                 if (formats[i].depth == m_visual_info.depth)
00064                 {
00065                         m_depth = formats[i].bits_per_pixel;
00066                         m_pitch = (width*m_depth+formats[i].scanline_pad-1)/formats[i].scanline_pad;
00067                         m_pitch *= formats[i].scanline_pad;
00068                         m_pitch = (m_pitch+7)/8;
00069                         break;
00070                 }
00071         }
00072         XFree(formats);
00073 
00074         // Allocate memory:
00075         int image_size = get_pitch()*height;
00076         
00077         m_shm_image = XShmCreateImage(
00078                 dpy,
00079                 visual_info.visual,
00080                 visual_info.depth, // PTC does this: DefaultDepth(dpy,0),
00081                 ZPixmap,
00082                 NULL,
00083                 &m_shminfo,
00084                 width,
00085                 height);
00086         
00087         cl_assert(m_shm_image != NULL);
00088 
00089         // Create shared memory segment:
00090         m_shminfo.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777);
00091         cl_assert(m_shminfo.shmid >= 0);
00092         
00093         // Get memory address to segment:
00094         m_shminfo.shmaddr = (char *) shmat(m_shminfo.shmid, 0, 0);
00095 
00096         // Catch access errors:
00097         cl_shm_oldhandler = XSetErrorHandler(cl_shm_errorhandler);
00098         
00099         // Tell XServer that it may only read from it and attach to display:
00100         m_shminfo.readOnly = True;
00101 
00102         // "Trick" to ensure that if client dies the shared memory segment is removed 
00103         shmctl(m_shminfo.shmid,IPC_RMID,0);
00104 
00105         XShmAttach (dpy, &m_shminfo);
00106 
00107         // Fill the XImage struct:
00108         m_shm_image->data = m_shminfo.shmaddr;
00109 
00110         XSync(m_dpy, 0);
00111         XSetErrorHandler(cl_shm_oldhandler);
00112 
00113         if (cl_shm_error)
00114         {
00115                 throw CL_Error("Cannot use shared memory ximage backbuffer");
00116         }
00117 }
00118                 
00119 CL_Target_XImage_Shm::~CL_Target_XImage_Shm()
00120 {
00121         XDestroyImage(m_shm_image);
00122 
00123         // Detach shm image from display:
00124         XShmDetach (m_dpy, &m_shminfo);
00125         
00126         // Clean up shared memory:
00127         shmdt(m_shminfo.shmaddr);
00128         shmctl(m_shminfo.shmid, IPC_RMID, 0);
00129 }
00130 
00131 void CL_Target_XImage_Shm::put_image(int x, int y, Drawable win, GC gc)
00132 {
00133         XShmPutImage(
00134                 m_dpy,
00135                 win,
00136                 gc,
00137                 m_shm_image,
00138                 0, 0,
00139                 x, y,
00140                 m_width,
00141                 m_height,
00142                 False);
00143 }
00144 
00145 void CL_Target_XImage_Shm::put_image(
00146         int x, int y,
00147         const class CL_Rect &rect,
00148         Drawable win, GC gc)
00149 {
00150         XShmPutImage(
00151                 m_dpy,
00152                 win,
00153                 gc,
00154                 m_shm_image,
00155                 rect.x1, rect.y1,
00156                 x, y,
00157                 rect.x2 - rect.x1,
00158                 rect.y2 - rect.y1,
00159                 False);
00160 }
00161 
00162 void CL_Target_XImage_Shm::lock()
00163 {
00164 //      return true;
00165 }
00166         
00167 void CL_Target_XImage_Shm::unlock()
00168 {
00169 }
00170 
00171 void *CL_Target_XImage_Shm::get_data() const
00172 {
00173         return m_shm_image->data;
00174 }
00175 
00176 unsigned int CL_Target_XImage_Shm::get_width() const
00177 {
00178         return m_width;
00179 }
00180 
00181 bool CL_Target_XImage_Shm::is_indexed() const
00182 {
00183         return false;
00184 }
00185 
00186 unsigned int CL_Target_XImage_Shm::get_height() const
00187 {
00188         return m_height;
00189 }
00190 
00191 unsigned int CL_Target_XImage_Shm::get_pitch() const
00192 {
00193         return m_pitch;
00194 }
00195         
00196 unsigned int CL_Target_XImage_Shm::get_depth() const
00197 {
00198         return m_depth;
00199 }
00200 
00201 unsigned int CL_Target_XImage_Shm::get_red_mask() const
00202 {
00203         return m_visual_info.red_mask;
00204 }
00205 
00206 unsigned int CL_Target_XImage_Shm::get_green_mask() const
00207 {
00208         return m_visual_info.green_mask;
00209 }
00210 
00211 unsigned int CL_Target_XImage_Shm::get_blue_mask() const
00212 {
00213         return m_visual_info.blue_mask;
00214 }
00215 
00216 unsigned int CL_Target_XImage_Shm::get_alpha_mask() const
00217 {
00218 //      return m_visual_info.alpha_mask; // no alpha mask in visualinfo struct!?
00219         return 0;
00220 }
00221 
00222 CL_Palette *CL_Target_XImage_Shm::get_palette() const
00223 {
00224         return NULL;
00225 }

Generated at Wed Apr 4 19:54:04 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001