aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gsr-config.h
blob: 31f89e2cc513c94cd40fd30c0513a1de8a05c189 (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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#pragma once

#include <stdbool.h>
#include <stdint.h>

#include <glib.h>

G_BEGIN_DECLS

/* ── Hotkey ──────────────────────────────────────────────────────── */

typedef struct {
    int64_t  keysym;
    uint32_t modifiers;
} GsrConfigHotkey;

/* ── Config struct ───────────────────────────────────────────────── */

typedef struct {
    /* Capture target */
    char    *record_area_option;   /* "window", "focused", "portal", or monitor name */
    int32_t  record_area_width;
    int32_t  record_area_height;
    int32_t  video_width;
    int32_t  video_height;

    /* Video */
    int32_t  fps;
    int32_t  video_bitrate;
    char    *color_range;          /* "limited", "full" */
    char    *quality;              /* "custom", "medium", "high", "very_high", "ultra" */
    char    *codec;                /* "auto", "h264", "hevc", etc. */
    char    *audio_codec;          /* "opus", "aac" */
    char    *framerate_mode;       /* "auto", "cfr", "vfr" */
    bool     overclock;
    bool     record_cursor;

    /* Audio */
    char   **audio_input;          /* NULL-terminated array, each "device:xxx" / "app:xxx" */
    int      n_audio_input;
    bool     merge_audio_tracks;
    bool     record_app_audio_inverted;

    /* Resolution */
    bool     change_video_resolution;

    /* Notifications */
    bool     show_recording_started_notifications;
    bool     show_recording_stopped_notifications;
    bool     show_recording_saved_notifications;

    /* UI state */
    bool     advanced_view;
    bool     hide_window_when_recording;
    bool     restore_portal_session;

    /* Warning flags (persisted, not shown in UI) */
    bool     software_encoding_warning_shown;
    bool     steam_deck_warning_shown;
    bool     hevc_amd_bug_warning_shown;
    bool     av1_amd_bug_warning_shown;

    /* Misc */
    bool     use_new_ui;
    int32_t  installed_gsr_global_hotkeys_version;
} GsrMainConfig;

typedef struct {
    char *streaming_service;   /* "twitch", "youtube", "custom" */
    char *youtube_stream_key;
    char *twitch_stream_key;
    char *custom_url;
    char *custom_container;    /* "mp4", "flv", "matroska", etc. */

    GsrConfigHotkey start_stop_hotkey;
} GsrStreamingConfig;

typedef struct {
    char *save_directory;
    char *container;

    GsrConfigHotkey start_stop_hotkey;
    GsrConfigHotkey pause_unpause_hotkey;
} GsrRecordConfig;

typedef struct {
    char    *save_directory;
    char    *container;
    int32_t  replay_time;

    GsrConfigHotkey start_stop_hotkey;
    GsrConfigHotkey save_hotkey;
} GsrReplayConfig;

typedef struct {
    GsrMainConfig      main_config;
    GsrStreamingConfig streaming_config;
    GsrRecordConfig    record_config;
    GsrReplayConfig    replay_config;
} GsrConfig;

/* ── API ─────────────────────────────────────────────────────────── */

/**
 * Initialize config to default values.
 * Must be called before gsr_config_read() or manual population.
 */
void gsr_config_init_defaults(GsrConfig *config);

/**
 * Read config from the standard file location.
 * Returns TRUE on success, FALSE if file not found or error.
 * On failure, config retains its default values.
 */
gboolean gsr_config_read(GsrConfig *config);

/**
 * Save config to the standard file location.
 * Creates config directory if needed.
 */
void gsr_config_save(const GsrConfig *config);

/**
 * Free all heap-allocated members (strings, arrays).
 * Does NOT free the GsrConfig struct itself.
 */
void gsr_config_clear(GsrConfig *config);

/**
 * Get the config directory path (e.g., ~/.config/gpu-screen-recorder).
 * Returns a newly allocated string; caller must g_free().
 */
char *gsr_config_get_dir(void);

/**
 * Get the default videos directory.
 * Returns a newly allocated string; caller must g_free().
 */
char *gsr_config_get_videos_dir(void);

/* ── Hotkey conversion utilities ─────────────────────────────────── */

/**
 * Convert a GsrConfigHotkey (custom modifier bitmask + keysym) to a
 * GTK accelerator string like "<Alt>1".
 * Returns a newly allocated string, or NULL if the hotkey is empty.
 */
char *gsr_config_hotkey_to_accel(const GsrConfigHotkey *hk);

/**
 * Convert a GTK accelerator string like "<Alt>1" to a GsrConfigHotkey.
 * Returns TRUE on success, FALSE if the accel string is invalid.
 * If accel is NULL, the hotkey is cleared (keysym=0, modifiers=0).
 */
gboolean gsr_config_hotkey_from_accel(GsrConfigHotkey *hk, const char *accel);

#ifdef HAVE_X11
/**
 * Convert a GsrConfigHotkey to an X11 modifier mask suitable for XGrabKey.
 * The keysym is returned unchanged in *out_keysym.
 */
void gsr_config_hotkey_to_x11(const GsrConfigHotkey *hk,
                               unsigned int *out_x11_modifiers,
                               uint64_t     *out_keysym);
#endif /* HAVE_X11 */

/**
 * Check if a hotkey is empty (no key assigned).
 */
static inline gboolean
gsr_config_hotkey_is_empty(const GsrConfigHotkey *hk)
{
    return hk->keysym == 0;
}

G_END_DECLS