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 <sys/types.h>
00034 #include <linux/fb.h>
00035 #include "mmsgui/fb/mmsfb.h"
00036 #include "mmsgui/fb/mmsfbsurfacemanager.h"
00037 #include <string.h>
00038 #include <stdlib.h>
00039
00040
00041 #ifdef DEBUG_LOCK_OUTPUT
00042 #include <sys/syscall.h>
00043 #define PRINT_LOCK(msg...) printf("%s (%lu)\n", ((string)(msg)).c_str(), (pid_t) syscall (SYS_gettid))
00044 #else
00045 #define PRINT_LOCK(msg...)
00046 #endif
00047
00048
00049 MMSFB *mmsfb = new MMSFB();
00050
00051
00052 #define INITCHECK if(!this->initialized){MMSFB_SetError(0,"not initialized");return false;}
00053
00054 void MMSFB_AtExit() {
00055 if (mmsfb)
00056 mmsfb->release();
00057 }
00058
00059 MMSFB::MMSFB() {
00060 this->argc = 0;
00061 this->argv = NULL;
00062 this->initialized = false;
00063 #ifdef __HAVE_DIRECTFB__
00064 this->dfb = NULL;
00065 #endif
00066 #ifdef __HAVE_FBDEV__
00067 this->mmsfbdev = NULL;
00068 #endif
00069 #ifdef __HAVE_KMS__
00070 this->mmskms = NULL;
00071 #endif
00072
00073 #ifdef __HAVE_XLIB__
00074 this->x_display = NULL;
00075 #endif
00076 #ifdef __HAVE_XV__
00077 this->xv_port = 0;
00078 #endif
00079 #ifdef __HAVE_OPENGL__
00080 this->bei = NULL;
00081 #endif
00082
00083
00084 atexit(MMSFB_AtExit);
00085 }
00086
00087 MMSFB::~MMSFB() {
00088 #ifdef __HAVE_XV__
00089 if(this->x_display && this->xv_port) {
00090 XvUngrabPort(this->x_display, this->xv_port, CurrentTime);
00091 }
00092 #endif
00093 }
00094
00095
00096 bool MMSFB::init(int argc, char **argv, MMSFBBackend backend, MMSFBRectangle x11_win_rect,
00097 bool extendedaccel, MMSFBFullScreenMode fullscreen, MMSFBPointerMode pointer,
00098 string appl_name, string appl_icon_name, bool hidden) {
00099
00100
00101 if (this->initialized) {
00102 MMSFB_SetError(0, "already initialized");
00103 return false;
00104 }
00105
00106
00107 this->argc = argc;
00108 this->argv = argv;
00109 this->bin = ((argc && argv) ? argv[0] : "");
00110 this->appliconname = appl_icon_name;
00111 this->applname = appl_name;
00112 this->fullscreen = fullscreen;
00113
00114
00115 memset(this->layer, 0, sizeof(MMSFBLayer *) * MMSFBLAYER_MAXNUM);
00116
00117 #ifdef __HAVE_XLIB__
00118 memset(this->x_windows, 0, sizeof(Window) * MMSFBLAYER_MAXNUM);
00119
00120 this->x11_win_rect = x11_win_rect;
00121 #endif
00122
00123
00124 this->backend = backend;
00125 if (this->backend == MMSFB_BE_DFB) {
00126 #ifdef __HAVE_DIRECTFB__
00127 #else
00128 MMSFB_SetError(0, "compile DFB support!");
00129 return false;
00130 #endif
00131 }
00132 else
00133 if (this->backend == MMSFB_BE_X11) {
00134 #ifdef __HAVE_XLIB__
00135 XInitThreads();
00136 this->resized=false;
00137 #else
00138 MMSFB_SetError(0, "compile X11 support!");
00139 return false;
00140 #endif
00141 }
00142 else
00143 if (this->backend == MMSFB_BE_FBDEV) {
00144 #ifdef __HAVE_FBDEV__
00145 #else
00146 MMSFB_SetError(0, "compile FBDEV support!");
00147 return false;
00148 #endif
00149 }
00150 else
00151 if (this->backend == MMSFB_BE_KMS) {
00152 #ifdef __HAVE_KMS__
00153 #else
00154 MMSFB_SetError(0, "compile KMS support!");
00155 return false;
00156 #endif
00157 }
00158 else {
00159 MMSFB_SetError(0, "wrong backend " + getMMSFBBackendString(backend));
00160 return false;
00161 }
00162
00163
00164 if (this->backend == MMSFB_BE_DFB) {
00165 #ifdef __HAVE_DIRECTFB__
00166 DFBResult dfbres;
00167
00168
00169 DirectFBInit(&this->argc,&this->argv);
00170
00171
00172 if ((dfbres = DirectFBCreate(&this->dfb)) != DFB_OK) {
00173 MMSFB_SetError(dfbres, "DirectFBCreate() failed");
00174 return false;
00175 }
00176 #endif
00177 }
00178 else
00179 if (this->backend == MMSFB_BE_X11) {
00180 #ifdef __HAVE_XLIB__
00181 if (!(this->x_display = XOpenDisplay((char*)0))) {
00182 MMSFB_SetError(0, "XOpenDisplay() failed");
00183 return false;
00184 }
00185
00186 this->x_screen = DefaultScreen(this->x_display);
00187
00188 Window myroot=RootWindow(this->x_display, this->x_screen);
00189 Window root_ret;
00190 int myx,myy;
00191 unsigned int borderw, depthret;
00192 XGetGeometry(this->x_display, myroot, &root_ret, &myx, &myy, (unsigned int *)&(this->display_w), (unsigned int *)&(this->display_h), &borderw, &depthret);
00193
00194 printf("w: %d, h: %d\n", this->display_w, this->display_h);
00195
00196 x_depth=DefaultDepth(this->x_display, this->x_screen);
00197 rootimage = XGetImage(mmsfb->x_display, myroot, 0, 0,
00198 mmsfb->display_w,mmsfb->display_h, -1, ZPixmap);
00199 x_depth=DefaultDepth(this->x_display, this->x_screen);
00200
00201 this->hidden = hidden;
00202 this->pointer = pointer;
00203 #endif
00204 }
00205
00206 this->initialized = true;
00207 return true;
00208 }
00209
00210 bool MMSFB::release() {
00211 #ifdef __HAVE_OPENGL__
00212
00213 if (this->bei) {
00214 delete this->bei;
00215 this->bei = NULL;
00216 }
00217 #endif
00218
00219 if (this->backend == MMSFB_BE_DFB) {
00220 #ifdef __HAVE_DIRECTFB__
00221 if (this->dfb)
00222 this->dfb->Release(this->dfb);
00223 #endif
00224 }
00225 else
00226 if (this->backend == MMSFB_BE_FBDEV) {
00227 #ifdef __HAVE_FBDEV__
00228 if (this->mmsfbdev) {
00229 delete this->mmsfbdev;
00230 this->mmsfbdev = NULL;
00231 }
00232 #endif
00233 }
00234 else
00235 if (this->backend == MMSFB_BE_KMS) {
00236 #ifdef __HAVE_KMS__
00237 if (this->mmskms) {
00238 delete this->mmskms;
00239 this->mmskms = NULL;
00240 }
00241 #endif
00242 }
00243 else {
00244 #ifdef __HAVE_XLIB__
00245 #endif
00246 }
00247
00248 this->initialized = false;
00249 return true;
00250 }
00251
00252 bool MMSFB::isInitialized() {
00253 return this->initialized;
00254 }
00255
00256 MMSFBBackend MMSFB::getBackend() {
00257 return this->backend;
00258 }
00259
00260 bool MMSFB::lock() {
00261 PRINT_LOCK("mmsfb::lock");
00262 this->Lock.lock();
00263 return true;
00264 }
00265
00266 bool MMSFB::unlock() {
00267 PRINT_LOCK("mmsfb::unlock");
00268
00269 if(this->Lock.unlock() == 0)
00270 return true;
00271 else
00272 return false;
00273 }
00274
00275 bool MMSFB::getLayer(int id, MMSFBLayer **layer, MMSFBOutputType outputtype, bool virtual_console) {
00276
00277
00278 INITCHECK;
00279
00280 if (this->layer[id]) {
00281
00282 *layer = this->layer[id];
00283 return true;
00284 }
00285
00286
00287
00288 if (this->backend == MMSFB_BE_X11) {
00289 if (outputtype == MMSFB_OT_XVSHM) {
00290 #ifdef __HAVE_XV__
00291 #else
00292 MMSFB_SetError(0, "compile X11/XV support!");
00293 return false;
00294 #endif
00295 }
00296 else
00297 if (outputtype == MMSFB_OT_OGL) {
00298 #ifdef __HAVE_OPENGL__
00299 #else
00300 MMSFB_SetError(0, "compile OPENGL support!");
00301 return false;
00302 #endif
00303 #ifdef __HAVE_GLX__
00304 #else
00305 #ifdef __HAVE_EGL__
00306 #else
00307 MMSFB_SetError(0, "compile GLX or EGL support!");
00308 return false;
00309 #endif
00310 #endif
00311 }
00312 }
00313 else
00314 if ((this->backend == MMSFB_BE_FBDEV) || (this->backend == MMSFB_BE_KMS)) {
00315 if (outputtype == MMSFB_OT_OGL) {
00316 #ifdef __HAVE_OPENGL__
00317 #else
00318 MMSFB_SetError(0, "compile OPENGL support!");
00319 return false;
00320 #endif
00321 #ifdef __HAVE_EGL__
00322 #else
00323 MMSFB_SetError(0, "compile EGL support!");
00324 return false;
00325 #endif
00326 }
00327 }
00328
00329
00330 if (this->backend == MMSFB_BE_FBDEV) {
00331 #ifdef __HAVE_FBDEV__
00332 if (!this->mmsfbdev) {
00333 if (outputtype == MMSFB_OT_MATROXFB) {
00334
00335 this->mmsfbdev = new MMSFBDevMatrox();
00336 }
00337 else
00338 if (outputtype == MMSFB_OT_DAVINCIFB) {
00339
00340 this->mmsfbdev = new MMSFBDevDavinci();
00341 }
00342 else
00343 if (outputtype == MMSFB_OT_OMAPFB) {
00344
00345 DEBUGMSG("MMSGUI", "create new MMSFBDevOmap()");
00346 this->mmsfbdev = new MMSFBDevOmap();
00347 DEBUGMSG("MMSGUI", "created new MMSFBDevOmap()");
00348 }
00349 else {
00350
00351 DEBUGMSG("MMSGUI", "create generic fbdev");
00352 this->mmsfbdev = new MMSFBDev();
00353 }
00354
00355 if (this->mmsfbdev) {
00356 if (!this->mmsfbdev->openDevice(NULL, (virtual_console) ? MMSFBDEV_QUERY_CONSOLE : MMSFBDEV_NO_CONSOLE)) {
00357 MMSFB_SetError(0, "MMSFBDEV device cannot be opened");
00358 return false;
00359 }
00360 }
00361 }
00362 #endif
00363 }
00364
00365 if (this->backend == MMSFB_BE_KMS) {
00366 #ifdef __HAVE_KMS__
00367 if (!this->mmskms) {
00368
00369 DEBUGMSG("MMSGUI", "create generic kms");
00370 this->mmskms = new MMSKms();
00371
00372 if (this->mmskms) {
00373 if (!this->mmskms->openDevice(outputtype)) {
00374 MMSFB_SetError(0, "MMSKms device cannot be opened");
00375 return false;
00376 }
00377 }
00378 }
00379 #endif
00380 }
00381
00382
00383
00384 if (outputtype == MMSFB_OT_OGL) {
00385 #ifdef __HAVE_OPENGL__
00386 if (!this->bei) {
00387
00388 this->bei = new MMSFBBackEndInterface();
00389 }
00390 #endif
00391 }
00392
00393
00394
00395
00396
00397 *layer = new MMSFBLayer(id, this->backend, outputtype);
00398 if (!*layer) {
00399 MMSFB_SetError(0, "cannot create new instance of MMSFBLayer");
00400 return false;
00401 }
00402 if (!(*layer)->isInitialized()) {
00403 delete *layer;
00404 *layer = NULL;
00405 MMSFB_SetError(0, "cannot initialize MMSFBLayer");
00406 return false;
00407 }
00408
00409
00410 this->layer[id] = *layer;
00411
00412 return true;
00413 }
00414
00415
00416 bool MMSFB::getLayer(int id, MMSFBLayer **layer) {
00417
00418
00419 INITCHECK;
00420
00421 if (this->layer[id]) {
00422
00423 *layer = this->layer[id];
00424 return true;
00425 }
00426
00427
00428 return false;
00429 }
00430
00431
00432 void *MMSFB::getX11Window() {
00433 if (this->backend == MMSFB_BE_DFB) {
00434 #ifdef __HAVE_DIRECTFB__
00435 #endif
00436 }
00437 else
00438 if (this->backend == MMSFB_BE_FBDEV) {
00439 #ifdef __HAVE_FBDEV__
00440 #endif
00441 }
00442 else
00443 if (this->backend == MMSFB_BE_KMS) {
00444 #ifdef __HAVE_KMS__
00445 #endif
00446 }
00447 else {
00448 #ifdef __HAVE_XLIB__
00449
00450 return &this->input_window;
00451
00452 #endif
00453 }
00454 return NULL;
00455 }
00456 void *MMSFB::getX11Display() {
00457 if (this->backend == MMSFB_BE_DFB) {
00458 #ifdef __HAVE_DIRECTFB__
00459 #endif
00460 }
00461 else
00462 if (this->backend == MMSFB_BE_FBDEV) {
00463 #ifdef __HAVE_FBDEV__
00464 #endif
00465 }
00466 else
00467 if (this->backend == MMSFB_BE_KMS) {
00468 #ifdef __HAVE_KMS__
00469 #endif
00470 }
00471 else {
00472 #ifdef __HAVE_XLIB__
00473 return this->x_display;
00474 #endif
00475 }
00476 return NULL;
00477 }
00478
00479 bool MMSFB::refresh() {
00480
00481 INITCHECK;
00482
00483 if (this->backend == MMSFB_BE_DFB) {
00484 #ifdef __HAVE_DIRECTFB__
00485 #endif
00486 }
00487 else
00488 if (this->backend == MMSFB_BE_FBDEV) {
00489 #ifdef __HAVE_FBDEV__
00490 #endif
00491 }
00492 else
00493 if (this->backend == MMSFB_BE_KMS) {
00494 #ifdef __HAVE_KMS__
00495 #endif
00496 }
00497 else {
00498 #ifdef __HAVE_XLIB__
00499 MMSFBSurface *suf;
00500 if (this->layer[0]->getSurface(&suf))
00501 suf->refresh();
00502 #endif
00503 }
00504
00505 return true;
00506 }
00507
00508 bool MMSFB::createSurface(MMSFBSurface **surface, int w, int h, MMSFBSurfacePixelFormat pixelformat, int backbuffer, bool systemonly) {
00509
00510 INITCHECK;
00511
00512
00513 *surface = mmsfbsurfacemanager->createSurface(w, h, pixelformat, backbuffer, systemonly);
00514
00515 if (*surface)
00516 return true;
00517 else
00518 return false;
00519 }
00520
00521 #ifdef __HAVE_DIRECTFB__
00522 bool MMSFB::createImageProvider(IDirectFBImageProvider **provider, string filename) {
00523 *provider = NULL;
00524 if (this->backend == MMSFB_BE_DFB) {
00525 #ifdef __HAVE_DIRECTFB__
00526 DFBResult dfbres;
00527
00528
00529 INITCHECK;
00530
00531
00532 if ((dfbres=this->dfb->CreateImageProvider(this->dfb, filename.c_str(), provider)) != DFB_OK) {
00533 MMSFB_SetError(dfbres, "IDirectFB::CreateImageProvider(" + filename + ") failed");
00534 return false;
00535 }
00536
00537 return true;
00538 #endif
00539 }
00540 if (this->backend == MMSFB_BE_FBDEV) {
00541 #ifdef __HAVE_FBDEV__
00542 #endif
00543 }
00544 else {
00545 #ifdef __HAVE_XLIB__
00546 #endif
00547 }
00548 return false;
00549 }
00550 #endif
00551
00552 bool MMSFB::createFont(MMSFBFont **font, string filename, int width, int height) {
00553
00554 INITCHECK;
00555
00556
00557 *font = new MMSFBFont(filename, width, height);
00558 if (!*font) {
00559 MMSFB_SetError(0, "cannot create new MMSFBFont instance for " + filename);
00560 return false;
00561 }
00562 if (!(*font)->isInitialized()) {
00563 delete *font;
00564 *font = NULL;
00565 MMSFB_SetError(0, "cannot initialize new MMSFBFont instance for " + filename);
00566 return false;
00567 }
00568 return true;
00569 }
00570
00571 #ifdef __HAVE_XLIB__
00572 bool MMSFB::resizeWindow() {
00573 printf("resize w,h: %d,%d\n", this->target_window_w, this->target_window_h );
00574 XWindowChanges chg;
00575 chg.width=this->target_window_w;
00576 chg.height=this->target_window_h;
00577 printf("rc %d\n",XConfigureWindow(this->x_display, this->x_window,CWWidth|CWHeight, &chg));
00578
00579 return true;
00580 }
00581 #endif
00582
00583 void MMSFB::realignLayer() {
00584 #ifdef __HAVE_XLIB__
00585 static bool first = true;
00586
00587 if(first==false)
00588 return;
00589
00590 first=false;
00591 for(int i=0; ;i++) {
00592 if(mmsfb->x_windows[i]==0)
00593 break;
00594 else if(mmsfb->x_windows[i]!=mmsfb->input_window) {
00595 XLockDisplay(mmsfb->x_display);
00596 XLowerWindow(mmsfb->x_display, mmsfb->x_windows[i]);
00597 XFlush(mmsfb->x_display);
00598 XSync(mmsfb->x_display,False);
00599 X11_IMPL *impl = (X11_IMPL *)mmsfb->layer[i]->getImplementation();
00600
00601 XPutImage(mmsfb->x_display, mmsfb->x_windows[i], impl->x_gc, mmsfb->rootimage, 0,0, 0, 0, mmsfb->display_w,
00602 mmsfb->display_h);
00603
00604
00605
00606 XSync(mmsfb->x_display,False);
00607
00608 XMapWindow(mmsfb->x_display, mmsfb->x_windows[i]);
00609 XRaiseWindow(mmsfb->x_display, mmsfb->input_window);
00610
00611
00612 XFlush(mmsfb->x_display);
00613 XSync(mmsfb->x_display,False);
00614 XUnlockDisplay(mmsfb->x_display);
00615 }
00616 }
00617 #endif
00618 }
00619
00620 #ifdef __HAVE_KMS__
00621 MMSKms *MMSFB::getKmsInterface() {
00622 return this->mmskms;
00623 }
00624 #endif