綺麗に

This commit is contained in:
2026-01-17 18:35:27 +09:00
parent b20fa6cc3a
commit fa83f224e2
9 changed files with 164 additions and 151 deletions

112
main.c
View File

@@ -4,73 +4,67 @@
#include "src/utils.h" #include "src/utils.h"
#include "src/control.h" #include "src/control.h"
XftColor color, btncolor;
Colormap colormap;
XftFont *font;
XftFont *prbfont;
XftFont *disfont;
Visual *visual;
const char *sofname = "ucalc"; const char *sofname = "ucalc";
const char *version = "0.0.0"; const char *version = "0.0.0";
const char *disname = "Unix Calc"; const char *disname = "Unix Calc";
int main() { int main() {
Display *display; UiSystem ui;
Window window;
XEvent event; XEvent event;
int screen; int screen;
GC gc = NULL;
XGCValues values; XGCValues values;
display = XOpenDisplay(NULL); ui.display = XOpenDisplay(NULL);
if (display == NULL) { if (ui.display == NULL) {
fprintf(stderr, "画面を開けられません。\n"); fprintf(stderr, "画面を開けられません。\n");
exit(1); exit(1);
} }
screen = DefaultScreen(display); screen = DefaultScreen(ui.display);
int sw = DisplayWidth(display, screen); int sw = DisplayWidth(ui.display, screen);
int sh = DisplayHeight(display, screen); int sh = DisplayHeight(ui.display, screen);
int window_x = (sw - window_width) / 3; int window_x = (sw - window_width) / 3;
int window_y = (sh - window_height) / 2; int window_y = (sh - window_height) / 2;
window = XCreateSimpleWindow(display, RootWindow(display, screen), ui.window = XCreateSimpleWindow(ui.display,
RootWindow(ui.display, screen),
window_x, window_y, window_width, window_height, 1, BTCOL, BGCOL); window_x, window_y, window_width, window_height, 1, BTCOL, BGCOL);
if (!window) { if (!ui.window) {
cleanup(display, window, gc, &color, &btncolor, font, disfont, prbfont, colormap, visual, backbuf); cleanup(&ui);
fprintf(stderr, "ウィンドウを作成に失敗。\n"); fprintf(stderr, "ウィンドウを作成に失敗。\n");
exit(1); exit(1);
} }
backbuf = XCreatePixmap(display, window, window_width, window_height, DefaultDepth(display, screen)); ui.backbuf = XCreatePixmap(ui.display, ui.window, window_width, window_height,
DefaultDepth(ui.display, screen));
ui.target = ui.backbuf;
Atom net_wm_window_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); Atom net_wm_window_type = XInternAtom(ui.display, "_NET_WM_WINDOW_TYPE", False);
Atom dialog = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); Atom dialog = XInternAtom(ui.display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
XChangeProperty(display, window, net_wm_window_type, XA_ATOM, 32, XChangeProperty(ui.display, ui.window, net_wm_window_type, XA_ATOM, 32,
PropModeReplace, (unsigned char *)&dialog, 1); PropModeReplace, (unsigned char *)&dialog, 1);
XStoreName(display, window, disname); XStoreName(ui.display, ui.window, disname);
Atom net_wm_name = XInternAtom(display, "_NET_WM_NAME", False); Atom net_wm_name = XInternAtom(ui.display, "_NET_WM_NAME", False);
char displayname[16]; char displayname[16];
snprintf(displayname, 16, "%s %s", disname, version); snprintf(displayname, 16, "%s %s", disname, version);
XChangeProperty(display, window, net_wm_name, XChangeProperty(ui.display, ui.window, net_wm_name,
XInternAtom(display, "UTF8_STRING", False), 8, XInternAtom(ui.display, "UTF8_STRING", False), 8,
PropModeReplace, (unsigned char *)displayname, strlen(displayname)); PropModeReplace, (unsigned char *)displayname, strlen(displayname));
XClassHint *classHint = XAllocClassHint(); XClassHint *classHint = XAllocClassHint();
if (classHint) { if (classHint) {
classHint->res_name = "unixcalc"; classHint->res_name = "unixcalc";
classHint->res_class = "UnixCalc"; classHint->res_class = "UnixCalc";
XSetClassHint(display, window, classHint); XSetClassHint(ui.display, ui.window, classHint);
XFree(classHint); XFree(classHint);
} }
XSetWindowBackground(display, window, BGCOL); XSetWindowBackground(ui.display, ui.window, BGCOL);
XSelectInput(display, window, XSelectInput(ui.display, ui.window,
ExposureMask ExposureMask
| ButtonPressMask | ButtonPressMask
| ButtonReleaseMask | ButtonReleaseMask
@@ -80,84 +74,84 @@ int main() {
// | StructureNotifyMask // | StructureNotifyMask
); );
gc = XCreateGC(display, window, 0, &values); ui.gc = XCreateGC(ui.display, ui.window, 0, &values);
if (!gc) { if (!ui.gc) {
cleanup(display, window, gc, &color, &btncolor, font, disfont, prbfont, colormap, visual, backbuf); cleanup(&ui);
fprintf(stderr, "GCを作成に失敗。\n"); fprintf(stderr, "GCを作成に失敗。\n");
exit(1); exit(1);
} }
visual = DefaultVisual(display, screen); ui.visual = *DefaultVisual(ui.display, screen);
colormap = XCreateColormap(display, window, visual, AllocNone); ui.colormap = XCreateColormap(ui.display, ui.window, &ui.visual, AllocNone);
if (colormap == None) { if (ui.colormap == None) {
cleanup(display, window, gc, &color, &btncolor, font, disfont, prbfont, colormap, visual, backbuf); cleanup(&ui);
fprintf(stderr, "カラーマップを作成に失敗。\n"); fprintf(stderr, "カラーマップを作成に失敗。\n");
exit(1); exit(1);
} }
font = XftFontOpenName(display, screen, "Noto Sans CJK-12"); ui.font = XftFontOpenName(ui.display, screen, "Noto Sans CJK-12");
if (!font) { if (!ui.font) {
cleanup(display, window, gc, &color, &btncolor, font, disfont, prbfont, colormap, visual, backbuf); cleanup(&ui);
fprintf(stderr, "フォントの読み込みに失敗。\n"); fprintf(stderr, "フォントの読み込みに失敗。\n");
exit(1); exit(1);
} }
prbfont = XftFontOpenName(display, screen, "Noto Sans CJK-24"); ui.prbfont = XftFontOpenName(ui.display, screen, "Noto Sans CJK-24");
if (!prbfont) { if (!ui.prbfont) {
cleanup(display, window, gc, &color, &btncolor, font, disfont, prbfont, colormap, visual, backbuf); cleanup(&ui);
fprintf(stderr, "問題フォントの読み込みに失敗。\n"); fprintf(stderr, "問題フォントの読み込みに失敗。\n");
exit(1); exit(1);
} }
disfont = XftFontOpenName(display, screen, "Noto Sans CJK-72"); ui.disfont = XftFontOpenName(ui.display, screen, "Noto Sans CJK-72");
if (!disfont) { if (!ui.disfont) {
cleanup(display, window, gc, &color, &btncolor, font, disfont, prbfont, colormap, visual, backbuf); cleanup(&ui);
fprintf(stderr, "解決フォントの読み込みに失敗。\n"); fprintf(stderr, "解決フォントの読み込みに失敗。\n");
exit(1); exit(1);
} }
if (!XftColorAllocName(display, visual, colormap, "#232020", &color)) { if (!XftColorAllocName(ui.display, &ui.visual, ui.colormap, "#232020", &ui.color)) {
cleanup(display, window, gc, &color, &btncolor, font, disfont, prbfont, colormap, visual, backbuf); cleanup(&ui);
fprintf(stderr, "色の役割に失敗。\n"); fprintf(stderr, "色の役割に失敗。\n");
exit(1); exit(1);
} }
XMapWindow(display, window); XMapWindow(ui.display, ui.window);
{ {
XWindowAttributes attr; XWindowAttributes attr;
XGetWindowAttributes(display, window, &attr); XGetWindowAttributes(ui.display, ui.window, &attr);
XEvent fake = { .type = Expose }; XEvent fake = { .type = Expose };
fake.xexpose.window = window; fake.xexpose.window = ui.window;
fake.xexpose.width = attr.width; fake.xexpose.width = attr.width;
fake.xexpose.height = attr.height; fake.xexpose.height = attr.height;
control_expose(display, window, gc, &event, &color, font, disfont, prbfont); control_expose(&ui, &event);
} }
while (isrunning) { while (isrunning) {
XNextEvent(display, &event); XNextEvent(ui.display, &event);
switch (event.type) { switch (event.type) {
case Expose: case Expose:
case ConfigureNotify: case ConfigureNotify:
XClearWindow(display, window); XClearWindow(ui.display, ui.window);
control_expose(display, window, gc, &event, &color, font, disfont, prbfont); control_expose(&ui, &event);
break; break;
case ButtonPress: case ButtonPress:
if (event.xbutton.button == Button1) { if (event.xbutton.button == Button1) {
handle_button_press(display, gc, event.xbutton.x, event.xbutton.y, &color, font); handle_button_press(&ui, event.xbutton.x, event.xbutton.y);
break; break;
} }
case ButtonRelease: case ButtonRelease:
if (event.xbutton.button == Button1) { if (event.xbutton.button == Button1) {
handle_button_release(display, window, gc, event.xbutton.x, event.xbutton.y, &color, font, disfont, prbfont); handle_button_release(&ui, event.xbutton.x, event.xbutton.y);
break; break;
} }
case KeyPress: case KeyPress:
handle_key_press(display, window, gc, &event, &color, font, disfont, prbfont); handle_key_press(&ui, &event);
break; break;
// case MotionNotify: // case MotionNotify:
// handle_mouse_hover(display, window, gc, &event, &color, font); // handle_mouse_hover(&ui, &event);
// break; // break;
case ClientMessage: case ClientMessage:
// WM_DELETE_WINDOW // WM_DELETE_WINDOW
@@ -165,7 +159,7 @@ int main() {
} }
} }
cleanup(display, window, gc, &color, &btncolor, font, disfont, prbfont, colormap, visual, backbuf); cleanup(&ui);
return 0; return 0;
} }

View File

@@ -120,78 +120,85 @@ double evaluate_simple(const char *expr) {
return res; return res;
} }
void control_expose(Display *dpy, Window wnd, GC gc, XEvent *e, XftColor *color, XftFont *f, XftFont *df, XftFont *pf) { void control_expose(UiSystem *ui, XEvent *e) {
(void)color;
if (e->type != Expose && e->type != ConfigureNotify) return; if (e->type != Expose && e->type != ConfigureNotify) return;
XWindowAttributes attr; XWindowAttributes attr;
XGetWindowAttributes(dpy, wnd, &attr); XGetWindowAttributes(ui->display, ui->window, &attr);
int w = attr.width; int w = attr.width;
int h = attr.height; int h = attr.height;
if (backbuf != None) { if (ui->backbuf != None) {
XFreePixmap(dpy, backbuf); XFreePixmap(ui->display, ui->backbuf);
ui->backbuf = None;
} }
backbuf = XCreatePixmap(dpy, wnd, w, h, DefaultDepth(dpy, DefaultScreen(dpy))); ui->backbuf = XCreatePixmap(ui->display, ui->window, w, h,
DefaultDepth(ui->display, DefaultScreen(ui->display)));
if (backbuf == None) { if (ui->backbuf == None) {
backbuf = wnd; fprintf(stderr, "バックバッファ作成失敗!\n");
ui->backbuf = ui->window;
} }
XftDraw *backdraw = XftDrawCreate(dpy, backbuf, ui->target = ui->backbuf;
DefaultVisual(dpy, DefaultScreen(dpy)), DefaultColormap(dpy, DefaultScreen(dpy)));
XftDraw *backdraw = XftDrawCreate(ui->display, ui->backbuf,
DefaultVisual(ui->display, DefaultScreen(ui->display)),
DefaultColormap(ui->display, DefaultScreen(ui->display)));
if (!backdraw) { if (!backdraw) {
fprintf(stderr, "Pixmap向けXftDrawの作成に失敗。\n"); fprintf(stderr, "Pixmap向けXftDrawの作成に失敗。\n");
XFreePixmap(dpy, backbuf); XFreePixmap(ui->display, ui->backbuf);
backbuf = None; ui->backbuf = None;
return; return;
} }
XSetForeground(dpy, gc, BGCOL); XSetForeground(ui->display, ui->gc, BGCOL);
XFillRectangle(dpy, backbuf, gc, 0, 0, w, h); XFillRectangle(ui->display, ui->backbuf, ui->gc, 0, 0, w, h);
// 出力 // 出力
if (displaytxt[0] != '\0' && df) { if (displaytxt[0] != '\0' && ui->disfont) {
const FcChar8 *text = (const FcChar8 *)displaytxt; const FcChar8 *text = (const FcChar8 *)displaytxt;
int len = strlen((const char *)text); int len = strlen((const char *)text);
XGlyphInfo extents; XGlyphInfo extents;
XftTextExtentsUtf8(dpy, df, text, len, &extents); XftTextExtentsUtf8(ui->display, ui->disfont, text, len, &extents);
int tx = w - 20 - extents.xOff; int tx = w - 20 - extents.xOff;
int ty = 160; int ty = 160;
XftColor discol; XftColor discol;
XftColorAllocName(dpy, DefaultVisual(dpy, DefaultScreen(dpy)), XftColorAllocName(ui->display, DefaultVisual(ui->display, DefaultScreen(ui->display)),
DefaultColormap(dpy, DefaultScreen(dpy)), DefaultColormap(ui->display, DefaultScreen(ui->display)),
"#ee4030", &discol); "#ee4030", &discol);
XftDrawStringUtf8(backdraw, &discol, df, tx, ty, text, len); XftDrawStringUtf8(backdraw, &discol, ui->disfont, tx, ty, text, len);
XftColorFree(dpy, DefaultVisual(dpy, DefaultScreen(dpy)), XftColorFree(ui->display, DefaultVisual(ui->display, DefaultScreen(ui->display)),
DefaultColormap(dpy, DefaultScreen(dpy)), &discol); DefaultColormap(ui->display, DefaultScreen(ui->display)), &discol);
} }
if (displayprb[0] != '\0' && pf) { if (displayprb[0] != '\0' && ui->prbfont) {
const FcChar8 *text = (const FcChar8 *)displayprb; const FcChar8 *text = (const FcChar8 *)displayprb;
int len = strlen((const char *)text); int len = strlen((const char *)text);
XGlyphInfo extents; XGlyphInfo extents;
XftTextExtentsUtf8(dpy, pf, text, len, &extents); XftTextExtentsUtf8(ui->display, ui->prbfont, text, len, &extents);
int tx = w - 20 - extents.xOff; int tx = w - 20 - extents.xOff;
int ty = 80; int ty = 80;
XftColor discol; XftColor discol;
XftColorAllocName(dpy, DefaultVisual(dpy, DefaultScreen(dpy)), XftColorAllocName(ui->display,
DefaultColormap(dpy, DefaultScreen(dpy)), DefaultVisual(ui->display, DefaultScreen(ui->display)),
"#b61729", &discol); DefaultColormap(ui->display, DefaultScreen(ui->display)),
"#b61729", &discol);
XftDrawStringUtf8(backdraw, &discol, pf, tx, ty, text, len); XftDrawStringUtf8(backdraw, &discol, ui->prbfont, tx, ty, text, len);
XftColorFree(dpy, DefaultVisual(dpy, DefaultScreen(dpy)), XftColorFree(ui->display,
DefaultColormap(dpy, DefaultScreen(dpy)), &discol); DefaultVisual(ui->display, DefaultScreen(ui->display)),
DefaultColormap(ui->display, DefaultScreen(ui->display)), &discol);
} }
int width = 93; int width = 93;
@@ -219,50 +226,54 @@ void control_expose(Display *dpy, Window wnd, GC gc, XEvent *e, XftColor *color,
btn.label = label; btn.label = label;
btn.pressed = 0; btn.pressed = 0;
drawbuttons(dpy, backbuf, gc, &btn, backdraw, color, f); drawbuttons(ui, &btn, backdraw);
} }
} }
XCopyArea(dpy, backbuf, wnd, gc, 0, 0, w, h, 0, 0); XCopyArea(ui->display, ui->backbuf, ui->window, ui->gc, 0, 0, w, h, 0, 0);
XftDrawDestroy(backdraw); XftDrawDestroy(backdraw);
XFlush(dpy); XFlush(ui->display);
} }
void handle_button_press(Display *dpy, GC gc, int mx, int my, XftColor *col, XftFont *f) { void handle_button_press(UiSystem *ui, int mx, int my) {
SuwaButton *btn = find_button_at(mx, my); SuwaButton *btn = find_button_at(mx, my);
if (!btn) return; if (!btn) return;
btn->pressed = 1; btn->pressed = 1;
XftDraw *backdraw = XftDrawCreate(dpy, backbuf, XftDraw *backdraw = XftDrawCreate(ui->display, ui->backbuf,
DefaultVisual(dpy, DefaultScreen(dpy)), DefaultColormap(dpy, DefaultScreen(dpy))); DefaultVisual(ui->display, DefaultScreen(ui->display)),
DefaultColormap(ui->display, DefaultScreen(ui->display)));
if (!backdraw) { if (!backdraw) {
fprintf(stderr, "Pixmap向けXftDrawの作成に失敗。\n"); fprintf(stderr, "Pixmap向けXftDrawの作成に失敗。\n");
XFreePixmap(dpy, backbuf); XFreePixmap(ui->display, ui->backbuf);
backbuf = None; ui->backbuf = None;
return; return;
} }
drawbuttons(dpy, backbuf, gc, btn, backdraw, col, f); drawbuttons(ui, btn, backdraw);
XFlush(dpy); XFlush(ui->display);
} }
void handle_button_release(Display *dpy, Window wnd, GC gc, int mx, int my, XftColor *col, XftFont *f, XftFont *df, XftFont *pf) { void handle_button_release(UiSystem *ui, int mx, int my) {
SuwaButton *btn = find_button_at(mx, my); SuwaButton *btn = find_button_at(mx, my);
if (!btn) return; if (!btn) return;
btn->pressed = 0; btn->pressed = 0;
XftDraw *backdraw = XftDrawCreate(dpy, backbuf, XftDraw *backdraw = XftDrawCreate(ui->display, ui->backbuf,
DefaultVisual(dpy, DefaultScreen(dpy)), DefaultColormap(dpy, DefaultScreen(dpy))); DefaultVisual(ui->display, DefaultScreen(ui->display)),
DefaultColormap(ui->display, DefaultScreen(ui->display)));
if (!backdraw) { if (!backdraw) {
fprintf(stderr, "Pixmap向けXftDrawの作成に失敗。\n"); fprintf(stderr, "Pixmap向けXftDrawの作成に失敗。\n");
XFreePixmap(dpy, backbuf); XFreePixmap(ui->display, ui->backbuf);
backbuf = None; ui->backbuf = None;
return; return;
} }
drawbuttons(dpy, backbuf, gc, btn, backdraw, col, f);
ui->target = ui->backbuf;
drawbuttons(ui, btn, backdraw);
XftDrawDestroy(backdraw); XftDrawDestroy(backdraw);
XFlush(dpy); XFlush(ui->display);
const char *label = btn->label; const char *label = btn->label;
if (strcmp(label, "C") == 0) { if (strcmp(label, "C") == 0) {
@@ -283,10 +294,10 @@ void handle_button_release(Display *dpy, Window wnd, GC gc, int mx, int my, XftC
append_to_input(label[0]); append_to_input(label[0]);
} }
control_expose(dpy, wnd, gc, &(XEvent){.type = Expose}, col, f, df, pf); control_expose(ui, &(XEvent){.type = Expose});
} }
void handle_key_press(Display *dpy, Window wnd, GC gc, XEvent *event, XftColor *col, XftFont *f, XftFont *df, XftFont *pf) { void handle_key_press(UiSystem *ui, XEvent *event) {
KeySym keysym; KeySym keysym;
char buf[32]; char buf[32];
int len; int len;
@@ -369,21 +380,21 @@ void handle_key_press(Display *dpy, Window wnd, GC gc, XEvent *event, XftColor *
return; return;
redraw: redraw:
control_expose(dpy, wnd, gc, &(XEvent){.type = Expose}, col, f, df, pf); control_expose(ui, &(XEvent){.type = Expose});
} }
// void handle_mouse_hover(Display *dpy, Window wnd, GC gc, XEvent *event, XftColor *col, XftFont *f) { // void handle_mouse_hover(UiSystem *ui, XEvent *event) {
// SuwaButton *hover = find_button_at(event->xmotion.x, event->xmotion.y); // SuwaButton *hover = find_button_at(event->xmotion.x, event->xmotion.y);
// if (hover != hovered_btn) { // if (hover != hovered_btn) {
// if (hovered_btn) { // if (hovered_btn) {
// hovered_btn->pressed = 0; // hovered_btn->pressed = 0;
// redraw_single_button(dpy, wnd, gc, col, f, hovered_btn); // redraw_single_button(&ui, hovered_btn);
// } // }
// hovered_btn = hover; // hovered_btn = hover;
// if (hovered_btn) { // if (hovered_btn) {
// redraw_single_button(dpy, wnd, gc, col, f, hovered_btn); // redraw_single_button(&ui, hovered_btn);
// } // }
// } // }
// } // }

View File

@@ -1,10 +1,9 @@
#pragma once #pragma once
#include <X11/Xlib.h> #include "ui.h"
#include <X11/Xft/Xft.h>
void control_expose(Display *dpy, Window wnd, GC gc, XEvent *event, XftColor *color, XftFont *f, XftFont *df, XftFont *pf); void control_expose(UiSystem *ui, XEvent *event);
void handle_button_press(Display *dpy, GC gc, int mx, int my, XftColor *col, XftFont *f); void handle_button_press(UiSystem *ui, int mx, int my);
void handle_button_release(Display *dpy, Window wnd, GC gc, int mx, int my, XftColor *col, XftFont *f, XftFont *df, XftFont *pf); void handle_button_release(UiSystem *ui, int mx, int my);
void handle_key_press(Display *dpy, Window wnd, GC gc, XEvent *event, XftColor *col, XftFont *f, XftFont *df, XftFont *pf); void handle_key_press(UiSystem *ui, XEvent *event);
void handle_mouse_hover(Display *dpy, Window wnd, GC gc, XEvent *event, XftColor *col, XftFont *f); void handle_mouse_hover(UiSystem *ui, XEvent *event);

View File

@@ -3,28 +3,28 @@
#include <string.h> #include <string.h>
void drawbuttons(Display *dpy, Drawable target, GC gc, SuwaButton *btn, void drawbuttons(UiSystem *ui, SuwaButton *btn, XftDraw *xftdraw) {
XftDraw *xftdraw, XftColor *textcolor, XftFont *font) {
unsigned long curbg = btn->pressed ? BTSEL : BTCOL; unsigned long curbg = btn->pressed ? BTSEL : BTCOL;
XSetForeground(dpy, gc, curbg); XSetForeground(ui->display, ui->gc, curbg);
XFillRectangle(dpy, target, gc, btn->x, btn->y, btn->width, btn->height); XFillRectangle(ui->display, ui->target, ui->gc, btn->x, btn->y, btn->width, btn->height);
// 文字の中央に // 文字の中央に
if (btn->label && font && xftdraw) { if (btn->label && ui->font && xftdraw) {
const FcChar8 *str = (const FcChar8 *)btn->label; const FcChar8 *str = (const FcChar8 *)btn->label;
int len = strlen((const char *)str); int len = strlen((const char *)str);
XGlyphInfo extents; XGlyphInfo extents;
XftTextExtentsUtf8(dpy, font, str, len, &extents); XftTextExtentsUtf8(ui->display, ui->font, str, len, &extents);
int text_w = extents.xOff; int text_w = extents.xOff;
int text_h = font->ascent + font->descent; int text_h = ui->font->ascent + ui->font->descent;
int tx = btn->x + (btn->width - text_w) / 2; int tx = btn->x + (btn->width - text_w) / 2;
int ty = btn->y + (btn->height - text_h) / 2 + font->ascent; int ty = btn->y + (btn->height - text_h) / 2 + ui->font->ascent;
// tx -= extents.x; // tx -= extents.x;
XftDrawStringUtf8(xftdraw, textcolor, font, tx, ty, (FcChar8 *)btn->label, len); XftDrawStringUtf8(xftdraw, &ui->textcolor, ui->font, tx, ty,
(FcChar8 *)btn->label, len);
} }
} }

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "program.h" #include "program.h"
#include "ui.h"
void drawbuttons(Display *dpy, Drawable target, GC gc, SuwaButton *btn, void drawbuttons(UiSystem *ui, SuwaButton *btn, XftDraw *xftdraw);
XftDraw *xftdraw, XftColor *textcolor, XftFont *font);

View File

@@ -1,7 +1,5 @@
#pragma once #pragma once
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include "ui.h" #include "ui.h"
#define FGCOL 0xfcfcfc #define FGCOL 0xfcfcfc
@@ -17,6 +15,5 @@ extern char displayprb[128];
extern char curinput[256]; extern char curinput[256];
extern char displaytxt[64]; extern char displaytxt[64];
extern int input_pos; extern int input_pos;
extern Pixmap backbuf;
extern SuwaButton *hovered_btn; extern SuwaButton *hovered_btn;
extern SuwaButton *pressed_btn; extern SuwaButton *pressed_btn;

View File

@@ -1,5 +1,21 @@
#pragma once #pragma once
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
typedef struct {
Display *display;
Window window;
Drawable target;
GC gc;
Visual visual;
XftDraw *xftdraw;
XftColor color, btncolor, textcolor;
XftFont *font, *prbfont, *disfont;
Colormap colormap;
Pixmap backbuf;
} UiSystem;
typedef struct { typedef struct {
int x, y, width, height; int x, y, width, height;
const char *label; const char *label;

View File

@@ -1,19 +1,18 @@
#include "utils.h" #include "utils.h"
void cleanup(Display *display, Window window, GC gc, void cleanup(UiSystem *ui) {
XftColor *color, XftColor *btncolor, XftFont *font, if (ui->btncolor.pixel != 0)
XftFont *disfont, XftFont *prbfont, Colormap colormap, Visual *visual, XftColorFree(ui->display, &ui->visual, ui->colormap, &ui->btncolor);
Pixmap backbuf) { if (ui->color.pixel != 0)
if (btncolor) XftColorFree(display, visual, colormap, btncolor); XftColorFree(ui->display, &ui->visual, ui->colormap, &ui->color);
if (color) XftColorFree(display, visual, colormap, color); if (ui->disfont) XftFontClose(ui->display, ui->disfont);
if (disfont) XftFontClose(display, disfont); if (ui->prbfont) XftFontClose(ui->display, ui->prbfont);
if (prbfont) XftFontClose(display, prbfont); if (ui->font) XftFontClose(ui->display, ui->font);
if (font) XftFontClose(display, font); if (ui->gc) XFreeGC(ui->display, ui->gc);
if (gc) XFreeGC(display, gc); if (ui->backbuf) {
if (backbuf) { XFreePixmap(ui->display, ui->backbuf);
XFreePixmap(display, backbuf); ui->backbuf = None;
backbuf = None;
} }
if (window) XDestroyWindow(display, window); if (ui->window) XDestroyWindow(ui->display, ui->window);
if (display) XCloseDisplay(display); if (ui->display) XCloseDisplay(ui->display);
} }

View File

@@ -2,7 +2,4 @@
#include "program.h" #include "program.h"
void cleanup(Display *display, Window window, GC gc, void cleanup(UiSystem *ui);
XftColor *color, XftColor *btncolor, XftFont *font,
XftFont *disfont, XftFont *prbfont, Colormap colormap, Visual *visual,
Pixmap backbuf);