Подтвердить что ты не робот

В GTK/Linux, какой правильный способ получить масштабный коэффициент DPI?

Контекст: Написание программы рисования, которая должна быть кросс-платформенной. Поэтому у меня есть несколько интерфейсов, ответственных за предоставление доступа к базовому классу в контексте Каира, обработку основных событий и информацию о размерах виджета. Недавно я решил добавить текущую шкалу пользовательского интерфейса (для дисплеев с высоким разрешением DPI) к этому последнему биту, прежде всего потому, что я хочу переключить графику на визуализацию в кеш-кеш, поэтому мне нужно знать самый высокий уровень детализации, который может поддерживать дисплей.

В моем кросс-платформенном мире я ожидаю, что интерфейсный адаптер для базового класса, о котором я говорю, правильно настроил контекст Cairo для работы в виртуализированных пикселях, прежде чем передать его мне. Мне просто нужна шкала, чтобы ограничить количество масштабирования, которое я использую для своих фрагментов.

В AppKit это было просто: попросите NSView масштабировать NSSize из 1 виртуального пикселя в "координаты хранилища резервных копий" и передать это второстепенному классу. Apple также была достаточно умна, чтобы обеспечить предварительно масштабированный контекст CoreGraphics, поэтому все, что мне нужно сделать, это запросить перевернутые координаты и перетащить CGContext в Каир.

В GTK я немного запутался. Кажется, слишком много способов сделать это. GtkWidget имеет "получить масштабный коэффициент", gint gtk_widget_get_scale_factor (GtkWidget *widget), который возвращает целочисленное значение. Это кажется немного слишком ограничительным, потому что вы не можете иметь дело с экранами, которые находятся между ними с таким сценарием. То есть 28-дюймовый монитор 3840x2160, на который я смотрел, должен быть 1,5-дюймовым монитором, но при GTK все будет слишком маленьким или слишком большим.

Ubuntu также бросает свой собственный ключ в свои работы, потому что у него есть собственный масштабный коэффициент DPI, который, похоже, отличается от всего остального. На самом деле это лишь некоторые приложения. Я включил его до 1,5; Firefox и скобки не масштабировались, Nautilus и терминал действительно масштабировались, а Empathy делает эту странную вещь, где все, кроме текста беседы, масштабируется. Так что это явно не общесистемно или даже встроено в GTK... blarrgh.

Кроме того, у X11 есть собственный способ получения информации DPI, которую я слышал, очень неточен и не стоит об этом думать, так как Мир и Уэйланд все равно заменят его.

Я не могу найти никакой информации об этом суперспециальном awesome Unity API для получения пользовательской шкалы пользовательского интерфейса. Таким образом, я собираюсь сейчас набрать собственный масштаб GTK, который я не считаю адекватным, но что угодно. Мне бы очень хотелось узнать, как захватить параметр масштаба Unity или любую другую среду рабочего стола с собственными параметрами масштабирования пользовательского интерфейса, но у меня есть ощущение, что мне, возможно, придется отправлять индивидуальные настройки для настройки масштабирования пользовательского интерфейса вручную для этого конкретного интерфейса.

(Для любопытных: мой код доступен здесь - базовый класс, о котором я говорю, находится в файле src/canvasview.cpp и в примерах front-end "view адаптеры" находятся в интерфейсах /gtk/src/CanvasWidget.cpp и frontends/appkit/src/ICAKCanvasView.m соответственно. Имейте в виду, что код в настоящее время находится в неисправном состоянии, поскольку я занят отладкой рендеринга на основе плитки.)

4b9b3361

Ответ 1

Я не видел получателя данных в GTK, но с некоторыми строками кода из открытых источников и некоторыми изменениями я обычно прошу X-сервер с этим фрагментом кода получить значения dpi для направлений x и y, Для отображаемого имени вы можете передать нужные значения через argv [].

Если вы назовете его 'getdpi.c', тогда скомпилируйте с помощью

gcc -Wall -std=c99  -o getdpi getdpi.c -lX11

Если это поможет вам, будет оценен голос.: -)

#include <X11/Xlib.h>

#include <stdio.h>
#include <stdlib.h>

const static unsigned int FALSE = 0;
const static unsigned int TRUE = 1;
typedef unsigned int bool;

int getDpi(Display *dpy, int scr, bool xRes)
{
    /*
     * an inch is 25.4 millimeters.
     * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
     *     = N pixels / (M inch / 25.4)
     *     = N * 25.4 pixels / M inch
     */

    double res = xRes ? ((((double) DisplayWidth(dpy,scr)) * 25.4) / ((double) DisplayWidthMM(dpy,scr)))
        : ((((double) DisplayHeight(dpy,scr)) * 25.4) / ((double) DisplayHeightMM(dpy,scr)));

    return (int) (res + 0.5);
} // print_Screen_info

int main(int argc, char *argv[])
{
    Display *dpy;           /* X connection */
    char *displayname = NULL;       /* set to what you want or need */
    dpy = XOpenDisplay (displayname);
    if (!dpy) 
    {
    fprintf (stderr, "xdpi:  unable to open display \"%s\".\n",
         XDisplayName (displayname));
    exit (1);
    }

    for (int i = 0; i < ScreenCount(dpy); ++i)
        printf ("Xdpi: %d, Ydpi %d\n", 
                getDpi(dpy, i, TRUE),
                getDpi(dpy, i, FALSE));
} // main