diff options
| author | Yuuki Harano | 2021-01-04 04:13:33 +0900 |
|---|---|---|
| committer | Yuuki Harano | 2021-01-04 04:13:33 +0900 |
| commit | bcb74798ed3068e324cffd8856f5a70f2c6c7687 (patch) | |
| tree | 44a8e192fee4f92018fe7d65de060f4a0754cc8c /src | |
| parent | 44f7f57c6833149799539c5e0abcadf4d7d61d43 (diff) | |
| download | emacs-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.c | 124 |
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 | ||
| 55 | static const char *pgtk_app_name = "Emacs"; | 55 | static const char *pgtk_app_name = "Emacs"; |
| 56 | 56 | ||
| 57 | /* scale factor manually set per monitor */ | ||
| 58 | static 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 | ||
| 66 | static double | ||
| 67 | pgtk_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 | |||
| 63 | struct pgtk_display_info * | 88 | struct pgtk_display_info * |
| 64 | check_pgtk_display_info (Lisp_Object object) | 89 | check_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 | ||
| 1143 | DEFUN ("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. | ||
| 1146 | Since Gdk's scale factor is integer, physical pixel width/height is | ||
| 1147 | incorrect when you specify fractional scale factor in compositor. | ||
| 1148 | If you set scale factor by this function, it is used instead of Gdk's one. | ||
| 1149 | |||
| 1150 | Pass nil as SCALE-FACTOR if you want to reset the specified monitor's | ||
| 1151 | scale 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 | |||
| 1118 | DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0, | 1187 | DEFUN ("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. |
| 1120 | Return an Emacs frame object. PARMS is an alist of frame parameters. | 1189 | Return 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; |