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

mmsfbwindowmanager.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 <cstring>
00034 #include "mmsgui/fb/mmsfbwindowmanager.h"
00035 #include "mmsinfo/mmsinfo.h"
00036 #include "mmsgui/fb/mmsfb.h"
00037 
00038 //#define DEBUG_LOCK_OUTPUT
00039 #ifdef DEBUG_LOCK_OUTPUT
00040 #include <sys/syscall.h>
00041 #define PRINT_LOCK(msg...) printf("%s %s - %d (%lu)\n", ((string)(msg)).c_str(),__FUNCTION__,__LINE__,(pid_t) syscall (SYS_gettid))
00042 #else
00043 #define PRINT_LOCK(msg...)
00044 #endif
00045 
00046 
00047 /* initialize the mmsfbwindowmanager object */
00048 MMSFBWindowManager *mmsfbwindowmanager = new MMSFBWindowManager();
00049 
00050 #define INITCHECK  if(!this->layer){MMSFB_SetError(0,"not initialized");return false;}
00051 
00052 MMSFBWindowManager::MMSFBWindowManager() {
00053     // init me
00054     this->layer = NULL;
00055     this->layer_surface = NULL;
00056     this->dst_surface = NULL;
00057     this->layer_pixelformat = MMSFB_PF_NONE;
00058     this->high_freq_surface = NULL;
00059     this->high_freq_saved_surface = NULL;
00060     this->high_freq_region.x1 = 0;
00061     this->high_freq_region.y1 = 0;
00062     this->high_freq_region.x2 = 0;
00063     this->high_freq_region.y2 = 0;
00064     this->high_freq_lastflip = 0;
00065     this->mmsfbwinmanthread = NULL;
00066 
00067     // init pointer values
00068     this->show_pointer = false;
00069     this->pointer_posx = -1;
00070     this->pointer_posy = -1;
00071     this->pointer_rect.x = 0;
00072     this->pointer_rect.y = 0;
00073     this->pointer_rect.w = 0;
00074     this->pointer_rect.h = 0;
00075     this->pointer_region.x1 = 0;
00076     this->pointer_region.y1 = 0;
00077     this->pointer_region.x2 = 0;
00078     this->pointer_region.y2 = 0;
00079     this->pointer_surface = NULL;
00080     this->pointer_opacity = 0;
00081     this->button_pressed = false;
00082     this->pointer_fadecnt = 0;
00083 }
00084 
00085 MMSFBWindowManager::~MMSFBWindowManager() {
00086     for (unsigned int i=0; i < this->windows.size(); i++) {
00087         delete this->windows.at(i).window;
00088     }
00089 }
00090 
00091 bool MMSFBWindowManager::init(MMSFBLayer *layer, bool show_pointer) {
00092 
00093     // check if already initialized
00094     if (this->layer) {
00095         MMSFB_SetError(0, "already initialized");
00096         return false;
00097     }
00098 
00099     // start my thread
00100     if (!this->mmsfbwinmanthread) {
00101         this->mmsfbwinmanthread = new MMSFBWindowManagerThread(&this->high_freq_surface,
00102                                                             &this->high_freq_saved_surface,
00103                                                             &this->high_freq_lastflip,
00104                                                             &this->lock);
00105         if (this->mmsfbwinmanthread)
00106             mmsfbwinmanthread->start();
00107     }
00108 
00109     // set values
00110     this->layer = layer;
00111     this->show_pointer = show_pointer;
00112 
00113     DEBUGMSG("MMSGUI", "MMSFBWindowManager: get layer surface");
00114 
00115     // get the surface of the layer
00116     if (!this->layer->getSurface(&this->layer_surface))
00117         return false;
00118     this->dst_surface = this->layer_surface;
00119 
00120     // get the pixelformat of the layer surface
00121     if (!this->layer_surface->getPixelFormat(&this->layer_pixelformat))
00122         return false;
00123 
00124     // get the pixelformat, create a little temp surface
00125     this->pixelformat = MMSFB_PF_NONE;
00126     this->ogl_mode = false;
00127     MMSFBSurface *ts;
00128     if (this->layer->createSurface(&ts, 8, 1)) {
00129         // okay, get the pixelformat from surface
00130         ts->getPixelFormat(&this->pixelformat);
00131         this->ogl_mode = (ts->allocated_by == MMSFBSurfaceAllocatedBy_ogl);
00132         delete ts;
00133     }
00134 
00135     // use taff?
00136     this->usetaff = false;
00137     switch (this->pixelformat) {
00138     case MMSFB_PF_ARGB:
00139         this->usetaff = true;
00140         this->taffpf = MMSTAFF_PF_ARGB;
00141         break;
00142     case MMSFB_PF_AiRGB:
00143         this->usetaff = true;
00144         this->taffpf = MMSTAFF_PF_AiRGB;
00145         break;
00146     case MMSFB_PF_AYUV:
00147         this->usetaff = true;
00148         this->taffpf = MMSTAFF_PF_AYUV;
00149         break;
00150     case MMSFB_PF_ARGB4444:
00151         this->usetaff = true;
00152         this->taffpf = MMSTAFF_PF_ARGB4444;
00153         break;
00154     case MMSFB_PF_RGB16:
00155         // if running in RGB16 mode, we use an ARGB surface for the mouse pointer
00156         this->usetaff = true;
00157         this->taffpf = MMSTAFF_PF_ARGB;
00158         break;
00159     case MMSFB_PF_ABGR:
00160         this->usetaff = true;
00161         this->taffpf = MMSTAFF_PF_ABGR;
00162         break;
00163     default:
00164         break;
00165     }
00166 
00167     return true;
00168 }
00169 
00170 bool MMSFBWindowManager::reset() {
00171 
00172     // check if initialized
00173     INITCHECK;
00174 
00175     // reset the high freq surface pointer
00176     this->high_freq_surface = NULL;
00177     this->high_freq_saved_surface = NULL;
00178     this->high_freq_lastflip = 0;
00179 
00180     return true;
00181 }
00182 
00183 bool MMSFBWindowManager::getLayer(MMSFBLayer **layer) {
00184 
00185     // check if initialized
00186     INITCHECK;
00187 
00188     // return the layer
00189     *layer = this->layer;
00190 
00191     return true;
00192 }
00193 
00194 void MMSFBWindowManager::lockWM() {
00195     // stop parallel processing
00196     lock.lock();
00197 }
00198 
00199 void MMSFBWindowManager::unlockWM() {
00200     // unlock
00201     lock.unlock();
00202 }
00203 
00204 bool MMSFBWindowManager::addWindow(MMSFBWindow *window) {
00205 
00206     /* check if initialized */
00207     INITCHECK;
00208 
00209     /* stop parallel processing */
00210     lock.lock();
00211 
00212     /* search for duplicate items */
00213     for (unsigned int i=0; i < this->windows.size(); i++)
00214         if (this->windows.at(i).window == window) {
00215             lock.unlock();
00216             return false;
00217         }
00218 
00219     /* add window */
00220     AVAILABLE_WINDOWS awin;
00221     awin.window = window;
00222     awin.vrect.x = 0;
00223     awin.vrect.y = 0;
00224     awin.vrect.w = 0;
00225     awin.vrect.h = 0;
00226     this->windows.push_back(awin);
00227 
00228     /* unlock */
00229     lock.unlock();
00230 
00231     return true;
00232 }
00233 
00234 bool MMSFBWindowManager::removeWindow(MMSFBWindow *window) {
00235 
00236     /* check if initialized */
00237     INITCHECK;
00238 
00239     /* stop parallel processing */
00240     lock.lock();
00241 
00242     /* search for item */
00243     for (unsigned int i=0; i < this->windows.size(); i++)
00244         if (this->windows.at(i).window == window) {
00245 
00246             /* hide the window before removing */
00247             hideWindow(window);
00248 
00249             /* remove it from list */
00250             this->windows.erase(this->windows.begin()+i);
00251 
00252             /* unlock */
00253             lock.unlock();
00254             return true;
00255         }
00256 
00257     /* not found */
00258     lock.unlock();
00259     return false;
00260 }
00261 
00262 bool MMSFBWindowManager::raiseToTop(MMSFBWindow *window) {
00263 
00264     // check if initialized
00265     INITCHECK;
00266 
00267     // stop parallel processing
00268     lock.lock();
00269 
00270     // search for item
00271     for (unsigned int oldpos = 0; oldpos < this->vwins.size(); oldpos++) {
00272         if (this->vwins.at(oldpos).window == window) {
00273             // reload windows config
00274             loadWindowConfig(window, &(this->vwins.at(oldpos)));
00275             VISIBLE_WINDOWS vw = this->vwins.at(oldpos);
00276             unsigned int newpos = oldpos;
00277 
00278             if (oldpos > 0) {
00279                 // check zlevel against lower windows
00280                 for (unsigned int i = oldpos - 1; i >= 0; i--) {
00281                     if (vw.zlevel <= this->vwins.at(i).zlevel) {
00282                         break;
00283                     }
00284                     newpos = i;
00285                 }
00286             }
00287 
00288             if (oldpos + 1 < this->vwins.size()) {
00289                 // check zlevel against upper windows
00290                 for (unsigned int i = oldpos + 1; i < this->vwins.size(); i++) {
00291                     if (vw.zlevel > this->vwins.at(i).zlevel) {
00292                         break;
00293                     }
00294                     newpos = i;
00295                 }
00296             }
00297 
00298             if (newpos != oldpos) {
00299                 // change position in the visible window stack
00300                 this->vwins.erase(this->vwins.begin()+oldpos);
00301                 this->vwins.insert(this->vwins.begin()+newpos, vw);
00302 
00303                 PRINT_LOCK("flipSurface");
00304                 // draw the window
00305                 vw.surface->lock();
00306                 flipSurface(vw.surface, NULL, true);
00307                 PRINT_LOCK("end flipSurface");
00308                 vw.surface->unlock();
00309             }
00310 
00311             // unlock
00312             lock.unlock();
00313             return true;
00314         }
00315     }
00316 
00317     PRINT_LOCK("not found");
00318     // not found
00319     lock.unlock();
00320     return false;
00321 
00322 
00323 /*    // get requested zorder index
00324     zlevel = this->vwins.size() - 1 - zlevel;
00325     if (zlevel < 0)
00326         zlevel = 0;
00327     else
00328     if (zlevel >= (int)this->vwins.size())
00329         zlevel = this->vwins.size() - 1;
00330 
00331     // search for item within visible list
00332     for (unsigned int i=0; i < this->vwins.size(); i++)
00333         if (this->vwins.at(i).window == window) {
00334             // window found
00335             if ((int)i < zlevel) {
00336                 // window is not at the top or the requested zlevel, raise it now
00337                 // if the requested zlevel is less than the current zlevel, nothing will be done
00338                 VISIBLE_WINDOWS vw = this->vwins.at(i);
00339                 this->vwins.erase(this->vwins.begin()+i);
00340                 this->vwins.insert(this->vwins.begin()+zlevel, vw);
00341 
00342                 // change the windows list
00343                 if ((int)this->vwins.size() <= zlevel+1) {
00344                     // at the top
00345                     for (unsigned int i=0; i < this->windows.size(); i++)
00346                         if (this->windows.at(i).window == window) {
00347                             // window found
00348                             if (i < this->windows.size()-1) {
00349                                 // put at the top
00350                                 AVAILABLE_WINDOWS aw = this->windows.at(i);
00351                                 this->windows.erase(this->windows.begin()+i);
00352                                 this->windows.push_back(aw);
00353                             }
00354                             break;
00355                         }
00356                 }
00357                 else {
00358                     for (unsigned int i=0; i < this->windows.size(); i++)
00359                         if (this->windows.at(i).window == window) {
00360                             // window found
00361                             if (i < this->windows.size()-1) {
00362                                 // put it behind the swin
00363                                 MMSFBWindow *swin = this->vwins.at(zlevel + 1).window;
00364                                 for (unsigned int j=0; j < this->windows.size(); j++)
00365                                     if (this->windows.at(j).window == swin) {
00366                                         // window found
00367                                         AVAILABLE_WINDOWS aw = this->windows.at(i);
00368                                         this->windows.insert(this->windows.begin()+j, aw);
00369                                         if (i>=j) i++;
00370                                         this->windows.erase(this->windows.begin()+i);
00371                                         break;
00372                                     }
00373                             }
00374                             break;
00375                         }
00376                 }
00377 
00378                 PRINT_LOCK("flipSurface");
00379                 // draw the window
00380                 vw.surface->lock();
00381                 flipSurface(vw.surface, NULL, true);
00382                 PRINT_LOCK("end flipSurface");
00383                 vw.surface->unlock();
00384             }
00385 
00386             // unlock
00387             lock.unlock();
00388             return true;
00389         }
00390 
00391 
00392     PRINT_LOCK("not found");
00393     // not found
00394     lock.unlock();
00395     return false;
00396 */
00397 
00398 }
00399 
00400 bool MMSFBWindowManager::lowerToBottom(MMSFBWindow *window) {
00401 
00402     /* check if initialized */
00403     INITCHECK;
00404 
00405     /* stop parallel processing */
00406     lock.lock();
00407 
00408     /* search for item */
00409     for (unsigned int i=0; i < this->windows.size(); i++)
00410         if (this->windows.at(i).window == window) {
00411             /* window found */
00412             if (i > 0) {
00413                 /* window is not at the bottom, lower it now */
00414                 AVAILABLE_WINDOWS aw = this->windows.at(i);
00415                 this->windows.erase(this->windows.begin()+i);
00416                 this->windows.insert(this->windows.begin(), aw);
00417 
00418                 /* search for item within visible list */
00419                 for (unsigned int j=0; j < this->vwins.size(); j++)
00420                     if (this->vwins.at(j).window == window) {
00421                         /* window found */
00422                         if (j > 0) {
00423                             /* window is not at the bottom, lower it now */
00424                             VISIBLE_WINDOWS vw = this->vwins.at(j);
00425                             this->vwins.erase(this->vwins.begin()+j);
00426                             this->vwins.insert(this->vwins.begin(), vw);
00427 
00428                             PRINT_LOCK("flipSurface");
00429                             /* draw the window */
00430                             vw.surface->lock();
00431                             flipSurface(vw.surface, NULL, true);
00432                             PRINT_LOCK("end flipSurface");
00433                             vw.surface->unlock();
00434                         }
00435                     }
00436             }
00437 
00438             /* unlock */
00439             lock.unlock();
00440             return true;
00441         }
00442 
00443     /* not found */
00444     lock.unlock();
00445     return false;
00446 }
00447 
00448 
00449 bool MMSFBWindowManager::loadWindowConfig(MMSFBWindow *window, VISIBLE_WINDOWS *vwin) {
00450     vwin->window = window;
00451     vwin->window->getSurface(&vwin->surface);
00452     MMSFBWindowConfig winconf;
00453     vwin->window->getConfiguration(&winconf);
00454     vwin->vrect.x = 0;
00455     vwin->vrect.y = 0;
00456     vwin->vrect.w = 0;
00457     vwin->vrect.h = 0;
00458     for (unsigned int i=0; i < this->windows.size(); i++)
00459         if (this->windows.at(i).window == window) {
00460             vwin->vrect = this->windows.at(i).vrect;
00461             break;
00462         }
00463     vwin->region.x1 = winconf.posx;
00464     vwin->region.y1 = winconf.posy;
00465     vwin->region.x2 = vwin->region.x1 + winconf.surface_config.w - 1;
00466     vwin->region.y2 = vwin->region.y1 + winconf.surface_config.h - 1;
00467     if ((vwin->vrect.w > 0)&&(vwin->vrect.h > 0)) {
00468         // visible rectangle set, so have to adjust region
00469         MMSFBRegion sr = vwin->region;
00470         sr.x1 += vwin->vrect.x;
00471         sr.y1 += vwin->vrect.y;
00472         sr.x2 = sr.x1 + vwin->vrect.w - 1;
00473         sr.y2 = sr.y1 + vwin->vrect.h - 1;
00474         if (sr.x1 < vwin->region.x1)
00475             sr.x1 = vwin->region.x1;
00476         if (sr.y1 < vwin->region.y1)
00477             sr.y1 = vwin->region.y1;
00478         if (sr.x2 > vwin->region.x2)
00479             sr.x2 = vwin->region.x2;
00480         if (sr.y2 > vwin->region.y2)
00481             sr.y2 = vwin->region.y2;
00482         if ((sr.x1 <= vwin->region.x2)&&(sr.y1 <= vwin->region.y2)&&(sr.x2 >= vwin->region.x1)&&(sr.y2 >= vwin->region.y1)) {
00483             // adjusted region okay, set it
00484             vwin->region = sr;
00485         }
00486         else {
00487             // window is outside it's visible region
00488             vwin->region.x1 = 0;
00489             vwin->region.y1 = 0;
00490             vwin->region.x2 = -1;
00491             vwin->region.y2 = -1;
00492         }
00493     }
00494     vwin->alphachannel = winconf.surface_config.surface_buffer->alphachannel;
00495     vwin->opacity = winconf.opacity;
00496     vwin->zlevel = winconf.zlevel;
00497     vwin->lastflip = 0;
00498     vwin->islayersurface = false;
00499     vwin->saved_surface = NULL;
00500     return true;
00501 }
00502 
00503 bool MMSFBWindowManager::showWindow(MMSFBWindow *window, bool locked, bool refresh) {
00504 
00505     /* check if initialized */
00506     INITCHECK;
00507 
00508     /* stop parallel processing */
00509     if (!locked)
00510         lock.lock();
00511 
00512     // search for item
00513     for (unsigned int i = 0; i < this->windows.size(); i++) {
00514         if (this->windows.at(i).window == window) {
00515             // search for duplicate items
00516             for (unsigned int j = 0; j < this->vwins.size(); j++) {
00517                 if (this->vwins.at(j).window == window) {
00518                     // the window is already visible
00519                     if (!locked)
00520                         lock.unlock();
00521                     return false;
00522                 }
00523             }
00524 
00525             // prepare new list item
00526             VISIBLE_WINDOWS vw;
00527             loadWindowConfig(window, &vw);
00528             int pos = 0;
00529 
00530             for (unsigned int j = 0; j < this->vwins.size(); j++) {
00531                 if (vw.zlevel > this->vwins.at(j).zlevel) {
00532                     break;
00533                 }
00534                 pos = j + 1;
00535             }
00536 
00537             // add window to visible list
00538             this->vwins.insert(this->vwins.begin() + pos, vw);
00539 
00540             // draw the window
00541             PRINT_LOCK("flipSurface");
00542             vw.surface->lock();
00543             flipSurface(vw.surface, NULL, true, refresh);
00544             PRINT_LOCK("end flipSurface");
00545             vw.surface->unlock();
00546 
00547             // unlock
00548             if (!locked)
00549                 lock.unlock();
00550 
00551             return true;
00552         }
00553     }
00554 
00555     // not found
00556     if (!locked)
00557         lock.unlock();
00558     return false;
00559 
00560 
00561 #ifdef dddddd
00562     for (unsigned int i = 0; i < this->windows.size(); i++) {
00563         if (this->windows.at(i).window == window) {
00564             /* search for duplicate items */
00565             for (unsigned int j=0; j < this->vwins.size(); j++)
00566                 if (this->vwins.at(j).window == window) {
00567                     /* the window is already visible */
00568                     if (!locked)
00569                         lock.unlock();
00570                     return false;
00571                 }
00572 
00573             /* prepare new list item */
00574             VISIBLE_WINDOWS vwin;
00575             loadWindowConfig(window, &vwin);
00576 
00577             /* add window to visible list */
00578             bool inserted = false;
00579             if (i < this->windows.size()-1) {
00580                 /* first searching for the right position within the window stack */
00581                 for (unsigned int j=0; j < this->vwins.size() && !inserted; j++)
00582                     for (unsigned int k=0; k < this->windows.size() && !inserted; k++)
00583                         if (this->vwins.at(j).window == this->windows.at(k).window)
00584                             if (k > i) {
00585                                 /* insert the window */
00586                                 this->vwins.insert(this->vwins.begin()+j, vwin);
00587                                 inserted = true;
00588                                 break;
00589                             }
00590             }
00591             if (!inserted)
00592                 /* insert at the end (this is the top) */
00593                 this->vwins.push_back(vwin);
00594 
00595             PRINT_LOCK("flipSurface");
00596             /* draw the window */
00597             flipSurface(vwin.surface, NULL, true, refresh);
00598             PRINT_LOCK("end flipSurface");
00599 
00600             /* unlock */
00601             if (!locked)
00602                 lock.unlock();
00603 
00604             return true;
00605         }
00606 
00607     /* not found */
00608     lock.unlock();
00609     return false;
00610 #endif
00611 
00612 
00613 }
00614 
00615 bool MMSFBWindowManager::hideWindow(MMSFBWindow *window, bool locked, bool refresh) {
00616 
00617     /* check if initialized */
00618     INITCHECK;
00619 
00620     /* stop parallel processing */
00621     if (!locked)
00622         lock.lock();
00623 
00624     /* search for item */
00625     for (unsigned int i=0; i < this->vwins.size(); i++)
00626         if (this->vwins.at(i).window == window) {
00627             /* redraw the window with no opacity because must redrawing other windows */
00628             this->vwins.at(i).opacity = 0;
00629 
00630             PRINT_LOCK("flipSurface");
00631             flipSurface(this->vwins.at(i).surface, NULL, true, refresh);
00632             PRINT_LOCK("end flipSurface");
00633 
00634             if (this->high_freq_surface==this->vwins.at(i).surface) {
00635                 /* i was the high_freq_surface */
00636                 this->high_freq_surface = NULL;
00637                 this->high_freq_saved_surface = NULL;
00638                 this->high_freq_lastflip = 0;
00639             }
00640 
00641             /* remove it from list */
00642             this->vwins.erase(this->vwins.begin()+i);
00643 
00644             /* unlock */
00645             if (!locked)
00646                 lock.unlock();
00647 
00648             return true;
00649         }
00650 
00651     /* not found */
00652     if (!locked)
00653         lock.unlock();
00654     return false;
00655 }
00656 
00657 bool MMSFBWindowManager::flipSurface(MMSFBSurface *surface, MMSFBRegion *region,
00658                                      bool locked, bool refresh) {
00659     VISIBLE_WINDOWS *vw = NULL;
00660     MMSFBRegion     ls_region;
00661     bool            high_freq = false;
00662     bool            cleared = false;
00663     bool            win_found = false;
00664 
00665     /* check if initialized */
00666     INITCHECK;
00667 
00668     PRINT_LOCK("enter flipSurface");
00669 
00670     /* stop parallel processing */
00671     if (!locked)
00672         lock.lock();
00673 
00674     if (this->ogl_mode) {
00675         // running in OpenGL mode
00676         // note: GLX can only flip the complete screen!!!
00677         //       EGL too, but currently we run EGL with FRONTONLY, so we do not need a layer flip
00678 //#ifdef  __HAVE_GLX__
00679         surface = NULL;
00680         region = NULL;
00681 //#endif
00682     }
00683 
00684 /*
00685 if (region)
00686 printf("#1winman: region = %d,%d,%d,%d\n", region->x1, region->y1, region->x2, region->y2);
00687 else
00688 printf("#1winman: region = NULL\n");
00689 */
00690 
00691     /* search for item */
00692     if (surface) {
00693         /* surface given */
00694         for (unsigned int i=0; i < this->vwins.size(); i++) {
00695             if (this->vwins.at(i).surface == surface) {
00696                 // surface found
00697                 vw = &(this->vwins.at(i));
00698                 ls_region = vw->region;
00699 
00700                 // calculate the affected region on the layer surface
00701                 if (region != NULL) {
00702                     // only a region
00703                     if (region->x1 > 0) {
00704                         ls_region.x2 = ls_region.x1 + region->x2;
00705                         ls_region.x1 = ls_region.x1 + region->x1;
00706                     }
00707                     else
00708                         ls_region.x2 = ls_region.x1 + region->x2;
00709                     if (region->y1 > 0) {
00710                         ls_region.y2 = ls_region.y1 + region->y2;
00711                         ls_region.y1 = ls_region.y1 + region->y1;
00712                     }
00713                     else
00714                         ls_region.y2 = ls_region.y1 + region->y2;
00715 
00716                     if ((vw->vrect.w > 0)&&(vw->vrect.h > 0)) {
00717                         // visible rectangle set, check calculated ls_region
00718                         ls_region.x1 -= vw->vrect.x;
00719                         ls_region.y1 -= vw->vrect.y;
00720                         ls_region.x2 -= vw->vrect.x;
00721                         ls_region.y2 -= vw->vrect.y;
00722 
00723                         if (ls_region.x1 < vw->region.x1)
00724                             ls_region.x1 = vw->region.x1;
00725                         if (ls_region.y1 < vw->region.y1)
00726                             ls_region.y1 = vw->region.y1;
00727                         if (ls_region.x2 > vw->region.x2)
00728                             ls_region.x2 = vw->region.x2;
00729                         if (ls_region.y2 > vw->region.y2)
00730                             ls_region.y2 = vw->region.y2;
00731 
00732                         if ((ls_region.x1 > ls_region.x2)||(ls_region.y1 > ls_region.y2)) {
00733                             // wrong region
00734                             vw = NULL;
00735                             break;
00736                         }
00737                     }
00738                 }
00739 
00740                 // check region
00741                 if (ls_region.x1 < 0) {
00742                     ls_region.x2+= ls_region.x1;
00743                     ls_region.x1 = 0;
00744                 }
00745                 if (ls_region.y1 < 0) {
00746                     ls_region.y2+= ls_region.y1;
00747                     ls_region.y1 = 0;
00748                 }
00749                 int ls_w, ls_h;
00750                 if (this->dst_surface->getSize(&ls_w, &ls_h)) {
00751                     if (ls_region.x2 >= ls_w)
00752                         ls_region.x2 = ls_w - 1;
00753                     if (ls_region.y2 >= ls_h)
00754                         ls_region.y2 = ls_h - 1;
00755                 }
00756 
00757                 break;
00758             }
00759         }
00760 
00761         if (!vw) {
00762             /* not found */
00763             if (!locked)
00764                 lock.unlock();
00765             PRINT_LOCK("leave flipSurface");
00766             return false;
00767         }
00768     }
00769     else {
00770         // no surface given, have to redraw a layer region?
00771         if (region == NULL) {
00772             // no
00773 /*            if (!locked)
00774                 lock.unlock();
00775             return false;*/
00776 
00777             if (!this->dst_surface->getSize(&ls_region.x2, &ls_region.y2)) {
00778                 if (!locked)
00779                     lock.unlock();
00780                 PRINT_LOCK("leave flipSurface");
00781                 return false;
00782             }
00783 
00784             ls_region.x1=0;
00785             ls_region.y1=0;
00786             ls_region.x2--;
00787             ls_region.y2--;
00788         }
00789         else {
00790             // take this region
00791             ls_region = *region;
00792         }
00793     }
00794 
00795     if ((region == NULL)&&(vw)) {
00796         /* this is only for whole (window) surfaces with an high flip frequency */
00797         struct  timeval tv;
00798         /* get the flip time */
00799         gettimeofday(&tv, NULL);
00800         int newfliptime = (((int)tv.tv_sec)%1000000)*1000+((int)tv.tv_usec)/1000;
00801         int diff = newfliptime - vw->lastflip;
00802 
00803         if ((diff > 0)&&(diff < 50)) {
00804             /* more than 20 pictures per second comes from this surface */
00805             high_freq = true;
00806         }
00807 
00808         if (vw->saved_surface) {
00809             /* save the frames if window works direct on the layer surface */
00810             if (vw->lastflip % 1000 < 40) {
00811             }
00812         }
00813 
00814         vw->lastflip = newfliptime;
00815     }
00816 
00817     if (high_freq) {
00818         /* this surface has an high flip frequency */
00819         if (!this->high_freq_surface) {
00820             /* this->high_freq_surface is not set, set it now */
00821             this->high_freq_region = ls_region;
00822             this->high_freq_lastflip = vw->lastflip;
00823             this->high_freq_surface = vw->surface;
00824             this->high_freq_saved_surface = vw->saved_surface;
00825         }
00826         else
00827             /* update the high_freq_lastflip */
00828             this->high_freq_lastflip = vw->lastflip;
00829     }
00830     else {
00831         bool check = (this->high_freq_surface!=NULL);
00832         if ((check)&&(vw))
00833             check = (this->high_freq_surface!=vw->surface);
00834         if (check) {
00835             /* high_freq_surface is set and i am not this surface */
00836             /* check if i am within high_freq_region */
00837             if ((this->high_freq_region.x1 <= ls_region.x1)
00838               &&(this->high_freq_region.y1 <= ls_region.y1)
00839               &&(this->high_freq_region.x2 >= ls_region.x2)
00840               &&(this->high_freq_region.y2 >= ls_region.y2)) {
00841                 /* yes, have to flip nothing */
00842                 if (!locked)
00843                     lock.unlock();
00844                 PRINT_LOCK("leave flipSurface");
00845                 return true;
00846             }
00847         }
00848         else {
00849             if ((this->high_freq_surface)&&(vw))
00850                 /* update the high_freq_lastflip */
00851                 this->high_freq_lastflip = vw->lastflip;
00852         }
00853     }
00854 
00855 
00856     this->dst_surface->lock();
00857     // set the region of the layer surface
00858     this->dst_surface->setClip(&ls_region);
00859 
00860     // check if i have to clear the background
00861     if (!vw)
00862         cleared = true;
00863     else
00864         cleared = (!((vw->alphachannel==false)&&(vw->opacity==255)));
00865 
00866 
00867 //printf("#2winman: flip windows\n");
00868 
00869     // two loops for optimized DEPTH TEST
00870     // FIRST:  find lowest window which is to blit
00871     // SECOND: blit the window stack beginning from lowest window
00872     int lowest_win = 0;
00873     MMSFBRegion tmpreg = MMSFBRegion(0,0,0,0);
00874     for (int depth_test = 1; depth_test >= 0; depth_test--) {
00875         // searching for affected windows and draw parts of it (in the second loop)
00876         for (unsigned int i = lowest_win; i < this->vwins.size(); i++) {
00877             VISIBLE_WINDOWS *aw = &(this->vwins.at(i));
00878             MMSFBRegion myreg = aw->region;
00879             MMSFBRegion *myregion = &myreg;
00880 
00881             // if the window has no opacity then continue
00882             if (!aw->opacity)
00883                 continue;
00884 
00885             // check if layer surface
00886             if (aw->islayersurface)
00887                 if (!cleared)
00888                     continue;
00889 
00890             if (!((myregion->x2 < ls_region.x1)||(myregion->y2 < ls_region.y1)
00891                 ||(myregion->x1 > ls_region.x2)||(myregion->y1 > ls_region.y2))) {
00892                 // the window is affected
00893                 if (depth_test) {
00894                     // FIRST loop: DEPTH TEST
00895                     if (myregion->x1 <= tmpreg.x1 && myregion->y1 <= tmpreg.y1
00896                             && myregion->x2 >= tmpreg.x2 && myregion->y2 >= tmpreg.y2) {
00897                         if ((!aw->alphachannel) || (MMSFBSURFACE_READ_BUFFER(aw->surface).opaque)) {
00898                             if (aw->opacity == 0xff) {
00899                                 tmpreg = *myregion;
00900                                 lowest_win = i;
00901                             }
00902                         }
00903                     }
00904                 }
00905                 else {
00906                     // SECOND loop: blit affected window
00907 
00908                     // check for locking on blit
00909                     if (aw->islayersurface) {
00910                         if (aw->saved_surface) {
00911                             if (!aw->saved_surface->tryToLock()) {
00912                                 printf("try lock failed - add to queue\n");
00913                                 if (mmsfbwinmanthread) {
00914                                     MMSFBWindowManagerThread::FLIP_STRUCT tmpFlipStruct = {NULL, NULL, refresh};
00915                                     mmsfbwinmanthread->flipQueue.push(tmpFlipStruct);
00916                                 }
00917                                 // reset the clip
00918                                 this->dst_surface->setClip(NULL);
00919                                 this->dst_surface->unlock();
00920                                 if (!locked)
00921                                     lock.unlock();
00922                                 return false;
00923                             }
00924                         }
00925                     }
00926                     else {
00927                         if (!aw->surface->tryToLock()) {
00928                             printf("try lock failed - add to queue\n");
00929                             if (mmsfbwinmanthread) {
00930                                 MMSFBWindowManagerThread::FLIP_STRUCT tmpFlipStruct = {NULL, NULL, refresh};
00931                                 mmsfbwinmanthread->flipQueue.push(tmpFlipStruct);
00932                             }
00933                             // reset the clip
00934                             this->dst_surface->setClip(NULL);
00935                             this->dst_surface->unlock();
00936                             if (!locked)
00937                                 lock.unlock();
00938                             return false;
00939                         }
00940                     }
00941 
00942                     // calc source and destination
00943                     MMSFBRectangle src_rect;
00944                     int dst_x = ls_region.x1;
00945                     int dst_y = ls_region.y1;
00946 
00947                     src_rect.x = ls_region.x1 - myregion->x1;
00948                     if (src_rect.x < 0) {
00949                         dst_x-= src_rect.x;
00950                         src_rect.x = 0;
00951                     }
00952 
00953                     src_rect.y = ls_region.y1 - myregion->y1;
00954                     if (src_rect.y < 0) {
00955                         dst_y-= src_rect.y;
00956                         src_rect.y = 0;
00957                     }
00958 
00959                     src_rect.w = myregion->x2 - myregion->x1 + 1 - src_rect.x;
00960                     if (myregion->x2 > ls_region.x2)
00961                         src_rect.w-= myregion->x2 - ls_region.x2;
00962 
00963                     src_rect.h = myregion->y2 - myregion->y1 + 1 - src_rect.y;
00964                     if (myregion->y2 > ls_region.y2)
00965                         src_rect.h-= myregion->y2 - ls_region.y2;
00966 
00967                     if ((aw->vrect.w > 0)&&(aw->vrect.h > 0)) {
00968                         // visible rectangle set, so have to adjust source offset
00969                         src_rect.x += aw->vrect.x;
00970                         src_rect.y += aw->vrect.y;
00971                     }
00972 /*
00973 printf("#3winman: flip window id = %d, opaque = %d, src_rect = %d,%d %dx%d, dst = %d,%d\n",
00974                         i, MMSFBSURFACE_READ_BUFFER(aw->surface).opaque,
00975                         src_rect.x, src_rect.y, src_rect.w, src_rect.h, dst_x, dst_y);
00976 */
00977 
00978                     // set the blitting flags and color
00979                     if ((aw->alphachannel)&&((win_found)||(!this->dst_surface->config.surface_buffer->alphachannel))) {
00980                         // the window has an alphachannel
00981                         if (!(MMSFBSURFACE_READ_BUFFER(aw->surface).opaque)) {
00982                             // (semi-)transparent surface buffer
00983                             if (aw->opacity < 255) {
00984                                 this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) (MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
00985                                 this->dst_surface->setColor(0, 0, 0, aw->opacity);
00986                             }
00987                             else {
00988                                 this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_BLEND_ALPHACHANNEL);
00989                             }
00990                         }
00991                         else {
00992                             // opaque surface buffer, we do not need MMSFB_BLIT_BLEND_ALPHACHANNEL
00993                             if (aw->opacity < 255) {
00994                                 this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_BLEND_COLORALPHA);
00995                                 this->dst_surface->setColor(0, 0, 0, aw->opacity);
00996                             }
00997                             else {
00998                                 this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_NOFX);
00999                             }
01000                         }
01001 
01002                         // first window?
01003                         if (!win_found) {
01004                             // yes, clear the layer before blitting the first window surface
01005                             if (cleared)
01006                                 this->dst_surface->clear();
01007                             win_found = true;
01008                         }
01009                     }
01010                     else {
01011                         // the window has no alphachannel
01012                         if (aw->opacity < 255) {
01013                             this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_BLEND_COLORALPHA);
01014                             this->dst_surface->setColor(0, 0, 0, aw->opacity);
01015                         }
01016                         else {
01017                             this->dst_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_NOFX);
01018                         }
01019 
01020                         // first window?
01021                         if (!win_found) {
01022                             // yes, clear the layer before blitting the first window surface
01023                             // but only, if the first window does not use the whole layer region
01024                             // else we do not have to clear the layer region and can save CPU
01025                             if (cleared)
01026                                 if ((aw->opacity < 255)||((dst_x != ls_region.x1) || (dst_y != ls_region.y1)
01027                                  || (dst_x + src_rect.w <= ls_region.x2) || (dst_y + src_rect.h <= ls_region.y2))) {
01028                                     this->dst_surface->clear();
01029                                 }
01030 
01031                             win_found = true;
01032                         }
01033                     }
01034 
01035                     // check if layer surface and blit
01036                     if (aw->islayersurface) {
01037                         if (aw->saved_surface) {
01038                             this->dst_surface->blit(aw->saved_surface, &src_rect, dst_x, dst_y);
01039                             this->dst_surface->unlock();
01040                         }
01041                     }
01042                     else {
01043                         this->dst_surface->blit(aw->surface, &src_rect, dst_x, dst_y);
01044                         aw->surface->unlock();
01045                     }
01046                 }
01047             }
01048         }
01049     }
01050 
01051     if (!win_found) {
01052         // if no window is drawn, check if we have to clear the layer region
01053         if (cleared)
01054             this->dst_surface->clear();
01055     }
01056 
01057     // draw the pointer
01058     drawPointer(&ls_region);
01059 
01060     // reset the clip
01061     this->dst_surface->setClip(NULL);
01062 
01063     // make changes visible
01064     if (refresh) {
01065         PRINT_LOCK("enter flip");
01066         this->dst_surface->flip(&ls_region);
01067         PRINT_LOCK("leave flip");
01068     }
01069 
01070     this->dst_surface->unlock();
01071 
01072     // unlock
01073     if (!locked)
01074         lock.unlock();
01075 
01076     PRINT_LOCK("leave flipSurface");
01077 
01078     return true;
01079 }
01080 
01081 bool MMSFBWindowManager::setWindowOpacity(MMSFBWindow *window) {
01082 
01083     /* check if initialized */
01084     INITCHECK;
01085 
01086     /* stop parallel processing */
01087     lock.lock();
01088 
01089     /* search for item */
01090     for (unsigned int i=0; i < this->vwins.size(); i++)
01091         if (this->vwins.at(i).window == window) {
01092             /* reload windows config */
01093             loadWindowConfig(window, &(this->vwins.at(i)));
01094 
01095             PRINT_LOCK("flipSurface");
01096             /* redraw the window */
01097             flipSurface(this->vwins.at(i).surface, NULL, true);
01098             PRINT_LOCK("end flipSurface");
01099 
01100             /* unlock */
01101             lock.unlock();
01102 
01103             return true;
01104         }
01105 
01106     /* not found */
01107     lock.unlock();
01108     return false;
01109 }
01110 
01111 bool MMSFBWindowManager::setWindowPosition(MMSFBWindow *window, MMSFBRectangle *vrect) {
01112 
01113     /* check if initialized */
01114     INITCHECK;
01115 
01116     /* stop parallel processing */
01117     lock.lock();
01118 
01119     // change visible rectangle and position in one step?
01120     if (vrect) {
01121         // yes, change visible rectangle
01122         for (unsigned int i=0; i < this->windows.size(); i++) {
01123             if (this->windows.at(i).window == window) {
01124                 // set rect
01125                 this->windows.at(i).vrect = *vrect;
01126                 break;
01127             }
01128         }
01129     }
01130 
01131     /* search for item */
01132     for (unsigned int i=0; i < this->vwins.size(); i++)
01133         if (this->vwins.at(i).window == window) {
01134             /* get the old config */
01135             VISIBLE_WINDOWS old_vwin;
01136             old_vwin = this->vwins.at(i);
01137 
01138             /* reload windows config */
01139             loadWindowConfig(window, &(this->vwins.at(i)));
01140 
01141             /* moving high_freq_surface? */
01142             if (this->high_freq_surface == this->vwins.at(i).surface) {
01143                 /* yes, reset it */
01144                 PRINT_LOCK("flipSurface");
01145                 mmsfbwindowmanager->flipSurface(this->high_freq_surface, NULL, true);
01146                 PRINT_LOCK("end flipSurface");
01147                 this->high_freq_surface = NULL;
01148                 this->high_freq_saved_surface = NULL;
01149                 this->high_freq_lastflip = 0;
01150             }
01151 
01152             PRINT_LOCK("flipSurface");
01153             /* redraw the window */
01154             flipSurface(this->vwins.at(i).surface, NULL, true);
01155             PRINT_LOCK("end flipSurface");
01156 
01157             /* redraw the old rects */
01158             if (old_vwin.region.y1 < this->vwins.at(i).region.y1) {
01159                 /* redraw above */
01160                 MMSFBRegion region;
01161                 region = old_vwin.region;
01162                 if (region.y2 >= this->vwins.at(i).region.y1)
01163                     region.y2 = this->vwins.at(i).region.y1 - 1;
01164                 PRINT_LOCK("flipSurface");
01165                 flipSurface(NULL, &region, true);
01166                 PRINT_LOCK("end flipSurface");
01167             }
01168             else
01169             if (old_vwin.region.y1 > this->vwins.at(i).region.y1) {
01170                 /* redraw below */
01171                 MMSFBRegion region;
01172                 region = old_vwin.region;
01173                 if (region.y1 <= this->vwins.at(i).region.y2)
01174                     region.y1 = this->vwins.at(i).region.y2 + 1;
01175                 PRINT_LOCK("flipSurface");
01176                 flipSurface(NULL, &region, true);
01177                 PRINT_LOCK("end flipSurface");
01178             }
01179             if (old_vwin.region.x1 < this->vwins.at(i).region.x1) {
01180                 /* redraw left side */
01181                 MMSFBRegion region;
01182                 region = old_vwin.region;
01183                 if  ((region.y2 >= this->vwins.at(i).region.y1)
01184                    &&(region.y1 <= this->vwins.at(i).region.y2)) {
01185                     if (region.x2 >= this->vwins.at(i).region.x1)
01186                         region.x2 = this->vwins.at(i).region.x1 - 1;
01187                     region.y1 = this->vwins.at(i).region.y1;
01188                     region.y2 = this->vwins.at(i).region.y2;
01189                     PRINT_LOCK("flipSurface");
01190                     flipSurface(NULL, &region, true);
01191                     PRINT_LOCK("end flipSurface");
01192                 }
01193             }
01194             else
01195             if (old_vwin.region.x1 > this->vwins.at(i).region.x1) {
01196                 /* redraw right side */
01197                 MMSFBRegion region;
01198                 region = old_vwin.region;
01199                 if  ((region.y2 >= this->vwins.at(i).region.y1)
01200                    &&(region.y1 <= this->vwins.at(i).region.y2)) {
01201                     if (region.x1 <= this->vwins.at(i).region.x2)
01202                         region.x1 = this->vwins.at(i).region.x2 + 1;
01203                     region.y1 = this->vwins.at(i).region.y1;
01204                     region.y2 = this->vwins.at(i).region.y2;
01205                     PRINT_LOCK("flipSurface");
01206                     flipSurface(NULL, &region, true);
01207                     PRINT_LOCK("end flipSurface");
01208                 }
01209             }
01210 
01211             /* unlock */
01212             lock.unlock();
01213 
01214             return true;
01215         }
01216 
01217     /* not found */
01218     lock.unlock();
01219     return false;
01220 }
01221 
01222 bool MMSFBWindowManager::setWindowSize(MMSFBWindow *window, int w, int h) {
01223 
01224     /* check if initialized */
01225     INITCHECK;
01226 
01227     /* stop parallel processing */
01228     lock.lock();
01229 
01230     /* search for item which is visible */
01231     for (unsigned int i=0; i < this->vwins.size(); i++)
01232         if (this->vwins.at(i).window == window) {
01233             /* found as visible window */
01234             VISIBLE_WINDOWS old_vwin;
01235             old_vwin = this->vwins.at(i);
01236             int old_w = old_vwin.region.x2 - old_vwin.region.x1 + 1;
01237             int old_h = old_vwin.region.y2 - old_vwin.region.y1 + 1;
01238 
01239             if ((old_w != w)||(old_h != h)) {
01240                 /* hide the window without updating the screen */
01241                 hideWindow(window, true, false);
01242 
01243                 /* resizing surface */
01244                 MMSFBSurface *surface;
01245                 window->getSurface(&surface);
01246                 surface->lock();
01247                 surface->resize(w, h);
01248                 surface->unlock();
01249 
01250                 /* search for item in the window list */
01251                 for (unsigned int j=0; j < this->windows.size(); j++)
01252                     if (this->windows.at(j).window == window) {
01253                         // reset the visible region
01254                         this->windows.at(j).vrect.x = 0;
01255                         this->windows.at(j).vrect.y = 0;
01256                         this->windows.at(j).vrect.w = 0;
01257                         this->windows.at(j).vrect.h = 0;
01258                         break;
01259                     }
01260 
01261                 /* re-show it */
01262                 if ((old_w <= w)&&(old_h <= h))
01263                     /* larger or equal */
01264                     showWindow(window, true, true);
01265                 else {
01266                     /* new window is less than the old one */
01267                     showWindow(window, true, false);
01268 
01269                     PRINT_LOCK("flipSurface");
01270                     /* flip the old region */
01271                     flipSurface(NULL, &old_vwin.region, true, true);
01272                     PRINT_LOCK("end flipSurface");
01273                 }
01274             }
01275 
01276             /* unlock */
01277             lock.unlock();
01278 
01279             return true;
01280         }
01281 
01282     /* search for item in the window list */
01283     for (unsigned int i=0; i < this->windows.size(); i++)
01284         if (this->windows.at(i).window == window) {
01285             /* found as window which is currently not shown */
01286             /* resizing surface */
01287             MMSFBSurface *surface;
01288             window->getSurface(&surface);
01289             surface->lock();
01290             surface->resize(w, h);
01291             surface->unlock();
01292 
01293             // reset the visible region
01294             this->windows.at(i).vrect.x = 0;
01295             this->windows.at(i).vrect.y = 0;
01296             this->windows.at(i).vrect.w = 0;
01297             this->windows.at(i).vrect.h = 0;
01298 
01299             /* unlock */
01300             lock.unlock();
01301 
01302             return true;
01303         }
01304 
01305     /* not found */
01306     lock.unlock();
01307     return false;
01308 }
01309 
01310 bool MMSFBWindowManager::setWindowVisibleRectangle(MMSFBWindow *window, MMSFBRectangle *rect) {
01311     bool ret = false;
01312 
01313     // check if initialized
01314     INITCHECK;
01315 
01316     // stop parallel processing
01317     lock.lock();
01318 
01319     // search for item in available list
01320     for (unsigned int i=0; i < this->windows.size(); i++)
01321         if (this->windows.at(i).window == window) {
01322             // set rect
01323             if (rect) {
01324                 this->windows.at(i).vrect = *rect;
01325             }
01326             else {
01327                 this->windows.at(i).vrect.x = 0;
01328                 this->windows.at(i).vrect.y = 0;
01329                 this->windows.at(i).vrect.w = 0;
01330                 this->windows.at(i).vrect.h = 0;
01331             }
01332 
01333             ret = true;
01334             break;
01335         }
01336 
01337     // search for item in visible list
01338     for (unsigned int i=0; i < this->vwins.size(); i++)
01339         if (this->vwins.at(i).window == window) {
01340             // reload windows config
01341             loadWindowConfig(window, &(this->vwins.at(i)));
01342 
01343             PRINT_LOCK("flipSurface");
01344             // redraw the window
01345             flipSurface(this->vwins.at(i).surface, NULL, true);
01346             PRINT_LOCK("end flipSurface");
01347 
01348             ret = true;
01349             break;
01350         }
01351 
01352     lock.unlock();
01353     return ret;
01354 }
01355 
01356 bool MMSFBWindowManager::getWindowVisibleRectangle(MMSFBWindow *window, MMSFBRectangle *rect) {
01357     bool ret = false;
01358 
01359     // check if initialized
01360     INITCHECK;
01361 
01362     // stop parallel processing
01363     lock.lock();
01364 
01365     // search for item in available list
01366     for (unsigned int i=0; i < this->windows.size(); i++)
01367         if (this->windows.at(i).window == window) {
01368             // set rect
01369             if (rect) *rect = this->windows.at(i).vrect;
01370             if ((this->windows.at(i).vrect.w > 0)&&(this->windows.at(i).vrect.h > 0))
01371                 ret = true;
01372             break;
01373         }
01374 
01375     lock.unlock();
01376     return ret;
01377 }
01378 
01379 bool MMSFBWindowManager::getScreenshot(MMSFBWindow *window) {
01380     bool ret = false;
01381 
01382     // check if initialized
01383     INITCHECK;
01384 
01385     // stop parallel processing
01386     lock.lock();
01387 
01388     // search for item in available list
01389     for (unsigned int i=0; i < this->windows.size(); i++)
01390         if (this->windows.at(i).window == window) {
01391             // window found, hide the window if shown
01392             bool shown = window->isShown();
01393             window->hide();
01394 
01395             // switch the dst_surface
01396             MMSFBSurface *saved_suf = this->dst_surface;
01397             if (window->getSurface(&this->dst_surface)) {
01398                 // draw the complete screen to the surface of the window
01399                 MMSFBRegion region;
01400                 this->dst_surface->getSize(&region.x2, &region.y2);
01401                 region.x1 = 0;
01402                 region.y1 = 0;
01403                 region.x2-= 1;
01404                 region.y2-= 1;
01405                 PRINT_LOCK("flipSurface");
01406                 flipSurface(NULL, &region, true, false);
01407                 PRINT_LOCK("end flipSurface");
01408             }
01409 
01410             // restore the dst_surface
01411             this->dst_surface = saved_suf;
01412 
01413             // show the window again
01414             if (shown)
01415                 window->show();
01416 
01417             ret = true;
01418             break;
01419         }
01420 
01421     lock.unlock();
01422     return ret;
01423 }
01424 
01425 
01426 void MMSFBWindowManager::setPointerPosition(int pointer_posx, int pointer_posy, bool pressed) {
01427     // changed?
01428     if (this->button_pressed == pressed)
01429         if ((this->pointer_posx == pointer_posx)&&(this->pointer_posy == pointer_posy))
01430             return;
01431     this->button_pressed = pressed;
01432 
01433     switch (this->layer_pixelformat) {
01434     case MMSFB_PF_YV12:
01435     case MMSFB_PF_I420:
01436         // use even pointer position for this pixelformats
01437         this->pointer_posx = pointer_posx & ~0x01;
01438         this->pointer_posy = pointer_posy & ~0x01;
01439         break;
01440     default:
01441         // use normal odd/even positions
01442         this->pointer_posx = pointer_posx;
01443         this->pointer_posy = pointer_posy;
01444         break;
01445     }
01446 
01447     // do nothing more if pointer will not be shown
01448     if (!this->show_pointer)
01449         return;
01450 
01451     // surface of pointer initialized?
01452     if (!this->pointer_surface)
01453         if (!loadPointer()) {
01454             // not loaded, set a primitive pointer
01455             this->pointer_rect.w = 21;
01456             this->pointer_rect.h = 21;
01457             if (this->layer->createSurface(&this->pointer_surface, this->pointer_rect.w, this->pointer_rect.h)) {
01458                 pointer_surface->lock();
01459                 this->pointer_surface->clear();
01460                 this->pointer_surface->setColor(255,255,255,255);
01461                 this->pointer_surface->drawLine(0,this->pointer_rect.h/2,this->pointer_rect.w-1,this->pointer_rect.h/2);
01462                 this->pointer_surface->drawLine(this->pointer_rect.w/2,0,this->pointer_rect.w/2,this->pointer_rect.h-1);
01463                 pointer_surface->unlock();
01464             }
01465             else
01466                 this->pointer_surface = NULL;
01467         }
01468 
01469     // save the old region
01470     MMSFBRegion old_region = this->pointer_region;
01471 
01472     // set the rectangle/region position
01473     this->pointer_rect.x = this->pointer_posx - (this->pointer_rect.w >> 1);
01474     this->pointer_rect.y = this->pointer_posy - (this->pointer_rect.h >> 1);
01475     this->pointer_region.x1 = this->pointer_rect.x;
01476     this->pointer_region.y1 = this->pointer_rect.y;
01477     this->pointer_region.x2 = this->pointer_rect.x + this->pointer_rect.w - 1;
01478     this->pointer_region.y2 = this->pointer_rect.y + this->pointer_rect.h - 1;
01479 
01480     // set opacity
01481     this->pointer_opacity = 255;
01482     this->pointer_fadecnt = 0;
01483 
01484     // check if i have to flip one or two regions
01485     if   ((old_region.x1 > this->pointer_region.x2)
01486         ||(old_region.y1 > this->pointer_region.y2)
01487         ||(old_region.x2 < this->pointer_region.x1)
01488         ||(old_region.y2 < this->pointer_region.y1)) {
01489         // two regions to be updated
01490         PRINT_LOCK("flipSurface");
01491         flipSurface(NULL, &this->pointer_region, false);
01492         PRINT_LOCK("end flipSurface");
01493         if (old_region.x1 != old_region.x2) {
01494             PRINT_LOCK("flipSurface");
01495             flipSurface(NULL, &old_region, false);
01496             PRINT_LOCK("end flipSurface");
01497         }
01498     }
01499     else {
01500         // one region
01501         if (old_region.x1 > this->pointer_region.x1)
01502             old_region.x1 = this->pointer_region.x1;
01503         else
01504             old_region.x2 = this->pointer_region.x2;
01505         if (old_region.y1 > this->pointer_region.y1)
01506             old_region.y1 = this->pointer_region.y1;
01507         else
01508             old_region.y2 = this->pointer_region.y2;
01509         PRINT_LOCK("flipSurface");
01510         flipSurface(NULL, &old_region, false);
01511         PRINT_LOCK("end flipSurface");
01512     }
01513 }
01514 
01515 bool MMSFBWindowManager::getPointerPosition(int &pointer_posx, int &pointer_posy) {
01516     // set?
01517     if ((this->pointer_posx<0)||(this->pointer_posy<0))
01518         return false;
01519     pointer_posx = this->pointer_posx;
01520     pointer_posy = this->pointer_posy;
01521     return true;
01522 }
01523 
01524 bool MMSFBWindowManager::loadPointer() {
01525     string imagefile = (string)getPrefix() + "/share/disko/mmsgui/mmspointer.png";
01526 
01527     // try to read from taff?
01528     if (this->usetaff) {
01529         // yes, try with taff
01530         // assume: the taffpf (supported taff pixelformat) is correctly set
01531         // first : try to read taff image without special pixelformat
01532         // second: try with pixelformat from my surfaces
01533         bool retry = false;
01534         do {
01535             MMSTaffFile *tafff;
01536             if (retry) {
01537                 retry = false;
01538                 DEBUGOUT("MMSFBWindowManager, retry\n");
01539                 // have to convert taff with special destination pixelformat
01540                 tafff = new MMSTaffFile(imagefile + ".taff", NULL,
01541                                         "", MMSTAFF_EXTERNAL_TYPE_IMAGE);
01542                 if (tafff) {
01543                     // set external file and requested pixelformat
01544                     tafff->setExternal(imagefile, MMSTAFF_EXTERNAL_TYPE_IMAGE);
01545                     DEBUGOUT("MMSFBWindowManager, taffpf = %d\n", taffpf);
01546                     tafff->setDestinationPixelFormat(taffpf);
01547                     // convert it
01548                     if (!tafff->convertExternal2TAFF()) {
01549                         // conversion failed
01550                         delete tafff;
01551                         break;
01552                     }
01553                     delete tafff;
01554                 }
01555             }
01556 
01557             // load image
01558             tafff = new MMSTaffFile(imagefile + ".taff", NULL,
01559                                     imagefile, MMSTAFF_EXTERNAL_TYPE_IMAGE);
01560 
01561             if (tafff) {
01562                 if (tafff->isLoaded()) {
01563 
01564                     // load the attributes
01565                     int         attrid;
01566                     char        *value_str;
01567                     int         value_int;
01568                     void        *img_buf = NULL;
01569                     int         img_width = 0;
01570                     int         img_height= 0;
01571                     int         img_pitch = 0;
01572                     int         img_size  = 0;
01573                     MMSTAFF_PF  img_pixelformat = MMSTAFF_PF_ARGB;
01574 
01575                     while ((attrid=tafff->getNextAttribute(&value_str, &value_int, NULL))>=0) {
01576                         switch (attrid) {
01577                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_width:
01578                             img_width = value_int;
01579                             break;
01580                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_height:
01581                             img_height = value_int;
01582                             break;
01583                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pitch:
01584                             img_pitch = value_int;
01585                             break;
01586                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_size:
01587                             img_size = value_int;
01588                             break;
01589                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_data:
01590                             img_buf = value_str;
01591                             break;
01592                         case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pixelformat:
01593                             img_pixelformat = (MMSTAFF_PF)value_int;
01594                             break;
01595                         default:
01596                             break;
01597                         }
01598                     }
01599 
01600                     if (img_pixelformat != taffpf) {
01601                         DEBUGOUT("MMSFBWindowManager, taffpf = %d\n", (int)taffpf);
01602                         // the image from the file has not the same pixelformat as the surface
01603                         if (!retry) {
01604                             // retry with surface pixelformat
01605                             DEBUGOUT("MMSFBWindowManager, request new pixf\n");
01606                             retry = true;
01607                             delete tafff;
01608                             continue;
01609                         }
01610                         else
01611                             retry = false;
01612                     }
01613                     else
01614                     if ((img_width)&&(img_height)&&(img_pitch)&&(img_size)&&(img_buf)) {
01615                         // successfully read, create a surface
01616                         if (!this->layer->createSurface(&this->pointer_surface, img_width, img_height, this->pixelformat)) {
01617                             DEBUGMSG("MMSFB", "cannot create surface for image file '%s'", imagefile.c_str());
01618                             return false;
01619                         }
01620 
01621                         this->pointer_surface->lock();
01622                         // blit from external buffer to surface
01623                         this->pointer_surface->blitBuffer(img_buf, img_pitch, this->pixelformat,
01624                                                             img_width, img_height, NULL, 0, 0);
01625                         this->pointer_surface->unlock();
01626 
01627                         // free
01628                         delete tafff;
01629 
01630                         DEBUGMSG("MMSFB", "MMSFBWindowManager has loaded: '%s'", imagefile.c_str());
01631 
01632                         // set pointer width & height
01633                         this->pointer_rect.w = img_width;
01634                         this->pointer_rect.h = img_height;
01635 
01636                         return true;
01637                     }
01638                 }
01639 
01640                 // free
01641                 delete tafff;
01642             }
01643         } while (retry);
01644     }
01645 
01646 
01647 #ifdef  __HAVE_DIRECTFB__
01648     IDirectFBImageProvider *imageprov = NULL;
01649     DFBSurfaceDescription   surface_desc;
01650 
01651     // create image provider
01652     if (!mmsfb->createImageProvider(&imageprov, imagefile)) {
01653         if (imageprov)
01654             imageprov->Release(imageprov);
01655         return false;
01656     }
01657 
01658     // get surface description
01659     if (imageprov->GetSurfaceDescription(imageprov, &surface_desc)!=DFB_OK) {
01660         imageprov->Release(imageprov);
01661         return false;
01662     }
01663 
01664     // create a surface
01665     if (!this->layer->createSurface(&this->pointer_surface, surface_desc.width, surface_desc.height)) {
01666         imageprov->Release(imageprov);
01667         return false;
01668     }
01669 
01670     // render to the surface
01671     if (imageprov->RenderTo(imageprov, (IDirectFBSurface *)this->pointer_surface->getDFBSurface(), NULL)!=DFB_OK) {
01672         imageprov->Release(imageprov);
01673         delete this->pointer_surface;
01674         return false;
01675     }
01676 
01677     // release imageprovider
01678     imageprov->Release(imageprov);
01679 
01680     // set pointer width & height
01681     this->pointer_rect.w = surface_desc.width;
01682     this->pointer_rect.h = surface_desc.height;
01683     return true;
01684 #endif
01685 
01686     return false;
01687 }
01688 
01689 void MMSFBWindowManager::drawPointer(MMSFBRegion *region) {
01690     // should draw the pointer?
01691     if (!this->show_pointer)
01692         return;
01693     if ((this->pointer_posx<0)||(this->pointer_posy<0))
01694         return;
01695     if (!this->pointer_surface)
01696         return;
01697     if (this->pointer_opacity == 0)
01698         return;
01699 
01700     this->layer_surface->lock();
01701     this->pointer_surface->lock();
01702 
01703     // blit the pointer surface with given opacity
01704     if (this->pointer_opacity < 255) {
01705         this->layer_surface->setBlittingFlags((MMSFBBlittingFlags) (MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
01706         this->layer_surface->setColor(0, 0, 0, this->pointer_opacity);
01707     }
01708     else
01709         this->layer_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_BLEND_ALPHACHANNEL);
01710     this->layer_surface->blit(this->pointer_surface, NULL, this->pointer_rect.x, this->pointer_rect.y);
01711     this->layer_surface->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_NOFX);
01712     this->layer_surface->setColor(0, 0, 0, 0);
01713     this->pointer_surface->unlock();
01714     this->layer_surface->unlock();
01715 }
01716 
01717 unsigned char MMSFBWindowManager::getPointerOpacity() {
01718     return this->pointer_opacity;
01719 }
01720 
01721 void MMSFBWindowManager::setPointerOpacity(unsigned char opacity) {
01722     // set it
01723     this->pointer_opacity = opacity;
01724     this->pointer_fadecnt = 0;
01725     PRINT_LOCK("flipSurface");
01726     flipSurface(NULL, &this->pointer_region, false);
01727     PRINT_LOCK("end flipSurface");
01728 }
01729 
01730 void MMSFBWindowManager::fadePointer() {
01731     if (!this->button_pressed) {
01732         if (this->pointer_opacity > 0) {
01733             if (this->pointer_fadecnt == 0)
01734                 this->pointer_fadecnt = 1;
01735             else
01736                 this->pointer_fadecnt*= 3;
01737 
01738             if (this->pointer_fadecnt >= 3) {
01739                 // set it
01740                 if (this->pointer_opacity > this->pointer_fadecnt / 3)
01741                     this->pointer_opacity-= this->pointer_fadecnt / 3;
01742                 else
01743                     this->pointer_opacity = 0;
01744                 PRINT_LOCK("flipSurface");
01745                 flipSurface(NULL, &this->pointer_region, false);
01746                 PRINT_LOCK("end flipSurface");
01747             }
01748         }
01749     }
01750 }
01751 

Generated by doxygen