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 <cstring>
00034 #include "mmsgui/fb/mmsfbwindowmanager.h"
00035 #include "mmsinfo/mmsinfo.h"
00036 #include "mmsgui/fb/mmsfb.h"
00037
00038
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
00048 MMSFBWindowManager *mmsfbwindowmanager = new MMSFBWindowManager();
00049
00050 #define INITCHECK if(!this->layer){MMSFB_SetError(0,"not initialized");return false;}
00051
00052 MMSFBWindowManager::MMSFBWindowManager() {
00053
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
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
00094 if (this->layer) {
00095 MMSFB_SetError(0, "already initialized");
00096 return false;
00097 }
00098
00099
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
00110 this->layer = layer;
00111 this->show_pointer = show_pointer;
00112
00113 DEBUGMSG("MMSGUI", "MMSFBWindowManager: get layer surface");
00114
00115
00116 if (!this->layer->getSurface(&this->layer_surface))
00117 return false;
00118 this->dst_surface = this->layer_surface;
00119
00120
00121 if (!this->layer_surface->getPixelFormat(&this->layer_pixelformat))
00122 return false;
00123
00124
00125 this->pixelformat = MMSFB_PF_NONE;
00126 this->ogl_mode = false;
00127 MMSFBSurface *ts;
00128 if (this->layer->createSurface(&ts, 8, 1)) {
00129
00130 ts->getPixelFormat(&this->pixelformat);
00131 this->ogl_mode = (ts->allocated_by == MMSFBSurfaceAllocatedBy_ogl);
00132 delete ts;
00133 }
00134
00135
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
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
00173 INITCHECK;
00174
00175
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
00186 INITCHECK;
00187
00188
00189 *layer = this->layer;
00190
00191 return true;
00192 }
00193
00194 void MMSFBWindowManager::lockWM() {
00195
00196 lock.lock();
00197 }
00198
00199 void MMSFBWindowManager::unlockWM() {
00200
00201 lock.unlock();
00202 }
00203
00204 bool MMSFBWindowManager::addWindow(MMSFBWindow *window) {
00205
00206
00207 INITCHECK;
00208
00209
00210 lock.lock();
00211
00212
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
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
00229 lock.unlock();
00230
00231 return true;
00232 }
00233
00234 bool MMSFBWindowManager::removeWindow(MMSFBWindow *window) {
00235
00236
00237 INITCHECK;
00238
00239
00240 lock.lock();
00241
00242
00243 for (unsigned int i=0; i < this->windows.size(); i++)
00244 if (this->windows.at(i).window == window) {
00245
00246
00247 hideWindow(window);
00248
00249
00250 this->windows.erase(this->windows.begin()+i);
00251
00252
00253 lock.unlock();
00254 return true;
00255 }
00256
00257
00258 lock.unlock();
00259 return false;
00260 }
00261
00262 bool MMSFBWindowManager::raiseToTop(MMSFBWindow *window) {
00263
00264
00265 INITCHECK;
00266
00267
00268 lock.lock();
00269
00270
00271 for (unsigned int oldpos = 0; oldpos < this->vwins.size(); oldpos++) {
00272 if (this->vwins.at(oldpos).window == window) {
00273
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
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
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
00300 this->vwins.erase(this->vwins.begin()+oldpos);
00301 this->vwins.insert(this->vwins.begin()+newpos, vw);
00302
00303 PRINT_LOCK("flipSurface");
00304
00305 vw.surface->lock();
00306 flipSurface(vw.surface, NULL, true);
00307 PRINT_LOCK("end flipSurface");
00308 vw.surface->unlock();
00309 }
00310
00311
00312 lock.unlock();
00313 return true;
00314 }
00315 }
00316
00317 PRINT_LOCK("not found");
00318
00319 lock.unlock();
00320 return false;
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 }
00399
00400 bool MMSFBWindowManager::lowerToBottom(MMSFBWindow *window) {
00401
00402
00403 INITCHECK;
00404
00405
00406 lock.lock();
00407
00408
00409 for (unsigned int i=0; i < this->windows.size(); i++)
00410 if (this->windows.at(i).window == window) {
00411
00412 if (i > 0) {
00413
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
00419 for (unsigned int j=0; j < this->vwins.size(); j++)
00420 if (this->vwins.at(j).window == window) {
00421
00422 if (j > 0) {
00423
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
00430 vw.surface->lock();
00431 flipSurface(vw.surface, NULL, true);
00432 PRINT_LOCK("end flipSurface");
00433 vw.surface->unlock();
00434 }
00435 }
00436 }
00437
00438
00439 lock.unlock();
00440 return true;
00441 }
00442
00443
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
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
00484 vwin->region = sr;
00485 }
00486 else {
00487
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
00506 INITCHECK;
00507
00508
00509 if (!locked)
00510 lock.lock();
00511
00512
00513 for (unsigned int i = 0; i < this->windows.size(); i++) {
00514 if (this->windows.at(i).window == window) {
00515
00516 for (unsigned int j = 0; j < this->vwins.size(); j++) {
00517 if (this->vwins.at(j).window == window) {
00518
00519 if (!locked)
00520 lock.unlock();
00521 return false;
00522 }
00523 }
00524
00525
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
00538 this->vwins.insert(this->vwins.begin() + pos, vw);
00539
00540
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
00548 if (!locked)
00549 lock.unlock();
00550
00551 return true;
00552 }
00553 }
00554
00555
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
00565 for (unsigned int j=0; j < this->vwins.size(); j++)
00566 if (this->vwins.at(j).window == window) {
00567
00568 if (!locked)
00569 lock.unlock();
00570 return false;
00571 }
00572
00573
00574 VISIBLE_WINDOWS vwin;
00575 loadWindowConfig(window, &vwin);
00576
00577
00578 bool inserted = false;
00579 if (i < this->windows.size()-1) {
00580
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
00586 this->vwins.insert(this->vwins.begin()+j, vwin);
00587 inserted = true;
00588 break;
00589 }
00590 }
00591 if (!inserted)
00592
00593 this->vwins.push_back(vwin);
00594
00595 PRINT_LOCK("flipSurface");
00596
00597 flipSurface(vwin.surface, NULL, true, refresh);
00598 PRINT_LOCK("end flipSurface");
00599
00600
00601 if (!locked)
00602 lock.unlock();
00603
00604 return true;
00605 }
00606
00607
00608 lock.unlock();
00609 return false;
00610 #endif
00611
00612
00613 }
00614
00615 bool MMSFBWindowManager::hideWindow(MMSFBWindow *window, bool locked, bool refresh) {
00616
00617
00618 INITCHECK;
00619
00620
00621 if (!locked)
00622 lock.lock();
00623
00624
00625 for (unsigned int i=0; i < this->vwins.size(); i++)
00626 if (this->vwins.at(i).window == window) {
00627
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
00636 this->high_freq_surface = NULL;
00637 this->high_freq_saved_surface = NULL;
00638 this->high_freq_lastflip = 0;
00639 }
00640
00641
00642 this->vwins.erase(this->vwins.begin()+i);
00643
00644
00645 if (!locked)
00646 lock.unlock();
00647
00648 return true;
00649 }
00650
00651
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
00666 INITCHECK;
00667
00668 PRINT_LOCK("enter flipSurface");
00669
00670
00671 if (!locked)
00672 lock.lock();
00673
00674 if (this->ogl_mode) {
00675
00676
00677
00678
00679 surface = NULL;
00680 region = NULL;
00681
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 if (surface) {
00693
00694 for (unsigned int i=0; i < this->vwins.size(); i++) {
00695 if (this->vwins.at(i).surface == surface) {
00696
00697 vw = &(this->vwins.at(i));
00698 ls_region = vw->region;
00699
00700
00701 if (region != NULL) {
00702
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
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
00734 vw = NULL;
00735 break;
00736 }
00737 }
00738 }
00739
00740
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
00763 if (!locked)
00764 lock.unlock();
00765 PRINT_LOCK("leave flipSurface");
00766 return false;
00767 }
00768 }
00769 else {
00770
00771 if (region == NULL) {
00772
00773
00774
00775
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
00791 ls_region = *region;
00792 }
00793 }
00794
00795 if ((region == NULL)&&(vw)) {
00796
00797 struct timeval tv;
00798
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
00805 high_freq = true;
00806 }
00807
00808 if (vw->saved_surface) {
00809
00810 if (vw->lastflip % 1000 < 40) {
00811 }
00812 }
00813
00814 vw->lastflip = newfliptime;
00815 }
00816
00817 if (high_freq) {
00818
00819 if (!this->high_freq_surface) {
00820
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
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
00836
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
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
00851 this->high_freq_lastflip = vw->lastflip;
00852 }
00853 }
00854
00855
00856 this->dst_surface->lock();
00857
00858 this->dst_surface->setClip(&ls_region);
00859
00860
00861 if (!vw)
00862 cleared = true;
00863 else
00864 cleared = (!((vw->alphachannel==false)&&(vw->opacity==255)));
00865
00866
00867
00868
00869
00870
00871
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
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
00882 if (!aw->opacity)
00883 continue;
00884
00885
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
00893 if (depth_test) {
00894
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
00907
00908
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
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
00934 this->dst_surface->setClip(NULL);
00935 this->dst_surface->unlock();
00936 if (!locked)
00937 lock.unlock();
00938 return false;
00939 }
00940 }
00941
00942
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
00969 src_rect.x += aw->vrect.x;
00970 src_rect.y += aw->vrect.y;
00971 }
00972
00973
00974
00975
00976
00977
00978
00979 if ((aw->alphachannel)&&((win_found)||(!this->dst_surface->config.surface_buffer->alphachannel))) {
00980
00981 if (!(MMSFBSURFACE_READ_BUFFER(aw->surface).opaque)) {
00982
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
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
01003 if (!win_found) {
01004
01005 if (cleared)
01006 this->dst_surface->clear();
01007 win_found = true;
01008 }
01009 }
01010 else {
01011
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
01021 if (!win_found) {
01022
01023
01024
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
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
01053 if (cleared)
01054 this->dst_surface->clear();
01055 }
01056
01057
01058 drawPointer(&ls_region);
01059
01060
01061 this->dst_surface->setClip(NULL);
01062
01063
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
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
01084 INITCHECK;
01085
01086
01087 lock.lock();
01088
01089
01090 for (unsigned int i=0; i < this->vwins.size(); i++)
01091 if (this->vwins.at(i).window == window) {
01092
01093 loadWindowConfig(window, &(this->vwins.at(i)));
01094
01095 PRINT_LOCK("flipSurface");
01096
01097 flipSurface(this->vwins.at(i).surface, NULL, true);
01098 PRINT_LOCK("end flipSurface");
01099
01100
01101 lock.unlock();
01102
01103 return true;
01104 }
01105
01106
01107 lock.unlock();
01108 return false;
01109 }
01110
01111 bool MMSFBWindowManager::setWindowPosition(MMSFBWindow *window, MMSFBRectangle *vrect) {
01112
01113
01114 INITCHECK;
01115
01116
01117 lock.lock();
01118
01119
01120 if (vrect) {
01121
01122 for (unsigned int i=0; i < this->windows.size(); i++) {
01123 if (this->windows.at(i).window == window) {
01124
01125 this->windows.at(i).vrect = *vrect;
01126 break;
01127 }
01128 }
01129 }
01130
01131
01132 for (unsigned int i=0; i < this->vwins.size(); i++)
01133 if (this->vwins.at(i).window == window) {
01134
01135 VISIBLE_WINDOWS old_vwin;
01136 old_vwin = this->vwins.at(i);
01137
01138
01139 loadWindowConfig(window, &(this->vwins.at(i)));
01140
01141
01142 if (this->high_freq_surface == this->vwins.at(i).surface) {
01143
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
01154 flipSurface(this->vwins.at(i).surface, NULL, true);
01155 PRINT_LOCK("end flipSurface");
01156
01157
01158 if (old_vwin.region.y1 < this->vwins.at(i).region.y1) {
01159
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, ®ion, true);
01166 PRINT_LOCK("end flipSurface");
01167 }
01168 else
01169 if (old_vwin.region.y1 > this->vwins.at(i).region.y1) {
01170
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, ®ion, true);
01177 PRINT_LOCK("end flipSurface");
01178 }
01179 if (old_vwin.region.x1 < this->vwins.at(i).region.x1) {
01180
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, ®ion, true);
01191 PRINT_LOCK("end flipSurface");
01192 }
01193 }
01194 else
01195 if (old_vwin.region.x1 > this->vwins.at(i).region.x1) {
01196
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, ®ion, true);
01207 PRINT_LOCK("end flipSurface");
01208 }
01209 }
01210
01211
01212 lock.unlock();
01213
01214 return true;
01215 }
01216
01217
01218 lock.unlock();
01219 return false;
01220 }
01221
01222 bool MMSFBWindowManager::setWindowSize(MMSFBWindow *window, int w, int h) {
01223
01224
01225 INITCHECK;
01226
01227
01228 lock.lock();
01229
01230
01231 for (unsigned int i=0; i < this->vwins.size(); i++)
01232 if (this->vwins.at(i).window == window) {
01233
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
01241 hideWindow(window, true, false);
01242
01243
01244 MMSFBSurface *surface;
01245 window->getSurface(&surface);
01246 surface->lock();
01247 surface->resize(w, h);
01248 surface->unlock();
01249
01250
01251 for (unsigned int j=0; j < this->windows.size(); j++)
01252 if (this->windows.at(j).window == window) {
01253
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
01262 if ((old_w <= w)&&(old_h <= h))
01263
01264 showWindow(window, true, true);
01265 else {
01266
01267 showWindow(window, true, false);
01268
01269 PRINT_LOCK("flipSurface");
01270
01271 flipSurface(NULL, &old_vwin.region, true, true);
01272 PRINT_LOCK("end flipSurface");
01273 }
01274 }
01275
01276
01277 lock.unlock();
01278
01279 return true;
01280 }
01281
01282
01283 for (unsigned int i=0; i < this->windows.size(); i++)
01284 if (this->windows.at(i).window == window) {
01285
01286
01287 MMSFBSurface *surface;
01288 window->getSurface(&surface);
01289 surface->lock();
01290 surface->resize(w, h);
01291 surface->unlock();
01292
01293
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
01300 lock.unlock();
01301
01302 return true;
01303 }
01304
01305
01306 lock.unlock();
01307 return false;
01308 }
01309
01310 bool MMSFBWindowManager::setWindowVisibleRectangle(MMSFBWindow *window, MMSFBRectangle *rect) {
01311 bool ret = false;
01312
01313
01314 INITCHECK;
01315
01316
01317 lock.lock();
01318
01319
01320 for (unsigned int i=0; i < this->windows.size(); i++)
01321 if (this->windows.at(i).window == window) {
01322
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
01338 for (unsigned int i=0; i < this->vwins.size(); i++)
01339 if (this->vwins.at(i).window == window) {
01340
01341 loadWindowConfig(window, &(this->vwins.at(i)));
01342
01343 PRINT_LOCK("flipSurface");
01344
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
01360 INITCHECK;
01361
01362
01363 lock.lock();
01364
01365
01366 for (unsigned int i=0; i < this->windows.size(); i++)
01367 if (this->windows.at(i).window == window) {
01368
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
01383 INITCHECK;
01384
01385
01386 lock.lock();
01387
01388
01389 for (unsigned int i=0; i < this->windows.size(); i++)
01390 if (this->windows.at(i).window == window) {
01391
01392 bool shown = window->isShown();
01393 window->hide();
01394
01395
01396 MMSFBSurface *saved_suf = this->dst_surface;
01397 if (window->getSurface(&this->dst_surface)) {
01398
01399 MMSFBRegion region;
01400 this->dst_surface->getSize(®ion.x2, ®ion.y2);
01401 region.x1 = 0;
01402 region.y1 = 0;
01403 region.x2-= 1;
01404 region.y2-= 1;
01405 PRINT_LOCK("flipSurface");
01406 flipSurface(NULL, ®ion, true, false);
01407 PRINT_LOCK("end flipSurface");
01408 }
01409
01410
01411 this->dst_surface = saved_suf;
01412
01413
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
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
01437 this->pointer_posx = pointer_posx & ~0x01;
01438 this->pointer_posy = pointer_posy & ~0x01;
01439 break;
01440 default:
01441
01442 this->pointer_posx = pointer_posx;
01443 this->pointer_posy = pointer_posy;
01444 break;
01445 }
01446
01447
01448 if (!this->show_pointer)
01449 return;
01450
01451
01452 if (!this->pointer_surface)
01453 if (!loadPointer()) {
01454
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
01470 MMSFBRegion old_region = this->pointer_region;
01471
01472
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
01481 this->pointer_opacity = 255;
01482 this->pointer_fadecnt = 0;
01483
01484
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
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
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
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
01528 if (this->usetaff) {
01529
01530
01531
01532
01533 bool retry = false;
01534 do {
01535 MMSTaffFile *tafff;
01536 if (retry) {
01537 retry = false;
01538 DEBUGOUT("MMSFBWindowManager, retry\n");
01539
01540 tafff = new MMSTaffFile(imagefile + ".taff", NULL,
01541 "", MMSTAFF_EXTERNAL_TYPE_IMAGE);
01542 if (tafff) {
01543
01544 tafff->setExternal(imagefile, MMSTAFF_EXTERNAL_TYPE_IMAGE);
01545 DEBUGOUT("MMSFBWindowManager, taffpf = %d\n", taffpf);
01546 tafff->setDestinationPixelFormat(taffpf);
01547
01548 if (!tafff->convertExternal2TAFF()) {
01549
01550 delete tafff;
01551 break;
01552 }
01553 delete tafff;
01554 }
01555 }
01556
01557
01558 tafff = new MMSTaffFile(imagefile + ".taff", NULL,
01559 imagefile, MMSTAFF_EXTERNAL_TYPE_IMAGE);
01560
01561 if (tafff) {
01562 if (tafff->isLoaded()) {
01563
01564
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
01603 if (!retry) {
01604
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
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
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
01628 delete tafff;
01629
01630 DEBUGMSG("MMSFB", "MMSFBWindowManager has loaded: '%s'", imagefile.c_str());
01631
01632
01633 this->pointer_rect.w = img_width;
01634 this->pointer_rect.h = img_height;
01635
01636 return true;
01637 }
01638 }
01639
01640
01641 delete tafff;
01642 }
01643 } while (retry);
01644 }
01645
01646
01647 #ifdef __HAVE_DIRECTFB__
01648 IDirectFBImageProvider *imageprov = NULL;
01649 DFBSurfaceDescription surface_desc;
01650
01651
01652 if (!mmsfb->createImageProvider(&imageprov, imagefile)) {
01653 if (imageprov)
01654 imageprov->Release(imageprov);
01655 return false;
01656 }
01657
01658
01659 if (imageprov->GetSurfaceDescription(imageprov, &surface_desc)!=DFB_OK) {
01660 imageprov->Release(imageprov);
01661 return false;
01662 }
01663
01664
01665 if (!this->layer->createSurface(&this->pointer_surface, surface_desc.width, surface_desc.height)) {
01666 imageprov->Release(imageprov);
01667 return false;
01668 }
01669
01670
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
01678 imageprov->Release(imageprov);
01679
01680
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
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
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
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
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