diff options
Diffstat (limited to 'src/drivers/Android/Fl_Android_Window_Driver.cxx')
| -rw-r--r-- | src/drivers/Android/Fl_Android_Window_Driver.cxx | 826 |
1 files changed, 0 insertions, 826 deletions
diff --git a/src/drivers/Android/Fl_Android_Window_Driver.cxx b/src/drivers/Android/Fl_Android_Window_Driver.cxx deleted file mode 100644 index 6538bf27a..000000000 --- a/src/drivers/Android/Fl_Android_Window_Driver.cxx +++ /dev/null @@ -1,826 +0,0 @@ -// -// Definition of Android window driver for the Fast Light Tool Kit (FLTK). -// -// Copyright 2018-2021 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - - -#include <config.h> -#include <FL/fl_draw.H> -#include <FL/Fl.H> -#include <FL/Fl_Window.H> -#include <FL/Fl_Image.H> -#include <FL/Fl_Bitmap.H> -#include <FL/Fl_Window.H> -#include <FL/Fl_Overlay_Window.H> -#include <FL/platform.H> -#include <math.h> -#include "Fl_Android_Window_Driver.H" -#include "Fl_Android_Screen_Driver.H" -#include "Fl_Android_Graphics_Driver.H" -#include "Fl_Android_Application.H" - - -Fl_Window_Driver *Fl_Window_Driver::newWindowDriver(Fl_Window *w) -{ - return new Fl_Android_Window_Driver(w); -} - - -Window fl_window = 0; - - -void Fl_Android_Window_Driver::show() -{ - if (!shown()) { - // make window - fl_open_display(); - if (pWindow->parent() && !Fl_X::i(pWindow->window())) { - pWindow->set_visible(); - return; - } - pWindow->set_visible(); - Fl_X *x = new Fl_X; - x->w = pWindow; - i(x); - x->next = Fl_X::first; - Fl_X::first = x; - // position window - // TODO: we want to scale the screen to hold all windows - // TODO: we want to allow for screen size hints to make apps look perfect, even if the screen is rotated - if (force_position()) { - // TODO: make sure that we are on a screen if this is just a regular window - } else { - // Center any new window on screen - pWindow->position( - (600-pWindow->w())/2, - (800-pWindow->h())/2 - ); - } - // show window or defer showing window - if (Fl_Android_Application::native_window()) { - pWindow->redraw(); - } else { - pWindow->wait_for_expose(); - } - } else { - // bring window to front - if (!pWindow->parent()) - Fl::first_window(pWindow); // TODO: does this really work? - expose_all(); - } -} - - -void Fl_Android_Window_Driver::hide() -{ - Fl_X* ip = Fl_X::i(pWindow); - if (hide_common()) return; - if (ip->region) { - delete ip->region; - ip->region = nullptr; - } - delete ip; - expose_all(); -} - - -void Fl_Android_Window_Driver::expose_all() -{ - for (Fl_X *x = Fl_X::first; x; x = x->next) { - Fl_Window *win = x->w; - Fl_Android_Window_Driver::driver(win)->wait_for_expose_value = 0; - win->damage(FL_DAMAGE_EXPOSE); - win->redraw(); - } - ((Fl_Android_Screen_Driver*)Fl::screen_driver())->pClearDesktop = true; -} - - -void Fl_Android_Window_Driver::make_current() -{ - // FXIME: that is quite a cludge: - ((Fl_Android_Screen_Driver*)Fl::screen_driver())->pContentChanged = true; - - Fl_Android_Graphics_Driver *gd = dynamic_cast<Fl_Android_Graphics_Driver*>(fl_graphics_driver); - if (gd) { - gd->make_current(pWindow); - } - -} - - -void Fl_Android_Window_Driver::resize(int X,int Y,int W,int H) -{ - int is_a_resize = (W != w() || H != h() || Fl_Window::is_a_rescale()); - if (X != x() || Y != y() || Fl_Window::is_a_rescale()) { - force_position(1); - } else { - if (!is_a_resize) - return; - } - if (is_a_resize) { - pWindow->Fl_Group::resize(X, Y, W, H); - if (visible_r()) { - pWindow->redraw(); - // only wait for exposure if this window has a size - a window - // with no width or height will never get an exposure event - Fl_X *i = Fl_X::i(pWindow); - if (i && W > 0 && H > 0) - wait_for_expose_value = 1; - } - } else { - x(X); - y(Y); - } - if (shown()) { - if (!pWindow->resizable()) - pWindow->size_range(w(), h(), w(), h()); - // compute window position and size in scaled units -// float s = Fl::screen_driver()->scale(screen_num()); -// int scaledX = ceil(X * s), scaledY = ceil(Y * s), scaledW = ceil(W * s), scaledH = ceil(H * s); -// if (scaledW <= 0) -// scaledW = 1; -// if (scaledH <= 0) -// scaledH = 1; -// //SetWindowPos(fl_xid(pWindow), 0, scaledX, scaledY, scaledW, scaledH, flags); - expose_all(); - } -} - -/** - Scroll a portion of the window. - FIXME: We are currently taking the easy way out, basically telling the caller that we don;t know how to scroll - and asking FLTK to draw the new area from scratch. It would be nice if clipping provides all calls - that we need to implement a more efficient scrolling code. - */ -int Fl_Android_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, - void (*draw_area)(void*, int,int,int,int), void* data) -{ -#if 0 - typedef int (WINAPI* fl_GetRandomRgn_func)(HDC, HRGN, INT); - static fl_GetRandomRgn_func fl_GetRandomRgn = 0L; - static char first_time = 1; - // We will have to do some Region magic now, so let's see if the - // required function is available (and it should be starting w/Win95) - if (first_time) { - HMODULE hMod = GetModuleHandle("GDI32.DLL"); - if (hMod) { - fl_GetRandomRgn = (fl_GetRandomRgn_func)GetProcAddress(hMod, "GetRandomRgn"); - } - first_time = 0; - } - float s = Fl::screen_driver()->scale(screen_num()); - src_x *= s; src_y *= s; src_w *= s; src_h *= s; dest_x *= s; dest_y *= s; - // Now check if the source scrolling area is fully visible. - // If it is, we will do a quick scroll and just update the - // newly exposed area. If it is not, we go the safe route and - // re-render the full area instead. - // Note 1: we could go and find the areas that are actually - // obscured and recursively call fl_scroll for the newly found - // rectangles. However, this practice would rely on the - // elements of the undocumented Rgn structure. - // Note 2: although this method should take care of most - // multi-screen solutions, it will not solve issues scrolling - // from a different resolution screen onto another. - // Note 3: this has been tested with image maps, too. - HDC gc = (HDC)fl_graphics_driver->gc(); - if (fl_GetRandomRgn) { - // get the DC region minus all overlapping windows - HRGN sys_rgn = CreateRectRgn(0, 0, 0, 0); - fl_GetRandomRgn(gc, sys_rgn, 4); - // now get the source scrolling rectangle - HRGN src_rgn = CreateRectRgn(src_x, src_y, src_x+src_w, src_y+src_h); - POINT offset = { 0, 0 }; - if (GetDCOrgEx(gc, &offset)) { - OffsetRgn(src_rgn, offset.x, offset.y); - } - // see if all source pixels are available in the system region - // Note: we could be a bit more merciful and subtract the - // scroll destination region as well. - HRGN dst_rgn = CreateRectRgn(0, 0, 0, 0); - int r = CombineRgn(dst_rgn, src_rgn, sys_rgn, RGN_DIFF); - DeleteObject(dst_rgn); - DeleteObject(src_rgn); - DeleteObject(sys_rgn); - if (r != NULLREGION) { - return 1; - } - } - // Great, we can do an accelerated scroll instead of re-rendering - BitBlt(gc, dest_x, dest_y, src_w, src_h, gc, src_x, src_y,SRCCOPY); - return 0; -#endif - return 1; -} - - -#if 0 - -Fl_WinAPI_Window_Driver::Fl_WinAPI_Window_Driver(Fl_Window *win) -: Fl_Window_Driver(win) -{ - icon_ = new icon_data; - memset(icon_, 0, sizeof(icon_data)); - cursor = NULL; - screen_num_ = -1; -} - - -Fl_WinAPI_Window_Driver::~Fl_WinAPI_Window_Driver() -{ - if (shape_data_) { - delete shape_data_->effective_bitmap_; - delete shape_data_; - } - delete icon_; -} - -int Fl_WinAPI_Window_Driver::screen_num() { - if (pWindow->parent()) { - screen_num_ = pWindow->top_window()->driver()->screen_num(); - } - return screen_num_ >= 0 ? screen_num_ : 0; -} - -//FILE*LOG=fopen("log.log","w"); - -void Fl_WinAPI_Window_Driver::screen_num(int n) { -//fprintf(LOG, "screen_num setter old=%d new=%d\n",screen_num_, n);fflush(LOG); - screen_num_ = n; -} - - -RECT // frame of the decorated window in screen coordinates - Fl_WinAPI_Window_Driver::border_width_title_bar_height( - int &bx, // left and right border width - int &by, // bottom border height (=bx) - int &bt // height of window title bar - ) -{ - Fl_Window *win = pWindow; - RECT r = {0,0,0,0}; - bx = by = bt = 0; - if (win->shown() && !win->parent() && win->border() && win->visible()) { - static HMODULE dwmapi_dll = LoadLibrary("dwmapi.dll"); - typedef HRESULT (WINAPI* DwmGetWindowAttribute_type)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute); - static DwmGetWindowAttribute_type DwmGetWindowAttribute = dwmapi_dll ? - (DwmGetWindowAttribute_type)GetProcAddress(dwmapi_dll, "DwmGetWindowAttribute") : NULL; - int need_r = 1; - if (DwmGetWindowAttribute) { - const DWORD DWMWA_EXTENDED_FRAME_BOUNDS = 9; - if ( DwmGetWindowAttribute(fl_xid(win), DWMWA_EXTENDED_FRAME_BOUNDS, &r, sizeof(RECT)) == S_OK ) { - need_r = 0; - } - } - if (need_r) { - GetWindowRect(fl_xid(win), &r); - } - int width, height; -#ifdef FLTK_HIDPI_SUPPORT - RECT rc; - GetClientRect(fl_xid(win), &rc); - width = rc.right; - height = rc.bottom; -#else - float scaling = ((Fl_WinAPI_Screen_Driver*)Fl::screen_driver())->DWM_scaling_factor(); - width = int(win->w() * scaling); - height = int(win->h() * scaling); -#endif - bx = (r.right - r.left - width)/2; - if (bx < 1) bx = 1; - by = bx; - bt = r.bottom - r.top - height - 2 * by; - } - return r; -} - - -// --- window data - -int Fl_WinAPI_Window_Driver::decorated_w() -{ - int bt, bx, by; - float s = Fl::screen_driver()->scale(screen_num()); - border_width_title_bar_height(bx, by, bt); - int mini_bx = bx/s; if (mini_bx < 1) mini_bx = 1; - return w() + 2 * mini_bx; -} - -int Fl_WinAPI_Window_Driver::decorated_h() -{ - int bt, bx, by; - border_width_title_bar_height(bx, by, bt); -#ifdef FLTK_HIDPI_SUPPORT - float s = Fl::screen_driver()->scale(screen_num()); - int mini_by = by/s; if (mini_by < 1) mini_by = 1; - return h() + (bt + by)/s + mini_by; -#else - float scaling = ((Fl_WinAPI_Screen_Driver*)Fl::screen_driver())->DWM_scaling_factor(); - return h() + bt/scaling + 2 * by +1; -#endif -} - - -// --- window management - - - -void Fl_WinAPI_Window_Driver::shape_bitmap_(Fl_Image* b) { - shape_data_->shape_ = b; -} - -void Fl_WinAPI_Window_Driver::shape_alpha_(Fl_Image* img, int offset) { - int i, j, d = img->d(), w = img->w(), h = img->h(), bytesperrow = (w+7)/8; - unsigned u; - uchar byte, onebit; - // build an Fl_Bitmap covering the non-fully transparent/black part of the image - const uchar* bits = new uchar[h*bytesperrow]; // to store the bitmap - const uchar* alpha = (const uchar*)*img->data() + offset; // points to alpha value of rgba pixels - for (i = 0; i < h; i++) { - uchar *p = (uchar*)bits + i * bytesperrow; - byte = 0; - onebit = 1; - for (j = 0; j < w; j++) { - if (d == 3) { - u = *alpha; - u += *(alpha+1); - u += *(alpha+2); - } - else u = *alpha; - if (u > 0) { // if the pixel is not fully transparent/black - byte |= onebit; // turn on the corresponding bit of the bitmap - } - onebit = onebit << 1; // move the single set bit one position to the left - if (onebit == 0 || j == w-1) { - onebit = 1; - *p++ = byte; // store in bitmap one pack of bits - byte = 0; - } - alpha += d; // point to alpha value of next pixel - } - } - Fl_Bitmap* bitmap = new Fl_Bitmap(bits, w, h); - bitmap->alloc_array = 1; - shape_bitmap_(bitmap); - shape_data_->effective_bitmap_ = bitmap; -} - -void Fl_WinAPI_Window_Driver::shape(const Fl_Image* img) { - if (shape_data_) { - if (shape_data_->effective_bitmap_) { delete shape_data_->effective_bitmap_; } - } - else { - shape_data_ = new shape_data_type; - } - memset(shape_data_, 0, sizeof(shape_data_type)); - pWindow->border(false); - int d = img->d(); - if (d && img->count() >= 2) shape_pixmap_((Fl_Image*)img); - else if (d == 0) shape_bitmap_((Fl_Image*)img); - else if (d == 2 || d == 4) shape_alpha_((Fl_Image*)img, d - 1); - else if ((d == 1 || d == 3) && img->count() == 1) shape_alpha_((Fl_Image*)img, 0); -} - - -static inline BYTE bit(int x) { return (BYTE)(1 << (x%8)); } - -static HRGN bitmap2region(Fl_Image* image) { - HRGN hRgn = 0; - /* Does this need to be dynamically determined, perhaps? */ - const int ALLOC_UNIT = 100; - DWORD maxRects = ALLOC_UNIT; - - RGNDATA* pData = (RGNDATA*)malloc(sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRects)); - pData->rdh.dwSize = sizeof(RGNDATAHEADER); - pData->rdh.iType = RDH_RECTANGLES; - pData->rdh.nCount = pData->rdh.nRgnSize = 0; - SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0); - - const int bytesPerLine = (image->w() + 7)/8; - BYTE* p, *data = (BYTE*)*image->data(); - for (int y = 0; y < image->h(); y++) { - // each row, left to right - for (int x = 0; x < image->w(); x++) { - int x0 = x; - while (x < image->w()) { - p = data + x / 8; - if (!((*p) & bit(x))) break; // transparent pixel - x++; - } - if (x > x0) { - RECT *pr; - /* Add the pixels (x0, y) to (x, y+1) as a new rectangle - * in the region - */ - if (pData->rdh.nCount >= maxRects) { - maxRects += ALLOC_UNIT; - pData = (RGNDATA*)realloc(pData, sizeof(RGNDATAHEADER) - + (sizeof(RECT)*maxRects)); - } - pr = (RECT*)&pData->Buffer; - SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1); - if (x0 < pData->rdh.rcBound.left) - pData->rdh.rcBound.left = x0; - if (y < pData->rdh.rcBound.top) - pData->rdh.rcBound.top = y; - if (x > pData->rdh.rcBound.right) - pData->rdh.rcBound.right = x; - if (y+1 > pData->rdh.rcBound.bottom) - pData->rdh.rcBound.bottom = y+1; - pData->rdh.nCount++; - /* On Windows98, ExtCreateRegion() may fail if the - * number of rectangles is too large (ie: > - * 4000). Therefore, we have to create the region by - * multiple steps. - */ - if (pData->rdh.nCount == 2000) { - HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) - + (sizeof(RECT)*maxRects), pData); - if (hRgn) { - CombineRgn(hRgn, hRgn, h, RGN_OR); - DeleteObject(h); - } else - hRgn = h; - pData->rdh.nCount = 0; - SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0); - } - } - } - /* Go to next row */ - data += bytesPerLine; - } - /* Create or extend the region with the remaining rectangles*/ - HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) - + (sizeof(RECT)*maxRects), pData); - if (hRgn) { - CombineRgn(hRgn, hRgn, h, RGN_OR); - DeleteObject(h); - } else hRgn = h; - free(pData); // I've created the region so I can free this now, right? - return hRgn; -} - - -void Fl_WinAPI_Window_Driver::draw_begin() -{ - if (shape_data_) { - float s = Fl::screen_driver()->scale(screen_num()); - if ((shape_data_->lw_ != s*w() || shape_data_->lh_ != s*h()) && shape_data_->shape_) { - // size of window has changed since last time - shape_data_->lw_ = s*w(); - shape_data_->lh_ = s*h(); - Fl_Image* temp = shape_data_->shape_->copy(shape_data_->lw_, shape_data_->lh_); - HRGN region = bitmap2region(temp); - SetWindowRgn(fl_xid(pWindow), region, TRUE); // the system deletes the region when it's no longer needed - delete temp; - } - } -} - - -void Fl_WinAPI_Window_Driver::flush_double() -{ - if (!shown()) return; - pWindow->make_current(); // make sure fl_gc is non-zero - Fl_X *i = Fl_X::i(pWindow); - if (!i) return; // window not yet created - - if (!other_xid) { - other_xid = fl_create_offscreen(w(), h()); - pWindow->clear_damage(FL_DAMAGE_ALL); - } - if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) { - fl_clip_region(i->region); i->region = 0; - fl_begin_offscreen(other_xid); - fl_graphics_driver->clip_region( 0 ); - draw(); - fl_end_offscreen(); - } - - int X = 0, Y = 0, W = 0, H = 0; - fl_clip_box(0, 0, w(), h(), X, Y, W, H); - if (other_xid) fl_copy_offscreen(X, Y, W, H, other_xid, X, Y); -} - - -void Fl_WinAPI_Window_Driver::flush_overlay() -{ - Fl_Overlay_Window *oWindow = pWindow->as_overlay_window(); - - if (!shown()) return; - pWindow->make_current(); // make sure fl_gc is non-zero - Fl_X *i = Fl_X::i(pWindow); - if (!i) return; // window not yet created - - int eraseoverlay = (pWindow->damage()&FL_DAMAGE_OVERLAY); - pWindow->clear_damage((uchar)(pWindow->damage()&~FL_DAMAGE_OVERLAY)); - - if (!other_xid) { - other_xid = fl_create_offscreen(w(), h()); - pWindow->clear_damage(FL_DAMAGE_ALL); - } - if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) { - fl_clip_region(i->region); i->region = 0; - fl_begin_offscreen(other_xid); - fl_graphics_driver->clip_region(0); - draw(); - fl_end_offscreen(); - } - - if (eraseoverlay) fl_clip_region(0); - int X = 0, Y = 0, W = 0, H = 0; - fl_clip_box(0, 0, w(), h(), X, Y, W, H); - if (other_xid) fl_copy_offscreen(X, Y, W, H, other_xid, X, Y); - - if (overlay() == oWindow) oWindow->draw_overlay(); -} - - -void Fl_WinAPI_Window_Driver::icons(const Fl_RGB_Image *icons[], int count) { - free_icons(); - - if (count > 0) { - icon_->icons = new Fl_RGB_Image*[count]; - icon_->count = count; - // FIXME: Fl_RGB_Image lacks const modifiers on methods - for (int i = 0;i < count;i++) - icon_->icons[i] = (Fl_RGB_Image*)((Fl_RGB_Image*)icons[i])->copy(); - } - - if (Fl_X::i(pWindow)) - set_icons(); -} - -const void *Fl_WinAPI_Window_Driver::icon() const { - return icon_->legacy_icon; -} - -void Fl_WinAPI_Window_Driver::icon(const void * ic) { - free_icons(); - icon_->legacy_icon = ic; -} - -void Fl_WinAPI_Window_Driver::free_icons() { - int i; - icon_->legacy_icon = 0L; - if (icon_->icons) { - for (i = 0;i < icon_->count;i++) - delete icon_->icons[i]; - delete [] icon_->icons; - icon_->icons = 0L; - } - icon_->count = 0; - if (icon_->big_icon) - DestroyIcon(icon_->big_icon); - if (icon_->small_icon) - DestroyIcon(icon_->small_icon); - icon_->big_icon = NULL; - icon_->small_icon = NULL; -} - - -void Fl_WinAPI_Window_Driver::make_current() { - fl_GetDC(fl_xid(pWindow)); - -#if USE_COLORMAP - // Windows maintains a hardware and software color palette; the - // SelectPalette() call updates the current soft->hard mapping - // for all drawing calls, so we must select it here before any - // code does any drawing... - fl_select_palette(); -#endif // USE_COLORMAP - - fl_graphics_driver->clip_region(0); - ((Fl_GDI_Graphics_Driver*)fl_graphics_driver)->scale(Fl::screen_driver()->scale(screen_num())); -} - -void Fl_WinAPI_Window_Driver::label(const char *name,const char *iname) { - if (shown() && !parent()) { - if (!name) name = ""; - size_t l = strlen(name); - // WCHAR *lab = (WCHAR*) malloc((l + 1) * sizeof(short)); - // l = fl_utf2unicode((unsigned char*)name, l, (wchar_t*)lab); - unsigned wlen = fl_utf8toUtf16(name, (unsigned) l, NULL, 0); // Pass NULL to query length - wlen++; - unsigned short * lab = (unsigned short*)malloc(sizeof(unsigned short)*wlen); - wlen = fl_utf8toUtf16(name, (unsigned) l, lab, wlen); - lab[wlen] = 0; - SetWindowTextW(fl_xid(pWindow), (WCHAR *)lab); - free(lab); - } -} - - -extern void fl_clipboard_notify_retarget(HWND wnd); -extern void fl_update_clipboard(void); - -void Fl_WinAPI_Window_Driver::hide() { - Fl_X* ip = Fl_X::i(pWindow); - // STR#3079: if there remains a window and a non-modal window, and the window is deleted, - // the app remains running without any apparent window. - // Bug mechanism: hiding an owner window unmaps the owned (non-modal) window(s) - // but does not delete it(them) in FLTK. - // Fix for it: - // when hiding a window, build list of windows it owns, and do hide/show on them. - int count = 0; - Fl_Window *win, **doit = NULL; - for (win = Fl::first_window(); win && ip; win = Fl::next_window(win)) { - if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == ip->xid) { - count++; - } - } - if (count) { - doit = new Fl_Window*[count]; - count = 0; - for (win = Fl::first_window(); win && ip; win = Fl::next_window(win)) { - if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == ip->xid) { - doit[count++] = win; - } - } - } - - if (hide_common()) return; - - // make sure any custom icons get freed -// icons(NULL, 0); // free_icons() is called by the Fl_Window destructor - // this little trick keeps the current clipboard alive, even if we are about - // to destroy the window that owns the selection. - if (GetClipboardOwner()==ip->xid) - fl_update_clipboard(); - // Make sure we unlink this window from the clipboard chain - fl_clipboard_notify_retarget(ip->xid); - // Send a message to myself so that I'll get out of the event loop... - PostMessage(ip->xid, WM_APP, 0, 0); - if (private_dc) fl_release_dc(ip->xid, private_dc); - if (ip->xid == fl_window && fl_graphics_driver->gc()) { - fl_release_dc(fl_window, (HDC)fl_graphics_driver->gc()); - fl_window = (HWND)-1; - fl_graphics_driver->gc(0); -# ifdef FLTK_HAVE_CAIROEXT - if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0); -# endif - } - - if (ip->region) Fl_Graphics_Driver::default_driver().XDestroyRegion(ip->region); - - // this little trickery seems to avoid the popup window stacking problem - HWND p = GetForegroundWindow(); - if (p==GetParent(ip->xid)) { - ShowWindow(ip->xid, SW_HIDE); - ShowWindow(p, SW_SHOWNA); - } - DestroyWindow(ip->xid); - // end of fix for STR#3079 - if (count) { - int ii; - for (ii = 0; ii < count; ii++) doit[ii]->hide(); - for (ii = 0; ii < count; ii++) { - if (ii != 0) doit[0]->show(); // Fix for STR#3165 - doit[ii]->show(); - } - delete[] doit; - } - // Try to stop the annoying "raise another program" behavior - if (pWindow->non_modal() && Fl::first_window() && Fl::first_window()->shown()) - Fl::first_window()->show(); - delete ip; - screen_num_ = -1; -} - - -void Fl_WinAPI_Window_Driver::map() { - ShowWindow(fl_xid(pWindow), SW_RESTORE); // extra map calls are harmless -} - - -void Fl_WinAPI_Window_Driver::unmap() { - ShowWindow(fl_xid(pWindow), SW_HIDE); -} - -#if !defined(FL_DOXYGEN) - -void Fl_WinAPI_Window_Driver::make_fullscreen(int X, int Y, int W, int H) { - Fl_Window *w = pWindow; - int top, bottom, left, right; - int sx, sy, sw, sh; - - top = fullscreen_screen_top(); - bottom = fullscreen_screen_bottom(); - left = fullscreen_screen_left(); - right = fullscreen_screen_right(); - - if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) { - top = screen_num(); - bottom = top; - left = top; - right = top; - } - - Fl::screen_xywh(sx, sy, sw, sh, top); - Y = sy; - Fl::screen_xywh(sx, sy, sw, sh, bottom); - H = sy + sh - Y; - Fl::screen_xywh(sx, sy, sw, sh, left); - X = sx; - Fl::screen_xywh(sx, sy, sw, sh, right); - W = sx + sw - X; - - DWORD flags = GetWindowLong(fl_xid(w), GWL_STYLE); - flags = flags & ~(WS_THICKFRAME|WS_CAPTION); - SetWindowLong(fl_xid(w), GWL_STYLE, flags); - - // SWP_NOSENDCHANGING is so that we can override size limits - float s = Fl::screen_driver()->scale(screen_num()); - SetWindowPos(fl_xid(w), HWND_TOP, X*s, Y*s, W*s, H*s, SWP_NOSENDCHANGING | SWP_FRAMECHANGED); -} - -#endif // !defined(FL_DOXYGEN) - - -void Fl_WinAPI_Window_Driver::fullscreen_on() { - pWindow->_set_fullscreen(); - make_fullscreen(x(), y(), w(), h()); - Fl::handle(FL_FULLSCREEN, pWindow); -} - - -void Fl_WinAPI_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { - pWindow->_clear_fullscreen(); - DWORD style = GetWindowLong(fl_xid(pWindow), GWL_STYLE); - // Remove the xid temporarily so that Fl_WinAPI_Window_Driver::fake_X_wm() behaves like it - // does in Fl_WinAPI_Window_Driver::makeWindow(). - HWND xid = fl_xid(pWindow); - Fl_X::i(pWindow)->xid = NULL; - int wx, wy, bt, bx, by; - switch (fake_X_wm(wx, wy, bt, bx, by)) { - case 0: - break; - case 1: - style |= WS_CAPTION; - break; - case 2: - if (border()) { - style |= WS_THICKFRAME | WS_CAPTION; - } - break; - } - Fl_X::i(pWindow)->xid = xid; - // compute window position and size in scaled units - float s = Fl::screen_driver()->scale(screen_num()); - int scaledX = ceil(X*s), scaledY= ceil(Y*s), scaledW = ceil(W*s), scaledH = ceil(H*s); - // Adjust for decorations (but not if that puts the decorations - // outside the screen) - if ((X != x()) || (Y != y())) { - scaledX -= bx; - scaledY -= by+bt; - } - scaledW += bx*2; - scaledH += by*2+bt; - SetWindowLong(fl_xid(pWindow), GWL_STYLE, style); - SetWindowPos(fl_xid(pWindow), 0, scaledX, scaledY, scaledW, scaledH, - SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); - Fl::handle(FL_FULLSCREEN, pWindow); -} - - -void Fl_WinAPI_Window_Driver::iconize() { - ShowWindow(fl_xid(pWindow), SW_SHOWMINNOACTIVE); -} - - -void Fl_WinAPI_Window_Driver::decoration_sizes(int *top, int *left, int *right, int *bottom) { - if (size_range_set() && (maxw() != minw() || maxh() != minh())) { - *left = *right = GetSystemMetrics(SM_CXSIZEFRAME); - *top = *bottom = GetSystemMetrics(SM_CYSIZEFRAME); - } else { - *left = *right = GetSystemMetrics(SM_CXFIXEDFRAME); - *top = *bottom = GetSystemMetrics(SM_CYFIXEDFRAME); - } - *top += GetSystemMetrics(SM_CYCAPTION); -} - - -Fl_WinAPI_Window_Driver::type_for_resize_window_between_screens Fl_WinAPI_Window_Driver::data_for_resize_window_between_screens_ = {0, false}; - -void Fl_WinAPI_Window_Driver::resize_after_screen_change(void *data) { - Fl_Window *win = (Fl_Window*)data; - RECT r; - GetClientRect(fl_xid(win), &r); - float old_f = float(r.right)/win->w(); - int ns = data_for_resize_window_between_screens_.screen; - win->driver()->resize_after_scale_change(ns, old_f, Fl::screen_driver()->scale(ns)); - data_for_resize_window_between_screens_.busy = false; -} - -#endif |
