annotate main.cpp @ 0:12567e0a7670 default tip

initial commit
author Yasuri <yasuri@charliesmp.net>
date Sun, 04 Oct 2026 12:56:43 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
1 #include <iostream>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
2 #include <stdexcept>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
3 #include <vector>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
4 #include <string>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
5 #include <sstream>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
6 #include <cstring>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
7 #include <unistd.h>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
8 #include <X11/Xlib.h>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
9 #include <X11/Xft/Xft.h>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
10 #include <fontconfig/fontconfig.h>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
11 #include <X11/keysym.h>
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
12 #include "calculate.h"
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
13 #include "x11.h"
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
14
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
15 extern "C" {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
16 #include "drw.h"
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
17 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
18 #include "config.h"
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
19
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
20 struct Button { int x, y, w, h; std::string label; };
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
21
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
22 std::vector<Button> makeButtons() {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
23 std::vector<Button> b;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
24 for (int r = 0; r < 4; r++)
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
25 for (int c = 0; c < 4; c++)
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
26 b.push_back({gridX + c*(btnW+gap), gridY+ r*(btnH+gap), btnW, btnH, labels[r][c]});
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
27 return b;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
28 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
29
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
30 void redraw(Drw* drw, Clr* btnScheme, Clr* dispScheme,
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
31 const std::vector<Button>& btns, const std::string& input) {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
32 // display area (also paints the pixmap's background)
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
33 drw_setscheme(drw, dispScheme);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
34 drw_rect(drw, 0, 0, 500, 500, 1, 1);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
35 drw_text(drw, 10, 10, 480, 70, 10, input.c_str(), 0);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
36
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
37 // buttons
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
38 drw_setscheme(drw, btnScheme);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
39 for (const auto& b : btns) {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
40 unsigned int tw = drw_fontset_getwidth(drw, b.label.c_str());
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
41 int lpad = (b.w - (int)tw) / 2;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
42 drw_text(drw, b.x, b.y, b.w, b.h, lpad, b.label.c_str(), 0);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
43 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
44 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
45
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
46 int main() {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
47 Display *dpy = displayopen();
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
48 int screen = DefaultScreen(dpy);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
49 Window root = RootWindow(dpy, screen);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
50 Window win = XCreateSimpleWindow(dpy, root, 0, 0, 500, 500, 1, 0xFFFFFF, 0x000000);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
51 XStoreName(dpy, win, "Calculator");
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
52 XSelectInput(dpy, win, ExposureMask | KeyPressMask | ButtonPressMask);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
53 XMapWindow(dpy, win);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
54
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
55 Atom wmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
56 XSetWMProtocols(dpy, win, &wmDelete, 1);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
57
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
58 Drw* drw = drw_create(dpy, screen, root, 500, 500);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
59 if (!drw) { std::cerr << "drw_create failed\n"; return 1; }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
60
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
61 if (!drw_fontset_create(drw, fonts, 1)) {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
62 std::cerr << "font load failed\n";
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
63 return 1;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
64 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
65
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
66 Clr* btnScheme = drw_scm_create(drw, btnColors, 3);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
67 Clr* dispScheme = drw_scm_create(drw, dispColors, 3);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
68
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
69 std::vector<Button> btns = makeButtons();
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
70 std::string input;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
71 XEvent ev;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
72 bool running = true;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
73
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
74 while (running) {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
75 XNextEvent(dpy, &ev);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
76 switch (ev.type) {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
77 case ClientMessage:
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
78 if ((Atom)ev.xclient.data.l[0] == wmDelete) running = false;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
79 break;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
80 case Expose:
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
81 if (ev.xexpose.count == 0) {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
82 redraw(drw, btnScheme, dispScheme, btns, input);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
83 drw_map(drw, win, 0, 0, winW, winH);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
84 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
85 break;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
86 case KeyPress: {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
87 KeySym k = XLookupKeysym(&ev.xkey, 0);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
88 if (k == XK_q) running = false;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
89 break;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
90 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
91 case ButtonPress:
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
92 if (ev.xbutton.button != Button1) break;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
93 for (const auto& b : btns) {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
94 bool hit = ev.xbutton.x >= b.x && ev.xbutton.x < b.x + b.w &&
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
95 ev.xbutton.y >= b.y && ev.xbutton.y < b.y + b.h;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
96 if (!hit) continue;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
97
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
98 if (b.label == "=") {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
99 size_t pos = input.find_first_of("+-*/", 1);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
100 if (pos != std::string::npos) {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
101 try {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
102 double x = std::stod(input.substr(0, pos));
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
103 double y = std::stod(input.substr(pos + 1));
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
104 char op = input[pos];
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
105 std::ostringstream ss;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
106 ss << calculate(x, y, op);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
107 input = ss.str();
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
108 } catch (const std::exception& e) {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
109 input = e.what();
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
110 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
111 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
112 } else if (b.label == "C") {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
113 input.clear();
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
114 } else {
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
115 input += b.label;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
116 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
117 XClearArea(dpy, win, 0, 0, 0, 0, True);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
118 break;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
119 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
120 break;
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
121 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
122 }
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
123
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
124 drw_free(drw);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
125 XCloseDisplay(dpy);
12567e0a7670 initial commit
Yasuri <yasuri@charliesmp.net>
parents:
diff changeset
126 }