Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsfblayer.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include "mmsgui/fb/mmsfblayer.h"
00034 #include "mmsgui/fb/mmsfb.h"
00035 #include <string.h>
00036 #include <cerrno>
00037 
00038 #ifdef __HAVE_XLIB__
00039 #include <sys/shm.h>
00040 #endif
00041 
00042 
00043 #ifdef  __HAVE_DIRECTFB__
00044 D_DEBUG_DOMAIN( MMS_Layer, "MMS/Layer", "MMS Layer" );
00045 #endif
00046 
00047 #ifdef __HAVE_XLIB__
00048 #define GUID_YUV12_PLANAR ('2'<<24)|('1'<<16)|('V'<<8)|'Y')
00049 #include <X11/Xatom.h>
00050 #endif
00051 
00052 #include <unistd.h>
00053 #include <stdlib.h>
00054 
00055 // static variables
00056 bool MMSFBLayer::firsttime_createsurface        = true;
00057 bool MMSFBLayer::firsttime_createwindow_usealpha= true;
00058 bool MMSFBLayer::firsttime_createwindow_noalpha = true;
00059 
00060 
00061 #define INITCHECK  if(!this->initialized){MMSFB_SetError(0,"not initialized");return false;}
00062 
00063 
00064 MMSFBLayer::MMSFBLayer(int id, MMSFBBackend backend, MMSFBOutputType outputtype) {
00065     // init me
00066     this->initialized = false;
00067     this->surface = NULL;
00068     this->flipflags = MMSFB_FLIP_NONE;
00069     this->config.avail = false;
00070     this->config.id = id;
00071     this->config.backend = backend;
00072     this->config.outputtype = outputtype;
00073     this->config.window_pixelformat = MMSFB_PF_ARGB;
00074     this->config.surface_pixelformat = MMSFB_PF_ARGB;
00075 
00076 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
00077     this->mmsfbdev_surface = NULL;
00078 #endif
00079 
00080 #ifdef __HAVE_XLIB__
00081     this->x_image1 = NULL;
00082     this->x_image2 = NULL;
00083     this->x_image_scaler = NULL;
00084     this->scaler = NULL;
00085 #endif
00086 #ifdef __HAVE_XV__
00087     this->xv_image1 = NULL;
00088     this->xv_image2 = NULL;
00089 #endif
00090 
00091     if (this->config.backend == MMSFB_BE_DFB) {
00092 #ifdef  __HAVE_DIRECTFB__
00093         // get the layer
00094         DFBResult   dfbres;
00095         this->dfblayer = NULL;
00096         if ((dfbres = mmsfb->dfb->GetDisplayLayer(mmsfb->dfb, this->config.id, &this->dfblayer)) != DFB_OK) {
00097             this->dfblayer = NULL;
00098             MMSFB_SetError(dfbres, "IDirectFB::GetDisplayLayer(" + iToStr(id) + ") failed");
00099             return;
00100         }
00101         this->initialized = true;
00102 #endif
00103     }
00104     else
00105     if (this->config.backend == MMSFB_BE_FBDEV) {
00106 #ifdef __HAVE_FBDEV__
00107         if (mmsfb->mmsfbdev) {
00108             // test layer initialization
00109             if (!mmsfb->mmsfbdev->testLayer(this->config.id)) {
00110                 MMSFB_SetError(0, "init test of layer " + iToStr(this->config.id) + " failed!");
00111                 return;
00112             }
00113 
00114             if (this->config.outputtype == MMSFB_OT_OGL) {
00115                 // check layer 0
00116                 if (this->config.id != 0) {
00117                     MMSFB_SetError(0, "OPENGL support needs layer 0!");
00118                     return;
00119                 }
00120             }
00121 
00122             this->initialized = true;
00123         }
00124 #endif
00125     }
00126     if (this->config.backend == MMSFB_BE_KMS) {
00127 #ifdef __HAVE_KMS__
00128         if (mmsfb->mmskms) {
00129             // test layer initialization
00130             if (!mmsfb->mmskms->testLayer(this->config.id)) {
00131                 MMSFB_SetError(0, "init test of layer " + iToStr(this->config.id) + " failed!");
00132                 return;
00133             }
00134 
00135             if (this->config.outputtype == MMSFB_OT_OGL) {
00136                 // check layer 0
00137                 if (this->config.id != 0) {
00138                     MMSFB_SetError(0, "OPENGL support needs layer 0!");
00139                     return;
00140                 }
00141             }
00142 
00143             this->initialized = true;
00144         }
00145 #endif
00146     }
00147     else
00148     if (this->config.backend == MMSFB_BE_X11) {
00149 #ifdef __HAVE_XLIB__
00150 
00151         // fill my config partly from mmsfb
00152         this->config.w = mmsfb->x11_win_rect.w;
00153         this->config.h = mmsfb->x11_win_rect.h;
00154         this->config.pixelformat = MMSFB_PF_NONE;
00155         this->config.buffermode = MMSFB_BM_BACKSYSTEM;
00156         this->config.options = MMSFB_LO_NONE;
00157         if (this->config.outputtype == MMSFB_OT_XSHM) {
00158             // XSHM
00159             switch (mmsfb->x_depth) {
00160             case 16:
00161                 this->config.pixelformat = MMSFB_PF_RGB16;
00162                 break;
00163             case 24:
00164                 this->config.pixelformat = MMSFB_PF_RGB24;
00165                 break;
00166             case 32:
00167                 this->config.pixelformat = MMSFB_PF_RGB32;
00168                 break;
00169             }
00170 
00171             this->initialized = true;
00172         }
00173         else
00174         if (this->config.outputtype == MMSFB_OT_XVSHM) {
00175             // XVSHM
00176             this->config.pixelformat = MMSFB_PF_YV12;
00177 
00178             this->initialized = true;
00179         }
00180         else
00181         if (this->config.outputtype == MMSFB_OT_OGL) {
00182             // OPENGL, check layer 0
00183             if (this->config.id != 0) {
00184                 MMSFB_SetError(0, "OPENGL support needs layer 0!");
00185                 return;
00186             }
00187 
00188             // fill my config partly from mmsfb
00189             this->config.w = mmsfb->x11_win_rect.w;
00190             this->config.h = mmsfb->x11_win_rect.h;
00191             this->config.pixelformat = MMSFB_PF_ARGB;
00192             this->config.buffermode = MMSFB_BM_BACKSYSTEM;
00193             this->config.options = MMSFB_LO_NONE;
00194 
00195             this->initialized = true;
00196         }
00197 #endif
00198     }
00199 
00200     // get the current config
00201     if (this->initialized) {
00202         MMSFBLayerConfig config;
00203         getConfiguration(&config);
00204     }
00205 }
00206 
00207 
00208 MMSFBLayer::~MMSFBLayer() {
00209     if (this->config.backend == MMSFB_BE_DFB) {
00210 #ifdef  __HAVE_DIRECTFB__
00211         if (this->dfblayer)
00212             this->dfblayer->Release(this->dfblayer);
00213 #endif
00214     }
00215     else
00216     if ((this->config.backend == MMSFB_BE_FBDEV) || (this->config.backend == MMSFB_BE_KMS)) {
00217 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
00218         if (this->mmsfbdev_surface)
00219             delete this->mmsfbdev_surface;
00220 #endif
00221     }
00222     else {
00223 #ifdef __HAVE_XLIB__
00224         if (this->config.outputtype == MMSFB_OT_XSHM) {
00225             // XSHM
00226             if (this->x_image1)
00227                 XFree(this->x_image1);
00228             if (this->x_image2)
00229                 XFree(this->x_image2);
00230         }
00231         else {
00232 #ifdef __HAVE_XV__
00233             // XVSHM
00234             if (this->xv_image1)
00235                 XFree(this->xv_image1);
00236             if (this->xv_image2)
00237                 XFree(this->xv_image2);
00238 #endif
00239         }
00240 #endif
00241     }
00242 }
00243 
00244 bool MMSFBLayer::isInitialized() {
00245     if (this->config.backend == MMSFB_BE_DFB) {
00246 #ifdef  __HAVE_DIRECTFB__
00247         return (this->dfblayer != NULL);
00248 #endif
00249     }
00250     else {
00251         return this->initialized;
00252     }
00253 
00254     return false;
00255 }
00256 
00257 bool MMSFBLayer::getID(int *id) {
00258 
00259     // check if initialized
00260     INITCHECK;
00261 
00262     // get configuration
00263     MMSFBLayerConfig config;
00264     if (!getConfiguration(&config))
00265         return false;
00266 
00267     // fill return values
00268     *id = this->config.id;
00269 
00270     return true;
00271 }
00272 
00273 bool MMSFBLayer::setExclusiveAccess() {
00274 
00275     // check if initialized
00276     INITCHECK;
00277 
00278     if (this->config.backend == MMSFB_BE_DFB) {
00279 #ifdef  __HAVE_DIRECTFB__
00280         DFBResult   dfbres;
00281 
00282         /* set cooperative level to exclusive */
00283         if ((dfbres=this->dfblayer->SetCooperativeLevel(this->dfblayer, DLSCL_EXCLUSIVE)) != DFB_OK) {
00284             MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetCooperativeLevel(DLSCL_EXCLUSIVE) failed");
00285             return false;
00286         }
00287 
00288         return true;
00289 #endif
00290     }
00291     else {
00292         return true;
00293     }
00294 
00295     return false;
00296 }
00297 
00298 bool MMSFBLayer::getConfiguration(MMSFBLayerConfig *config) {
00299 
00300     // check if initialized
00301     INITCHECK;
00302 
00303     if (this->config.avail) {
00304         // fill return config
00305         if (config)
00306             *config = this->config;
00307         return true;
00308     }
00309 
00310     if (this->config.backend == MMSFB_BE_DFB) {
00311 #ifdef  __HAVE_DIRECTFB__
00312         DFBResult               dfbres;
00313         DFBDisplayLayerConfig   dlc;
00314 
00315         /* get configuration */
00316         if ((dfbres=this->dfblayer->GetConfiguration(this->dfblayer, &dlc)) != DFB_OK) {
00317             MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::GetConfiguration() failed");
00318             return false;
00319         }
00320 
00321         // fill my config
00322         this->config.avail = true;
00323         this->config.w = dlc.width;
00324         this->config.h = dlc.height;
00325         this->config.pixelformat = getMMSFBPixelFormatFromDFBPixelFormat(dlc.pixelformat);
00326         this->config.buffermode = getDFBLayerBufferModeString(dlc.buffermode);
00327         this->config.options = getDFBLayerOptionsString(dlc.options);
00328 
00329 #endif
00330     }
00331     else {
00332         this->config.avail = true;
00333     }
00334 
00335     if (!config) {
00336         DEBUGMSG("MMSGUI", "Layer properties:");
00337 
00338 /*        if (mmsfb->backend == MMSFB_BE_DFB) {
00339 #ifdef  __HAVE_DIRECTFB__
00340             DEBUGMSG("MMSGUI", " backend:     DFB");
00341 #endif
00342         }
00343         else
00344         if (mmsfb->backend == MMSFB_BACKEND_FBDEV) {
00345 #ifdef __HAVE_FBDEV__
00346             DEBUGMSG("MMSGUI", " backend:     FBDEV");
00347 #endif
00348         }
00349         else {
00350 #ifdef __HAVE_XLIB__
00351             if (mmsfb->outputtype == MMS_OT_XSHM) {
00352                 // XSHM
00353 
00354                 DEBUGMSG("MMSGUI", " backend:     XSHM");
00355             }
00356             else {
00357                 // XVSHM
00358 
00359                 DEBUGMSG("MMSGUI", " backend:     XVSHM");
00360             }
00361 #endif
00362         }
00363 */
00364 
00365         DEBUGMSG("MMSGUI", " backend:     " + getMMSFBBackendString(this->config.backend));
00366         DEBUGMSG("MMSGUI", " outputtype:  " + getMMSFBOutputTypeString(this->config.outputtype));
00367 
00368         DEBUGMSG("MMSGUI", " size:        " + iToStr(this->config.w) + "x" + iToStr(this->config.h));
00369 
00370         DEBUGMSG("MMSGUI", " pixelformat: " + getMMSFBPixelFormatString(this->config.pixelformat));
00371 
00372         if (this->config.buffermode!="")
00373             DEBUGMSG("MMSGUI", " buffermode:  " + this->config.buffermode);
00374         else
00375             DEBUGMSG("MMSGUI", " buffermode:  NONE");
00376 
00377         if (this->config.options!="")
00378             DEBUGMSG("MMSGUI", " options:     " + this->config.options);
00379         else
00380             DEBUGMSG("MMSGUI", " options:     NONE");
00381     }
00382 
00383     // fill return config
00384     if (config)
00385         *config = this->config;
00386 
00387     return true;
00388 }
00389 
00390 bool MMSFBLayer::getResolution(int *w, int *h) {
00391 
00392     // check if initialized
00393     INITCHECK;
00394 
00395     /* get configuration */
00396     MMSFBLayerConfig config;
00397     if (!getConfiguration(&config))
00398         return false;
00399 
00400     /* fill return values */
00401     *w = this->config.w;
00402     *h = this->config.h;
00403 
00404     return true;
00405 }
00406 
00407 bool MMSFBLayer::getPixelFormat(MMSFBSurfacePixelFormat *pixelformat) {
00408 
00409     // check if initialized
00410     INITCHECK;
00411 
00412     /* get configuration */
00413     MMSFBLayerConfig config;
00414     if (!getConfiguration(&config))
00415         return false;
00416 
00417     /* fill return values */
00418     *pixelformat = this->config.pixelformat;
00419 
00420     return true;
00421 }
00422 
00423 bool MMSFBLayer::setConfiguration(int w, int h, MMSFBSurfacePixelFormat pixelformat, string buffermode, string options,
00424                                   MMSFBSurfacePixelFormat window_pixelformat, MMSFBSurfacePixelFormat surface_pixelformat) {
00425 
00426     // check if initialized
00427     INITCHECK;
00428     if (this->config.backend == MMSFB_BE_DFB) {
00429 #ifdef  __HAVE_DIRECTFB__
00430         // get configuration
00431         MMSFBLayerConfig config;
00432         if (!getConfiguration(&config))
00433             return false;
00434 
00435         // change the config of the layer only, if the attributes are changed
00436         if (config.w != w || config.h != h || config.pixelformat != pixelformat || config.buffermode != buffermode) {
00437             // change config data
00438             DFBResult dfbres;
00439             DFBDisplayLayerConfig dlc;
00440             dlc.flags = DLCONF_NONE;
00441             dlc.width = w;
00442             dlc.height = h;
00443             dlc.pixelformat = getDFBPixelFormatFromMMSFBPixelFormat(pixelformat);
00444             dlc.buffermode = getDFBLayerBufferModeFromString(buffermode);
00445             dlc.options = getDFBLayerOptionsFromString(options);
00446 
00447             if (dlc.width > 0)
00448                 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_WIDTH);
00449             if (dlc.height > 0)
00450                 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_HEIGHT);
00451             if (dlc.pixelformat != DSPF_UNKNOWN)
00452                 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_PIXELFORMAT);
00453             if (dlc.buffermode != DLBM_UNKNOWN)
00454                 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_BUFFERMODE);
00455           //  if (dlc.options != DLOP_NONE) {
00456                 DEBUGOUT("\nSET OPTIONS 0x%08x!!!!\n", dlc.options);
00457                 dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags | DLCONF_OPTIONS);
00458           //  }
00459 
00460             // test configuration
00461             DFBDisplayLayerConfigFlags failedFlags;
00462             if ((dfbres=this->dfblayer->TestConfiguration(this->dfblayer, &dlc, &failedFlags)) != DFB_OK) {
00463                 if(failedFlags & DLCONF_PIXELFORMAT) {
00464                     MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::TestConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00465                     DEBUGMSG("MMSGUI", "Your configuration contains a pixelformat that is not supported.");
00466                     return false;
00467                 }
00468                 if(failedFlags & DLCONF_BUFFERMODE) {
00469                     MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::TestConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00470                     DEBUGMSG("MMSGUI", "Your configuration contains a buffermode that is not supported.");
00471                     return false;
00472                 }
00473                 if(failedFlags & DLCONF_OPTIONS) {
00474                     MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::TestConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00475                     DEBUGMSG("MMSGUI", "Your configuration contains options that are not supported.");
00476                     return false;
00477                 }
00478 
00479                 /* check if desired resolution is unsupported */
00480                 if(failedFlags & DLCONF_WIDTH)
00481                     dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags & ~DLCONF_WIDTH);
00482                 if(failedFlags & DLCONF_HEIGHT)
00483                     dlc.flags = (DFBDisplayLayerConfigFlags)(dlc.flags & ~DLCONF_HEIGHT);
00484                 if ((dfbres=this->dfblayer->TestConfiguration(this->dfblayer, &dlc, &failedFlags)) != DFB_OK) {
00485                     MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::TestConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00486                     return false;
00487                 }
00488                 DEBUGMSG("MMSGUI", "Your configuration contains a resolution that is not supported.");
00489             }
00490 
00491             // set configuration
00492             if((dfbres = this->dfblayer->SetConfiguration(this->dfblayer, &dlc)) != DFB_OK) {
00493                 MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetConfiguration(" + iToStr(w) + "x" + iToStr(h) + "," + getMMSFBPixelFormatString(pixelformat) + "," + buffermode + "," + options + ") failed");
00494                 return false;
00495             }
00496         }
00497 
00498         // get configuration
00499         this->config.avail = false;
00500         if (!getConfiguration())
00501             return false;
00502 
00503         // set background
00504         this->dfblayer->SetBackgroundMode(this->dfblayer, DLBM_COLOR);
00505         this->dfblayer->SetBackgroundColor(this->dfblayer, 0, 0, 0, 0);
00506 
00507         // set special config
00508         this->config.window_pixelformat = window_pixelformat;
00509         this->config.surface_pixelformat = surface_pixelformat;
00510 
00511         return true;
00512 #endif
00513     }
00514     else
00515     if (this->config.backend == MMSFB_BE_FBDEV) {
00516 #ifdef __HAVE_FBDEV__
00517         if (!mmsfb->mmsfbdev)
00518             return false;
00519 
00520         // initializing layer
00521         if (!mmsfb->mmsfbdev->initLayer(this->config.id, w, h, pixelformat,
00522             (buffermode == MMSFB_BM_BACKVIDEO)?1:(buffermode == MMSFB_BM_TRIPLE)?2:0)) {
00523             MMSFB_SetError(0, "init layer " + iToStr(this->config.id) + " failed!");
00524             return false;
00525         }
00526 
00527         // get fb memory ptr
00528         MMSFBSurfacePlanesBuffer buffers;
00529         memset(&buffers, 0, sizeof(buffers));
00530         if (!mmsfb->mmsfbdev->getFrameBufferPtr(this->config.id, buffers, &this->config.w, &this->config.h)) {
00531             MMSFB_SetError(0, "getFrameBufferPtr() failed");
00532             return false;
00533         }
00534         mmsfb->mmsfbdev->getPixelFormat(this->config.id, &this->config.pixelformat);
00535         this->config.buffermode = buffermode;
00536         this->config.options = MMSFB_LO_NONE;
00537 
00538         // create a new surface instance for the framebuffer memory
00539         this->mmsfbdev_surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat,
00540                                                   MMSFB_MAX_SURFACE_PLANES_BUFFERS - 1, buffers);
00541         if (!this->mmsfbdev_surface) {
00542             MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
00543             return false;
00544         }
00545 
00546         if (this->config.outputtype == MMSFB_OT_OGL) {
00547             // we must switch extended accel off
00548             this->mmsfbdev_surface->setExtendedAcceleration(false);
00549         }
00550         else {
00551             // we must switch extended accel on
00552             this->mmsfbdev_surface->setExtendedAcceleration(true);
00553         }
00554 
00555         // mark this surface as a layer surface
00556         this->mmsfbdev_surface->setLayerSurface();
00557 
00558         if (this->config.outputtype == MMSFB_OT_OGL) {
00559 #ifdef __HAVE_OPENGL__
00560 #ifdef __HAVE_EGL__
00561             // initialize the backend interface server
00562             mmsfb->bei->init();
00563 #endif
00564 #endif
00565         }
00566 
00567         // get configuration
00568         this->config.avail = false;
00569         if (!getConfiguration()) {
00570             printf("getconfiguration failed!");
00571             return false;
00572         }
00573 
00574 
00575         // set special config
00576         this->config.window_pixelformat = window_pixelformat;
00577         this->config.surface_pixelformat = surface_pixelformat;
00578 
00579 
00580         return true;
00581 #endif
00582     }
00583     else
00584     if (this->config.backend == MMSFB_BE_KMS) {
00585 #ifdef __HAVE_KMS__
00586         if (!mmsfb->mmskms)
00587             return false;
00588 
00589         // initializing layer
00590         if (!mmsfb->mmskms->initLayer(this->config.id, w, h, pixelformat,
00591             (buffermode == MMSFB_BM_BACKVIDEO)?1:(buffermode == MMSFB_BM_TRIPLE)?2:0)) {
00592             MMSFB_SetError(0, "init layer " + iToStr(this->config.id) + " failed!");
00593             return false;
00594         }
00595 
00596         // get fb memory ptr
00597         MMSFBSurfacePlanesBuffer buffers;
00598         memset(&buffers, 0, sizeof(buffers));
00599         if (!mmsfb->mmskms->getFrameBufferPtr(this->config.id, buffers, &this->config.w, &this->config.h)) {
00600             MMSFB_SetError(0, "getFrameBufferPtr() failed");
00601             return false;
00602         }
00603         mmsfb->mmskms->getPixelFormat(this->config.id, &this->config.pixelformat);
00604         this->config.buffermode = buffermode;
00605         this->config.options = MMSFB_LO_NONE;
00606 
00607         // create a new surface instance for the framebuffer memory
00608         this->mmsfbdev_surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat,
00609                                                   MMSFB_MAX_SURFACE_PLANES_BUFFERS - 1, buffers);
00610         if (!this->mmsfbdev_surface) {
00611             MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
00612             return false;
00613         }
00614 
00615         if (this->config.outputtype == MMSFB_OT_OGL) {
00616             // we must switch extended accel off
00617             this->mmsfbdev_surface->setExtendedAcceleration(false);
00618         }
00619         else {
00620             // we must switch extended accel on
00621             this->mmsfbdev_surface->setExtendedAcceleration(true);
00622         }
00623 
00624         // mark this surface as a layer surface
00625         this->mmsfbdev_surface->setLayerSurface();
00626 
00627         if (this->config.outputtype == MMSFB_OT_OGL) {
00628 #ifdef __HAVE_OPENGL__
00629 #ifdef __HAVE_EGL__
00630             // initialize the backend interface server
00631             mmsfb->bei->init();
00632 #endif
00633 #endif
00634         }
00635 
00636         // get configuration
00637         this->config.avail = false;
00638         if (!getConfiguration()) {
00639             printf("getconfiguration failed!");
00640             return false;
00641         }
00642 
00643 
00644         // set special config
00645         this->config.window_pixelformat = window_pixelformat;
00646         this->config.surface_pixelformat = surface_pixelformat;
00647 
00648 
00649         return true;
00650 #endif
00651     }
00652     else {
00653 #ifdef __HAVE_XLIB__
00654         // get configuration
00655         this->config.avail = false;
00656         if (!getConfiguration())
00657             return false;
00658         printf("setConfiguration called for id: %d\n", this->config.id);
00659 
00660         // if we use XLIB, currently we cannot change the layer attributes
00661         this->config.window_pixelformat = window_pixelformat;
00662         this->config.surface_pixelformat = surface_pixelformat;
00663         this->config.pixelformat = pixelformat;
00664 
00665         XLockDisplay(mmsfb->x_display);
00666 
00667         Colormap colormap;
00668         Window root = RootWindow(mmsfb->x_display, mmsfb->x_screen);
00669 
00670 
00671 
00672 
00673 
00674         if(config.pixelformat == MMSFB_PF_ARGB) {
00675 //TODO: change the ifdef, what to do if XRenderComposite not available?
00676 #ifdef __HAVE_XV__
00677             //check the composite extension
00678             int major, minor;
00679             if (!XCompositeQueryVersion(mmsfb->x_display,&major, &minor)) {
00680                     printf("No Composite extension available, and ARGB is requested for Window Pixelformat\n");
00681                     return false;
00682             } else {
00683                 printf("Composite: %d.%d\n", major, minor);
00684             }
00685 
00686             //go for rgba visual
00687             if (!XRenderQueryVersion(mmsfb->x_display, &major, &minor)) {
00688                 printf("no render extension available, just go for rgba visual \n");
00689                 return false;
00690             } else {
00691                 printf("render extension: %d.%d\n", major, minor);
00692 
00693                 //get rgba picture
00694                 /* lookup a ARGB picture format */
00695                 pict_format = NULL;
00696                 XRenderPictFormat *pict_visualformat = NULL;
00697                 XRenderPictFormat pf;
00698                 XVisualInfo xvinfo_template;
00699                 XVisualInfo *xvinfos;
00700 
00701                 pict_format = XRenderFindStandardFormat(mmsfb->x_display, PictStandardARGB32);
00702                 if (pict_format == NULL) {
00703                     fprintf(stderr, "Can't find standard format for ARGB32\n");
00704 
00705                     /* lookup an other ARGB picture format */
00706                     pf.type = PictTypeDirect;
00707                     pf.depth = 32;
00708 
00709                     pf.direct.alphaMask = 0xff;
00710                     pf.direct.redMask = 0xff;
00711                     pf.direct.greenMask = 0xff;
00712                     pf.direct.blueMask = 0xff;
00713 
00714                     pf.direct.alpha = 24;
00715                     pf.direct.red = 16;
00716                     pf.direct.green = 8;
00717                     pf.direct.blue = 0;
00718 
00719                     pict_format = XRenderFindFormat(mmsfb->x_display,(PictFormatType | PictFormatDepth |PictFormatRedMask | PictFormatRed |
00720                                                    PictFormatGreenMask | PictFormatGreen |PictFormatBlueMask | PictFormatBlue |PictFormatAlphaMask | PictFormatAlpha),
00721                                                     &pf, 0);
00722 
00723                     if (pict_format == NULL) {
00724                         fprintf(stderr, "Can't find format for ARGB32\n");
00725                         this->initialized = false;
00726                         return false;
00727                     }
00728                 }
00729 
00730                 /* try to lookup a RGBA visual */
00731                 int count = 0;
00732                 xvinfo_template.screen = mmsfb->x_screen;
00733                 xvinfo_template.depth = 32;
00734                 xvinfo_template.bits_per_rgb = 8;
00735 
00736                 xvinfos = XGetVisualInfo(mmsfb->x_display, (VisualScreenMask | VisualDepthMask | VisualBitsPerRGBMask), &xvinfo_template, &count);
00737                 if (xvinfos == NULL) {
00738                     fprintf(stderr, "No visual matching criteria\n");
00739                 } else {
00740                     for(int i = 0; i < count; i++) {
00741                         pict_visualformat = XRenderFindVisualFormat(mmsfb->x_display, xvinfos[i].visual);
00742                         if (pict_visualformat != NULL && pict_visualformat->id == pict_format->id) {
00743 
00744                                 this->x_visual=xvinfos[i].visual;
00745                                 break;
00746                         }
00747                     }
00748                 }
00749 
00750                 /* create/get the colormap associated to the visual */
00751                 colormap = XCreateColormap(mmsfb->x_display,
00752                              root,
00753                              this->x_visual,
00754                              AllocNone);
00755 
00756                 XInstallColormap(mmsfb->x_display, colormap);
00757 
00758                 XSetWindowAttributes x_window_attr;
00759                 x_window_attr.event_mask        = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |PointerMotionMask|EnterWindowMask|ResizeRedirectMask;
00760                 x_window_attr.background_pixel  = 0;
00761                 x_window_attr.border_pixel      = 0;
00762                 x_window_attr.colormap = colormap;
00763                 unsigned long x_window_mask;
00764                 // create window;
00765                 if(mmsfb->fullscreen == MMSFB_FSM_TRUE) {
00766                     x_window_mask = CWBackPixel | CWBorderPixel |  CWEventMask /*|CWOverrideRedirect*/|CWColormap;
00767                     //x_window_attr.override_redirect = True;
00768 
00769                     this->x_window = XCreateWindow(mmsfb->x_display,DefaultRootWindow(mmsfb->x_display) , 0, 0, mmsfb->display_w, mmsfb->display_h, 0, 32,
00770                                                    InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00771                     this->x_window_w = mmsfb->display_w;
00772                     this->x_window_h = mmsfb->display_h;
00773 
00774                     Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
00775                     XChangeProperty(mmsfb->x_display, this->x_window,XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE", False), XInternAtom(mmsfb->x_display, "ATOM[]/32", False), 32, PropModePrepend, (unsigned char*) &the_atom,1);
00776 
00777                     XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
00778 
00779                 } else {
00780                     x_window_mask = CWBackPixel | CWBorderPixel |  CWEventMask /*|CWOverrideRedirect*/ | CWColormap;
00781                     //x_window_attr.override_redirect = True;
00782 
00783                     this->x_window = XCreateWindow(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), mmsfb->x11_win_rect.x, mmsfb->x11_win_rect.y, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, 0, 32,
00784                                                    InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00785                     this->x_window_w = mmsfb->x11_win_rect.w;
00786                     this->x_window_h = mmsfb->x11_win_rect.h;
00787                 }
00788 
00789                 Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
00790                 XChangeProperty(mmsfb->x_display, this->x_window,XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE", False), XInternAtom(mmsfb->x_display, "ATOM[]/32", False), 32, PropModePrepend, (unsigned char*) &the_atom,1);
00791 
00792                 XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
00793 
00794                 XFlush(mmsfb->x_display);
00795                 XSync(mmsfb->x_display, False);
00796 
00797                 XGCValues gcvalues;
00798                   /* create the graphic context */
00799                   gcvalues.foreground = None;
00800                   gcvalues.background = None;
00801                   gcvalues.function = GXcopy;
00802                   gcvalues.plane_mask = XAllPlanes();
00803                   gcvalues.clip_mask = None;
00804 
00805                 this->x_gc = XCreateGC(mmsfb->x_display, this->x_window, 0, NULL);
00806 
00807                 XRenderPictureAttributes pict_attr;
00808                 pict_attr.component_alpha = False;
00809 
00810                 /* create pixmaps */
00811                 pixmap = XCreatePixmap(mmsfb->x_display, this->x_window,mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, 32);
00812 
00813 
00814                 this->x_pixmap_pict = XRenderCreatePicture(mmsfb->x_display,
00815                                    pixmap,
00816                                    pict_format,
00817                                    CPComponentAlpha,
00818                                    &pict_attr);
00819 
00820                 this->x_window_pict = XRenderCreatePicture(mmsfb->x_display,
00821                                    this->x_window,
00822                                    pict_format,
00823                                    CPComponentAlpha,
00824                                    &pict_attr);
00825 
00826                 // create x11 buffer #1
00827                 this->x_image1 = XShmCreateImage(mmsfb->x_display, this->x_visual, 32, ZPixmap,
00828                                                  NULL, &this->x_shminfo1, this->config.w, this->config.h);
00829                 if (!this->x_image1) {
00830                     XUnlockDisplay(mmsfb->x_display);
00831                     MMSFB_SetError(0, "XShmCreateImage() failed");
00832                     return false;
00833                 }
00834 
00835                 // map shared memory for x-server communication
00836                 this->x_shminfo1.shmid    = shmget(IPC_PRIVATE, this->x_image1->bytes_per_line * this->x_image1->height, IPC_CREAT | 0777);
00837                 this->x_shminfo1.shmaddr  = this->x_image1->data = (char *)shmat(this->x_shminfo1.shmid, 0, 0);
00838                 this->x_shminfo1.readOnly = False;
00839 
00840                 // attach the x-server to that segment
00841                 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo1)) {
00842                     shmctl(this->x_shminfo1.shmid, IPC_RMID, 0);
00843                     XFree(this->x_image1);
00844                     this->x_image1 = NULL;
00845                     XUnlockDisplay(mmsfb->x_display);
00846                     MMSFB_SetError(0, "XShmAttach() failed");
00847                     return false;
00848                 }
00849                 shmctl(this->x_shminfo1.shmid, IPC_RMID, 0);
00850 
00851                 // create x11 buffer #2
00852                 this->x_image2 = XShmCreateImage(mmsfb->x_display, this->x_visual, 32, ZPixmap,
00853                                                  NULL, &this->x_shminfo2, this->config.w, this->config.h);
00854                 if (!this->x_image2) {
00855                     XUnlockDisplay(mmsfb->x_display);
00856                     MMSFB_SetError(0, "XShmCreateImage() failed");
00857                     return false;
00858                 }
00859 
00860                 // map shared memory for x-server communication
00861                 this->x_shminfo2.shmid    = shmget(IPC_PRIVATE, this->x_image2->bytes_per_line * this->x_image2->height, IPC_CREAT | 0777);
00862                 this->x_shminfo2.shmaddr  = this->x_image2->data = (char *)shmat(this->x_shminfo2.shmid, 0, 0);
00863                 this->x_shminfo2.readOnly = False;
00864 
00865                 // attach the x-server to that segment
00866                 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo2)) {
00867                     shmctl(this->x_shminfo2.shmid, IPC_RMID, 0);
00868                     XFree(this->x_image2);
00869                     this->x_image2 = NULL;
00870                     XUnlockDisplay(mmsfb->x_display);
00871                     MMSFB_SetError(0, "XShmAttach() failed");
00872                     return false;
00873                 }
00874                 shmctl(this->x_shminfo2.shmid, IPC_RMID, 0);
00875 
00876                 if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)&&(1==0)) {
00877 
00878                     // calc ratio
00879                     MMSFBRectangle dest;
00880                     calcAspectRatio(this->config.w, this->config.h, mmsfb->display_w, mmsfb->display_h, dest,
00881                                     (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), false);
00882 
00883                     // create scale buffer
00884                     this->x_image_scaler = XShmCreateImage(mmsfb->x_display, this->x_visual, 32, ZPixmap,
00885                                                            NULL, &this->x_shminfo_scaler, dest.w, dest.h);
00886                     if (!this->x_image_scaler) {
00887                         XUnlockDisplay(mmsfb->x_display);
00888                         MMSFB_SetError(0, "XShmCreateImage() failed");
00889                         return false;
00890                     }
00891 
00892                     // map shared memory for x-server communication
00893                     this->x_shminfo_scaler.shmid    = shmget(IPC_PRIVATE, this->x_image_scaler->bytes_per_line * this->x_image_scaler->height, IPC_CREAT | 0777);
00894                     this->x_shminfo_scaler.shmaddr  = this->x_image_scaler->data = (char *)shmat(this->x_shminfo_scaler.shmid, 0, 0);
00895                     this->x_shminfo_scaler.readOnly = False;
00896 
00897                     // attach the x-server to that segment
00898                     if (!XShmAttach(mmsfb->x_display, &this->x_shminfo_scaler)) {
00899                         shmctl(this->x_shminfo_scaler.shmid, IPC_RMID, 0);
00900                         XFree(this->x_image_scaler);
00901                         this->x_image_scaler = NULL;
00902                         XUnlockDisplay(mmsfb->x_display);
00903                         MMSFB_SetError(0, "XShmAttach() failed");
00904                         return false;
00905                     }
00906                     shmctl(this->x_shminfo_scaler.shmid, IPC_RMID, 0);
00907 
00908                     // create a scaler surface
00909                     this->scaler = new MMSFBSurface(dest.w, dest.h, this->config.pixelformat,
00910                                                 this->x_image_scaler, NULL, NULL);
00911                     if (!this->scaler) {
00912                         XUnlockDisplay(mmsfb->x_display);
00913                         MMSFB_SetError(0, "cannot create scaler surface");
00914                         return false;
00915                     }
00916                     this->scaler->layer=this;
00917                     // we must switch extended accel on
00918                     this->scaler->setExtendedAcceleration(true);
00919                 }
00920             }
00921 
00922             XFlush(mmsfb->x_display);
00923             XSync(mmsfb->x_display, False);
00924 
00925             this->impl.x_display = mmsfb->x_display;
00926             this->impl.x_gc = this->x_gc;
00927             this->impl.x_window = this->x_window;
00928             this->impl.w = this->x_window_w;
00929             this->impl.h = this->x_window_h;
00930             this->impl.x_screen = mmsfb->x_screen;
00931 #endif
00932         } else if(config.pixelformat == MMSFB_PF_RGB32 || config.pixelformat == MMSFB_PF_RGB24) {
00933 
00934             this->x_visual = DefaultVisual(mmsfb->x_display, mmsfb->x_screen);
00935             mmsfb->x_depth=DefaultDepth(mmsfb->x_display, mmsfb->x_screen);
00936             XSetWindowAttributes x_window_attr;
00937             x_window_attr.event_mask        = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |PointerMotionMask|EnterWindowMask|ResizeRedirectMask;
00938             x_window_attr.background_pixel  = 0;
00939             x_window_attr.border_pixel      = 0;
00940             x_window_attr.colormap = colormap;
00941             unsigned long x_window_mask;
00942             // create window;
00943             if(mmsfb->fullscreen == MMSFB_FSM_TRUE) {
00944                 x_window_mask = CWBackPixel | CWBorderPixel |  CWEventMask /*|CWOverrideRedirect*/|CWColormap;
00945                 //x_window_attr.override_redirect = True;
00946 
00947                 this->x_window = XCreateWindow(mmsfb->x_display,DefaultRootWindow(mmsfb->x_display) , 0, 0, mmsfb->display_w, mmsfb->display_h, 0, mmsfb->x_depth,
00948                                                InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00949 
00950                 this->x_window_w = mmsfb->display_w;
00951                 this->x_window_h = mmsfb->display_h;
00952 
00953                 Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
00954                 XChangeProperty(mmsfb->x_display, this->x_window,XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE", False), XInternAtom(mmsfb->x_display, "ATOM[]/32", False), 32, PropModePrepend, (unsigned char*) &the_atom,1);
00955 
00956                 XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
00957 
00958             } else {
00959                 x_window_mask = CWBackPixel | CWBorderPixel |  CWEventMask /*|CWOverrideRedirect*/ | CWColormap;
00960                 //x_window_attr.override_redirect = True;
00961 
00962                 this->x_window = XCreateWindow(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), mmsfb->x11_win_rect.x, mmsfb->x11_win_rect.y, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, 0, mmsfb->x_depth,
00963                                                InputOutput, this->x_visual, x_window_mask, &x_window_attr);
00964                 this->x_window_w = mmsfb->x11_win_rect.w;
00965                 this->x_window_h = mmsfb->x11_win_rect.h;
00966             }
00967 
00968 
00969             XFlush(mmsfb->x_display);
00970             XSync(mmsfb->x_display, False);
00971 
00972             this->x_gc = XCreateGC(mmsfb->x_display, this->x_window, 0, NULL);
00973 
00974             // create x11 buffer #1
00975             this->x_image1 = XShmCreateImage(mmsfb->x_display, this->x_visual, mmsfb->x_depth, ZPixmap,
00976                                              NULL, &this->x_shminfo1, this->config.w, this->config.h);
00977             if (!this->x_image1) {
00978                 XUnlockDisplay(mmsfb->x_display);
00979                 MMSFB_SetError(0, "XShmCreateImage() failed");
00980                 return false;
00981             }
00982 
00983             // map shared memory for x-server communication
00984             this->x_shminfo1.shmid    = shmget(IPC_PRIVATE, this->x_image1->bytes_per_line * this->x_image1->height, IPC_CREAT | 0777);
00985             this->x_shminfo1.shmaddr  = this->x_image1->data = (char *)shmat(this->x_shminfo1.shmid, 0, 0);
00986             this->x_shminfo1.readOnly = False;
00987 
00988             // attach the x-server to that segment
00989             if (!XShmAttach(mmsfb->x_display, &this->x_shminfo1)) {
00990                 shmctl(this->x_shminfo1.shmid, IPC_RMID, 0);
00991                 XFree(this->x_image1);
00992                 this->x_image1 = NULL;
00993                 XUnlockDisplay(mmsfb->x_display);
00994                 MMSFB_SetError(0, "XShmAttach() failed");
00995                 return false;
00996             }
00997             shmctl(this->x_shminfo1.shmid, IPC_RMID, 0);
00998 
00999             // create x11 buffer #2
01000             this->x_image2 = XShmCreateImage(mmsfb->x_display, this->x_visual, mmsfb->x_depth, ZPixmap,
01001                                              NULL, &this->x_shminfo2, this->config.w, this->config.h);
01002             if (!this->x_image2) {
01003                 XUnlockDisplay(mmsfb->x_display);
01004                 MMSFB_SetError(0, "XShmCreateImage() failed");
01005                 return false;
01006             }
01007 
01008             // map shared memory for x-server communication
01009             this->x_shminfo2.shmid    = shmget(IPC_PRIVATE, this->x_image2->bytes_per_line * this->x_image2->height, IPC_CREAT | 0777);
01010             this->x_shminfo2.shmaddr  = this->x_image2->data = (char *)shmat(this->x_shminfo2.shmid, 0, 0);
01011             this->x_shminfo2.readOnly = False;
01012 
01013             // attach the x-server to that segment
01014             if (!XShmAttach(mmsfb->x_display, &this->x_shminfo2)) {
01015                 shmctl(this->x_shminfo2.shmid, IPC_RMID, 0);
01016                 XFree(this->x_image2);
01017                 this->x_image2 = NULL;
01018                 XUnlockDisplay(mmsfb->x_display);
01019                 MMSFB_SetError(0, "XShmAttach() failed");
01020                 return false;
01021             }
01022             shmctl(this->x_shminfo2.shmid, IPC_RMID, 0);
01023 
01024             if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)&&(1==0)) {
01025 
01026                 // calc ratio
01027                 MMSFBRectangle dest;
01028                 calcAspectRatio(this->config.w, this->config.h, mmsfb->display_w, mmsfb->display_h, dest,
01029                                 (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), false);
01030 
01031                 // create scale buffer
01032                 this->x_image_scaler = XShmCreateImage(mmsfb->x_display, this->x_visual, mmsfb->x_depth, ZPixmap,
01033                                                        NULL, &this->x_shminfo_scaler, dest.w, dest.h);
01034                 if (!this->x_image_scaler) {
01035                     XUnlockDisplay(mmsfb->x_display);
01036                     MMSFB_SetError(0, "XShmCreateImage() failed");
01037                     return false;
01038                 }
01039 
01040                 // map shared memory for x-server communication
01041                 this->x_shminfo_scaler.shmid    = shmget(IPC_PRIVATE, this->x_image_scaler->bytes_per_line * this->x_image_scaler->height, IPC_CREAT | 0777);
01042                 this->x_shminfo_scaler.shmaddr  = this->x_image_scaler->data = (char *)shmat(this->x_shminfo_scaler.shmid, 0, 0);
01043                 this->x_shminfo_scaler.readOnly = False;
01044 
01045                 // attach the x-server to that segment
01046                 if (!XShmAttach(mmsfb->x_display, &this->x_shminfo_scaler)) {
01047                     shmctl(this->x_shminfo_scaler.shmid, IPC_RMID, 0);
01048                     XFree(this->x_image_scaler);
01049                     this->x_image_scaler = NULL;
01050                     XUnlockDisplay(mmsfb->x_display);
01051                     MMSFB_SetError(0, "XShmAttach() failed");
01052                     return false;
01053                 }
01054                 shmctl(this->x_shminfo_scaler.shmid, IPC_RMID, 0);
01055 
01056                 // create a scaler surface
01057                 this->scaler = new MMSFBSurface(dest.w, dest.h, this->config.pixelformat,
01058                                             this->x_image_scaler, NULL, NULL);
01059                 if (!this->scaler) {
01060                     XUnlockDisplay(mmsfb->x_display);
01061                     MMSFB_SetError(0, "cannot create scaler surface");
01062                     return false;
01063                 }
01064                 this->scaler->layer=this;
01065                 // we must switch extended accel on
01066                 this->scaler->setExtendedAcceleration(true);
01067             }
01068 
01069             XFlush(mmsfb->x_display);
01070             XSync(mmsfb->x_display, False);
01071 
01072             this->impl.x_display = mmsfb->x_display;
01073             this->impl.x_gc = this->x_gc;
01074             this->impl.x_window = this->x_window;
01075             this->impl.w = this->x_window_w;
01076             this->impl.h = this->x_window_h;
01077             this->impl.x_screen = mmsfb->x_screen;
01078         } else if(config.pixelformat == MMSFB_PF_YV12) {
01079 #ifdef __HAVE_XV__
01080             // XVSHM
01081             unsigned int    p_version,
01082                             p_release,
01083                             p_request_base,
01084                             p_event_base,
01085                             p_error_base;
01086 
01087             if (XvQueryExtension(mmsfb->x_display, &p_version, &p_release, &p_request_base, &p_event_base, &p_error_base) != Success) {
01088                 MMSFB_SetError(0, "XvQueryExtension() failed");
01089                 fflush(stdout);
01090                 return false;
01091             }
01092 
01093             unsigned int num_adaptors;
01094             XvAdaptorInfo *ai;
01095             if (XvQueryAdaptors(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), &num_adaptors, &ai)) {
01096                 MMSFB_SetError(0, "XvQueryAdaptors() failed");
01097                 return false;
01098             }
01099             printf("DISKO: Available xv adaptors:\n");
01100             for(unsigned int cnt=0;cnt<num_adaptors;cnt++) {
01101                 /* grab the first port with XvImageMask bit */
01102                 if((mmsfb->xv_port == 0) &&
01103                    (ai[cnt].type & XvImageMask) &&
01104                    (XvGrabPort(mmsfb->x_display, ai[cnt].base_id, 0) == Success)) {
01105                     mmsfb->xv_port = ai[cnt].base_id;
01106                     printf("  %s (used)\n", ai[cnt].name);
01107                 }
01108                 else
01109                     printf("  %s\n", ai[cnt].name);
01110             }
01111             XvFreeAdaptorInfo(ai);
01112 
01113 
01114             // important to set the image width to a multiple of 128
01115             // a few hardware need this to create a buffer where to U/V planes immediately follows the Y plane
01116             int image_width = this->config.w & ~0x7f;
01117             if (this->config.w & 0x7f)
01118                 image_width += 0x80;
01119 
01120             // get id for yv12 pixelformat
01121             int nFormats, xvPixFormat = (('2'<<24)|('1'<<16)|('V'<<8)|'Y');
01122             XvImageFormatValues *formats = XvListImageFormats(mmsfb->x_display, mmsfb->xv_port, &nFormats);
01123             if(formats) {
01124                 for(int i = 0; i < nFormats; i++) {
01125                     if(formats[i].type == XvYUV && formats[i].format == XvPlanar) {
01126                         xvPixFormat = formats[i].id;
01127                         break;
01128                     }
01129                 }
01130                 XFree(formats);
01131             }
01132 
01133             // create x11 buffer #1
01134             this->xv_image1 = XvShmCreateImage(mmsfb->x_display, mmsfb->xv_port, xvPixFormat, 0, image_width, this->config.h, &this->xv_shminfo1);
01135             if(!this->xv_image1) {
01136                 XUnlockDisplay(mmsfb->x_display);
01137                 MMSFB_SetError(0, "XvShmCreateImage() failed");
01138                 return false;
01139             }
01140             if(this->xv_image1->data_size == 0) {
01141                 XFree(this->xv_image1);
01142                 XUnlockDisplay(mmsfb->x_display);
01143                 this->xv_image1 = NULL;
01144                 MMSFB_SetError(0, "XvShmCreateImage() returned zero size");
01145                 return false;
01146             }
01147 
01148             // map shared memory for x-server communication
01149             this->xv_shminfo1.shmid = shmget(IPC_PRIVATE, this->xv_image1->data_size, IPC_CREAT | 0777);
01150             if(this->xv_shminfo1.shmid < 0) {
01151                 MMSFB_SetError(0, string("Error in shmget: ") + strerror(errno));
01152                 XFree(this->xv_image1);
01153                 XUnlockDisplay(mmsfb->x_display);
01154                 this->xv_image1 = NULL;
01155                 return false;
01156             }
01157 
01158             this->xv_shminfo1.shmaddr  = this->xv_image1->data = (char *)shmat(this->xv_shminfo1.shmid, 0, 0);
01159             if(!this->xv_shminfo1.shmaddr || (this->xv_shminfo1.shmaddr == (char*)-1)) {
01160                 MMSFB_SetError(0, string("Error in shmat: ") + strerror(errno));
01161                 XFree(this->xv_image1);
01162                 XUnlockDisplay(mmsfb->x_display);
01163                 this->xv_image1 = NULL;
01164                 return false;
01165             }
01166 
01167             this->xv_shminfo1.readOnly = False;
01168 
01169             // attach the x-server to that segment
01170             if (!XShmAttach(mmsfb->x_display, &this->xv_shminfo1)) {
01171                 XFree(this->xv_image1);
01172                 XUnlockDisplay(mmsfb->x_display);
01173                 this->xv_image1 = NULL;
01174                 MMSFB_SetError(0, "XShmAttach() failed");
01175                 return false;
01176             }
01177 
01178             //XFlush(mmsfb->x_display);
01179             XSync(mmsfb->x_display, False);
01180             shmctl(this->xv_shminfo1.shmid, IPC_RMID, 0);
01181 
01182             // create x11 buffer #2
01183             this->xv_image2 = XvShmCreateImage(mmsfb->x_display, mmsfb->xv_port, xvPixFormat, 0, image_width, this->config.h, &this->xv_shminfo2);
01184             if (!this->xv_image2) {
01185                 XFree(this->xv_image1);
01186                 XUnlockDisplay(mmsfb->x_display);
01187                 this->xv_image1 = NULL;
01188                 MMSFB_SetError(0, "XvShmCreateImage() failed");
01189                 return false;
01190             }
01191             if(this->xv_image2->data_size == 0) {
01192                 XFree(this->xv_image1);
01193                 XFree(this->xv_image2);
01194                 XUnlockDisplay(mmsfb->x_display);
01195                 this->xv_image1 = NULL;
01196                 this->xv_image2 = NULL;
01197                 MMSFB_SetError(0, "XvShmCreateImage() returned zero size");
01198                 return false;
01199             }
01200 
01201             // map shared memory for x-server communication
01202             this->xv_shminfo2.shmid    = shmget(IPC_PRIVATE, this->xv_image2->data_size, IPC_CREAT | 0777);
01203             if(this->xv_shminfo2.shmid < 0) {
01204                 MMSFB_SetError(0, string("Error in shmget: ") + strerror(errno));
01205                 XFree(this->xv_image1);
01206                 XFree(this->xv_image2);
01207                 XUnlockDisplay(mmsfb->x_display);
01208                 this->xv_image1 = NULL;
01209                 this->xv_image2 = NULL;
01210                 return false;
01211             }
01212 
01213             this->xv_shminfo2.shmaddr  = this->xv_image2->data = (char *)shmat(this->xv_shminfo2.shmid, 0, 0);
01214             if(!this->xv_shminfo2.shmaddr || (this->xv_shminfo2.shmaddr == (char*)-1)) {
01215                 MMSFB_SetError(0, string("Error in shmat: ") + strerror(errno));
01216                 XFree(this->xv_image1);
01217                 XFree(this->xv_image2);
01218                 XUnlockDisplay(mmsfb->x_display);
01219                 this->xv_image1 = NULL;
01220                 this->xv_image2 = NULL;
01221                 return false;
01222             }
01223 
01224             this->xv_shminfo2.readOnly = False;
01225 
01226             // attach the x-server to that segment
01227             if (!XShmAttach(mmsfb->x_display, &this->xv_shminfo2)) {
01228                 XFree(this->xv_image1);
01229                 XFree(this->xv_image2);
01230                 XUnlockDisplay(mmsfb->x_display);
01231                 this->xv_image1 = NULL;
01232                 this->xv_image2 = NULL;
01233                 MMSFB_SetError(0, "XShmAttach() failed");
01234                 return false;
01235             }
01236 
01237             //XFlush(mmsfb->x_display);
01238             XSync(mmsfb->x_display, False);
01239             shmctl(this->xv_shminfo2.shmid, IPC_RMID, 0);
01240 
01241             XSetWindowAttributes x_window_attr;
01242             unsigned long x_window_mask;
01243             this->x_visual = DefaultVisual(mmsfb->x_display,mmsfb->x_screen);
01244 
01245             // create window;
01246             x_window_attr.event_mask        = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |PointerMotionMask|EnterWindowMask|ResizeRedirectMask;
01247             x_window_attr.background_pixel  = 0;
01248             x_window_attr.border_pixel      = 0;
01249             if(mmsfb->fullscreen == MMSFB_FSM_TRUE) {
01250                 x_window_mask = CWBackPixel | CWBorderPixel |  CWEventMask ; //|CWOverrideRedirect ;
01251                 //x_window_attr.override_redirect = True;
01252                 this->x_window = XCreateWindow(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), 0, 0, mmsfb->display_w, mmsfb->display_h, 0, CopyFromParent,
01253                                                InputOutput, this->x_visual, x_window_mask, &x_window_attr);
01254 
01255                 this->x_window_w = mmsfb->display_w;
01256                 this->x_window_h = mmsfb->display_h;
01257                 Atom the_atom = XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
01258                 XChangeProperty(mmsfb->x_display, this->x_window,XInternAtom(mmsfb->x_display, "_NET_WM_WINDOW_TYPE", False), XInternAtom(mmsfb->x_display, "ATOM[]/32", False), 32, PropModePrepend, (unsigned char*) &the_atom,1);
01259 
01260                 XSetWMProtocols(mmsfb->x_display, this->x_window, &the_atom, 1);
01261             } else {
01262                 x_window_mask = CWBackPixel | CWBorderPixel |  CWEventMask ; //|CWOverrideRedirect;
01263                 //x_window_attr.override_redirect = True;
01264                 this->x_window_w = mmsfb->x11_win_rect.w;
01265                 this->x_window_h = mmsfb->x11_win_rect.h;
01266                 this->x_window = XCreateWindow(mmsfb->x_display, DefaultRootWindow(mmsfb->x_display), mmsfb->x11_win_rect.x, mmsfb->x11_win_rect.y, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, 0, CopyFromParent,
01267                                                InputOutput, this->x_visual, x_window_mask, &x_window_attr);
01268 
01269             }
01270 
01271             this->x_gc = XCreateGC(mmsfb->x_display, this->x_window, 0, 0);
01272 
01273             this->impl.x_display = mmsfb->x_display;
01274             this->impl.x_gc = this->x_gc;
01275             this->impl.x_window = this->x_window;
01276             this->impl.w = this->x_window_w;
01277             this->impl.h = this->x_window_h;
01278             this->impl.xv_image1 = this->xv_image1;
01279             this->impl.xv_image2 = this->xv_image2;
01280             this->impl.xv_port = mmsfb->xv_port;
01281             this->impl.x_screen = mmsfb->x_screen;
01282 #endif
01283         }
01284 
01285 
01286         if (this->config.outputtype == MMSFB_OT_OGL) {
01287 #ifdef __HAVE_OPENGL__
01288 #if defined(__HAVE_GLX__) || defined(__HAVE_EGL__)
01289             XUnlockDisplay(mmsfb->x_display);
01290             mmsfb->bei->init(mmsfb->x_display, mmsfb->x_screen, this->x_window, mmsfb->x11_win_rect);
01291             XLockDisplay(mmsfb->x_display);
01292 #endif
01293 #endif
01294         }
01295 
01296         mmsfb->x_windows[this->config.id] = this->x_window;
01297 
01298         if(this->config.id == 0) {
01299             mmsfb->input_window = this->x_window;
01300             XStoreName(mmsfb->x_display, this->x_window, mmsfb->applname.c_str());
01301             XSetIconName(mmsfb->x_display, this->x_window, mmsfb->appliconname.c_str());
01302             XClassHint clhi;
01303             clhi.res_name=(basename((char *)mmsfb->bin.c_str()));
01304 //          clhi.res_name=(char*)"disko";
01305             clhi.res_class=(char*)"disko";
01306             XSetClassHint(mmsfb->x_display, this->x_window,&clhi);
01307             if(!mmsfb->hidden) {
01308                 XMapWindow(mmsfb->x_display, this->x_window);
01309                 XEvent x_event;
01310                 do {
01311                     XNextEvent(mmsfb->x_display, &x_event);
01312                 }
01313                 while (x_event.type != MapNotify || x_event.xmap.event != this->x_window);
01314 
01315                 XRaiseWindow(mmsfb->x_display, this->x_window);
01316             }
01317             // hide X cursor
01318             if (mmsfb->pointer != MMSFB_PM_EXTERNAL) {
01319                 Pixmap bm_no;
01320                 Colormap cmap;
01321                 Cursor no_ptr;
01322                 XColor black, dummy;
01323                 static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0};
01324 
01325                 cmap = DefaultColormap(mmsfb->x_display, DefaultScreen(mmsfb->x_display));
01326                 XAllocNamedColor(mmsfb->x_display, cmap, "black", &black, &dummy);
01327                 bm_no = XCreateBitmapFromData(mmsfb->x_display, this->x_window, bm_no_data, 8, 8);
01328                 no_ptr = XCreatePixmapCursor(mmsfb->x_display, bm_no, bm_no, &black, &black, 0, 0);
01329 
01330                 XDefineCursor(mmsfb->x_display, this->x_window, no_ptr);
01331                 XFreeCursor(mmsfb->x_display, no_ptr);
01332                 if (bm_no != None)
01333                         XFreePixmap(mmsfb->x_display, bm_no);
01334                 XFreeColors(mmsfb->x_display, cmap, &black.pixel, 1, 0);
01335             }
01336             if(!mmsfb->hidden)
01337                 XSetInputFocus(mmsfb->x_display, this->x_window,RevertToPointerRoot,CurrentTime);
01338         } else {
01339             if(!mmsfb->hidden) {
01340                 XMapWindow(mmsfb->x_display, this->x_window);
01341                 XEvent x_event;
01342                 do {
01343                     XNextEvent(mmsfb->x_display, &x_event);
01344                 }
01345                 while (x_event.type != MapNotify || x_event.xmap.event != this->x_window);
01346 
01347                 XRaiseWindow(mmsfb->x_display, this->x_window);
01348             }
01349         }
01350         XUnlockDisplay(mmsfb->x_display);
01351 
01352         return true;
01353 #endif
01354     }
01355 
01356     return false;
01357 }
01358 
01359 bool MMSFBLayer::setOpacity(unsigned char opacity) {
01360 
01361     // check if initialized
01362     INITCHECK;
01363 
01364     if (this->config.backend == MMSFB_BE_DFB) {
01365 #ifdef  __HAVE_DIRECTFB__
01366         DFBResult   dfbres;
01367 
01368         /* invert the opacity for inverted pixelformats */
01369         if (this->config.pixelformat == MMSFB_PF_AiRGB) {
01370             opacity = 255 - opacity;
01371         }
01372 
01373         /* set the opacity */
01374         if ((dfbres=this->dfblayer->SetOpacity(this->dfblayer, opacity)) != DFB_OK) {
01375             MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetOpacity(" + iToStr(opacity) + ") failed");
01376             return false;
01377         }
01378 
01379         return true;
01380 #endif
01381     }
01382 
01383     return false;
01384 }
01385 
01386 bool MMSFBLayer::setLevel(int level) {
01387 
01388     // check if initialized
01389     INITCHECK;
01390 
01391     if (this->config.backend == MMSFB_BE_DFB) {
01392 #ifdef  __HAVE_DIRECTFB__
01393         DFBResult   dfbres;
01394 
01395         /* set the opacity */
01396         if ((dfbres=this->dfblayer->SetLevel(this->dfblayer, level)) != DFB_OK) {
01397             MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::SetLevel(" + iToStr(level) + ") failed");
01398             return false;
01399         }
01400         return true;
01401 #endif
01402     } else if (this->config.backend == MMSFB_BE_X11) {
01403 #ifdef __HAVE_XLIB__
01404         XRaiseWindow(mmsfb->x_display, this->x_window);
01405 
01406 #endif
01407     }
01408     return false;
01409 }
01410 
01411 bool MMSFBLayer::getSurface(MMSFBSurface **surface, bool clear) {
01412 
01413     // check if initialized
01414     INITCHECK;
01415 
01416     if (this->surface) {
01417         // i have already a surface
01418         *surface = this->surface;
01419         DEBUGMSG("MMSGUI", "have already a surface");
01420 
01421         if (clear) {
01422             // clear the display
01423             this->surface->lock();
01424             this->surface->clear();
01425             this->surface->flip();
01426             this->surface->unlock();
01427         }
01428 
01429         return true;
01430     }
01431 
01432     // reset surface pointer
01433     *surface = NULL;
01434 
01435     if (this->config.backend == MMSFB_BE_DFB) {
01436 #ifdef  __HAVE_DIRECTFB__
01437         // get layers surface
01438         DFBResult           dfbres;
01439         IDirectFBSurface    *dfbsurface;
01440         DEBUGMSG("MMSGUI", "calling DFB->GetSurface()");
01441         if ((dfbres=this->dfblayer->GetSurface(this->dfblayer, &dfbsurface)) != DFB_OK) {
01442             MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::GetSurface() failed");
01443             return false;
01444         }
01445         DEBUGMSG("MMSGUI", "setting blitting flags");
01446         dfbsurface->SetBlittingFlags(dfbsurface, DSBLIT_NOFX);
01447 
01448         // create a new surface instance
01449         *surface = new MMSFBSurface(dfbsurface);
01450         if (!*surface) {
01451             dfbsurface->Release(dfbsurface);
01452             MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01453             return false;
01454         }
01455 #endif
01456     }
01457     else
01458     if (this->config.backend == MMSFB_BE_FBDEV) {
01459 #ifdef __HAVE_FBDEV__
01460         if (this->config.outputtype == MMSFB_OT_OGL) {
01461 #ifdef __HAVE_OPENGL__
01462             // create a new surface instance
01463             *surface = new MMSFBSurface(this->config.w, this->config.h, MMSFBSurfaceAllocatedBy_ogl);
01464             if (!*surface) {
01465                 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface for OPENGL");
01466                 return false;
01467             }
01468 #endif
01469         }
01470         else
01471         if (this->config.buffermode == MMSFB_BM_FRONTONLY) {
01472             // we have only the front buffer, no backbuffer to be allocated
01473             *surface = this->mmsfbdev_surface;
01474             if (!*surface) {
01475                 MMSFB_SetError(0, "layer surface is not initialized");
01476                 return false;
01477             }
01478         }
01479         else
01480         if (this->config.buffermode == MMSFB_BM_BACKSYSTEM) {
01481             // create a new backbuffer surface instance
01482             *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat);
01483             if (!*surface) {
01484                 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01485                 return false;
01486             }
01487 
01488             // the surface has to know the fbdev surface, so surface->flip() can update the fbdev memory
01489             (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01490 
01491             // we must switch extended accel on
01492             (*surface)->setExtendedAcceleration(true);
01493         }
01494         else {
01495             // we assume that we have at least one backbuffer in video memory
01496             *surface = this->mmsfbdev_surface;
01497             if (!*surface) {
01498                 MMSFB_SetError(0, "layer surface is not initialized");
01499                 return false;
01500             }
01501 
01502             // the surface has to know the fbdev surface, so surface->flip() can update the fbdev memory
01503             // here we point to the same surface, in this case the flip can save the memcpy() and
01504             // can use the hardware panning instead
01505             (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01506         }
01507 #endif
01508     }
01509     else
01510     if (this->config.backend == MMSFB_BE_KMS) {
01511 #ifdef __HAVE_KMS__
01512         if (this->config.outputtype == MMSFB_OT_OGL) {
01513 #ifdef __HAVE_OPENGL__
01514             // create a new surface instance
01515             *surface = new MMSFBSurface(this->config.w, this->config.h, MMSFBSurfaceAllocatedBy_ogl);
01516             if (!*surface) {
01517                 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface for OPENGL");
01518                 return false;
01519             }
01520 #endif
01521         }
01522         else
01523         if (this->config.buffermode == MMSFB_BM_FRONTONLY) {
01524             // we have only the front buffer, no backbuffer to be allocated
01525             *surface = this->mmsfbdev_surface;
01526             if (!*surface) {
01527                 MMSFB_SetError(0, "layer surface is not initialized");
01528                 return false;
01529             }
01530         }
01531         else
01532         if (this->config.buffermode == MMSFB_BM_BACKSYSTEM) {
01533             // create a new backbuffer surface instance
01534             *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat);
01535             if (!*surface) {
01536                 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01537                 return false;
01538             }
01539 
01540             // the surface has to know the fbdev surface, so surface->flip() can update the fbdev memory
01541             (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01542 
01543             // we must switch extended accel on
01544             (*surface)->setExtendedAcceleration(true);
01545         }
01546         else {
01547             // we assume that we have at least one backbuffer in video memory
01548             *surface = this->mmsfbdev_surface;
01549             if (!*surface) {
01550                 MMSFB_SetError(0, "layer surface is not initialized");
01551                 return false;
01552             }
01553 
01554             // the surface has to know the fbdev surface, so surface->flip() can update the fbdev memory
01555             // here we point to the same surface, in this case the flip can save the memcpy() and
01556             // can use the hardware panning instead
01557             (*surface)->config.surface_buffer->mmsfbdev_surface = this->mmsfbdev_surface;
01558         }
01559 #endif
01560     }
01561     else
01562     if (this->config.backend == MMSFB_BE_X11) {
01563 #ifdef __HAVE_XLIB__
01564         if (this->config.outputtype == MMSFB_OT_OGL) {
01565 #ifdef __HAVE_OPENGL__
01566             // create a new surface instance
01567             *surface = new MMSFBSurface(this->config.w, this->config.h, MMSFBSurfaceAllocatedBy_ogl);
01568             if (!*surface) {
01569                 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface for OPENGL");
01570                 return false;
01571             }
01572 #endif
01573         }
01574         else
01575         if (isRGBPixelFormat(this->config.pixelformat)) {
01576             // XSHM
01577             if ((!this->x_image1)||(!this->x_image2)) {
01578                 MMSFB_SetError(0, "x_image not available, cannot get surface");
01579                 return false;
01580             }
01581 
01582             // create a new surface instance
01583             *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat,
01584                                         this->x_image1, this->x_image2, this->scaler);
01585             if (!*surface) {
01586                 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01587                 return false;
01588             }
01589 
01590             // we must switch extended accel on
01591             (*surface)->setExtendedAcceleration(true);
01592             (*surface)->layer=this;
01593         }
01594         else {
01595 #ifdef __HAVE_XV__
01596 
01597             // XVSHM
01598             if ((!this->xv_image1)||(!this->xv_image2)) {
01599                 MMSFB_SetError(0, "xv_image not available, cannot get surface");
01600                 return false;
01601             }
01602 
01603             // create a new surface instance
01604             *surface = new MMSFBSurface(this->config.w, this->config.h, this->config.pixelformat,
01605                                         this->xv_image1, this->xv_image2);
01606             if (!*surface) {
01607                 MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
01608                 return false;
01609             }
01610 
01611             // we must switch extended accel on
01612             (*surface)->setExtendedAcceleration(true);
01613             (*surface)->layer=this;
01614 #endif
01615         }
01616 #endif
01617     }
01618 
01619     // save this for the next call
01620     this->surface = *surface;
01621 
01622     if (this->surface) {
01623         this->surface->lock();
01624         // mark this surface as a layer surface
01625         this->surface->setLayerSurface();
01626 
01627         if (clear) {
01628             // clear the display
01629             this->surface->clear();
01630             this->surface->flip();
01631         }
01632 
01633         // initialize the flip flags for the layer surface
01634         this->surface->setFlipFlags(this->flipflags);
01635 
01636         this->surface->unlock();
01637 
01638         return true;
01639     }
01640 
01641     return false;
01642 }
01643 
01644 bool MMSFBLayer::setFlipFlags(MMSFBFlipFlags flags) {
01645     this->flipflags = flags;
01646 
01647     /* if the layer surface does exist, update it */
01648     if (this->surface) {
01649         this->surface->lock();
01650         this->surface->setFlipFlags(this->flipflags);
01651         this->surface->unlock();
01652     }
01653 
01654     return true;
01655 }
01656 
01657 bool MMSFBLayer::releaseLayer() {
01658 
01659     // check if initialized
01660     INITCHECK;
01661 
01662     if (this->config.backend == MMSFB_BE_FBDEV) {
01663 #ifdef __HAVE_FBDEV__
01664         if (mmsfb->mmsfbdev) {
01665             return mmsfb->mmsfbdev->releaseLayer(this->config.id);
01666         }
01667 #endif
01668     } else if (this->config.backend == MMSFB_BE_KMS) {
01669 #ifdef __HAVE_KMS__
01670         if (mmsfb->mmskms) {
01671             return mmsfb->mmskms->releaseLayer(this->config.id);
01672         }
01673 #endif
01674     }
01675 
01676     return false;
01677 }
01678 
01679 bool MMSFBLayer::restoreLayer() {
01680 
01681     // check if initialized
01682     INITCHECK;
01683 
01684     if (this->config.backend == MMSFB_BE_FBDEV) {
01685 #ifdef __HAVE_FBDEV__
01686         if (mmsfb->mmsfbdev) {
01687             return mmsfb->mmsfbdev->restoreLayer(this->config.id);
01688         }
01689 #endif
01690     } else if (this->config.backend == MMSFB_BE_KMS) {
01691 #ifdef __HAVE_KMS__
01692         if (mmsfb->mmskms) {
01693             return mmsfb->mmskms->restoreLayer(this->config.id);
01694         }
01695 #endif
01696     }
01697 
01698     return false;
01699 }
01700 
01701 bool MMSFBLayer::createSurface(MMSFBSurface **surface, int w, int h,
01702                                MMSFBSurfacePixelFormat pixelformat, int backbuffer) {
01703 
01704     // check if initialized
01705     INITCHECK;
01706 
01707     if (pixelformat == MMSFB_PF_NONE) {
01708         pixelformat = this->config.surface_pixelformat;
01709 
01710         if (this->config.outputtype == MMSFB_OT_OGL) {
01711             pixelformat = MMSFB_PF_ABGR;
01712         }
01713 
01714 /*toberemoved        pixelformat = this->config.pixelformat;
01715         if (!isAlphaPixelFormat(pixelformat)) {
01716             // the gui internally needs surfaces with alpha channel
01717             // now we have to decide if we are working in RGB or YUV color space
01718             pixelformat = this->config.surface_pixelformat;
01719             if ((pixelformat == MMSFB_PF_NONE)||((pixelformat != MMSFB_PF_ARGB)&&(pixelformat != MMSFB_PF_AiRGB)&&(pixelformat != MMSFB_PF_AYUV))) {
01720                 // use autodetection
01721                 if (!isRGBPixelFormat(pixelformat))
01722                     // so switch all non-alpha pixelformats to AYUV
01723                     pixelformat = MMSFB_PF_AYUV;
01724                 else
01725                     // so switch all non-alpha pixelformats to ARGB
01726                     pixelformat = MMSFB_PF_ARGB;
01727             }
01728         }
01729         else
01730         if (isIndexedPixelFormat(pixelformat))
01731             // the gui internally needs non-indexed surfaces
01732             // so switch all indexed pixelformats to ARGB
01733             pixelformat = MMSFB_PF_ARGB;
01734 */
01735     }
01736 
01737     if (firsttime_createsurface) {
01738         printf("DISKO: Pixelformat %s is used for surfaces.\n", getMMSFBPixelFormatString(pixelformat).c_str());
01739         firsttime_createsurface = false;
01740     }
01741     if (mmsfb->createSurface(surface, w, h, pixelformat, backbuffer, (this->config.buffermode == MMSFB_BM_BACKSYSTEM))) {
01742         (*surface)->layer = this;
01743         return true;
01744     } else {
01745         return false;
01746     }
01747 }
01748 
01749 bool MMSFBLayer::createWindow(MMSFBWindow **window, int x, int y, int w, int h,
01750                               MMSFBSurfacePixelFormat pixelformat, bool usealpha, int backbuffer) {
01751 
01752     // check if initialized
01753     INITCHECK;
01754 
01755     /* check if i am the right layer */
01756     MMSFBLayer *layer;
01757     mmsfbwindowmanager->getLayer(&layer);
01758     if (layer != this) {
01759         MMSFB_SetError(0, "not the right layer, cannot create MMSFBWindow");
01760         return false;
01761     }
01762 
01763     if (pixelformat == MMSFB_PF_NONE) {
01764         if (usealpha) {
01765             // use preset window pixelformat
01766             pixelformat = this->config.window_pixelformat;
01767         }
01768         else {
01769             // use layer pixelformat
01770             pixelformat = this->config.pixelformat;
01771 /*          if (isAlphaPixelFormat(pixelformat)) {
01772                 // switch all alpha pixelformats to RGB32
01773                 pixelformat = MMSFB_PF_RGB32;
01774             }
01775             else
01776             if (isIndexedPixelFormat(pixelformat)) {
01777                 // switch all indexed pixelformats to RGB32
01778                 pixelformat = MMSFB_PF_RGB32;
01779             }*/
01780         }
01781 
01782         if (this->config.outputtype == MMSFB_OT_OGL) {
01783             pixelformat = MMSFB_PF_ABGR;
01784         }
01785 
01786     }
01787 
01788 
01789     if (usealpha) {
01790         if (firsttime_createwindow_usealpha) {
01791             printf("DISKO: Pixelformat %s is used for windows with alphachannel.\n", getMMSFBPixelFormatString(pixelformat).c_str());
01792             firsttime_createwindow_usealpha = false;
01793         }
01794     }
01795     else
01796         if (firsttime_createwindow_noalpha) {
01797             printf("DISKO: Pixelformat %s is used for windows with no alphachannel.\n", getMMSFBPixelFormatString(pixelformat).c_str());
01798             firsttime_createwindow_noalpha = false;
01799         }
01800 
01801 
01802 #ifdef USE_DFB_WINMAN
01803 
01804     DFBResult               dfbres;
01805     IDirectFBWindow         *dfbwindow;
01806     DFBWindowDescription    window_desc;
01807 
01808     /* create window description */
01809     window_desc.flags = (DFBWindowDescriptionFlags)(DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT | DWDESC_CAPS);
01810     window_desc.posx = x;
01811     window_desc.posy = y;
01812     window_desc.width = w;
01813     window_desc.height = h;
01814     window_desc.pixelformat = getDFBPixelFormatFromString(pixelformat);
01815 
01816     /* set caps - differs between alpha and non-alpha pixelformats */
01817     if (!isAlphaPixelFormat(pixelformat)) {
01818         if (backbuffer)
01819             window_desc.caps = (DFBWindowCapabilities)(DWCAPS_DOUBLEBUFFER);
01820         else
01821             window_desc.caps = (DFBWindowCapabilities)0;
01822     }
01823     else {
01824         if (backbuffer)
01825             window_desc.caps = (DFBWindowCapabilities)(DWCAPS_DOUBLEBUFFER | DWCAPS_ALPHACHANNEL);
01826         else
01827             window_desc.caps = (DFBWindowCapabilities)(DWCAPS_ALPHACHANNEL);
01828     }
01829 
01830     /* create the window */
01831     if ((dfbres=this->dfblayer->CreateWindow(this->dfblayer, &window_desc, &dfbwindow)) != DFB_OK) {
01832         MMSFB_SetError(dfbres, "IDirectFBDisplayLayer::CreateWindow(" + iToStr(w) + "x" + iToStr(h) + "," + getDFBPixelFormatString(window_desc.pixelformat) + ") failed");
01833         return false;
01834     }
01835 
01836     /* create a new window instance */
01837     *window = new MMSFBWindow(dfbwindow, window_desc.posx, window_desc.posy);
01838     if (!*window) {
01839         dfbwindow->Release(dfbwindow);
01840         MMSFB_SetError(0, "cannot create new instance of MMSFBWindow");
01841         return false;
01842     }
01843 
01844 #endif
01845 
01846 #ifdef USE_MMSFB_WINMAN
01847 
01848     // create a window surface
01849     MMSFBSurface *surface;
01850     if (!mmsfb->createSurface(&surface, w, h, pixelformat, backbuffer, (this->config.buffermode == MMSFB_BM_BACKSYSTEM)))
01851         return false;
01852     surface->layer=this;
01853     // create a new window instance
01854     *window = new MMSFBWindow(surface, x, y);
01855     if (!*window) {
01856         delete surface;
01857         MMSFB_SetError(0, "cannot create new instance of MMSFBWindow");
01858         return false;
01859     }
01860 
01861     // that is a window surface
01862     surface->setWinSurface();
01863 
01864     // inform the window manager
01865     mmsfbwindowmanager->addWindow(*window);
01866 
01867 #endif
01868 
01869     return true;
01870 }
01871 
01872 void *MMSFBLayer::getImplementation() {
01873 #ifdef __HAVE_XLIB__
01874     return &(this->impl);
01875 #else
01876     return NULL;
01877 #endif
01878 }
01879 
01880 
01881 

Generated by doxygen