This repository has no description
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include "modules/raylib.h"
5
6#define WIDTH 300
7#define HEIGHT 50
8
9// Hardcorded settings for bottom right of 2160p monitor
10#define SCREENX 3360
11#define SCREENY 2110
12
13char* execute_command(const char *cmd) {
14 FILE *fp;
15 char *output = malloc(128);
16
17 if (!output) {
18 perror("malloc");
19 return NULL;
20 }
21
22 fp = popen(cmd, "r");
23 if (!fp) {
24 perror("popen");
25 free(output);
26 return NULL;
27 }
28
29 if (fgets(output, 128, fp) == NULL) {
30 perror("fgets");
31 fclose(fp);
32 free(output);
33 return NULL;
34 }
35
36 fclose(fp);
37 return output;
38}
39
40float read_volume() {
41 float volume = 0.0f;
42 char *output = execute_command("mixerctl outputs.master");
43 if (output) {
44 printf("Current volume: %s", output);
45 int i;
46 for (i = 0; i < strlen(output); i++) {
47 if (output[i] == ',') {
48 char temp_vol[4];
49 strncpy(temp_vol, output + (i + 1), strlen(output) - (i + 1));
50 volume = atof(temp_vol);
51 }
52 }
53 free(output);
54 }
55 return volume;
56}
57
58void set_volume(const char *volume) {
59 char cmd[256];
60 snprintf(cmd, sizeof(cmd), "mixerctl outputs.master=%s", volume);
61
62 char *output = execute_command(cmd);
63 if (output) {
64 printf("Volume set to: %s", output);
65 free(output);
66 }
67}
68
69int main() {
70 EnableEventWaiting();
71 InitWindow(WIDTH, HEIGHT, "Volume Slider");
72 SetWindowPosition(SCREENX, SCREENY);
73
74 char temp_vol_str[8];
75 float volume = read_volume();
76 Rectangle track = { WIDTH / 4, HEIGHT / 2 - 10, WIDTH / 2, 20 };
77 Rectangle knob = { track.x + ((volume / 255) * track.width) - 5, track.y - 5, 10, 30 };
78
79 bool dragging = false;
80 bool snapping = false;
81 bool shouldRecheckSysVolume = true;
82
83 SetTargetFPS(10);
84 while (!WindowShouldClose()) {
85 // Re-check sys volume every other second to ensure we're in sync
86 // TODO: better method so I'm not checking GetTime AND setting a recheck var
87 if ((int)GetTime() % 10 == 0) {
88 if (shouldRecheckSysVolume) {
89 float new_volume = read_volume();
90 if ((int)volume != (int)new_volume) {
91 printf("This GUI is out of sync with system volume. Quitting.\n");
92 return 1;
93 }
94 }
95 shouldRecheckSysVolume = false;
96 } else {
97 shouldRecheckSysVolume = true;
98 }
99
100
101 Vector2 mousePosition = GetMousePosition();
102 Rectangle mouseRect = { mousePosition.x, mousePosition.y, 1, 1 };
103
104 if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionRecs(mouseRect, knob)) {
105 dragging = true;
106 }
107 if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && !CheckCollisionRecs(mouseRect, knob) && CheckCollisionRecs(mouseRect, track)) {
108 snapping = true;
109 }
110
111 if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) {
112 dragging = false;
113 snapping = false;
114 }
115
116 if (dragging || snapping) {
117 knob.x = GetMouseX() - knob.width / 2;
118
119 // Constrain knob to track
120 if (knob.x < track.x) knob.x = track.x;
121 if (knob.x > track.x + track.width - knob.width) knob.x = track.x + track.width - knob.width;
122
123 volume = (float)((knob.x - track.x) / (float)(track.width - knob.width)) * 255;
124 int rounded_volume = (int)volume;
125
126 // Format the result as "rounded_volume,rounded_volume"
127 snprintf(temp_vol_str, sizeof(temp_vol_str), "%i,%i", (int)volume, (int)volume);
128 set_volume(temp_vol_str);
129 }
130
131 BeginDrawing();
132 ClearBackground(RAYWHITE);
133
134 DrawRectangleRec(track, GRAY);
135 DrawRectangleRec(knob, DARKGRAY);
136
137 DrawText(TextFormat("Volume: %.2f", volume), 4, 4, 8, BLACK);
138
139 EndDrawing();
140 }
141
142 CloseWindow();
143 return 0;
144}