SDL_DirectFB_WM.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_window.h"
#include "../../events/SDL_windowevents_c.h"
#define COLOR_EXPAND(col) col.r, col.g, col.b, col.a
static DFB_Theme theme_std = {
4, 4, 8, 8,
{255, 200, 200, 200},
24,
{255, 0, 0, 255},
16,
{255, 255, 255, 255},
"/usr/share/fonts/truetype/freefont/FreeSans.ttf",
{255, 255, 0, 0},
{255, 255, 255, 0},
};
static DFB_Theme theme_none = {
0, 0, 0, 0,
{0, 0, 0, 0},
0,
{0, 0, 0, 0},
0,
{0, 0, 0, 0},
NULL
};
static void
DrawTriangle(IDirectFBSurface * s, int down, int x, int y, int w)
{
int x1, x2, x3;
int y1, y2, y3;
if (down) {
x1 = x + w / 2;
x2 = x;
x3 = x + w;
y1 = y + w;
y2 = y;
y3 = y;
} else {
x1 = x + w / 2;
x2 = x;
x3 = x + w;
y1 = y;
y2 = y + w;
y3 = y + w;
}
s->FillTriangle(s, x1, y1, x2, y2, x3, y3);
}
static void
LoadFont(_THIS, SDL_Window * window)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
if (windata->font != NULL) {
SDL_DFB_RELEASE(windata->font);
windata->font = NULL;
SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
}
if (windata->theme.font != NULL)
{
DFBFontDescription fdesc;
SDL_zero(fdesc);
fdesc.flags = DFDESC_HEIGHT;
fdesc.height = windata->theme.font_size;
SDL_DFB_CHECK(devdata->
dfb->CreateFont(devdata->dfb, windata->theme.font,
&fdesc, &windata->font));
SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
}
}
static void
DrawCraption(_THIS, IDirectFBSurface * s, int x, int y, char *text)
{
DFBSurfaceTextFlags flags;
flags = DSTF_CENTER | DSTF_TOP;
s->DrawString(s, text, -1, x, y, flags);
}
void
DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
IDirectFBSurface *s = windata->window_surface;
DFB_Theme *t = &windata->theme;
int i;
int d = (t->caption_size - t->font_size) / 2;
int x, y, w;
if (!windata->is_managed || (window->flags & SDL_WINDOW_FULLSCREEN))
return;
SDL_DFB_CHECK(s->SetSrcBlendFunction(s, DSBF_ONE));
SDL_DFB_CHECK(s->SetDstBlendFunction(s, DSBF_ZERO));
SDL_DFB_CHECK(s->SetDrawingFlags(s, DSDRAW_NOFX));
SDL_DFB_CHECK(s->SetBlittingFlags(s, DSBLIT_NOFX));
LoadFont(_this, window);
/* s->SetDrawingFlags(s, DSDRAW_BLEND); */
s->SetColor(s, COLOR_EXPAND(t->frame_color));
/* top */
for (i = 0; i < t->top_size; i++)
s->DrawLine(s, 0, i, windata->size.w, i);
/* bottom */
for (i = windata->size.h - t->bottom_size; i < windata->size.h; i++)
s->DrawLine(s, 0, i, windata->size.w, i);
/* left */
for (i = 0; i < t->left_size; i++)
s->DrawLine(s, i, 0, i, windata->size.h);
/* right */
for (i = windata->size.w - t->right_size; i < windata->size.w; i++)
s->DrawLine(s, i, 0, i, windata->size.h);
/* Caption */
s->SetColor(s, COLOR_EXPAND(t->caption_color));
s->FillRectangle(s, t->left_size, t->top_size, windata->client.w,
t->caption_size);
/* Close Button */
w = t->caption_size;
x = windata->size.w - t->right_size - w + d;
y = t->top_size + d;
s->SetColor(s, COLOR_EXPAND(t->close_color));
DrawTriangle(s, 1, x, y, w - 2 * d);
/* Max Button */
s->SetColor(s, COLOR_EXPAND(t->max_color));
DrawTriangle(s, window->flags & SDL_WINDOW_MAXIMIZED ? 1 : 0, x - w,
y, w - 2 * d);
/* Caption */
if (*window->title) {
s->SetColor(s, COLOR_EXPAND(t->font_color));
DrawCraption(_this, s, (x - w) / 2, t->top_size + d, window->title);
}
/* Icon */
if (windata->icon) {
DFBRectangle dr;
dr.x = t->left_size + d;
dr.y = t->top_size + d;
dr.w = w - 2 * d;
dr.h = w - 2 * d;
s->SetBlittingFlags(s, DSBLIT_BLEND_ALPHACHANNEL);
s->StretchBlit(s, windata->icon, NULL, &dr);
}
windata->wm_needs_redraw = 0;
}
DFBResult
DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch)
{
SDL_DFB_WINDOWDATA(window);
IDirectFBWindow *dfbwin = windata->dfbwin;
SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, cw, ch));
dfbwin->GetSize(dfbwin, cw, ch);
*cw -= windata->theme.left_size + windata->theme.right_size;
*ch -=
windata->theme.top_size + windata->theme.caption_size +
windata->theme.bottom_size;
return DFB_OK;
}
void
DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h)
{
SDL_DFB_WINDOWDATA(window);
if (!windata->is_managed)
windata->theme = theme_none;
else if (flags & SDL_WINDOW_BORDERLESS)
/* desc.caps |= DWCAPS_NODECORATION;) */
windata->theme = theme_none;
else if (flags & SDL_WINDOW_FULLSCREEN) {
windata->theme = theme_none;
} else if (flags & SDL_WINDOW_MAXIMIZED) {
windata->theme = theme_std;
windata->theme.left_size = 0;
windata->theme.right_size = 0;
windata->theme.top_size = 0;
windata->theme.bottom_size = 0;
} else {
windata->theme = theme_std;
}
windata->client.x = windata->theme.left_size;
windata->client.y = windata->theme.top_size + windata->theme.caption_size;
windata->client.w = w;
windata->client.h = h;
windata->size.w =
w + windata->theme.left_size + windata->theme.right_size;
windata->size.h =
h + windata->theme.top_size +
windata->theme.caption_size + windata->theme.bottom_size;
}
enum
{
WM_POS_NONE = 0x00,
WM_POS_CAPTION = 0x01,
WM_POS_CLOSE = 0x02,
WM_POS_MAX = 0x04,
WM_POS_LEFT = 0x08,
WM_POS_RIGHT = 0x10,
WM_POS_TOP = 0x20,
WM_POS_BOTTOM = 0x40,
};
static int
WMIsClient(DFB_WindowData * p, int x, int y)
{
x -= p->client.x;
y -= p->client.y;
if (x < 0 || y < 0)
return 0;
if (x >= p->client.w || y >= p->client.h)
return 0;
return 1;
}
static int
WMPos(DFB_WindowData * p, int x, int y)
{
int pos = WM_POS_NONE;
if (!WMIsClient(p, x, y)) {
if (y < p->theme.top_size) {
pos |= WM_POS_TOP;
} else if (y < p->client.y) {
if (x <
p->size.w - p->theme.right_size - 2 * p->theme.caption_size) {
pos |= WM_POS_CAPTION;
} else if (x <
p->size.w - p->theme.right_size -
p->theme.caption_size) {
pos |= WM_POS_MAX;
} else {
pos |= WM_POS_CLOSE;
}
} else if (y >= p->size.h - p->theme.bottom_size) {
pos |= WM_POS_BOTTOM;
}
if (x < p->theme.left_size) {
pos |= WM_POS_LEFT;
} else if (x >= p->size.w - p->theme.right_size) {
pos |= WM_POS_RIGHT;
}
}
return pos;
}
int
DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
IDirectFBWindow *dfbwin = windata->dfbwin;
DFBWindowOptions wopts;
if (!windata->is_managed)
return 0;
SDL_DFB_CHECK(dfbwin->GetOptions(dfbwin, &wopts));
switch (evt->type) {
case DWET_BUTTONDOWN:
if (evt->buttons & DIBM_LEFT) {
int pos = WMPos(windata, evt->x, evt->y);
switch (pos) {
case WM_POS_NONE:
return 0;
case WM_POS_CLOSE:
windata->wm_grab = WM_POS_NONE;
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0,
0);
return 1;
case WM_POS_MAX:
windata->wm_grab = WM_POS_NONE;
if (window->flags & SDL_WINDOW_MAXIMIZED) {
SDL_RestoreWindow(window);
} else {
SDL_MaximizeWindow(window);
}
return 1;
case WM_POS_CAPTION:
if (!(wopts & DWOP_KEEP_STACKING)) {
DirectFB_RaiseWindow(_this, window);
}
if (window->flags & SDL_WINDOW_MAXIMIZED)
return 1;
/* fall through */
default:
windata->wm_grab = pos;
if (gwindata != NULL)
SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
SDL_DFB_CHECK(dfbwin->GrabPointer(dfbwin));
windata->wm_lastx = evt->cx;
windata->wm_lasty = evt->cy;
}
}
return 1;
case DWET_BUTTONUP:
if (!windata->wm_grab)
return 0;
if (!(evt->buttons & DIBM_LEFT)) {
if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
int dx = evt->cx - windata->wm_lastx;
int dy = evt->cy - windata->wm_lasty;
if (!(wopts & DWOP_KEEP_SIZE)) {
int cw, ch;
if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
dx = 0;
else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
dy = 0;
SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
/* necessary to trigger an event - ugly */
SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx + 1, ch + dy));
SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
}
}
SDL_DFB_CHECK(dfbwin->UngrabPointer(dfbwin));
if (gwindata != NULL)
SDL_DFB_CHECK(gwindata->dfbwin->GrabPointer(gwindata->dfbwin));
windata->wm_grab = WM_POS_NONE;
return 1;
}
break;
case DWET_MOTION:
if (!windata->wm_grab)
return 0;
if (evt->buttons & DIBM_LEFT) {
int dx = evt->cx - windata->wm_lastx;
int dy = evt->cy - windata->wm_lasty;
if (windata->wm_grab & WM_POS_CAPTION) {
if (!(wopts & DWOP_KEEP_POSITION))
SDL_DFB_CHECK(dfbwin->Move(dfbwin, dx, dy));
}
if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
if (!(wopts & DWOP_KEEP_SIZE)) {
int cw, ch;
/* Make sure all events are disabled for this operation ! */
SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
dx = 0;
else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
dy = 0;
SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
}
}
windata->wm_lastx = evt->cx;
windata->wm_lasty = evt->cy;
return 1;
}
break;
case DWET_KEYDOWN:
break;
case DWET_KEYUP:
break;
default:
;
}
return 0;
}
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
DirectFB_WM_AdjustWindowLayout
void DirectFB_WM_AdjustWindowLayout(SDL_Window *window, int flags, int w, int h)
NULL
#define NULL
Definition: begin_code.h:167
DirectFB_WM_GetClientSize
DFBResult DirectFB_WM_GetClientSize(_THIS, SDL_Window *window, int *cw, int *ch)
SDL_WINDOWEVENT_CLOSE
@ SDL_WINDOWEVENT_CLOSE
Definition: SDL_video.h:167
SDL_WINDOW_FULLSCREEN
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:100
SDL_WINDOW_MAXIMIZED
@ SDL_WINDOW_MAXIMIZED
Definition: SDL_video.h:107
x1
GLuint GLfloat GLfloat GLfloat x1
Definition: SDL_opengl_glext.h:8583
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
SDL_DirectFB_window.h
DirectFB_RaiseWindow
void DirectFB_RaiseWindow(_THIS, SDL_Window *window)
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:73
p
GLfloat GLfloat p
Definition: SDL_opengl_glext.h:11090
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:118
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
t
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
SDL_DFB_RELEASE
#define SDL_DFB_RELEASE(x)
Definition: SDL_DirectFB_video.h:78
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
text
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:47
SDL_DFB_DEVICEDATA
#define SDL_DFB_DEVICEDATA(dev)
Definition: SDL_DirectFB_video.h:126
SDL_RestoreWindow
#define SDL_RestoreWindow
Definition: SDL_dynapi_overrides.h:538
SDL_DFB_CHECK
#define SDL_DFB_CHECK(x...)
Definition: SDL_DirectFB_video.h:99
SDL_DFB_WINDOWDATA
#define SDL_DFB_WINDOWDATA(win)
Definition: SDL_DirectFB_window.h:28
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:537
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
x2
GLfixed GLfixed x2
Definition: SDL_opengl_glext.h:4583
s
GLdouble s
Definition: SDL_opengl.h:2063
DirectFB_WM_RedrawLayout
void DirectFB_WM_RedrawLayout(_THIS, SDL_Window *window)
y1
GLfixed y1
Definition: SDL_opengl_glext.h:4583
SDL_MaximizeWindow
#define SDL_MaximizeWindow
Definition: SDL_dynapi_overrides.h:536
SDL_SendWindowEvent
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
Definition: SDL_windowevents.c:74
y2
GLfixed GLfixed GLfixed y2
Definition: SDL_opengl_glext.h:4583
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
DirectFB_WM_ProcessEvent
int DirectFB_WM_ProcessEvent(_THIS, SDL_Window *window, DFBWindowEvent *evt)
SDL_DirectFB_video.h
d
const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char const char const SDL_SCANF_FORMAT_STRING char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
Definition: SDL_dynapi_procs.h:117
SDL_WINDOW_BORDERLESS
@ SDL_WINDOW_BORDERLESS
Definition: SDL_video.h:104
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731