HiDPI support for WIN32 platform: begin to support screen-specific scale factor.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12280 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
c6c4e8d426
commit
7dc496e97d
@ -1112,7 +1112,8 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
#ifdef FLTK_HIDPI_SUPPORT
|
||||
case 0x02E0: { // WM_DPICHANGED:
|
||||
float f = HIWORD(wParam)/96.;
|
||||
Fl::screen_driver()->scale(0, f);
|
||||
//for now, same scale factor for each screen
|
||||
for (int i = 0; i < Fl::screen_count(); i++) Fl::screen_driver()->scale(i, f);
|
||||
Fl_Graphics_Driver::default_driver().scale(f);
|
||||
//fprintf(LOG,"WM_DPICHANGED f=%.2f\n", f);fflush(LOG);
|
||||
if (!window->parent()) {
|
||||
@ -1445,7 +1446,17 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
if (nx & 0x8000) nx -= 65536;
|
||||
if (ny & 0x8000) ny -= 65536;
|
||||
//fprintf(LOG,"WM_MOVE position(%d,%d) s=%.2f\n",int(nx/scale),int(ny/scale),scale);
|
||||
window->position(nx/scale, ny/scale); }
|
||||
window->position(nx/scale, ny/scale);
|
||||
// detect when window changes screen
|
||||
Fl_WinAPI_Screen_Driver *sd = (Fl_WinAPI_Screen_Driver*)Fl::screen_driver();
|
||||
int news = sd->screen_num_unscaled(nx + window->w()*scale, ny + window->h()*scale);
|
||||
Fl_WinAPI_Window_Driver *wd = Fl_WinAPI_Window_Driver::driver(window);
|
||||
int olds = wd->screen_num();
|
||||
if (olds != news) {
|
||||
wd->screen_num(news);
|
||||
//fprintf(LOG,"olds=%d news=%d\n",olds,news);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETCURSOR:
|
||||
@ -1529,7 +1540,7 @@ static int fake_X_wm_style(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, in
|
||||
int ret = bx = by = bt = 0;
|
||||
|
||||
int fallback = 1;
|
||||
float s = Fl::screen_driver()->scale(((Fl_Window*)w)->driver()->screen_num());
|
||||
float s = Fl::screen_driver()->scale(w->driver()->screen_num());
|
||||
if (!w->parent()) {
|
||||
if (fl_xid(w)) {
|
||||
Fl_WinAPI_Window_Driver *dr = (Fl_WinAPI_Window_Driver*)w->driver();
|
||||
@ -1801,7 +1812,19 @@ Fl_X* Fl_WinAPI_Window_Driver::makeWindow() {
|
||||
DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
DWORD styleEx = WS_EX_LEFT;
|
||||
|
||||
float s = Fl::screen_driver()->scale(0);
|
||||
//compute adequate screen where to put the window
|
||||
int nscreen = 0;
|
||||
if (w->parent()) {
|
||||
nscreen = w->top_window()->driver()->screen_num();
|
||||
} else if (w->driver()->force_position() && Fl_WinAPI_Window_Driver::driver(w)->screen_num_ >= 0) {
|
||||
nscreen = w->driver()->screen_num();
|
||||
} else {
|
||||
Fl_Window *hint = Fl::first_window();
|
||||
if (hint) {
|
||||
nscreen = hint->top_window()->driver()->screen_num();
|
||||
}
|
||||
}
|
||||
float s = Fl::screen_driver()->scale(nscreen);
|
||||
int xp = w->x() * s; // these are in graphical units
|
||||
int yp = w->y() * s;
|
||||
int wp = w->w() * s;
|
||||
@ -1978,7 +2001,7 @@ void Fl_WinAPI_Window_Driver::set_minmax(LPMINMAXINFO minmax)
|
||||
hd *= 2;
|
||||
hd += td;
|
||||
|
||||
float s = Fl::screen_driver()->scale(0);
|
||||
float s = Fl::screen_driver()->scale(screen_num());
|
||||
minmax->ptMinTrackSize.x = s*minw() + wd;
|
||||
minmax->ptMinTrackSize.y = s*minh() + hd;
|
||||
if (maxw()) {
|
||||
|
||||
@ -37,14 +37,14 @@ protected:
|
||||
RECT screens[MAX_SCREENS];
|
||||
RECT work_area[MAX_SCREENS];
|
||||
float dpi[MAX_SCREENS][2];
|
||||
float scale_of_screen[MAX_SCREENS];
|
||||
|
||||
static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM);
|
||||
BOOL screen_cb(HMONITOR mon, HDC, LPRECT r);
|
||||
int screen_num_unscaled(int x, int y);
|
||||
int get_mouse_unscaled(int &mx, int &my);
|
||||
|
||||
public:
|
||||
Fl_WinAPI_Screen_Driver() : Fl_Screen_Driver() { scale_ = 1; }
|
||||
Fl_WinAPI_Screen_Driver() : Fl_Screen_Driver() { }
|
||||
// --- display management
|
||||
virtual int visual(int flags);
|
||||
// --- screen configuration
|
||||
@ -55,6 +55,7 @@ public:
|
||||
virtual int h();
|
||||
virtual void screen_xywh(int &X, int &Y, int &W, int &H, int n);
|
||||
virtual void screen_dpi(float &h, float &v, int n=0);
|
||||
int screen_num_unscaled(int x, int y);
|
||||
float DWM_scaling_factor(int screen_num);
|
||||
virtual void screen_work_area(int &X, int &Y, int &W, int &H, int n);
|
||||
// --- audible output
|
||||
@ -87,11 +88,9 @@ public:
|
||||
return SYSTEMWIDE_APP_SCALING;
|
||||
}
|
||||
#endif
|
||||
virtual float scale(int n) {return scale_;}
|
||||
virtual void scale(int n, float f) { scale_ = f;}
|
||||
virtual float scale(int n) {return scale_of_screen[n];}
|
||||
virtual void scale(int n, float f) { scale_of_screen[n] = f;}
|
||||
virtual float desktop_scale_factor();
|
||||
private:
|
||||
float scale_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -100,6 +100,7 @@ BOOL Fl_WinAPI_Screen_Driver::screen_cb(HMONITOR mon, HDC, LPRECT r)
|
||||
screens[num_screens] = mi.rcMonitor;
|
||||
// If we also want to record the work area, we would also store mi.rcWork at this point
|
||||
work_area[num_screens] = mi.rcWork;
|
||||
scale_of_screen[num_screens] = 1;
|
||||
/*fl_alert("screen %d %d,%d,%d,%d work %d,%d,%d,%d",num_screens,
|
||||
screens[num_screens].left,screens[num_screens].right,screens[num_screens].top,screens[num_screens].bottom,
|
||||
work_area[num_screens].left,work_area[num_screens].right,work_area[num_screens].top,work_area[num_screens].bottom);
|
||||
@ -152,6 +153,7 @@ void Fl_WinAPI_Screen_Driver::init()
|
||||
screens[0].right = GetSystemMetrics(SM_CXSCREEN);
|
||||
screens[0].bottom = GetSystemMetrics(SM_CYSCREEN);
|
||||
work_area[0] = screens[0];
|
||||
scale_of_screen[0] = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -159,10 +161,10 @@ void Fl_WinAPI_Screen_Driver::screen_work_area(int &X, int &Y, int &W, int &H, i
|
||||
{
|
||||
if (num_screens < 0) init();
|
||||
if (n < 0 || n >= num_screens) n = 0;
|
||||
X = work_area[n].left/scale_;
|
||||
Y = work_area[n].top/scale_;
|
||||
W = (work_area[n].right - X)/scale_;
|
||||
H = (work_area[n].bottom - Y)/scale_;
|
||||
X = work_area[n].left/scale_of_screen[n];
|
||||
Y = work_area[n].top/scale_of_screen[n];
|
||||
W = (work_area[n].right - X)/scale_of_screen[n];
|
||||
H = (work_area[n].bottom - Y)/scale_of_screen[n];
|
||||
}
|
||||
|
||||
|
||||
@ -174,10 +176,10 @@ void Fl_WinAPI_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H, int n)
|
||||
n = 0;
|
||||
|
||||
if (num_screens > 0) {
|
||||
X = screens[n].left/scale_;
|
||||
Y = screens[n].top/scale_;
|
||||
W = (screens[n].right - screens[n].left)/scale_;
|
||||
H = (screens[n].bottom - screens[n].top)/scale_;
|
||||
X = screens[n].left/scale_of_screen[n];
|
||||
Y = screens[n].top/scale_of_screen[n];
|
||||
W = (screens[n].right - screens[n].left)/scale_of_screen[n];
|
||||
H = (screens[n].bottom - screens[n].top)/scale_of_screen[n];
|
||||
} else {
|
||||
/* Fallback if something is broken... */
|
||||
X = 0;
|
||||
|
||||
@ -61,6 +61,7 @@ class FL_EXPORT Fl_WinAPI_Window_Driver : public Fl_Window_Driver
|
||||
HICON big_icon;
|
||||
HICON small_icon;
|
||||
};
|
||||
int screen_num_;
|
||||
private:
|
||||
void shape_bitmap_(Fl_Image* b);
|
||||
void shape_alpha_(Fl_Image* img, int offset);
|
||||
@ -70,6 +71,8 @@ public:
|
||||
static inline Fl_WinAPI_Window_Driver* driver(Fl_Window *w) {return (Fl_WinAPI_Window_Driver*)w->driver();}
|
||||
HDC private_dc; // used for OpenGL
|
||||
RECT border_width_title_bar_height(int &bx, int &by, int &bt);
|
||||
virtual void screen_num(int n) { screen_num_ = n; }
|
||||
virtual int screen_num();
|
||||
|
||||
struct icon_data *icon_;
|
||||
HCURSOR cursor;
|
||||
|
||||
@ -48,6 +48,7 @@ Fl_WinAPI_Window_Driver::Fl_WinAPI_Window_Driver(Fl_Window *win)
|
||||
icon_ = new icon_data;
|
||||
memset(icon_, 0, sizeof(icon_data));
|
||||
cursor = NULL;
|
||||
screen_num_ = -1;
|
||||
}
|
||||
|
||||
|
||||
@ -60,6 +61,13 @@ Fl_WinAPI_Window_Driver::~Fl_WinAPI_Window_Driver()
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
RECT // frame of the decorated window in screen coordinates
|
||||
Fl_WinAPI_Window_Driver::border_width_title_bar_height(
|
||||
@ -395,7 +403,7 @@ void Fl_WinAPI_Window_Driver::make_current() {
|
||||
#endif // USE_COLORMAP
|
||||
|
||||
fl_graphics_driver->clip_region(0);
|
||||
fl_graphics_driver->scale(Fl::screen_driver()->scale(0));
|
||||
fl_graphics_driver->scale(Fl::screen_driver()->scale(screen_num()));
|
||||
fl_graphics_driver->line_style(FL_SOLID); // scale also default line width
|
||||
}
|
||||
|
||||
@ -489,6 +497,7 @@ void Fl_WinAPI_Window_Driver::hide() {
|
||||
if (pWindow->non_modal() && Fl::first_window() && Fl::first_window()->shown())
|
||||
Fl::first_window()->show();
|
||||
delete ip;
|
||||
screen_num_ = -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user