summaryrefslogtreecommitdiff
path: root/src/drivers/Android/Fl_Android_Window_Driver.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/Android/Fl_Android_Window_Driver.cxx')
-rw-r--r--src/drivers/Android/Fl_Android_Window_Driver.cxx826
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