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

mmsfbmanager.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/mmsfbmanager.h"
00034 #include "mmsgui/fb/mmsfbsurfacemanager.h"
00035 #include <string.h>
00036 #include <stdlib.h>
00037 
00038 #ifdef __HAVE_XRANDR__
00039 #include <X11/extensions/Xrandr.h>
00040 #endif
00041 
00042 MMS_CREATEERROR(MMSFBManagerError);
00043 
00044 /* initialize the mmsfbmanager object */
00045 MMSFBManager mmsfbmanager;
00046 
00047 /* exit handler routine */
00048 void mmsfbmanager_onexit(int num, void *arg) {
00049     MMSFBManager *o=(MMSFBManager*)arg;
00050     o->release();
00051 }
00052 
00053 MMSFBManager::MMSFBManager() {
00054     // init me
00055     this->graphicslayer = NULL;
00056     this->videolayer = NULL;
00057     this->graphicslayerid = -1;
00058     this->videolayerid = -1;
00059     this->layercount = 0;
00060 }
00061 
00062 MMSFBManager::~MMSFBManager() {
00063 }
00064 
00065 bool MMSFBManager::init(int argc, char **argv, string appl_name, string appl_icon_name,
00066                         bool virtual_console, bool flip_flush) {
00067     int myargc=argc;
00068     char *myargv[255];
00069     int i;
00070 
00071     // save virtual console state
00072     this->virtual_console = virtual_console;
00073 
00074     // per default we have one layer
00075     this->layercount = 1;
00076 
00077     for(i=0;i<argc;i++)
00078         myargv[i]=strdup(argv[i]);
00079 
00080     DEBUGMSG("MMSGUI", "init mmsfb");
00081     bool ea = config.getExtendedAccel();
00082 #ifdef  __HAVE_DIRECTFB__
00083     if (config.getAllocMethod() == "DFB") {
00084         // use dfb even if extended accel
00085         ea = false;
00086     }
00087 #endif
00088 
00089     if (this->config.getRotateScreen() == 180) {
00090         // set rotate by 180° flag
00091         MMSFBBase_rotate180 = true;
00092     }
00093 
00094     // get layer settings from config
00095     MMSConfigDataLayer videolayer_conf = this->config.getVideoLayer();
00096     MMSConfigDataLayer graphicslayer_conf = this->config.getGraphicsLayer();
00097 
00098 #ifdef  __HAVE_DIRECTFB__
00099     if(videolayer_conf.outputtype == MMSFB_OT_X11) {
00100         myargv[myargc++] = strdup("--dfb:system=x11");
00101         char mode[24];
00102         snprintf(mode, 24, "--dfb:mode=%dx%d", graphicslayer_conf.rect.w, graphicslayer_conf.rect.h);
00103         myargv[myargc++] = strdup(mode);
00104     }
00105 #endif
00106 
00107     // init the MMSFB class
00108     if (!mmsfb->init(myargc, myargv, config.getBackend(), graphicslayer_conf.rect,
00109                      ea, config.getFullScreen(), config.getPointer(), appl_name, appl_icon_name, config.getHideApplication())) {
00110         DEBUGMSG("MMSGUI", "init mmsfb failed!");
00111         throw MMSFBManagerError(0, MMSFB_LastErrorString);
00112     }
00113 
00114     DEBUGMSG("MMSGUI", "get video layer");
00115     if (!mmsfb->getLayer(videolayer_conf.id, &this->videolayer, videolayer_conf.outputtype, this->virtual_console))
00116         throw MMSFBManagerError(0, MMSFB_LastErrorString);
00117 
00118     if (videolayer_conf.id == graphicslayer_conf.id) {
00119         DEBUGMSG("MMSGUI", "video layer and graphics layer are the same");
00120         this->graphicslayer = this->videolayer;
00121 
00122         if (!flip_flush)
00123             this->graphicslayer->setFlipFlags(MMSFB_FLIP_ONSYNC);
00124         else
00125             this->graphicslayer->setFlipFlags(MMSFB_FLIP_ONSYNC | MMSFB_FLIP_FLUSH);
00126     }
00127     else {
00128         this->layercount++;
00129         DEBUGMSG("MMSGUI", "get graphics layer");
00130         if (!mmsfb->getLayer(graphicslayer_conf.id, &this->graphicslayer, graphicslayer_conf.outputtype, false))
00131             throw MMSFBManagerError(0, MMSFB_LastErrorString);
00132 
00133         if (!flip_flush)
00134             this->graphicslayer->setFlipFlags(MMSFB_FLIP_ONSYNC);
00135         else
00136             this->graphicslayer->setFlipFlags(MMSFB_FLIP_ONSYNC | MMSFB_FLIP_FLUSH);
00137 
00138         if (videolayer_conf.outputtype == MMSFB_OT_MATROXFB)
00139             this->videolayer->setFlipFlags(MMSFB_FLIP_WAITFORSYNC);
00140         else
00141             this->videolayer->setFlipFlags(MMSFB_FLIP_ONSYNC);
00142     }
00143 
00144     if (!this->graphicslayer->getID(&this->graphicslayerid))
00145         throw MMSFBManagerError(0, MMSFB_LastErrorString);
00146 
00147     if (!this->videolayer->getID(&this->videolayerid))
00148         throw MMSFBManagerError(0, MMSFB_LastErrorString);
00149 
00150     /* set on exit handler */
00151     on_exit(mmsfbmanager_onexit, this);
00152 
00153     return true;
00154 }
00155 
00156 void MMSFBManager::release() {
00157     DEBUGMSG("MMSGUI", "release mmsfb");
00158     if (this->videolayer)
00159         delete this->videolayer;
00160     mmsfb->release();
00161 }
00162 
00163 void MMSFBManager::applySettings() {
00164     DEBUGMSG("MMSGUI", "configure graphics layer");
00165 
00166     // get layer settings from config
00167     MMSConfigDataLayer videolayer_conf = this->config.getVideoLayer();
00168     MMSConfigDataLayer graphicslayer_conf = this->config.getGraphicsLayer();
00169 
00170     // get the window pixelformat
00171     MMSFBSurfacePixelFormat window_pixelformat = config.getGraphicsWindowPixelformat();
00172     switch (window_pixelformat) {
00173     case MMSFB_PF_ARGB:
00174     case MMSFB_PF_AiRGB:
00175     case MMSFB_PF_AYUV:
00176     case MMSFB_PF_ARGB4444:
00177     case MMSFB_PF_RGB16:
00178         break;
00179     default:
00180         // window pixelformat not set or unsupported, use the layer pixelformat
00181         window_pixelformat = graphicslayer_conf.pixelformat;
00182         if (!isAlphaPixelFormat(window_pixelformat)) {
00183             // the gui internally needs surfaces with alpha channel
00184             // now we have to decide if we are working in RGB or YUV color space
00185             if (!isRGBPixelFormat(window_pixelformat))
00186                 // so switch all non-alpha pixelformats to AYUV
00187                 window_pixelformat = MMSFB_PF_AYUV;
00188             else
00189                 // so switch all non-alpha pixelformats to ARGB
00190                 window_pixelformat = MMSFB_PF_ARGB;
00191         }
00192         else
00193         if (isIndexedPixelFormat(window_pixelformat)) {
00194             // the gui internally needs non-indexed surfaces
00195             // so switch all indexed pixelformats to ARGB
00196             window_pixelformat = MMSFB_PF_ARGB;
00197         }
00198         break;
00199     }
00200 
00201     // get the surface pixelformat
00202     MMSFBSurfacePixelFormat surface_pixelformat = config.getGraphicsSurfacePixelformat();
00203     switch (surface_pixelformat) {
00204     case MMSFB_PF_ARGB:
00205     case MMSFB_PF_AiRGB:
00206     case MMSFB_PF_AYUV:
00207     case MMSFB_PF_ARGB4444:
00208     case MMSFB_PF_RGB16:
00209         break;
00210     default:
00211         // surface pixelformat not set or unsupported, use the layer pixelformat
00212         surface_pixelformat = graphicslayer_conf.pixelformat;
00213         if (!isAlphaPixelFormat(surface_pixelformat)) {
00214             // the gui internally needs surfaces with alpha channel
00215             // now we have to decide if we are working in RGB or YUV color space
00216             if (!isRGBPixelFormat(surface_pixelformat))
00217                 // so switch all non-alpha pixelformats to AYUV
00218                 surface_pixelformat = MMSFB_PF_AYUV;
00219             else
00220                 // so switch all non-alpha pixelformats to ARGB
00221                 surface_pixelformat = MMSFB_PF_ARGB;
00222         }
00223         else
00224         if (isIndexedPixelFormat(surface_pixelformat)) {
00225             // the gui internally needs non-indexed surfaces
00226             // so switch all indexed pixelformats to ARGB
00227             surface_pixelformat = MMSFB_PF_ARGB;
00228         }
00229         break;
00230     }
00231 
00232     // set exclusive access to the graphics layer
00233     DEBUGMSG("MMSGUI", "set exclusive access");
00234     if (!this->graphicslayer->setExclusiveAccess())
00235         throw MMSFBManagerError(0, MMSFB_LastErrorString);
00236 
00237     DEBUGMSG("MMSGUI", "set configuration");
00238     if(!this->graphicslayer->setConfiguration(graphicslayer_conf.rect.w, graphicslayer_conf.rect.h,
00239                                                graphicslayer_conf.pixelformat,
00240                                                graphicslayer_conf.buffermode,
00241                                                graphicslayer_conf.options,
00242                                                window_pixelformat,
00243                                                surface_pixelformat))
00244         throw MMSFBManagerError(0, MMSFB_LastErrorString);
00245 
00246 #ifdef __HAVE_XRANDR__
00247     if(config.getBackend() == MMSFB_BE_X11 && MMSFBBase_rotate180) {
00248         X11_IMPL *impl = (X11_IMPL*)this->graphicslayer->getImplementation();
00249         
00250         /* check for RandR extension */
00251         int event_base, error_base;
00252         if (!XRRQueryExtension (impl->x_display, &event_base, &error_base)) {
00253             fprintf(stderr, "RandR extension missing: Rotation not supported\n");
00254         } else {
00255             Window root = DefaultRootWindow(impl->x_display);
00256             XRRScreenConfiguration *sc = XRRGetScreenInfo(impl->x_display, root);
00257             if(sc) {
00258                 Rotation rot = RR_Rotate_0;
00259                 SizeID size = XRRConfigCurrentConfiguration(sc, &rot);
00260                 if(rot != RR_Rotate_180) {
00261                     XRRSetScreenConfig(impl->x_display, sc, root, size, RR_Rotate_180, CurrentTime);
00262                 }
00263                 MMSFBBase_rotate180 = false;
00264             }
00265         }       
00266     }
00267 #endif
00268 
00269     if (this->videolayerid != this->graphicslayerid) {
00270 #ifdef  __HAVE_DIRECTFB__
00271         if (config.getBackend() == MMSFB_BE_X11) {
00272             //give a little time to window routines
00273             usleep(300000);
00274         }
00275 #endif
00276 
00277         // use both layers
00278         DEBUGMSG("MMSGUI", "configure video layer");
00279 
00280         DEBUGMSG("MMSGUI", "set exclusive access");
00281         // set exclusive access to the video layer
00282         if (!this->videolayer->setExclusiveAccess())
00283             throw MMSFBManagerError(0, MMSFB_LastErrorString);
00284 
00285         DEBUGMSG("MMSGUI", "set configuration");
00286         // set video layer's config
00287         if (!this->videolayer->setConfiguration(videolayer_conf.rect.w, videolayer_conf.rect.h,
00288                                                 videolayer_conf.pixelformat,
00289                                                 videolayer_conf.buffermode,
00290                                                 videolayer_conf.options))
00291             throw MMSFBManagerError(0, MMSFB_LastErrorString);
00292         //this->videolayer->dfblayer->SetFieldParity(this->videolayer->dfblayer,0);
00293 
00294         // set the full opacity of the graphics layer
00295         this->graphicslayer->setOpacity(0);
00296 
00297         if (graphicslayer_conf.outputtype == MMSFB_OT_VIAFB) {
00298             // set the video layer behind the graphics layer
00299             DEBUGMSG("MMSGUI", "set the video layer behind the graphics layer");
00300             this->videolayer->setLevel(-1);
00301         }
00302         else
00303         if (graphicslayer_conf.outputtype == MMSFB_OT_XSHM) {
00304             DEBUGMSG("MMSGUI", "set the video layer behind the graphics layer");
00305             this->graphicslayer->setLevel(+1);
00306         }
00307     }
00308 
00309     // set global surface attributes
00310     string buffermode = graphicslayer_conf.buffermode;
00311     MMSFBSurface *gls;
00312     if (this->graphicslayer->getSurface(&gls, this->virtual_console)) {
00313         // set the static extended accel flag
00314         gls->setExtendedAcceleration(config.getExtendedAccel());
00315 
00316         // set the global alloc method (default is malloc)
00317         if (mmsfb->getBackend() == MMSFB_BE_DFB) {
00318 #ifdef  __HAVE_DIRECTFB__
00319             string am = config.getAllocMethod();
00320             if (am == "MALLOC") {
00321                 if (!config.getExtendedAccel())
00322                     gls->setAllocMethod(MMSFBSurfaceAllocMethod_dfb);
00323             }
00324             else
00325                 gls->setAllocMethod(MMSFBSurfaceAllocMethod_dfb);
00326 #endif
00327         }
00328         else
00329         if (graphicslayer_conf.outputtype == MMSFB_OT_OGL) {
00330             gls->setAllocMethod(MMSFBSurfaceAllocMethod_ogl);
00331         }
00332     }
00333 
00334     // init the mmsfbwindowmanager
00335     mmsfbwindowmanager->init(this->graphicslayer, (config.getPointer()==MMSFB_PM_TRUE));
00336 
00337     DEBUGMSG("MMSGUI", "creating temporary surface: %dx%d, %s", graphicslayer_conf.rect.w, graphicslayer_conf.rect.h, getMMSFBPixelFormatString(surface_pixelformat).c_str());
00338     mmsfbsurfacemanager->createTemporarySurface(graphicslayer_conf.rect.w, graphicslayer_conf.rect.h, surface_pixelformat, (buffermode == MMSFB_BM_BACKSYSTEM));
00339 }
00340 
00341 
00342 MMSFBLayer *MMSFBManager::getVideoLayer() {
00343     return this->videolayer;
00344 }
00345 
00346 MMSFBLayer *MMSFBManager::getGraphicsLayer() {
00347     return this->graphicslayer;
00348 }
00349 
00350 int MMSFBManager::getLayerCount() {
00351     return this->layercount;
00352 }
00353 

Generated by doxygen