00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00054 {
00055 throw CL_Error("Cannot use shared memory ximage backbuffer");
00056 }
00057
00058
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
00075 int image_size = get_pitch()*height;
00076
00077 m_shm_image = XShmCreateImage(
00078 dpy,
00079 visual_info.visual,
00080 visual_info.depth,
00081 ZPixmap,
00082 NULL,
00083 &m_shminfo,
00084 width,
00085 height);
00086
00087 cl_assert(m_shm_image != NULL);
00088
00089
00090 m_shminfo.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777);
00091 cl_assert(m_shminfo.shmid >= 0);
00092
00093
00094 m_shminfo.shmaddr = (char *) shmat(m_shminfo.shmid, 0, 0);
00095
00096
00097 cl_shm_oldhandler = XSetErrorHandler(cl_shm_errorhandler);
00098
00099
00100 m_shminfo.readOnly = True;
00101
00102
00103 shmctl(m_shminfo.shmid,IPC_RMID,0);
00104
00105 XShmAttach (dpy, &m_shminfo);
00106
00107
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
00124 XShmDetach (m_dpy, &m_shminfo);
00125
00126
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
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
00219 return 0;
00220 }
00221
00222 CL_Palette *CL_Target_XImage_Shm::get_palette() const
00223 {
00224 return NULL;
00225 }