00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00045 MMSFBManager mmsfbmanager;
00046
00047
00048 void mmsfbmanager_onexit(int num, void *arg) {
00049 MMSFBManager *o=(MMSFBManager*)arg;
00050 o->release();
00051 }
00052
00053 MMSFBManager::MMSFBManager() {
00054
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
00072 this->virtual_console = virtual_console;
00073
00074
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
00085 ea = false;
00086 }
00087 #endif
00088
00089 if (this->config.getRotateScreen() == 180) {
00090
00091 MMSFBBase_rotate180 = true;
00092 }
00093
00094
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
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
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
00167 MMSConfigDataLayer videolayer_conf = this->config.getVideoLayer();
00168 MMSConfigDataLayer graphicslayer_conf = this->config.getGraphicsLayer();
00169
00170
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
00181 window_pixelformat = graphicslayer_conf.pixelformat;
00182 if (!isAlphaPixelFormat(window_pixelformat)) {
00183
00184
00185 if (!isRGBPixelFormat(window_pixelformat))
00186
00187 window_pixelformat = MMSFB_PF_AYUV;
00188 else
00189
00190 window_pixelformat = MMSFB_PF_ARGB;
00191 }
00192 else
00193 if (isIndexedPixelFormat(window_pixelformat)) {
00194
00195
00196 window_pixelformat = MMSFB_PF_ARGB;
00197 }
00198 break;
00199 }
00200
00201
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
00212 surface_pixelformat = graphicslayer_conf.pixelformat;
00213 if (!isAlphaPixelFormat(surface_pixelformat)) {
00214
00215
00216 if (!isRGBPixelFormat(surface_pixelformat))
00217
00218 surface_pixelformat = MMSFB_PF_AYUV;
00219 else
00220
00221 surface_pixelformat = MMSFB_PF_ARGB;
00222 }
00223 else
00224 if (isIndexedPixelFormat(surface_pixelformat)) {
00225
00226
00227 surface_pixelformat = MMSFB_PF_ARGB;
00228 }
00229 break;
00230 }
00231
00232
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
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
00273 usleep(300000);
00274 }
00275 #endif
00276
00277
00278 DEBUGMSG("MMSGUI", "configure video layer");
00279
00280 DEBUGMSG("MMSGUI", "set exclusive access");
00281
00282 if (!this->videolayer->setExclusiveAccess())
00283 throw MMSFBManagerError(0, MMSFB_LastErrorString);
00284
00285 DEBUGMSG("MMSGUI", "set configuration");
00286
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
00293
00294
00295 this->graphicslayer->setOpacity(0);
00296
00297 if (graphicslayer_conf.outputtype == MMSFB_OT_VIAFB) {
00298
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
00310 string buffermode = graphicslayer_conf.buffermode;
00311 MMSFBSurface *gls;
00312 if (this->graphicslayer->getSurface(&gls, this->virtual_console)) {
00313
00314 gls->setExtendedAcceleration(config.getExtendedAccel());
00315
00316
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
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