SDL_rpivideo.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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_RPI
/* References
* http://elinux.org/RPi_VideoCore_APIs
* https://github.com/raspberrypi/firmware/blob/master/opt/vc/src/hello_pi/hello_triangle/triangle.c
* http://cgit.freedesktop.org/wayland/weston/tree/src/rpi-renderer.c
* http://cgit.freedesktop.org/wayland/weston/tree/src/compositor-rpi.c
*/
/* SDL internals */
#include "../SDL_sysvideo.h"
#include "SDL_version.h"
#include "SDL_syswm.h"
#include "SDL_loadso.h"
#include "SDL_events.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
#ifdef SDL_INPUT_LINUXEV
#include "../../core/linux/SDL_evdev.h"
#endif
/* RPI declarations */
#include "SDL_rpivideo.h"
#include "SDL_rpievents_c.h"
#include "SDL_rpiopengles.h"
#include "SDL_rpimouse.h"
static int
RPI_Available(void)
{
return 1;
}
static void
RPI_Destroy(SDL_VideoDevice * device)
{
/* SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */
if (device->driverdata != NULL) {
device->driverdata = NULL;
}
}
static SDL_VideoDevice *
RPI_Create()
{
SDL_VideoDevice *device;
SDL_VideoData *phdata;
/* Initialize SDL_VideoDevice structure */
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
if (device == NULL) {
SDL_OutOfMemory();
return NULL;
}
/* Initialize internal data */
phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
if (phdata == NULL) {
SDL_OutOfMemory();
SDL_free(device);
return NULL;
}
device->driverdata = phdata;
/* Setup amount of available displays and current display */
device->num_displays = 0;
/* Set device free function */
device->free = RPI_Destroy;
/* Setup all functions which we can handle */
device->VideoInit = RPI_VideoInit;
device->VideoQuit = RPI_VideoQuit;
device->GetDisplayModes = RPI_GetDisplayModes;
device->SetDisplayMode = RPI_SetDisplayMode;
device->CreateWindow = RPI_CreateWindow;
device->CreateWindowFrom = RPI_CreateWindowFrom;
device->SetWindowTitle = RPI_SetWindowTitle;
device->SetWindowIcon = RPI_SetWindowIcon;
device->SetWindowPosition = RPI_SetWindowPosition;
device->SetWindowSize = RPI_SetWindowSize;
device->ShowWindow = RPI_ShowWindow;
device->HideWindow = RPI_HideWindow;
device->RaiseWindow = RPI_RaiseWindow;
device->MaximizeWindow = RPI_MaximizeWindow;
device->MinimizeWindow = RPI_MinimizeWindow;
device->RestoreWindow = RPI_RestoreWindow;
device->SetWindowGrab = RPI_SetWindowGrab;
device->DestroyWindow = RPI_DestroyWindow;
device->GetWindowWMInfo = RPI_GetWindowWMInfo;
device->GL_LoadLibrary = RPI_GLES_LoadLibrary;
device->GL_GetProcAddress = RPI_GLES_GetProcAddress;
device->GL_UnloadLibrary = RPI_GLES_UnloadLibrary;
device->GL_CreateContext = RPI_GLES_CreateContext;
device->GL_MakeCurrent = RPI_GLES_MakeCurrent;
device->GL_SetSwapInterval = RPI_GLES_SetSwapInterval;
device->GL_GetSwapInterval = RPI_GLES_GetSwapInterval;
device->GL_SwapWindow = RPI_GLES_SwapWindow;
device->GL_DeleteContext = RPI_GLES_DeleteContext;
device->PumpEvents = RPI_PumpEvents;
return device;
}
VideoBootStrap RPI_bootstrap = {
"RPI",
"RPI Video Driver",
RPI_Available,
RPI_Create
};
/*****************************************************************************/
/* SDL Video and Display initialization/handling functions */
/*****************************************************************************/
int
RPI_VideoInit(_THIS)
{
SDL_VideoDisplay display;
SDL_DisplayMode current_mode;
SDL_DisplayData *data;
uint32_t w,h;
/* Initialize BCM Host */
bcm_host_init();
SDL_zero(current_mode);
if (graphics_get_display_size( 0, &w, &h) < 0) {
return -1;
}
current_mode.w = w;
current_mode.h = h;
/* FIXME: Is there a way to tell the actual refresh rate? */
current_mode.refresh_rate = 60;
/* 32 bpp for default */
current_mode.format = SDL_PIXELFORMAT_ABGR8888;
current_mode.driverdata = NULL;
SDL_zero(display);
display.desktop_mode = current_mode;
display.current_mode = current_mode;
/* Allocate display internal data */
data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
if (data == NULL) {
return SDL_OutOfMemory();
}
data->dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
display.driverdata = data;
SDL_AddVideoDisplay(&display);
#ifdef SDL_INPUT_LINUXEV
SDL_EVDEV_Init();
#endif
RPI_InitMouse(_this);
return 1;
}
void
RPI_VideoQuit(_THIS)
{
#ifdef SDL_INPUT_LINUXEV
SDL_EVDEV_Quit();
#endif
}
void
RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
/* Only one display mode available, the current one */
SDL_AddDisplayMode(display, &display->current_mode);
}
int
RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
return 0;
}
int
RPI_CreateWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *wdata;
SDL_VideoDisplay *display;
SDL_DisplayData *displaydata;
VC_RECT_T dst_rect;
VC_RECT_T src_rect;
VC_DISPMANX_ALPHA_T dispman_alpha;
DISPMANX_UPDATE_HANDLE_T dispman_update;
/* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */
dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
dispman_alpha.opacity = 0xFF;
dispman_alpha.mask = 0;
/* Allocate window internal data */
wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
if (wdata == NULL) {
return SDL_OutOfMemory();
}
display = SDL_GetDisplayForWindow(window);
displaydata = (SDL_DisplayData *) display->driverdata;
/* Windows have one size for now */
window->w = display->desktop_mode.w;
window->h = display->desktop_mode.h;
/* OpenGL ES is the law here, buddy */
window->flags |= SDL_WINDOW_OPENGL;
/* Create a dispman element and associate a window to it */
dst_rect.x = 0;
dst_rect.y = 0;
dst_rect.width = window->w;
dst_rect.height = window->h;
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = window->w << 16;
src_rect.height = window->h << 16;
dispman_update = vc_dispmanx_update_start( 0 );
wdata->dispman_window.element = vc_dispmanx_element_add ( dispman_update, displaydata->dispman_display, SDL_RPI_VIDEOLAYER /* layer */, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, &dispman_alpha /*alpha*/, 0/*clamp*/, 0/*transform*/);
wdata->dispman_window.width = window->w;
wdata->dispman_window.height = window->h;
vc_dispmanx_update_submit_sync( dispman_update );
if (!_this->egl_data) {
if (SDL_GL_LoadLibrary(NULL) < 0) {
return -1;
}
}
wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) &wdata->dispman_window);
if (wdata->egl_surface == EGL_NO_SURFACE) {
return SDL_SetError("Could not create GLES window surface");
}
/* Setup driver data for this window */
window->driverdata = wdata;
/* One window, it always has focus */
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);
/* Window has been successfully created */
return 0;
}
void
RPI_DestroyWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if(data) {
#if SDL_VIDEO_OPENGL_EGL
if (data->egl_surface != EGL_NO_SURFACE) {
SDL_EGL_DestroySurface(_this, data->egl_surface);
}
#endif
SDL_free(data);
window->driverdata = NULL;
}
}
int
RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
return -1;
}
void
RPI_SetWindowTitle(_THIS, SDL_Window * window)
{
}
void
RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
}
void
RPI_SetWindowPosition(_THIS, SDL_Window * window)
{
}
void
RPI_SetWindowSize(_THIS, SDL_Window * window)
{
}
void
RPI_ShowWindow(_THIS, SDL_Window * window)
{
}
void
RPI_HideWindow(_THIS, SDL_Window * window)
{
}
void
RPI_RaiseWindow(_THIS, SDL_Window * window)
{
}
void
RPI_MaximizeWindow(_THIS, SDL_Window * window)
{
}
void
RPI_MinimizeWindow(_THIS, SDL_Window * window)
{
}
void
RPI_RestoreWindow(_THIS, SDL_Window * window)
{
}
void
RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
}
/*****************************************************************************/
/* SDL Window Manager function */
/*****************************************************************************/
SDL_bool
RPI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
{
if (info->version.major <= SDL_MAJOR_VERSION) {
return SDL_TRUE;
} else {
SDL_SetError("application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
/* Failed to get window manager information */
return SDL_FALSE;
}
#endif /* SDL_VIDEO_DRIVER_RPI */
/* vi: set ts=4 sw=4 expandtab: */
SDL_RPI_VIDEOLAYER
#define SDL_RPI_VIDEOLAYER
Definition: SDL_rpivideo.h:53
SDL_MINOR_VERSION
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
RPI_DestroyWindow
void RPI_DestroyWindow(_THIS, SDL_Window *window)
RPI_RestoreWindow
void RPI_RestoreWindow(_THIS, SDL_Window *window)
SDL_VideoDevice::RestoreWindow
void(* RestoreWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:208
RPI_GLES_GetProcAddress
void * RPI_GLES_GetProcAddress(_THIS, const char *proc)
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:612
RPI_CreateWindowFrom
int RPI_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
SDL_Window::w
int w
Definition: SDL_sysvideo.h:78
RPI_SetWindowTitle
void RPI_SetWindowTitle(_THIS, SDL_Window *window)
SDL_DisplayMode::w
int w
Definition: SDL_video.h:56
RPI_SetWindowGrab
void RPI_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
RPI_GLES_LoadLibrary
int RPI_GLES_LoadLibrary(_THIS, const char *path)
SDL_MAJOR_VERSION
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
SDL_VideoDevice::CreateWindowFrom
int(* CreateWindowFrom)(_THIS, SDL_Window *window, const void *data)
Definition: SDL_sysvideo.h:196
window
SDL_Window * window
Definition: testautomation_render.c:26
SDL_VideoDevice::free
void(* free)(_THIS)
Definition: SDL_sysvideo.h:345
RPI_GLES_UnloadLibrary
void RPI_GLES_UnloadLibrary(_THIS)
RPI_GetDisplayModes
void RPI_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:332
SDL_events.h
SDL_VideoDevice::GL_SetSwapInterval
int(* GL_SetSwapInterval)(_THIS, int interval)
Definition: SDL_sysvideo.h:240
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
RPI_GLES_MakeCurrent
int RPI_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
SDL_VideoDevice::ShowWindow
void(* ShowWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:203
SDL_DisplayMode
The structure that defines a display mode.
Definition: SDL_video.h:53
SDL_SysWMinfo::version
SDL_version version
Definition: SDL_syswm.h:183
SDL_version::major
Uint8 major
Definition: SDL_version.h:53
SDL_VideoDevice::SetWindowSize
void(* SetWindowSize)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:200
SDL_DisplayMode::refresh_rate
int refresh_rate
Definition: SDL_video.h:58
RPI_RaiseWindow
void RPI_RaiseWindow(_THIS, SDL_Window *window)
RPI_GLES_GetSwapInterval
int RPI_GLES_GetSwapInterval(_THIS)
RPI_MaximizeWindow
void RPI_MaximizeWindow(_THIS, SDL_Window *window)
SDL_SetMouseFocus
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:103
SDL_VideoDevice::GL_SwapWindow
void(* GL_SwapWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:242
SDL_GL_LoadLibrary
#define SDL_GL_LoadLibrary
Definition: SDL_dynapi_overrides.h:557
SDL_AddVideoDisplay
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:593
SDL_VideoDevice::GL_LoadLibrary
int(* GL_LoadLibrary)(_THIS, const char *path)
Definition: SDL_sysvideo.h:234
RPI_VideoInit
int RPI_VideoInit(_THIS)
SDL_DisplayData
Definition: SDL_cocoamodes.h:26
SDL_VideoDevice::SetDisplayMode
int(* SetDisplayMode)(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
Definition: SDL_sysvideo.h:189
SDL_WindowData
Definition: SDL_androidwindow.h:34
RPI_SetWindowIcon
void RPI_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:114
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:126
SDL_VideoDevice::HideWindow
void(* HideWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:204
SDL_VideoDevice::RaiseWindow
void(* RaiseWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:205
SDL_rpiopengles.h
SDL_calloc
void * SDL_calloc(size_t nmemb, size_t size)
SDL_VideoDevice::GetWindowWMInfo
SDL_bool(* GetWindowWMInfo)(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
Definition: SDL_sysvideo.h:227
SDL_VideoDevice::GL_CreateContext
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:237
SDL_SysWMinfo
Definition: SDL_syswm.h:181
SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:253
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
RPI_PumpEvents
void RPI_PumpEvents(_THIS)
SDL_VideoDevice::GL_MakeCurrent
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
Definition: SDL_sysvideo.h:238
SDL_free
void SDL_free(void *mem)
SDL_WindowData::dispman_window
EGL_DISPMANX_WINDOW_T dispman_window
Definition: SDL_rpivideo.h:47
SDL_DisplayMode::driverdata
void * driverdata
Definition: SDL_video.h:59
RPI_HideWindow
void RPI_HideWindow(_THIS, SDL_Window *window)
VideoBootStrap
Definition: SDL_sysvideo.h:348
SDL_VideoDevice::num_displays
int num_displays
Definition: SDL_sysvideo.h:279
RPI_SetWindowSize
void RPI_SetWindowSize(_THIS, SDL_Window *window)
SDL_VideoDisplay::current_mode
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:127
mode
GLenum mode
Definition: SDL_opengl_glext.h:1122
SDL_VideoDevice::DestroyWindow
void(* DestroyWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:214
RPI_GLES_DeleteContext
void RPI_GLES_DeleteContext(_THIS, SDL_GLContext context)
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:355
SDL_DisplayMode::h
int h
Definition: SDL_video.h:57
SDL_VideoDevice::SetWindowIcon
void(* SetWindowIcon)(_THIS, SDL_Window *window, SDL_Surface *icon)
Definition: SDL_sysvideo.h:198
SDL_DisplayData::dispman_display
DISPMANX_DISPLAY_HANDLE_T dispman_display
Definition: SDL_rpivideo.h:41
SDL_TRUE
Definition: SDL_stdinc.h:129
RPI_VideoQuit
void RPI_VideoQuit(_THIS)
SDL_VideoDisplay
Definition: SDL_sysvideo.h:120
SDL_Window::h
int h
Definition: SDL_sysvideo.h:78
SDL_VideoDevice::GL_UnloadLibrary
void(* GL_UnloadLibrary)(_THIS)
Definition: SDL_sysvideo.h:236
SDL_VideoDevice::GetDisplayModes
void(* GetDisplayModes)(_THIS, SDL_VideoDisplay *display)
Definition: SDL_sysvideo.h:181
NULL
#define NULL
Definition: begin_code.h:143
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
RPI_GLES_SwapWindow
void RPI_GLES_SwapWindow(_THIS, SDL_Window *window)
SDL_VideoDisplay::desktop_mode
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:126
uint32_t
unsigned int uint32_t
Definition: SDL_config_windows.h:62
SDL_VideoDevice::VideoQuit
void(* VideoQuit)(_THIS)
Definition: SDL_sysvideo.h:161
RPI_ShowWindow
void RPI_ShowWindow(_THIS, SDL_Window *window)
RPI_MinimizeWindow
void RPI_MinimizeWindow(_THIS, SDL_Window *window)
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:36
SDL_loadso.h
RPI_SetDisplayMode
int RPI_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
SDL_GetDisplayForWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1039
SDL_VideoDevice::SetWindowPosition
void(* SetWindowPosition)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:199
SDL_VideoDevice::CreateWindow
int(* CreateWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:195
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:71
RPI_GLES_CreateContext
SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window *window)
SDL_VideoDevice::MinimizeWindow
void(* MinimizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:207
SDL_FALSE
Definition: SDL_stdinc.h:128
SDL_VideoDevice
Definition: SDL_sysvideo.h:142
SDL_VideoData
Definition: SDL_androidvideo.h:35
RPI_CreateWindow
int RPI_CreateWindow(_THIS, SDL_Window *window)
SDL_AddDisplayMode
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:709
SDL_VideoDevice::VideoInit
int(* VideoInit)(_THIS)
Definition: SDL_sysvideo.h:155
SDL_version.h
SDL_WINDOW_OPENGL
Definition: SDL_video.h:99
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731
SDL_Window::driverdata
void * driverdata
Definition: SDL_sysvideo.h:106
SDL_VideoDevice::GL_DeleteContext
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
Definition: SDL_sysvideo.h:243
SDL_rpievents_c.h
SDL_DisplayMode::format
Uint32 format
Definition: SDL_video.h:55
SDL_VideoDevice::SetWindowTitle
void(* SetWindowTitle)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:197
SDL_VideoDevice::GL_GetSwapInterval
int(* GL_GetSwapInterval)(_THIS)
Definition: SDL_sysvideo.h:241
SDL_VideoDevice::MaximizeWindow
void(* MaximizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:206
SDL_Window::flags
Uint32 flags
Definition: SDL_sysvideo.h:81
RPI_GetWindowWMInfo
SDL_bool RPI_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
RPI_SetWindowPosition
void RPI_SetWindowPosition(_THIS, SDL_Window *window)
SDL_rpimouse.h
SDL_VideoDevice::SetWindowGrab
void(* SetWindowGrab)(_THIS, SDL_Window *window, SDL_bool grabbed)
Definition: SDL_sysvideo.h:213
SDL_syswm.h
RPI_InitMouse
void RPI_InitMouse(_THIS)
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
SDL_rpivideo.h
SDL_VideoDevice::GL_GetProcAddress
void *(* GL_GetProcAddress)(_THIS, const char *proc)
Definition: SDL_sysvideo.h:235
SDL_WindowData::egl_surface
EGLSurface egl_surface
Definition: SDL_androidwindow.h:36
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:133
SDL_VideoDevice::PumpEvents
void(* PumpEvents)(_THIS)
Definition: SDL_sysvideo.h:249
RPI_GLES_SetSwapInterval
int RPI_GLES_SetSwapInterval(_THIS, int interval)