/* skykit.c — OrionOS native UI toolkit implementation */ #include "skykit.h" void sk_app_init(SKApp *app) { app->dpy = XOpenDisplay(NULL); if (!app->dpy) { fputs("skykit: cannot open display\n", stderr); exit(1); } app->screen = DefaultScreen(app->dpy); app->root = RootWindow(app->dpy, app->screen); app->cmap = DefaultColormap(app->dpy, app->screen); app->vis = DefaultVisual(app->dpy, app->screen); app->depth = DefaultDepth(app->dpy, app->screen); app->font_ui = XftFontOpenName(app->dpy, app->screen, SK_FONT_UI); app->font_sm = XftFontOpenName(app->dpy, app->screen, SK_FONT_SM); app->font_hdr = XftFontOpenName(app->dpy, app->screen, SK_FONT_HDR); app->font_mono = XftFontOpenName(app->dpy, app->screen, SK_FONT_MONO); if (!app->font_ui) { fputs("skykit: cannot open UI font\n", stderr); exit(1); } if (!app->font_sm) app->font_sm = app->font_ui; if (!app->font_hdr) app->font_hdr = app->font_ui; if (!app->font_mono) app->font_mono = app->font_ui; } void sk_app_free(SKApp *app) { if (app->font_ui) XftFontClose(app->dpy, app->font_ui); if (app->font_sm && app->font_sm != app->font_ui) XftFontClose(app->dpy, app->font_sm); if (app->font_hdr && app->font_hdr != app->font_ui) XftFontClose(app->dpy, app->font_hdr); if (app->font_mono && app->font_mono != app->font_ui) XftFontClose(app->dpy, app->font_mono); XCloseDisplay(app->dpy); } unsigned long sk_color(SKApp *app, unsigned long rgb) { XColor c = { .red = ((rgb >> 16) & 0xFF) * 257, .green = ((rgb >> 8) & 0xFF) * 257, .blue = ( rgb & 0xFF) * 257, .flags = DoRed | DoGreen | DoBlue }; XAllocColor(app->dpy, app->cmap, &c); return c.pixel; } void sk_xft_color(SKApp *app, unsigned long rgb, XftColor *out) { XRenderColor rc = { .red = ((rgb >> 16) & 0xFF) * 257, .green = ((rgb >> 8) & 0xFF) * 257, .blue = ( rgb & 0xFF) * 257, .alpha = 0xFFFF }; XftColorAllocValue(app->dpy, app->vis, app->cmap, &rc, out); } void sk_fill(SKPainter *p, unsigned long rgb, int x, int y, int w, int h) { XSetForeground(p->app->dpy, p->gc, sk_color(p->app, rgb)); XFillRectangle(p->app->dpy, p->drw, p->gc, x, y, (unsigned)w, (unsigned)h); } void sk_rect(SKPainter *p, unsigned long rgb, int x, int y, int w, int h) { XSetForeground(p->app->dpy, p->gc, sk_color(p->app, rgb)); XDrawRectangle(p->app->dpy, p->drw, p->gc, x, y, (unsigned)(w-1), (unsigned)(h-1)); } void sk_line(SKPainter *p, unsigned long rgb, int x1, int y1, int x2, int y2) { XSetForeground(p->app->dpy, p->gc, sk_color(p->app, rgb)); XDrawLine(p->app->dpy, p->drw, p->gc, x1, y1, x2, y2); } void sk_text(SKPainter *p, XftFont *font, unsigned long rgb, int x, int y, const char *s) { if (!s || !s[0]) return; XftDraw *xd = XftDrawCreate(p->app->dpy, p->drw, p->app->vis, p->app->cmap); XftColor col; sk_xft_color(p->app, rgb, &col); XftDrawStringUtf8(xd, &col, font, x, y, (const FcChar8 *)s, (int)strlen(s)); XftColorFree(p->app->dpy, p->app->vis, p->app->cmap, &col); XftDrawDestroy(xd); } void sk_text_clip(SKPainter *p, XftFont *font, unsigned long rgb, int x, int y, const char *s, int cx, int cy, int cw, int ch) { if (!s || !s[0]) return; XftDraw *xd = XftDrawCreate(p->app->dpy, p->drw, p->app->vis, p->app->cmap); XRectangle clip = { (short)cx, (short)cy, (unsigned short)cw, (unsigned short)ch }; XftDrawSetClipRectangles(xd, 0, 0, &clip, 1); XftColor col; sk_xft_color(p->app, rgb, &col); XftDrawStringUtf8(xd, &col, font, x, y, (const FcChar8 *)s, (int)strlen(s)); XftColorFree(p->app->dpy, p->app->vis, p->app->cmap, &col); XftDrawSetClip(xd, None); XftDrawDestroy(xd); } int sk_textw(SKApp *app, XftFont *font, const char *s) { if (!s || !s[0]) return 0; XGlyphInfo ext; XftTextExtentsUtf8(app->dpy, font, (const FcChar8 *)s, (int)strlen(s), &ext); return ext.xOff; } int sk_baseline(XftFont *font, int y, int h) { return y + (h + font->ascent - font->descent) / 2; } int sk_in_rect(int mx, int my, int x, int y, int w, int h) { return mx >= x && mx < x + w && my >= y && my < y + h; } void sk_draw_btn(SKPainter *p, SKApp *app, XftFont *font, const SKBtn *b, int hovered, unsigned long bg, unsigned long bghov) { unsigned long bbg = hovered ? bghov : bg; sk_fill(p, bbg, b->x, b->y, b->w, b->h); sk_rect(p, SK_BORDER, b->x, b->y, b->w, b->h); int tx = b->x + (b->w - sk_textw(app, font, b->label)) / 2; sk_text(p, font, SK_TEXT_HDR, tx, sk_baseline(font, b->y, b->h), b->label); }