PatchworkOS
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
2#include <stdint.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#define LABEL_ID 1234
8#define LABEL_HEIGHT (42)
9
10#define NUMPAD_COLUMNS 4
11#define NUMPAD_ROWS 4
12#define NUMPAD_PADDING 6
13#define NUMPAD_BUTTON_WIDTH (64)
14
15#define NUMPAD_COLUMN_TO_WINDOW(column) (NUMPAD_PADDING * ((column) + 1) + NUMPAD_BUTTON_WIDTH * (column))
16#define NUMPAD_ROW_TO_WINDOW(row) (LABEL_HEIGHT + NUMPAD_PADDING * ((row) + 2) + NUMPAD_BUTTON_WIDTH * (row))
17
18#define LABEL_WIDTH (NUMPAD_COLUMN_TO_WINDOW(NUMPAD_COLUMNS) - NUMPAD_PADDING * 2)
19
20#define WINDOW_WIDTH (NUMPAD_COLUMN_TO_WINDOW(NUMPAD_COLUMNS))
21#define WINDOW_HEIGHT (NUMPAD_ROW_TO_WINDOW(NUMPAD_ROWS))
22
23static uint64_t numpad_button_create(element_t* elem, font_t* font, uint64_t column, uint64_t row, const char* name,
24 element_id_t id)
25{
28 element_t* button = button_new(elem, id, &rect, name, ELEMENT_NONE);
29 if (button == NULL)
30 {
31 return ERR;
32 }
33 element_get_text_props(button)->font = font;
34
35 return 0;
36}
37
45
46static uint64_t procedure(window_t* win, element_t* elem, const event_t* event)
47{
48 switch (event->type)
49 {
50 case LEVENT_INIT:
51 {
52 calculator_t* calc = malloc(sizeof(calculator_t));
53 if (calc == NULL)
54 {
55 return ERR;
56 }
57 calc->input = 0;
58 calc->accumulator = 0;
59 calc->operation = '=';
60 calc->largeFont = font_new(window_get_display(win), "default", "regular", 32);
61 if (calc->largeFont == NULL)
62 {
63 free(calc);
64 return ERR;
65 }
66
67 for (uint64_t column = 0; column < 3; column++)
68 {
69 for (uint64_t row = 0; row < 3; row++)
70 {
71 element_id_t id = 9 - ((2 - column) + row * 3);
72 char name[2] = {'0' + id, '\0'};
73
74 if (numpad_button_create(elem, calc->largeFont, column, row, name, id) == ERR)
75 {
76 font_free(calc->largeFont);
77 free(calc);
78 return ERR;
79 }
80 }
81 }
82
83 if (numpad_button_create(elem, calc->largeFont, 1, 3, "0", 0) == ERR ||
84 numpad_button_create(elem, calc->largeFont, 3, 0, "/", '/') == ERR ||
85 numpad_button_create(elem, calc->largeFont, 3, 1, "*", '*') == ERR ||
86 numpad_button_create(elem, calc->largeFont, 3, 2, "-", '-') == ERR ||
87 numpad_button_create(elem, calc->largeFont, 3, 3, "+", '+') == ERR ||
88 numpad_button_create(elem, calc->largeFont, 0, 3, "<", '<') == ERR ||
89 numpad_button_create(elem, calc->largeFont, 2, 3, "=", '=') == ERR)
90 {
91 font_free(calc->largeFont);
92 free(calc);
93 return ERR;
94 }
95
97 element_t* label = label_new(elem, LABEL_ID, &labelRect, "0", ELEMENT_NONE);
98 if (label == NULL)
99 {
100 font_free(calc->largeFont);
101 free(calc);
102 return ERR;
103 }
104
105 text_props_t* props = element_get_text_props(label);
106 props->font = calc->largeFont;
107 props->xAlign = ALIGN_MAX;
108
109 element_set_private(elem, calc);
110 }
111 break;
112 case LEVENT_DEINIT:
113 {
114 calculator_t* calc = element_get_private(elem);
115 if (calc == NULL)
116 {
117 break;
118 }
119 font_free(calc->largeFont);
120 free(calc);
121 }
122 break;
123 case LEVENT_ACTION:
124 {
125 if (event->lAction.type != ACTION_RELEASE)
126 {
127 break;
128 }
129
130 calculator_t* calc = element_get_private(elem);
131
132 element_t* label = element_find(elem, LABEL_ID);
133 if (label == NULL)
134 {
135 return ERR;
136 }
137
138 if (event->lAction.source <= 9)
139 {
140 calc->input = calc->input * 10 + event->lAction.source;
141 }
142 else if (event->lAction.source == '<')
143 {
144 calc->input /= 10;
145 }
146 else
147 {
148 switch (calc->operation)
149 {
150 case '/':
151 if (calc->input == 0)
152 {
153 element_set_text(label, "DIV BY ZERO");
154 element_redraw(label, false);
155 return 0;
156 }
157 calc->accumulator /= calc->input;
158 break;
159 case '*':
160 calc->accumulator *= calc->input;
161 break;
162 case '-':
163 calc->accumulator -= calc->input;
164 break;
165 case '+':
166 calc->accumulator += calc->input;
167 break;
168 case '=':
169 calc->accumulator = calc->input;
170 break;
171 default:
172 return 0;
173 }
174 calc->input = 0;
175
176 calc->operation = event->lAction.source;
177 }
178
179 char buffer[32];
180 ulltoa(event->lAction.source == '=' ? calc->accumulator : calc->input, buffer, 10);
181 element_set_text(label, buffer);
182 element_redraw(label, false);
183 }
184 break;
185 case LEVENT_QUIT:
186 {
188 }
189 break;
190 }
191
192 return 0;
193}
194
195int main(void)
196{
197 display_t* disp = display_new();
198 if (disp == NULL)
199 {
200 return EXIT_FAILURE;
201 }
202
204 window_t* win = window_new(disp, "Calculator", &rect, SURFACE_WINDOW, WINDOW_DECO, procedure, NULL);
205 if (win == NULL)
206 {
207 display_free(disp);
208 return EXIT_FAILURE;
209 }
210
211 if (window_set_visible(win, true) == ERR)
212 {
213 window_free(win);
214 display_free(disp);
215 return EXIT_FAILURE;
216 }
217
218 event_t event = {0};
219 while (display_next(disp, &event, CLOCKS_NEVER) != ERR)
220 {
221 display_dispatch(disp, &event);
222 }
223
224 window_free(win);
225 display_free(disp);
226 return EXIT_SUCCESS;
227}
#define CLOCKS_NEVER
Definition clock_t.h:16
static char id[MAX_NAME]
Definition dwm.c:20
void font_free(font_t *font)
Definition font.c:91
font_t * font_new(display_t *disp, const char *family, const char *weight, uint64_t size)
Definition font.c:17
void display_disconnect(display_t *disp)
Disconnect the display connection.
Definition display.c:161
uint64_t display_next(display_t *disp, event_t *event, clock_t timeout)
Retrieve the next event from the display connection.
Definition display.c:213
uint64_t display_dispatch(display_t *disp, const event_t *event)
Dispatch an event to the appropriate surface.
Definition display.c:440
void display_free(display_t *disp)
Free a display connection.
Definition display.c:113
display_t * display_new(void)
Create a new display connection.
Definition display.c:36
@ ALIGN_MAX
Definition drawable.h:50
text_props_t * element_get_text_props(element_t *elem)
Get the text properties of an element.
Definition element.c:361
void element_set_private(element_t *elem, void *private)
Set private data for an element.
Definition element.c:163
element_t * element_find(element_t *elem, element_id_t id)
Find a child element by its ID.
Definition element.c:134
#define ELEMENT_NONE
Definition element.h:43
uint64_t element_id_t
Element identifier type.
Definition element_id.h:23
void element_redraw(element_t *elem, bool shouldPropagate)
Redraw an element.
Definition element.c:450
uint64_t element_set_text(element_t *elem, const char *text)
Set the text of an element.
Definition element.c:343
void * element_get_private(element_t *elem)
Get private data for an element.
Definition element.c:173
#define LEVENT_QUIT
Definition event.h:103
#define LEVENT_DEINIT
Definition event.h:100
#define LEVENT_INIT
Definition event.h:99
#define LEVENT_ACTION
Definition event.h:102
@ ACTION_RELEASE
Definition event.h:50
@ SURFACE_WINDOW
Definition surface.h:35
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:308
element_t * label_new(element_t *parent, element_id_t id, const rect_t *rect, const char *text, element_flags_t flags)
Create a new label element.
Definition label.c:45
uint64_t window_set_visible(window_t *win, bool isVisible)
Set the visibility of the window.
Definition window.c:692
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 *private)
Allocate and initialize a new window.
Definition window.c:301
void window_free(window_t *win)
Free a window.
Definition window.c:415
display_t * window_get_display(window_t *win)
Get the display associated with the window.
Definition window.c:467
@ WINDOW_DECO
Enable decorations (titlebar, close/minimize buttons, etc).
Definition window.h:46
#define NULL
Pointer error value.
Definition NULL.h:23
EFI_PHYSICAL_ADDRESS buffer
Definition mem.c:15
#define ERR
Definition main.c:44
int main()
Definition main.c:97
#define NUMPAD_COLUMN_TO_WINDOW(column)
Definition main.c:15
#define LABEL_WIDTH
Definition main.c:18
#define LABEL_HEIGHT
Definition main.c:8
static uint64_t numpad_button_create(element_t *elem, font_t *font, uint64_t column, uint64_t row, const char *name, element_id_t id)
Definition main.c:23
#define WINDOW_WIDTH
Definition main.c:20
#define LABEL_ID
Definition main.c:7
#define WINDOW_HEIGHT
Definition main.c:21
#define NUMPAD_PADDING
Definition main.c:12
#define NUMPAD_ROW_TO_WINDOW(row)
Definition main.c:16
#define NUMPAD_BUTTON_WIDTH
Definition main.c:13
static uint64_t procedure(window_t *win, element_t *elem, const event_t *event)
Definition main.c:46
#define RECT_INIT_DIM(x, y, width, height)
Definition rect.h:32
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC char * ulltoa(unsigned long long number, char *str, int base)
Definition ulltoa.c:5
#define EXIT_SUCCESS
Definition stdlib.h:46
#define EXIT_FAILURE
Definition stdlib.h:47
_PUBLIC void * malloc(size_t size)
Definition malloc.c:5
_PUBLIC void free(void *ptr)
Definition free.c:11
font_t * largeFont
Definition main.c:43
char operation
Definition main.c:42
uint64_t input
Definition main.c:40
uint64_t accumulator
Definition main.c:41
Opaque display structure.
Definition internal.h:61
Opaque element structure.
Definition internal.h:23
Event structure.
Definition event.h:271
event_type_t type
Definition event.h:272
levent_action_t lAction
Definition event.h:288
action_type_t type
Definition event.h:246
element_id_t source
Definition event.h:245
Definition rect.h:13
Element text properties structure.
Definition element.h:63
font_t * font
Definition element.h:66
align_t xAlign
Definition element.h:64
Opaque window structure.
Definition internal.h:44