aboutsummaryrefslogtreecommitdiff
path: root/src/Utils.cpp
blob: 3032f22800d0b95e5aa65734d946fd9cffc62403 (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
#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 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;

        char *gdk_scale = getenv("GDK_SCALE");
        if(gdk_scale) {
            setlocale(LC_ALL, "C"); // Sigh... stupid C
            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;
    }

    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;
    }

    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;
    }

    int64_t get_unix_time_monotonic() {
        struct timespec t;
        if(clock_gettime(CLOCK_MONOTONIC, &t) == -1) {
            fprintf(stderr, "This kernel version doesn't support CLOCK_MONOTONIC\n");
            abort();
        }
        return t.tv_sec;
    }
}