aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuuki Harano2021-01-04 04:13:33 +0900
committerYuuki Harano2021-01-04 04:13:33 +0900
commitbcb74798ed3068e324cffd8856f5a70f2c6c7687 (patch)
tree44a8e192fee4f92018fe7d65de060f4a0754cc8c /src
parent44f7f57c6833149799539c5e0abcadf4d7d61d43 (diff)
downloademacs-bcb74798ed3068e324cffd8856f5a70f2c6c7687.tar.gz
emacs-bcb74798ed3068e324cffd8856f5a70f2c6c7687.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/pgtkfns.c124
1 files changed, 102 insertions, 22 deletions
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 7d2183d2a0a..63e121f1180 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -54,12 +54,37 @@ static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object);
54 54
55static const char *pgtk_app_name = "Emacs"; 55static const char *pgtk_app_name = "Emacs";
56 56
57/* scale factor manually set per monitor */
58static Lisp_Object monitor_scale_factor_alist;
59
57/* ========================================================================== 60/* ==========================================================================
58 61
59 Internal utility functions 62 Internal utility functions
60 63
61 ========================================================================== */ 64 ========================================================================== */
62 65
66static double
67pgtk_get_monitor_scale_factor (const char *model)
68{
69 Lisp_Object mdl = build_string (model);
70 Lisp_Object tem = Fassoc(mdl, monitor_scale_factor_alist, Qnil);
71 if (NILP (tem))
72 return 0;
73 Lisp_Object cdr = Fcdr (tem);
74 if (NILP (cdr))
75 return 0;
76 if (FIXNUMP (cdr))
77 {
78 return XFIXNUM (cdr);
79 }
80 else if (FLOATP (cdr))
81 {
82 return XFLOAT_DATA (cdr);
83 }
84 else
85 error ("unknown type of scale-factor");
86}
87
63struct pgtk_display_info * 88struct pgtk_display_info *
64check_pgtk_display_info (Lisp_Object object) 89check_pgtk_display_info (Lisp_Object object)
65{ 90{
@@ -1115,6 +1140,50 @@ pgtk_default_font_parameter (struct frame *f, Lisp_Object parms)
1115 1140
1116 ========================================================================== */ 1141 ========================================================================== */
1117 1142
1143DEFUN ("pgtk-set-monitor-scale-factor", Fpgtk_set_monitor_scale_factor,
1144 Spgtk_set_monitor_scale_factor, 2, 2, 0,
1145 doc: /* Set monitor MONITOR-MODEL's scale factor to SCALE-FACTOR.
1146Since Gdk's scale factor is integer, physical pixel width/height is
1147incorrect when you specify fractional scale factor in compositor.
1148If you set scale factor by this function, it is used instead of Gdk's one.
1149
1150Pass nil as SCALE-FACTOR if you want to reset the specified monitor's
1151scale factor. */ )
1152 (Lisp_Object monitor_model, Lisp_Object scale_factor)
1153{
1154 CHECK_STRING (monitor_model);
1155 if (!NILP (scale_factor))
1156 {
1157 CHECK_NUMBER (scale_factor);
1158 if (FIXNUMP (scale_factor))
1159 {
1160 if (XFIXNUM (scale_factor) <= 0)
1161 error ("scale factor must be > 0.");
1162 }
1163 else if (FLOATP (scale_factor))
1164 {
1165 if (XFLOAT_DATA (scale_factor) <= 0.0)
1166 error ("scale factor must be > 0.");
1167 }
1168 else
1169 error ("unknown type of scale-factor");
1170 }
1171
1172 Lisp_Object tem = Fassoc (monitor_model, monitor_scale_factor_alist, Qnil);
1173 if (NILP (tem))
1174 {
1175 if (!NILP (scale_factor))
1176 monitor_scale_factor_alist = Fcons (Fcons (monitor_model, scale_factor),
1177 monitor_scale_factor_alist);
1178 }
1179 else
1180 {
1181 Fsetcdr (tem, scale_factor);
1182 }
1183
1184 return scale_factor;
1185}
1186
1118DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0, 1187DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0,
1119 doc: /* Make a new X window, which is called a "frame" in Emacs terms. 1188 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
1120Return an Emacs frame object. PARMS is an alist of frame parameters. 1189Return an Emacs frame object. PARMS is an alist of frame parameters.
@@ -2419,17 +2488,19 @@ each physical monitor, use `display-monitor-attributes-list'. */)
2419 for (i = 0; i < n_monitors; ++i) 2488 for (i = 0; i < n_monitors; ++i)
2420 { 2489 {
2421 GdkRectangle rec; 2490 GdkRectangle rec;
2422 int scale = 1; 2491 double scale = 1;
2423 2492
2424 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i); 2493 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
2425 gdk_monitor_get_geometry (monitor, &rec); 2494 gdk_monitor_get_geometry (monitor, &rec);
2426 2495
2427 /* GTK returns scaled sizes for the workareas. */ 2496 /* GTK returns scaled sizes for the workareas. */
2428 scale = gdk_monitor_get_scale_factor (monitor); 2497 scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
2429 rec.x *= scale; 2498 if (scale == 0.0)
2430 rec.y *= scale; 2499 scale = gdk_monitor_get_scale_factor (monitor);
2431 rec.width *= scale; 2500 rec.x = rec.x * scale + 0.5;
2432 rec.height *= scale; 2501 rec.y = rec.y * scale + 0.5;
2502 rec.width = rec.width * scale + 0.5;
2503 rec.height = rec.height * scale + 0.5;
2433 2504
2434 width = max(width, rec.x + rec.width); 2505 width = max(width, rec.x + rec.width);
2435 } 2506 }
@@ -2463,17 +2534,19 @@ each physical monitor, use `display-monitor-attributes-list'. */)
2463 for (i = 0; i < n_monitors; ++i) 2534 for (i = 0; i < n_monitors; ++i)
2464 { 2535 {
2465 GdkRectangle rec; 2536 GdkRectangle rec;
2466 int scale = 1; 2537 double scale = 1;
2467 2538
2468 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i); 2539 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
2469 gdk_monitor_get_geometry (monitor, &rec); 2540 gdk_monitor_get_geometry (monitor, &rec);
2470 2541
2471 /* GTK returns scaled sizes for the workareas. */ 2542 /* GTK returns scaled sizes for the workareas. */
2472 scale = gdk_monitor_get_scale_factor (monitor); 2543 scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
2473 rec.x *= scale; 2544 if (scale == 0.0)
2474 rec.y *= scale; 2545 scale = gdk_monitor_get_scale_factor (monitor);
2475 rec.width *= scale; 2546 rec.x = rec.x * scale + 0.5;
2476 rec.height *= scale; 2547 rec.y = rec.y * scale + 0.5;
2548 rec.width = rec.width * scale + 0.5;
2549 rec.height = rec.height * scale + 0.5;
2477 2550
2478 height = max(height, rec.y + rec.height); 2551 height = max(height, rec.y + rec.height);
2479 } 2552 }
@@ -2540,7 +2613,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
2540 gint width_mm, height_mm; 2613 gint width_mm, height_mm;
2541 GdkRectangle rec, work; 2614 GdkRectangle rec, work;
2542 struct MonitorInfo *mi = &monitors[i]; 2615 struct MonitorInfo *mi = &monitors[i];
2543 int scale = 1; 2616 double scale = 1;
2544 2617
2545 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i); 2618 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
2546 if (gdk_monitor_is_primary (monitor)) 2619 if (gdk_monitor_is_primary (monitor))
@@ -2552,15 +2625,17 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
2552 gdk_monitor_get_workarea (monitor, &work); 2625 gdk_monitor_get_workarea (monitor, &work);
2553 2626
2554 /* GTK returns scaled sizes for the workareas. */ 2627 /* GTK returns scaled sizes for the workareas. */
2555 scale = gdk_monitor_get_scale_factor (monitor); 2628 scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
2556 rec.x *= scale; 2629 if (scale == 0.0)
2557 rec.y *= scale; 2630 scale = gdk_monitor_get_scale_factor (monitor);
2558 rec.width *= scale; 2631 rec.x = rec.x * scale + 0.5;
2559 rec.height *= scale; 2632 rec.y = rec.y * scale + 0.5;
2560 work.x *= scale; 2633 rec.width = rec.width * scale + 0.5;
2561 work.y *= scale; 2634 rec.height = rec.height * scale + 0.5;
2562 work.width *= scale; 2635 work.x = work.x * scale + 0.5;
2563 work.height *= scale; 2636 work.y = work.y * scale + 0.5;
2637 work.width = work.width * scale + 0.5;
2638 work.height = work.height * scale + 0.5;
2564 2639
2565 mi->geom.x = rec.x; 2640 mi->geom.x = rec.x;
2566 mi->geom.y = rec.y; 2641 mi->geom.y = rec.y;
@@ -3885,12 +3960,17 @@ be used as the image of the icon representing the frame. */);
3885 defsubr (&Spgtk_print_frames_dialog); 3960 defsubr (&Spgtk_print_frames_dialog);
3886 defsubr (&Spgtk_backend_display_class); 3961 defsubr (&Spgtk_backend_display_class);
3887 3962
3963 defsubr (&Spgtk_set_monitor_scale_factor);
3964
3888 defsubr (&Sx_file_dialog); 3965 defsubr (&Sx_file_dialog);
3889 3966
3890 as_status = 0; 3967 as_status = 0;
3891 as_script = Qnil; 3968 as_script = Qnil;
3892 as_result = 0; 3969 as_result = 0;
3893 3970
3971 monitor_scale_factor_alist = Qnil;
3972 staticpro (&monitor_scale_factor_alist);
3973
3894 tip_timer = Qnil; 3974 tip_timer = Qnil;
3895 staticpro (&tip_timer); 3975 staticpro (&tip_timer);
3896 tip_frame = Qnil; 3976 tip_frame = Qnil;