/*
* secde -- experimental lightweight Wayland/X11 server
* Copyright (C) 2019 Samuel Lidén Borell
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include "fbops.h"
struct FbAddrInfo {
/* TODO support for non byte addressable pixel formats */
unsigned char *start;
};
int fbops_cliprect(struct FbRect *rect,
const struct FbRect *clip)
{
int end, clipend;
/* Left */
if (rect->x < clip->x) {
int diff = clip->x - rect->x;
rect->x += diff;
if (rect->w <= diff) return 0;
rect->w -= diff;
}
/* Top */
if (rect->y < clip->y) {
int diff = clip->y - rect->y;
rect->y += diff;
if (rect->h <= diff) return 0;
rect->h -= diff;
}
/* Right */
end = rect->x + rect->w;
clipend = clip->x + clip->w;
if (end < clipend) {
int diff = clipend - end;
if (rect->w <= diff) return 0;
rect->w -= diff;
}
/* Bottom */
end = rect->y + rect->h;
clipend = clip->y + clip->h;
if (end < clipend) {
int diff = clipend - end;
if (rect->h <= diff) return 0;
rect->h -= diff;
}
return 1;
}
int fbops_cliprect1(struct FbRect *destrect,
struct FbRect *srcrect,
const struct FbRect *destclip)
{
(void) destrect;
(void) srcrect;
(void) destclip;
/* TODO */
return 0;
}
static unsigned char *getaddr(const struct FbPixelFormat *format,
const struct FbSurf *surf,
short x, short y)
{
return &surf->pixels[surf->line_length*y +
format->bytes_per_pixel*x];
}
void fbops_fillrect(struct FbDestSurf *destsurf,
const struct FbRect *rect,
const FbColor color)
{
unsigned char *p = getaddr(destsurf->format, destsurf->surf,
rect->x, rect->y);
short h = rect->h;
short len = rect->w * destsurf->format->bytes_per_pixel;
short linelen = destsurf->surf->line_length;
if (color <= 255) { /* high bits zero = direct byte value */
while (h--) {
memset(p, color, len);
p += linelen;
}
} else {
while (h--) {
/* TODO */
p += linelen;
}
}
}
void fbops_copysurf(struct FbDestSurf *destsurf,
short x, short y,
const struct FbSurf *srcsurf)
{
struct FbRect srcrect = { 0, 0, srcsurf->w, srcsurf->h };
fbops_copysurf1(destsurf, x, y, srcsurf, &srcrect);
}
void fbops_copysurf1(struct FbDestSurf *destsurf,
short x, short y,
const struct FbSurf *srcsurf,
const struct FbRect *srcrect)
{
short h = srcrect->h;
short d_linelen = destsurf->surf->line_length;
short s_linelen = srcsurf->line_length;
short len = srcrect->w * destsurf->format->bytes_per_pixel;
unsigned char *dp, *sp;
dp = getaddr(destsurf->format, destsurf->surf, x, y);
sp = getaddr(destsurf->format, srcsurf,
srcrect->x, srcrect->y);
while (h--) {
memcpy(dp, sp, len);
dp += d_linelen;
sp += s_linelen;
}
}
void fbops_moverect(struct FbDestSurf *destsurf,
short destx, short desty,
const struct FbRect *srcrect)
{
short sx = srcrect->x;
short sy = srcrect->y;
short w = srcrect->w;
short h = srcrect->h;
if (desty < sy ||
destx+w < sx || sx+w > destx ||
desty+h < sy || sy+h > desty) {
/* Non-overlapping copy, or copying "down".
In this case we can use a plain copysurf */
fbops_copysurf1(destsurf, destx, desty, destsurf->surf, srcrect);
return;
}
/* TODO */
}