ref: edcf7d821652f17d23641dc193f769eb1e02be77
dir: /gui-wl/wl-screen.c/
#define _GNU_SOURCE
#include "u.h"
#include "lib.h"
#include "dat.h"
#include "fns.h"
#include "user.h"
#include <draw.h>
#include <memdraw.h>
#undef up
#include <wayland-client.h>
#include <wayland-client-protocol.h>
#include <linux/input-event-codes.h>
#include <xkbcommon/xkbcommon.h>
#include "xdg-shell-protocol.h"
#include "screen.h"
#include "wl-inc.h"
static Wlwin *gwin;
Memimage *gscreen;
static Wlwin*
newwlwin(void)
{
Wlwin *wl;
wl = mallocz(sizeof *wl, 1);
if(wl == nil)
panic("malloc Wlwin");
wl->dx = 1024;
wl->dy = 1024;
wl->monx = wl->dx;
wl->mony = wl->dy;
return wl;
}
void
wlclose(Wlwin *wl)
{
wl->runing = 0;
exits(nil);
}
void
wltogglemaximize(Wlwin *wl)
{
if(wl->maximized)
xdg_toplevel_unset_maximized(wl->xdg_toplevel);
else
xdg_toplevel_set_maximized(wl->xdg_toplevel);
}
void
wlminimize(Wlwin *wl)
{
xdg_toplevel_set_minimized(wl->xdg_toplevel);
}
void
wlmove(Wlwin *wl, uint32_t serial)
{
xdg_toplevel_move(wl->xdg_toplevel, wl->seat, serial);
}
void
wlmenu(Wlwin *wl, uint32_t serial)
{
xdg_toplevel_show_window_menu(wl->xdg_toplevel, wl->seat, serial, wl->mouse.xy.x, wl->mouse.xy.y);
}
static void
wlupdatecsdrects(Wlwin *wl)
{
Point offset;
Rectangle button;
if(!wl->client_side_deco) {
memset(&wl->csd_rects, 0, sizeof wl->csd_rects);
return;
}
wl->csd_rects.bar = Rect(0, 0, wl->dx, csd_bar_height);
offset = Pt(csd_button_width + 4, 0);
button = Rect(0, 4, csd_button_width, csd_button_width + 4);
button = rectsubpt(button, offset);
wl->csd_rects.button_close = button = rectaddpt(button, Pt(wl->dx, 0));
wl->csd_rects.button_maximize = button = rectsubpt(button, offset);
wl->csd_rects.button_minimize = rectsubpt(button, offset);
}
static void
wlfillrect(Wlwin *wl, Rectangle rect, uint32_t color)
{
Point p;
uint32_t *data = wl->shm_data;
for(p.y = rect.min.y; p.y < rect.max.y; p.y++)
for(p.x = rect.min.x; p.x < rect.max.x; p.x++)
data[p.y * wl->dx + p.x] = color;
}
static void
wldrawcsd(Wlwin *wl)
{
if(!wl->client_side_deco)
return;
wlfillrect(wl, wl->csd_rects.bar, 0xAAAAAA);
wlfillrect(wl, wl->csd_rects.button_close, DRed >> 8);
wlfillrect(wl, wl->csd_rects.button_maximize, DGreen >> 8);
wlfillrect(wl, wl->csd_rects.button_minimize, DYellow >> 8);
}
void
wlflush(Wlwin *wl)
{
Point p;
wl_surface_attach(wl->surface, wl->screenbuffer, 0, 0);
if(wl->dirty){
p.x = wl->r.min.x;
for(p.y = wl->r.min.y; p.y < wl->r.max.y; p.y++)
memcpy(wl->shm_data+(p.y*wl->dx+p.x)*4, byteaddr(gscreen, p), Dx(wl->r)*4);
wl_surface_damage(wl->surface, p.x, wl->r.min.y, Dx(wl->r), Dy(wl->r));
wl->dirty = 0;
}
wl_surface_commit(wl->surface);
}
void _screenresize(Rectangle);
void
wlresize(Wlwin *wl, int x, int y)
{
Rectangle r;
wl->dx = x;
wl->dy = y;
wlupdatecsdrects(wl);
qlock(&drawlock);
wlallocbuffer(wl);
r = Rect(0, wl->csd_rects.bar.max.y, wl->dx, wl->dy);
gscreen = allocmemimage(r, XRGB32);
gscreen->clipr = ZR;
qunlock(&drawlock);
screenresize(r);
qlock(&drawlock);
wl->dirty = 1;
wl->r = r;
wlflush(wl);
wldrawcsd(wl);
qunlock(&drawlock);
}
void
dispatchproc(void *a)
{
Wlwin *wl;
wl = a;
while(wl->runing)
wl_display_dispatch(wl->display);
}
static Wlwin*
wlattach(char *label)
{
Rectangle r;
Wlwin *wl;
wl = newwlwin();
gwin = wl;
wl->display = wl_display_connect(nil);
if(wl->display == nil)
panic("could not connect to display");
memimageinit();
wlsetcb(wl);
wlupdatecsdrects(wl);
wlflush(wl);
wlsettitle(wl, label);
r = Rect(0, wl->csd_rects.bar.max.y, wl->dx, wl->dy);
gscreen = allocmemimage(r, XRGB32);
gscreen->clipr = r;
gscreen->r = r;
rectclip(&(gscreen->clipr), gscreen->r);
wl->runing = 1;
kproc("wldispatch", dispatchproc, wl);
qlock(&drawlock);
terminit();
wlflush(wl);
wldrawcsd(wl);
qunlock(&drawlock);
return wl;
}
void
screeninit(void)
{
wlattach("drawterm");
}
void
guimain(void)
{
cpubody();
}
Memdata*
attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen)
{
*r = gscreen->clipr;
*chan = gscreen->chan;
*depth = gscreen->depth;
*width = gscreen->width;
*softscreen = 1;
gscreen->data->ref++;
return gscreen->data;
}
void
flushmemscreen(Rectangle r)
{
gwin->dirty = 1;
gwin->r = r;
wlflush(gwin);
}
void
screensize(Rectangle r, ulong chan)
{
flushmemscreen(r);
}
void
setcursor(void)
{
qlock(&drawlock);
wldrawcursor(gwin, &cursor);
qunlock(&drawlock);
}
void
mouseset(Point p)
{
wlsetmouse(gwin, p);
}
char*
clipread(void)
{
return wlgetsnarf(gwin);
}
int
clipwrite(char *data)
{
wlsetsnarf(gwin, data);
return strlen(data);
}
void
getcolor(ulong i, ulong *r, ulong *g, ulong *b)
{
}
void
setcolor(ulong index, ulong red, ulong green, ulong blue)
{
}