Mercurial > x11calc
diff main.cpp @ 0:12567e0a7670 default tip
initial commit
| author | Yasuri <yasuri@charliesmp.net> |
|---|---|
| date | Sun, 04 Oct 2026 12:56:43 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Oct 04 12:56:43 2026 -0500 @@ -0,0 +1,126 @@ +#include <iostream> +#include <stdexcept> +#include <vector> +#include <string> +#include <sstream> +#include <cstring> +#include <unistd.h> +#include <X11/Xlib.h> +#include <X11/Xft/Xft.h> +#include <fontconfig/fontconfig.h> +#include <X11/keysym.h> +#include "calculate.h" +#include "x11.h" + +extern "C" { +#include "drw.h" +} +#include "config.h" + +struct Button { int x, y, w, h; std::string label; }; + +std::vector<Button> makeButtons() { + std::vector<Button> b; + for (int r = 0; r < 4; r++) + for (int c = 0; c < 4; c++) + b.push_back({gridX + c*(btnW+gap), gridY+ r*(btnH+gap), btnW, btnH, labels[r][c]}); + return b; +} + +void redraw(Drw* drw, Clr* btnScheme, Clr* dispScheme, + const std::vector<Button>& btns, const std::string& input) { + // display area (also paints the pixmap's background) + drw_setscheme(drw, dispScheme); + drw_rect(drw, 0, 0, 500, 500, 1, 1); + drw_text(drw, 10, 10, 480, 70, 10, input.c_str(), 0); + + // buttons + drw_setscheme(drw, btnScheme); + for (const auto& b : btns) { + unsigned int tw = drw_fontset_getwidth(drw, b.label.c_str()); + int lpad = (b.w - (int)tw) / 2; + drw_text(drw, b.x, b.y, b.w, b.h, lpad, b.label.c_str(), 0); + } +} + +int main() { + Display *dpy = displayopen(); + int screen = DefaultScreen(dpy); + Window root = RootWindow(dpy, screen); + Window win = XCreateSimpleWindow(dpy, root, 0, 0, 500, 500, 1, 0xFFFFFF, 0x000000); + XStoreName(dpy, win, "Calculator"); + XSelectInput(dpy, win, ExposureMask | KeyPressMask | ButtonPressMask); + XMapWindow(dpy, win); + + Atom wmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + XSetWMProtocols(dpy, win, &wmDelete, 1); + + Drw* drw = drw_create(dpy, screen, root, 500, 500); + if (!drw) { std::cerr << "drw_create failed\n"; return 1; } + + if (!drw_fontset_create(drw, fonts, 1)) { + std::cerr << "font load failed\n"; + return 1; + } + + Clr* btnScheme = drw_scm_create(drw, btnColors, 3); + Clr* dispScheme = drw_scm_create(drw, dispColors, 3); + + std::vector<Button> btns = makeButtons(); + std::string input; + XEvent ev; + bool running = true; + + while (running) { + XNextEvent(dpy, &ev); + switch (ev.type) { + case ClientMessage: + if ((Atom)ev.xclient.data.l[0] == wmDelete) running = false; + break; + case Expose: + if (ev.xexpose.count == 0) { + redraw(drw, btnScheme, dispScheme, btns, input); + drw_map(drw, win, 0, 0, winW, winH); + } + break; + case KeyPress: { + KeySym k = XLookupKeysym(&ev.xkey, 0); + if (k == XK_q) running = false; + break; + } + case ButtonPress: + if (ev.xbutton.button != Button1) break; + for (const auto& b : btns) { + bool hit = ev.xbutton.x >= b.x && ev.xbutton.x < b.x + b.w && + ev.xbutton.y >= b.y && ev.xbutton.y < b.y + b.h; + if (!hit) continue; + + if (b.label == "=") { + size_t pos = input.find_first_of("+-*/", 1); + if (pos != std::string::npos) { + try { + double x = std::stod(input.substr(0, pos)); + double y = std::stod(input.substr(pos + 1)); + char op = input[pos]; + std::ostringstream ss; + ss << calculate(x, y, op); + input = ss.str(); + } catch (const std::exception& e) { + input = e.what(); + } + } + } else if (b.label == "C") { + input.clear(); + } else { + input += b.label; + } + XClearArea(dpy, win, 0, 0, 0, 0, True); + break; + } + break; + } + } + + drw_free(drw); + XCloseDisplay(dpy); +}
