Add a function to set monitor scale factor manually
* src/pgtkfns.c (pgtk_get_monitor_scale_factor): New function to get manual scale factor from alist. (Fpgtk_set_monitor_scale_factor): New function to set manual scale factor into alist. (Fx_display_pixel_width): Use manual scale factor first, if not set, use gdk's one. (Fx_display_pixel_height): Use manual scale factor first, if not set, use gdk's one. (Fpgtk_display_monitor_attributes_list): Use manual scale factor first, if not set, use gdk's one. (syms_of_pgtkfns): initialize alist.
This commit is contained in:
parent
44f7f57c68
commit
bcb74798ed
1 changed files with 102 additions and 22 deletions
124
src/pgtkfns.c
124
src/pgtkfns.c
|
@ -54,12 +54,37 @@ static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object);
|
|||
|
||||
static const char *pgtk_app_name = "Emacs";
|
||||
|
||||
/* scale factor manually set per monitor */
|
||||
static Lisp_Object monitor_scale_factor_alist;
|
||||
|
||||
/* ==========================================================================
|
||||
|
||||
Internal utility functions
|
||||
|
||||
========================================================================== */
|
||||
|
||||
static double
|
||||
pgtk_get_monitor_scale_factor (const char *model)
|
||||
{
|
||||
Lisp_Object mdl = build_string (model);
|
||||
Lisp_Object tem = Fassoc(mdl, monitor_scale_factor_alist, Qnil);
|
||||
if (NILP (tem))
|
||||
return 0;
|
||||
Lisp_Object cdr = Fcdr (tem);
|
||||
if (NILP (cdr))
|
||||
return 0;
|
||||
if (FIXNUMP (cdr))
|
||||
{
|
||||
return XFIXNUM (cdr);
|
||||
}
|
||||
else if (FLOATP (cdr))
|
||||
{
|
||||
return XFLOAT_DATA (cdr);
|
||||
}
|
||||
else
|
||||
error ("unknown type of scale-factor");
|
||||
}
|
||||
|
||||
struct pgtk_display_info *
|
||||
check_pgtk_display_info (Lisp_Object object)
|
||||
{
|
||||
|
@ -1115,6 +1140,50 @@ pgtk_default_font_parameter (struct frame *f, Lisp_Object parms)
|
|||
|
||||
========================================================================== */
|
||||
|
||||
DEFUN ("pgtk-set-monitor-scale-factor", Fpgtk_set_monitor_scale_factor,
|
||||
Spgtk_set_monitor_scale_factor, 2, 2, 0,
|
||||
doc: /* Set monitor MONITOR-MODEL's scale factor to SCALE-FACTOR.
|
||||
Since Gdk's scale factor is integer, physical pixel width/height is
|
||||
incorrect when you specify fractional scale factor in compositor.
|
||||
If you set scale factor by this function, it is used instead of Gdk's one.
|
||||
|
||||
Pass nil as SCALE-FACTOR if you want to reset the specified monitor's
|
||||
scale factor. */ )
|
||||
(Lisp_Object monitor_model, Lisp_Object scale_factor)
|
||||
{
|
||||
CHECK_STRING (monitor_model);
|
||||
if (!NILP (scale_factor))
|
||||
{
|
||||
CHECK_NUMBER (scale_factor);
|
||||
if (FIXNUMP (scale_factor))
|
||||
{
|
||||
if (XFIXNUM (scale_factor) <= 0)
|
||||
error ("scale factor must be > 0.");
|
||||
}
|
||||
else if (FLOATP (scale_factor))
|
||||
{
|
||||
if (XFLOAT_DATA (scale_factor) <= 0.0)
|
||||
error ("scale factor must be > 0.");
|
||||
}
|
||||
else
|
||||
error ("unknown type of scale-factor");
|
||||
}
|
||||
|
||||
Lisp_Object tem = Fassoc (monitor_model, monitor_scale_factor_alist, Qnil);
|
||||
if (NILP (tem))
|
||||
{
|
||||
if (!NILP (scale_factor))
|
||||
monitor_scale_factor_alist = Fcons (Fcons (monitor_model, scale_factor),
|
||||
monitor_scale_factor_alist);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fsetcdr (tem, scale_factor);
|
||||
}
|
||||
|
||||
return scale_factor;
|
||||
}
|
||||
|
||||
DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0,
|
||||
doc: /* Make a new X window, which is called a "frame" in Emacs terms.
|
||||
Return an Emacs frame object. PARMS is an alist of frame parameters.
|
||||
|
@ -2419,17 +2488,19 @@ each physical monitor, use `display-monitor-attributes-list'. */)
|
|||
for (i = 0; i < n_monitors; ++i)
|
||||
{
|
||||
GdkRectangle rec;
|
||||
int scale = 1;
|
||||
double scale = 1;
|
||||
|
||||
GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
|
||||
gdk_monitor_get_geometry (monitor, &rec);
|
||||
|
||||
/* GTK returns scaled sizes for the workareas. */
|
||||
scale = gdk_monitor_get_scale_factor (monitor);
|
||||
rec.x *= scale;
|
||||
rec.y *= scale;
|
||||
rec.width *= scale;
|
||||
rec.height *= scale;
|
||||
scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
|
||||
if (scale == 0.0)
|
||||
scale = gdk_monitor_get_scale_factor (monitor);
|
||||
rec.x = rec.x * scale + 0.5;
|
||||
rec.y = rec.y * scale + 0.5;
|
||||
rec.width = rec.width * scale + 0.5;
|
||||
rec.height = rec.height * scale + 0.5;
|
||||
|
||||
width = max(width, rec.x + rec.width);
|
||||
}
|
||||
|
@ -2463,17 +2534,19 @@ each physical monitor, use `display-monitor-attributes-list'. */)
|
|||
for (i = 0; i < n_monitors; ++i)
|
||||
{
|
||||
GdkRectangle rec;
|
||||
int scale = 1;
|
||||
double scale = 1;
|
||||
|
||||
GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
|
||||
gdk_monitor_get_geometry (monitor, &rec);
|
||||
|
||||
/* GTK returns scaled sizes for the workareas. */
|
||||
scale = gdk_monitor_get_scale_factor (monitor);
|
||||
rec.x *= scale;
|
||||
rec.y *= scale;
|
||||
rec.width *= scale;
|
||||
rec.height *= scale;
|
||||
scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
|
||||
if (scale == 0.0)
|
||||
scale = gdk_monitor_get_scale_factor (monitor);
|
||||
rec.x = rec.x * scale + 0.5;
|
||||
rec.y = rec.y * scale + 0.5;
|
||||
rec.width = rec.width * scale + 0.5;
|
||||
rec.height = rec.height * scale + 0.5;
|
||||
|
||||
height = max(height, rec.y + rec.height);
|
||||
}
|
||||
|
@ -2540,7 +2613,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
|
|||
gint width_mm, height_mm;
|
||||
GdkRectangle rec, work;
|
||||
struct MonitorInfo *mi = &monitors[i];
|
||||
int scale = 1;
|
||||
double scale = 1;
|
||||
|
||||
GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
|
||||
if (gdk_monitor_is_primary (monitor))
|
||||
|
@ -2552,15 +2625,17 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
|
|||
gdk_monitor_get_workarea (monitor, &work);
|
||||
|
||||
/* GTK returns scaled sizes for the workareas. */
|
||||
scale = gdk_monitor_get_scale_factor (monitor);
|
||||
rec.x *= scale;
|
||||
rec.y *= scale;
|
||||
rec.width *= scale;
|
||||
rec.height *= scale;
|
||||
work.x *= scale;
|
||||
work.y *= scale;
|
||||
work.width *= scale;
|
||||
work.height *= scale;
|
||||
scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
|
||||
if (scale == 0.0)
|
||||
scale = gdk_monitor_get_scale_factor (monitor);
|
||||
rec.x = rec.x * scale + 0.5;
|
||||
rec.y = rec.y * scale + 0.5;
|
||||
rec.width = rec.width * scale + 0.5;
|
||||
rec.height = rec.height * scale + 0.5;
|
||||
work.x = work.x * scale + 0.5;
|
||||
work.y = work.y * scale + 0.5;
|
||||
work.width = work.width * scale + 0.5;
|
||||
work.height = work.height * scale + 0.5;
|
||||
|
||||
mi->geom.x = rec.x;
|
||||
mi->geom.y = rec.y;
|
||||
|
@ -3885,12 +3960,17 @@ be used as the image of the icon representing the frame. */);
|
|||
defsubr (&Spgtk_print_frames_dialog);
|
||||
defsubr (&Spgtk_backend_display_class);
|
||||
|
||||
defsubr (&Spgtk_set_monitor_scale_factor);
|
||||
|
||||
defsubr (&Sx_file_dialog);
|
||||
|
||||
as_status = 0;
|
||||
as_script = Qnil;
|
||||
as_result = 0;
|
||||
|
||||
monitor_scale_factor_alist = Qnil;
|
||||
staticpro (&monitor_scale_factor_alist);
|
||||
|
||||
tip_timer = Qnil;
|
||||
staticpro (&tip_timer);
|
||||
tip_frame = Qnil;
|
||||
|
|
Loading…
Add table
Reference in a new issue