Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members
X11Renderer.cpp
00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: X11Renderer.cpp * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * $Id: X11Renderer.cpp,v 1.12 2006/01/20 15:37:18 mkropfbe Exp $ 00041 * * 00042 ***********************************************************************/ 00043 00044 #ifndef WIN32 00045 00046 #include "global.hpp" 00047 #include "IO.hpp" 00048 #include "Frame.hpp" 00049 #include "X11Renderer.hpp" 00050 #include "X11FrameBuffer.hpp" 00051 #include "VideoRenderer.hpp" 00052 00053 00054 X11Renderer::X11Renderer(const VideoESInfo *_es, UncompressedVideoFrame::ColorSpace colorSpace, 00055 int width, int height, bool pollEvents, 00056 bool isLabelResizable, bool fixAspectRatio, bool allowUpscaleX) 00057 : VideoRenderer(_es, colorSpace, width, height, isLabelResizable, fixAspectRatio, allowUpscaleX) 00058 { 00059 dprintf_full("X11Renderer Construct %s ES %p\n",this->url, this->es); 00060 strcpy(this->url,"X11Renderer"); 00061 this->pollEvents = pollEvents; 00062 } 00063 00064 X11Renderer::~X11Renderer() 00065 { 00066 showCursor(display,xwin); 00067 00068 XDestroyWindow(display,xwin); 00069 XCloseDisplay(display); 00070 } 00071 00072 bool X11Renderer::updateDisplayRegion() { 00073 00074 if (!es || !es->isVisualStream()) { 00075 dprintf_err("X11Renderer::updateDisplayRegion(): invalid members: es = %p\n",es); 00076 ::exit(1); 00077 return false; 00078 } 00079 00080 return VideoRenderer::updateDisplayRegion(); 00081 } 00082 00083 00084 void X11Renderer::hideCursor(Display * disp, Window win) 00085 { 00086 Cursor no_ptr; 00087 Pixmap bm_no; 00088 XColor black, dummy; 00089 Colormap colormap; 00090 static char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 00091 00092 00093 colormap = DefaultColormap(disp, DefaultScreen(disp)); 00094 XAllocNamedColor(disp, colormap, "black", &black, &dummy); 00095 bm_no = XCreateBitmapFromData(disp, win, bm_no_data, 8, 8); 00096 no_ptr = XCreatePixmapCursor(disp, bm_no, bm_no, &black, &black, 0, 0); 00097 XDefineCursor(disp, win, no_ptr); 00098 XFreeCursor(disp, no_ptr); 00099 if (bm_no != None) 00100 XFreePixmap(disp, bm_no); 00101 XFreeColors(disp,colormap,&black.pixel,1,0); 00102 } 00103 00104 void X11Renderer::showCursor(Display * disp, Window win) 00105 { 00106 XDefineCursor(disp, win, 0); 00107 } 00108 00109 00110 bool X11Renderer::open() 00111 { 00112 if (state != CLOSED) { 00113 dprintf_err("X11Renderer::open state was not CLOSED but state=%i!\n",state); 00114 return false; 00115 } 00116 00117 if (!updateDisplayRegion()) { 00118 state = STREAMERR; 00119 return false; 00120 } 00121 00122 char hostname[MAX_STR_LEN]; 00123 char *envhost = getenv("DISPLAY"); 00124 if (!envhost) 00125 strcpy(hostname,"localhost:0"); 00126 else 00127 strcpy(hostname,envhost); 00128 00129 display = XOpenDisplay(hostname); 00130 assert(display); 00131 screennr = XDefaultScreen(display); 00132 screen = XDefaultScreenOfDisplay(display); 00133 depth = XDefaultDepth(display,screennr); 00134 winAttrib.background_pixel = BlackPixel(display, screennr); 00135 winAttrib.border_pixel = BlackPixel(display, screennr); 00136 winAttrib.backing_store = Always; 00137 winAttrib.bit_gravity = StaticGravity; 00138 XVisualInfo visual_info; 00139 Visual *def_visual = XDefaultVisual(display,screennr); 00140 unsigned int attr_val = CWBackingStore | CWBackPixel | CWBorderPixel; 00141 int visualClass = -1; 00142 00143 setOutputDepth(depth); 00144 00145 /* FIXME: only tested for DirectColor on 16/24 bit X11 display! */ 00146 if (!XMatchVisualInfo(display, screennr, depth, PseudoColor, &visual_info)) { 00147 if (!XMatchVisualInfo(display, screennr, depth, DirectColor, &visual_info)) { 00148 /* No PseudoColor visual available at default_depth; 00149 * some applications might try for a GrayScale 00150 * visual here if they can use gray to advantage, 00151 * before giving up and using black and white */ 00152 dprintf_err("X11Renderer::open() could not find PseudoColor or DirectColor visual!\n"); 00153 ::exit(0); 00154 } else 00155 visualClass = DirectColor; 00156 } else 00157 visualClass = PseudoColor; 00158 00159 dprintf_full("X11Renderer:open outputDepth %i, defaultVisual %p, pseudo/directColor visualID 0x%x\n", 00160 depth, def_visual, (int)visual_info.visualid); 00161 00162 00163 00164 00165 if (visualClass != DirectColor) 00166 XCreateColormap(display, RootWindowOfScreen(screen), visual_info.visual, AllocNone); 00167 else { 00168 XColor cols[256]; 00169 unsigned int cm_size, red_mask, green_mask, blue_mask; 00170 unsigned int k, r, g, b, ru, gu, bu, m, rv, gv, bv, rvu, gvu, bvu; 00171 cm_size = visual_info.colormap_size; 00172 red_mask = visual_info.red_mask; 00173 green_mask = visual_info.green_mask; 00174 blue_mask = visual_info.blue_mask; 00175 ru = (red_mask & (red_mask - 1)) ^ red_mask; 00176 gu = (green_mask & (green_mask - 1)) ^ green_mask; 00177 bu = (blue_mask & (blue_mask - 1)) ^ blue_mask; 00178 rvu = 65536ull * ru / (red_mask + ru); 00179 gvu = 65536ull * gu / (green_mask + gu); 00180 bvu = 65536ull * bu / (blue_mask + bu); 00181 r = g = b = 0; 00182 rv = gv = bv = 0; 00183 m = DoRed | DoGreen | DoBlue; 00184 for (k = 0; k < cm_size; k++) { 00185 unsigned int t; 00186 00187 cols[k].pixel = r | g | b; 00188 cols[k].red = rv; 00189 cols[k].green = gv; 00190 cols[k].blue = bv; 00191 cols[k].flags = m; 00192 t = (r + ru) & red_mask; 00193 if (t < r) 00194 m &= ~DoRed; 00195 r = t; 00196 t = (g + gu) & green_mask; 00197 if (t < g) 00198 m &= ~DoGreen; 00199 g = t; 00200 t = (b + bu) & blue_mask; 00201 if (t < b) 00202 m &= ~DoBlue; 00203 b = t; 00204 rv += rvu; 00205 gv += gvu; 00206 bv += bvu; 00207 } 00208 winAttrib.colormap = XCreateColormap(display, RootWindowOfScreen(screen), visual_info.visual, AllocAll); 00209 XStoreColors(display, winAttrib.colormap, cols, cm_size); 00210 } 00211 00212 XInstallColormap(display, winAttrib.colormap); // put cm into hardware! 00213 00214 attr_val |= CWColormap; 00215 00216 xwin=XCreateWindow(display, XRootWindow(display,screennr) 00217 ,0, 0, out_label_info.width, out_label_info.height, 1 00218 ,depth, InputOutput, 00219 visual_info.visual 00220 //def_visual 00221 , attr_val, &winAttrib); 00222 00223 XStoreName(display, xwin, "ViTooKi X11Renderer"); 00224 XSetIconName(display, xwin, "ViTooKi X11Renderer"); 00225 XSetWindowBackground(display, xwin, 0xFFFFFF); 00226 XMapWindow(display, xwin); 00227 XSync(display, 0); 00228 00229 hideCursor(display,xwin); 00230 00231 /* initialize frameBuffer */ 00232 if (frameBuffer) { 00233 delete frameBuffer; 00234 frameBuffer = NULL; 00235 } 00236 00237 bool gray = false; 00238 switch (colorSpace) { 00239 case UncompressedVideoFrame::ColorSpaceGRAY8: 00240 dprintf_full("X11Renderer::open() ColorSpaceGRAY8\n"); 00241 gray=true; 00242 frame_info.size = frame_info.width * frame_info.height; 00243 break; 00244 case UncompressedVideoFrame::ColorSpaceRGB24: 00245 dprintf_full("X11Renderer::open() ColorSpaceRGB24\n"); 00246 frame_info.size = frame_info.width * frame_info.height * 3; 00247 break; 00248 case UncompressedVideoFrame::ColorSpaceRGB32: 00249 dprintf_full("X11Renderer::open() ColorSpaceRGB32\n"); 00250 frame_info.size = frame_info.width * frame_info.height * 4; 00251 break; 00252 case UncompressedVideoFrame::ColorSpaceRGB565: 00253 dprintf_full("X11Renderer::open() ColorSpaceRGB565\n"); 00254 frame_info.size = frame_info.width * frame_info.height * 2; 00255 break; 00256 case UncompressedVideoFrame::ColorSpaceYV12: 00257 case UncompressedVideoFrame::ColorSpaceI420: 00258 dprintf_err("X11Renderer::open() ColorSpaceYV12 or I420 NOT SUPPORTED on X11!!!\n"); 00259 ::exit(1); 00260 break; 00261 default: 00262 dprintf_err("X11Renderer::open(): invalid color space: %d\n", colorSpace); 00263 state = STREAMERR; 00264 return false; 00265 } 00266 00267 if ( (depth == 16) && //FIXME: sorry, but 24 bitBlt does not seem to work... 32bit is untested 00268 (depth == UncompressedVideoFrame::mapColorSpaceToBitDepth(colorSpace) ) && 00269 (out_label_info.width == frame_info.width) && (out_label_info.height == frame_info.height) && 00270 (display_region.left == 0) && (display_region.top == 0) ) 00271 directBitBlt=true; //optimize via rgbSurface bitBlitting 00272 else 00273 directBitBlt=false; //use slow pixel-per-pixel painting and scaling 00274 00275 00276 frameBuffer = new X11FrameBuffer(display, &xwin, depth, gray, display_region.width, display_region.height ); 00277 00278 if (!frameBuffer) { 00279 dprintf_err("X11Renderer::open(): X11FrameBuffer creation FAILED! (w = %d, h = %d)\n", 00280 display_region.width, display_region.height ); 00281 state = STREAMERR; 00282 return false; 00283 } 00284 00285 state = OPEN; 00286 framesSeen = 0; 00287 currentFrameNumber = 0; 00288 dprintf_small("X11Renderer::open(): initialized frame and display regions:\n" 00289 " frame: width = %d, height = %d, size = %d, scaleX = %5.3f, scaleY = %5.3f\n" 00290 " display: x(%d:%d), y(%d:%d), width = %d, height = %d\n", 00291 frame_info.width, frame_info.height, frame_info.size, 00292 FIXED2DOUBLE(frame_info.scaleX), FIXED2DOUBLE(frame_info.scaleY), 00293 display_region.left, display_region.left + display_region.width, 00294 display_region.top, display_region.top + display_region.height, 00295 display_region.width, display_region.height); 00296 return true; 00297 } 00298 00299 00300 int X11Renderer::writeFrame(Frame * frm, ESInfo *out_es) { 00301 return VideoRenderer::writeFrame(frm, out_es); 00302 00303 } 00304 00305 #endif /* WIN32 */ 00306