aboutsummaryrefslogtreecommitdiff
path: root/src/Utils.cpp
blob: 3919bec23d8e392bee066c6c1d7d57f905eee3e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "../include/Utils.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>

namespace QuickMedia {
    static float scale = 1.0f;
    static bool scale_set = false;
    static float font_scale = 1.0f;
    static bool font_scale_set = false;
    static bool qm_enable_touch = false;
    static bool qm_enable_touch_set = false;
    static bool wayland_display_set = false;
    static const char *wayland_display = nullptr;

    static const int XFT_DPI_DEFAULT = 96;
    // Returns 96 on error
    static int xrdb_get_dpi() {
        int xft_dpi = XFT_DPI_DEFAULT;

        FILE *xrdb_query = popen("xrdb -query", "r");
        if(!xrdb_query)
            return xft_dpi;

        char line[512];
        while(fgets(line, sizeof(line), xrdb_query)) {
            int line_length = strlen(line);
            if(line_length > 0 && line[line_length - 1] == '\n') {
                line[line_length - 1] = '\0';
                line_length--;
            }

            if(line_length > 8 && memcmp(line, "Xft.dpi:", 8) == 0) {
                int xft_dpi_file = atoi(line + 8);
                if(xft_dpi_file > 0) {
                    xft_dpi = xft_dpi_file;
                    break;
                }
            }
        }

        pclose(xrdb_query);
        return xft_dpi;
    }

    float get_ui_scale() {
        if(scale_set)
            return scale;

        setlocale(LC_ALL, "C"); // Sigh... stupid C
        char *qm_scale = getenv("QM_SCALE");
        if(qm_scale) {
            scale = atof(qm_scale);
            if(scale < 0.0001f)
                scale = 1.0f;
            
            scale_set = true;
            return scale;
        }

        char *gdk_scale = getenv("GDK_SCALE");
        if(gdk_scale) {
            scale = atof(gdk_scale);
            if(scale < 0.0001f)
                scale = 1.0f;
        } else {
            scale = (float)xrdb_get_dpi() / (float)XFT_DPI_DEFAULT;
        }

        scale_set = true;
        return scale;
    }

    float get_font_scale() {
        if(font_scale_set)
            return font_scale;

        char *qm_font_scale = getenv("QM_FONT_SCALE");
        if(qm_font_scale) {
            setlocale(LC_ALL, "C"); // Sigh... stupid C
            font_scale = atof(qm_font_scale);
            if(font_scale < 0.0001f)
                font_scale = 1.0f;
        } else {
            font_scale = 1.0f;
        }

        font_scale_set = true;
        return font_scale;
    }

    void show_virtual_keyboard() {
        if(!is_touch_enabled())
            return;

        fprintf(stderr, "Show virtual keyboard\n");
        system("busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true");
    }

    void hide_virtual_keyboard() {
        if(!is_touch_enabled())
            return;

        fprintf(stderr, "Hide virtual keyboard\n");
        system("busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false");
    }

    bool is_touch_enabled() {
        if(qm_enable_touch_set)
            return qm_enable_touch;

        const char *qm_enable_touch_env = getenv("QM_ENABLE_TOUCH");
        if(qm_enable_touch_env && qm_enable_touch_env[0] == '1')
            qm_enable_touch = true;

        qm_enable_touch_set = true;
        return qm_enable_touch;
    }

    // TODO: Find a better way to detect this. This will return true on ubuntu when running gnome in x11 mode
    bool is_running_wayland() {
        if(wayland_display_set)
            return wayland_display;
        
        wayland_display = getenv("WAYLAND_DISPLAY");
        wayland_display_set = true;
        return wayland_display;
    }

    time_t iso_utc_to_unix_time(const char *time_str) {
        int year = 0;
        int month = 0;
        int day = 0;
        int hour = 0;
        int minute = 0;
        int second = 0;
        // TODO: Handle timezone
        sscanf(time_str, "%d-%d-%dT%d:%d:%d", &year, &month, &day, &hour, &minute, &second);
        if(year == 0) return 0;
        
        struct tm time;
        memset(&time, 0, sizeof(time));
        time.tm_year = year - 1900;
        time.tm_mon = month - 1;
        time.tm_mday = day;
        time.tm_hour = hour;
        time.tm_min = minute;
        time.tm_sec = second;
        return timegm(&time);
    }

    std::string unix_time_to_local_time_str(time_t unix_time) {
        struct tm time_tm;
        localtime_r(&unix_time, &time_tm);
        char time_str[128] = {0};
        strftime(time_str, sizeof(time_str) - 1, "%Y %b %d, %a %H:%M", &time_tm);
        return time_str;
    }
}