PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
start_menu.c
Go to the documentation of this file.
1#include "start_menu.h"
2
3#include "taskbar.h"
4
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <sys/defs.h>
10#include <sys/fs.h>
11#include <sys/proc.h>
12
13#define START_ENTRY_MAX 16
14
15typedef struct
16{
17 const char* name;
18 const char* path;
21
23
24#define START_MENU_HEIGHT(frameSize) (frameSize + 12 * START_BUTTON_HEIGHT)
25
26#define START_MENU_YPOS_START(screenRect, panelSize, frameSize) (RECT_HEIGHT(screenRect))
27#define START_MENU_YPOS_END(screenRect, panelSize, frameSize) \
28 (RECT_HEIGHT(screenRect) - START_MENU_HEIGHT(frameSize) - panelSize)
29
30static uint64_t startmenu_procedure(window_t* win, element_t* elem, const event_t* event)
31{
32 const theme_t* theme = element_get_theme(elem);
33
34 switch (event->type)
35 {
36 case EVENT_LIB_INIT:
37 {
38 start_menu_t* menu = malloc(sizeof(start_menu_t));
39 if (menu == NULL)
40 {
41 printf("startmenu: failed to allocate start menu private data\n");
42 errno = ENOMEM;
43 return ERR;
44 }
45 menu->win = win;
46 menu->taskbar = element_get_private(elem);
47 menu->animationStartTime = uptime();
49
51
52 element_set_private(elem, menu);
53 }
54 break;
56 {
58 if (menu == NULL)
59 {
60 break;
61 }
62 free(menu);
63 }
64 break;
66 {
68
69 drawable_t draw;
70 element_draw_begin(elem, &draw);
71
74 draw_rect(&draw, &rect, theme->deco.backgroundNormal);
75
76 rect.right = rect.left + theme->titlebarSize;
78 DIRECTION_VERTICAL, false);
79
80 element_draw_end(elem, &draw);
81 }
82 break;
84 {
86 if (event->libAction.type == ACTION_RELEASE)
87 {
89
90 const char* argv[] = {entries[event->libAction.source].path, NULL};
92 {
93 char buffer[MAX_PATH];
94 sprintf(buffer, "Failed to spawn (%s)!", entries[event->libAction.source].path);
95
96 popup_open(buffer, "Error!", POPUP_OK);
97 }
98 }
99 }
100 break;
101 case EVENT_TIMER:
102 {
103 start_menu_t* menu = element_get_private(elem);
106
109
110 clock_t timeElapsed = uptime() - menu->animationStartTime;
111
112 double fraction;
113 int64_t currentY = 0;
114 bool isAnimComplete = false;
115
116 if (menu->state == START_MENU_OPENING)
117 {
118 fraction = (double)timeElapsed / START_MENU_ANIMATION_TIME;
119 if (fraction >= 1.0)
120 {
121 fraction = 1.0;
122 isAnimComplete = true;
123 }
124 currentY = (int64_t)((double)startY + ((double)endY - startY) * fraction);
125 }
126 else if (menu->state == START_MENU_CLOSING)
127 {
128 fraction = (double)timeElapsed / START_MENU_ANIMATION_TIME;
129 if (fraction >= 1.0)
130 {
131 fraction = 1.0;
132 isAnimComplete = true;
133 }
134 currentY = (int64_t)((double)endY + ((double)startY - endY) * fraction);
135 }
136 else
137 {
138 return 0;
139 }
140
141 rect_t rect = window_get_rect(win);
142 uint64_t height = RECT_HEIGHT(&rect);
143 rect.top = currentY;
144 rect.bottom = currentY + height;
145 if (window_move(win, &rect) == ERR)
146 {
147 printf("startmenu: failed to move window during animation (%s)\n", strerror(errno));
148 }
149
150 if (isAnimComplete)
151 {
153 {
154 printf("startmenu: failed to disable timer (%s)\n", strerror(errno));
155 }
156 if (menu->state == START_MENU_OPENING)
157 {
158 menu->state = START_MENU_OPEN;
159 }
160 else if (menu->state == START_MENU_CLOSING)
161 {
162 menu->state = START_MENU_CLOSED;
163 }
164 }
165 }
166 break;
167 }
168
169 return 0;
170}
171
173{
174 const theme_t* theme = theme_global_get();
177
178 rect_t rect =
181
182 window_t* win = window_new(disp, "StartMenu", &rect, SURFACE_WINDOW, WINDOW_NONE, startmenu_procedure, taskbar);
183 if (win == NULL)
184 {
185 printf("startmenu: failed to create start menu window\n");
186 return NULL;
187 }
188
189 if (window_set_visible(win, true) == ERR)
190 {
191 window_free(win);
192 return NULL;
193 }
194
195 return win;
196}
197
198static void start_menu_load_entries(window_t* startMenu)
199{
200 config_t* config = config_open("taskbar", "main");
201 if (config == NULL)
202 {
203 printf("startmenu: failed to open start menu config\n");
204 return;
205 }
206
207 bool changed = false;
208 for (uint64_t i = 0; i < ARRAY_SIZE(entries); i++)
209 {
210 char entryKey[32];
211 snprintf(entryKey, sizeof(entryKey), "entry%lu", i);
212 config_array_t* entryArray = config_get_array(config, "start", entryKey);
213 if (entryArray == NULL || entryArray->length != 2)
214 {
215 break;
216 }
217
218 if (entries[i].name != NULL || entries[i].path != NULL)
219 {
220 if (strcmp(entries[i].name, entryArray->items[0]) == 0 &&
221 strcmp(entries[i].path, entryArray->items[1]) == 0)
222 {
223 continue;
224 }
225 free((void*)entries[i].name);
226 free((void*)entries[i].path);
227 }
228
229 changed = true;
230 entries[i].name = strdup(entryArray->items[0]);
231 if (entries[i].name == NULL)
232 {
233 break;
234 }
235 entries[i].path = strdup(entryArray->items[1]);
236 if (entries[i].path == NULL)
237 {
238 free((void*)entries[i].name);
239 break;
240 }
241 }
242
243 config_close(config);
244
245 if (!changed)
246 {
247 return;
248 }
249
250 // Clear existing buttons
251 for (uint64_t i = 0; i < ARRAY_SIZE(entries); i++)
252 {
253 if (entries[i].button != NULL)
254 {
255 element_free(entries[i].button);
256 entries[i].button = NULL;
257 }
258 }
259
260 const theme_t* theme = theme_global_get();
261 for (uint64_t i = 0; i < ARRAY_SIZE(entries); i++)
262 {
263 if (entries[i].name == NULL || entries[i].path == NULL)
264 {
265 break;
266 }
267
268 rect_t buttonRect =
271
272 entries[i].button =
273 button_new(window_get_client_element(startMenu), i, &buttonRect, entries[i].name, ELEMENT_FLAT);
274 }
275}
276
277void start_menu_open(window_t* startMenu)
278{
279 element_t* elem = window_get_client_element(startMenu);
280 const theme_t* theme = element_get_theme(elem);
281 start_menu_t* menu = element_get_private(elem);
282
283 if (menu->state == START_MENU_OPEN || menu->state == START_MENU_OPENING)
284 {
285 return;
286 }
287
288 start_menu_load_entries(startMenu);
289
292
294
295 rect_t rect = window_get_rect(startMenu);
296 uint64_t height = RECT_HEIGHT(&rect);
297 rect.top = startY;
298 rect.bottom = startY + height;
299 window_move(startMenu, &rect);
300
301 menu->animationStartTime = uptime();
304
305 window_set_focus(startMenu);
306}
307
309{
310 element_t* elem = window_get_client_element(startMenu);
311 start_menu_t* menu = element_get_private(elem);
312 if (menu->state == START_MENU_CLOSED || menu->state == START_MENU_CLOSING)
313 {
314 return;
315 }
316
317 menu->animationStartTime = uptime();
320
322}
323
325{
326 if (startMenu == NULL)
327 {
328 return START_MENU_CLOSED;
329 }
330
331 element_t* elem = window_get_client_element(startMenu);
332 start_menu_t* menu = element_get_private(elem);
333 return menu->state;
334}
#define MAX_PATH
Maximum length of filepaths.
Definition MAX_PATH.h:11
EFI_PHYSICAL_ADDRESS buffer
Definition main.c:237
static uint64_t height
Definition screen.c:14
#define CLOCKS_NEVER
Definition clock_t.h:18
#define CLOCKS_PER_SEC
Definition clock_t.h:15
@ TIMER_NONE
Definition cmd.h:76
@ TIMER_REPEAT
Definition cmd.h:77
static rect_t screenRect
Definition compositor.c:10
config_array_t * config_get_array(config_t *config, const char *section, const char *key)
Get an array of strings from a configuration file.
Definition config.c:335
config_t * config_open(const char *prefix, const char *name)
Open a configuration file.
Definition config.c:93
void config_close(config_t *config)
Close a configuration file.
Definition config.c:202
void display_push(display_t *disp, surface_id_t target, event_type_t type, void *data, uint64_t size)
Push an event to the display's internal event queue.
Definition display.c:321
uint64_t display_get_screen(display_t *disp, rect_t *rect, uint64_t index)
Get the rectangle of a screen.
Definition display.c:573
void draw_gradient(drawable_t *draw, const rect_t *rect, pixel_t start, pixel_t end, direction_t direction, bool shouldAddNoise)
Draw a gradient filled rectangle.
Definition drawable.c:382
void draw_rect(drawable_t *draw, const rect_t *rect, pixel_t pixel)
Draw a filled rectangle.
Definition drawable.c:7
void draw_frame(drawable_t *draw, const rect_t *rect, uint64_t width, pixel_t foreground, pixel_t background)
Draw a skeuomorphic frame.
Definition drawable.c:204
@ DIRECTION_VERTICAL
Definition drawable.h:60
theme_t * element_get_theme(element_t *elem)
Get the theme of an element.
Definition element.c:401
void element_draw_end(element_t *elem, drawable_t *draw)
End drawing to an element.
Definition element.c:427
rect_t element_get_content_rect(element_t *elem)
Get the element's rectangle in local coordinates.
Definition element.c:213
void element_draw_begin(element_t *elem, drawable_t *draw)
Begin drawing to an element.
Definition element.c:411
void element_free(element_t *elem)
Deinitialize and free an element and all its children.
Definition element.c:113
void element_set_private(element_t *elem, void *data)
Set private data for an element.
Definition element.c:163
void * element_get_private(element_t *elem)
Get private data for an element.
Definition element.c:173
#define ELEMENT_FLAT
Definition element.h:45
#define EVENT_LIB_DEINIT
Definition event.h:99
#define EVENT_LIB_INIT
Definition event.h:98
#define EVENT_LIB_REDRAW
Definition event.h:100
#define EVENT_LIB_ACTION
Definition event.h:101
#define EVENT_TIMER
Definition event.h:85
@ ACTION_RELEASE
Definition event.h:49
@ SURFACE_WINDOW
Definition surface.h:35
theme_t * theme_global_get(void)
Get the global theme.
Definition theme.c:97
element_t * button_new(element_t *parent, element_id_t id, const rect_t *rect, const char *text, element_flags_t flags)
Create a new button element.
Definition button.c:309
uint64_t window_set_visible(window_t *win, bool isVisible)
Set the visibility of the window.
Definition window.c:704
rect_t window_get_rect(window_t *win)
Get the window's rectangle in screen coordinates.
Definition window.c:459
uint64_t window_move(window_t *win, const rect_t *rect)
Move and/or resize the window.
Definition window.c:519
uint64_t window_set_focus(window_t *win)
Set the focus to the window.
Definition window.c:685
surface_id_t window_get_id(window_t *win)
Get the surface ID of the window.
Definition window.c:489
uint64_t window_set_timer(window_t *win, timer_flags_t flags, clock_t timeout)
Set the window timer.
Definition window.c:545
window_t * window_new(display_t *disp, const char *name, const rect_t *rect, surface_type_t type, window_flags_t flags, procedure_t procedure, void *data)
Allocate and initialize a new window.
Definition window.c:313
element_t * window_get_client_element(window_t *win)
Get the client element of the window.
Definition window.c:509
void window_free(window_t *win)
Free a window.
Definition window.c:427
display_t * window_get_display(window_t *win)
Get the display associated with the window.
Definition window.c:479
@ WINDOW_NONE
Definition window.h:45
#define ENOMEM
Out of memory.
Definition errno.h:92
#define errno
Error number variable.
Definition errno.h:27
#define ARRAY_SIZE(x)
Get the number of elements in a static array.
Definition defs.h:111
pid_t spawn(const char **argv, spawn_flags_t flags)
System call for spawning new processes.
Definition spawn.c:6
clock_t uptime(void)
System call for retreving the time since boot.
Definition uptime.c:6
@ SPAWN_EMPTY_GROUP
Don't inherit the parent's process group, instead create a new group.
Definition proc.h:66
@ SPAWN_STDIO_FDS
Only inherit stdin, stdout and stderr from the parent process.
Definition proc.h:63
@ SPAWN_COPY_NS
Don't share the parent's namespace, instead create a new copy of it.
Definition proc.h:67
#define NULL
Pointer error value.
Definition NULL.h:25
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
popup_result_t popup_open(const char *text, const char *title, popup_type_t type)
Definition popup.c:87
@ POPUP_OK
Definition popup.h:22
#define RECT_SHRINK(rect, margin)
Definition rect.h:81
#define RECT_INIT_DIM(x, y, width, height)
Definition rect.h:32
#define RECT_INIT(left, top, right, bottom)
Definition rect.h:26
#define RECT_HEIGHT(rect)
Definition rect.h:39
#define START_MENU_YPOS_START(screenRect, panelSize, frameSize)
Definition start_menu.c:26
static void start_menu_load_entries(window_t *startMenu)
Definition start_menu.c:198
static uint64_t startmenu_procedure(window_t *win, element_t *elem, const event_t *event)
Definition start_menu.c:30
start_menu_state_t start_menu_get_state(window_t *startMenu)
Definition start_menu.c:324
#define START_MENU_HEIGHT(frameSize)
Definition start_menu.c:24
#define START_ENTRY_MAX
Definition start_menu.c:13
static start_entry_t entries[START_ENTRY_MAX]
Definition start_menu.c:22
void start_menu_close(window_t *startMenu)
Definition start_menu.c:308
void start_menu_open(window_t *startMenu)
Definition start_menu.c:277
window_t * start_menu_new(window_t *taskbar, display_t *disp)
Definition start_menu.c:172
#define START_MENU_YPOS_END(screenRect, panelSize, frameSize)
Definition start_menu.c:27
#define START_BUTTON_HEIGHT
Definition start_menu.h:6
#define EVENT_USER_START_MENU_CLOSE
Definition start_menu.h:12
#define START_MENU_WIDTH
Definition start_menu.h:8
start_menu_state_t
Definition start_menu.h:15
@ START_MENU_CLOSING
Definition start_menu.h:18
@ START_MENU_OPEN
Definition start_menu.h:17
@ START_MENU_OPENING
Definition start_menu.h:19
@ START_MENU_CLOSED
Definition start_menu.h:16
#define START_MENU_ANIMATION_TIME
Definition start_menu.h:10
__INT32_TYPE__ int32_t
Definition stdint.h:14
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__INT64_TYPE__ int64_t
Definition stdint.h:16
_PUBLIC int printf(const char *_RESTRICT format,...)
Definition printf.c:3
_PUBLIC int snprintf(char *_RESTRICT s, size_t n, const char *_RESTRICT format,...)
Definition snprintf.c:3
_PUBLIC int sprintf(char *_RESTRICT s, const char *_RESTRICT format,...)
Definition sprintf.c:5
_PUBLIC void * malloc(size_t size)
Definition malloc.c:5
_PUBLIC void free(void *ptr)
Definition free.c:11
_PUBLIC char * strerror(int errnum)
Definition strerror.c:6
char * strdup(const char *src)
Definition strdup.c:5
_PUBLIC int strcmp(const char *s1, const char *s2)
Definition strcmp.c:3
Configuration array structure.
Definition config.h:38
char ** items
Definition config.h:39
uint64_t length
Definition config.h:40
Opaque configuration structure.
Definition config.c:28
Opaque display structure.
Definition internal.h:68
Drawable structure.
Definition drawable.h:35
Opaque element structure.
Definition internal.h:23
action_type_t type
Definition event.h:281
element_id_t source
Definition event.h:280
Event structure.
Definition event.h:306
event_lib_action_t libAction
Definition event.h:323
event_type_t type
Definition event.h:307
Definition rect.h:13
int32_t bottom
Definition rect.h:17
int32_t top
Definition rect.h:15
int32_t right
Definition rect.h:16
int32_t left
Definition rect.h:14
Definition start_menu.c:16
const char * name
Definition start_menu.c:17
element_t * button
Definition start_menu.c:19
const char * path
Definition start_menu.c:18
start_menu_state_t state
Definition start_menu.h:27
window_t * win
Definition start_menu.h:24
clock_t animationStartTime
Definition start_menu.h:26
window_t * taskbar
Definition start_menu.h:25
pixel_t backgroundNormal
Definition theme.h:35
pixel_t backgroundSelectedEnd
Definition theme.h:37
pixel_t highlight
Definition theme.h:45
pixel_t shadow
Definition theme.h:46
pixel_t backgroundSelectedStart
Definition theme.h:36
Theme structure.
Definition theme.h:71
int64_t smallPadding
Definition theme.h:88
theme_color_set_t deco
Definition theme.h:76
int64_t panelSize
Definition theme.h:86
int64_t titlebarSize
Definition theme.h:85
int64_t frameSize
Definition theme.h:83
Opaque window structure.
Definition internal.h:44
static theme_t theme
Definition theme.c:12