forked from bartvdbraak/blender
629 lines
25 KiB
C++
629 lines
25 KiB
C++
/*
|
|
* $Id: GHOST_WindowSDL.cpp 38349 2011-07-13 00:49:22Z gsrb3d $
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
*
|
|
* 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 2
|
|
* 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, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Contributor(s): Campbell Barton
|
|
*
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
*/
|
|
|
|
/** \file ghost/intern/GHOST_WindowSDL.cpp
|
|
* \ingroup GHOST
|
|
*/
|
|
|
|
#include "GHOST_WindowSDL.h"
|
|
#include "SDL_mouse.h"
|
|
#include <assert.h>
|
|
|
|
static SDL_GLContext s_firstContext= NULL;
|
|
|
|
GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system,
|
|
const STR_String& title,
|
|
GHOST_TInt32 left,
|
|
GHOST_TInt32 top,
|
|
GHOST_TUns32 width,
|
|
GHOST_TUns32 height,
|
|
GHOST_TWindowState state,
|
|
const GHOST_TEmbedderWindowID parentWindow,
|
|
GHOST_TDrawingContextType type,
|
|
const bool stereoVisual,
|
|
const GHOST_TUns16 numOfAASamples
|
|
)
|
|
:
|
|
GHOST_Window(width,height,state,type,stereoVisual,numOfAASamples),
|
|
m_system (system),
|
|
m_invalid_window(false),
|
|
m_sdl_custom_cursor(NULL)
|
|
{
|
|
m_sdl_win= SDL_CreateWindow(title,
|
|
left,
|
|
top,
|
|
width,
|
|
height,
|
|
SDL_WINDOW_RESIZABLE|SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN);
|
|
|
|
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
|
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
|
|
|
m_sdl_glcontext= SDL_GL_CreateContext(m_sdl_win);
|
|
|
|
//fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
|
|
// theEvent->error_code, theEvent->request_code) ;
|
|
|
|
setTitle(title);
|
|
}
|
|
|
|
GHOST_WindowSDL::~GHOST_WindowSDL()
|
|
{
|
|
if(m_sdl_custom_cursor) {
|
|
SDL_FreeCursor(m_sdl_custom_cursor);
|
|
}
|
|
|
|
if (m_sdl_glcontext != s_firstContext) {
|
|
SDL_GL_DeleteContext(m_sdl_glcontext);
|
|
}
|
|
|
|
SDL_DestroyWindow(m_sdl_win);
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::installDrawingContext(GHOST_TDrawingContextType type)
|
|
{
|
|
// only support openGL for now.
|
|
GHOST_TSuccess success;
|
|
switch (type) {
|
|
case GHOST_kDrawingContextTypeOpenGL:
|
|
m_sdl_glcontext= SDL_GL_CreateContext(m_sdl_win);
|
|
|
|
if (m_sdl_glcontext != NULL) {
|
|
if (!s_firstContext) {
|
|
s_firstContext= m_sdl_glcontext;
|
|
}
|
|
|
|
success= (SDL_GL_MakeCurrent(m_sdl_win, m_sdl_glcontext) < 0) ?
|
|
GHOST_kFailure : GHOST_kSuccess;
|
|
}
|
|
else {
|
|
success= GHOST_kFailure;
|
|
}
|
|
|
|
break;
|
|
|
|
case GHOST_kDrawingContextTypeNone:
|
|
success= GHOST_kSuccess;
|
|
break;
|
|
|
|
default:
|
|
success= GHOST_kFailure;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::invalidate(void)
|
|
{
|
|
// So the idea of this function is to generate an expose event
|
|
// for the window.
|
|
// Unfortunately X does not handle expose events for you and
|
|
// it is the client's job to refresh the dirty part of the window.
|
|
// We need to queue up invalidate calls and generate GHOST events
|
|
// for them in the system.
|
|
|
|
// We implement this by setting a boolean in this class to concatenate
|
|
// all such calls into a single event for this window.
|
|
|
|
// At the same time we queue the dirty windows in the system class
|
|
// and generate events for them at the next processEvents call.
|
|
|
|
if (m_invalid_window == false) {
|
|
m_system->addDirtyWindow(this);
|
|
m_invalid_window= true;
|
|
}
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::swapBuffers()
|
|
{
|
|
if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) {
|
|
SDL_GL_SwapWindow(m_sdl_win);
|
|
return GHOST_kSuccess;
|
|
}
|
|
else {
|
|
return GHOST_kFailure;
|
|
}
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::activateDrawingContext()
|
|
{
|
|
if (m_sdl_glcontext !=NULL) {
|
|
int status=SDL_GL_MakeCurrent(m_sdl_win, m_sdl_glcontext);
|
|
(void)status;
|
|
return GHOST_kSuccess;
|
|
}
|
|
return GHOST_kFailure;
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::removeDrawingContext()
|
|
{
|
|
GHOST_TSuccess success;
|
|
|
|
if (m_sdl_glcontext != NULL) {
|
|
SDL_GL_DeleteContext(m_sdl_glcontext);
|
|
success= GHOST_kSuccess;
|
|
}
|
|
else {
|
|
success= GHOST_kFailure;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::setState(GHOST_TWindowState state)
|
|
{
|
|
switch(state) {
|
|
case GHOST_kWindowStateNormal:
|
|
SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE);
|
|
SDL_RestoreWindow(m_sdl_win);
|
|
break;
|
|
case GHOST_kWindowStateMaximized:
|
|
SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE);
|
|
SDL_MaximizeWindow(m_sdl_win);
|
|
break;
|
|
case GHOST_kWindowStateMinimized:
|
|
SDL_MinimizeWindow(m_sdl_win);
|
|
break;
|
|
case GHOST_kWindowStateFullScreen:
|
|
SDL_SetWindowFullscreen(m_sdl_win, SDL_TRUE);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
|
|
GHOST_TWindowState
|
|
GHOST_WindowSDL::getState() const
|
|
{
|
|
Uint32 flags= SDL_GetWindowFlags(m_sdl_win);
|
|
|
|
if(flags & SDL_WINDOW_FULLSCREEN) return GHOST_kWindowStateFullScreen;
|
|
else if(flags & SDL_WINDOW_MAXIMIZED) return GHOST_kWindowStateMaximized;
|
|
else if(flags & SDL_WINDOW_MINIMIZED) return GHOST_kWindowStateMinimized;
|
|
return GHOST_kWindowStateNormal;
|
|
}
|
|
|
|
|
|
void
|
|
GHOST_WindowSDL::setTitle(const STR_String& title)
|
|
{
|
|
SDL_SetWindowTitle(m_sdl_win, title.ReadPtr());
|
|
}
|
|
|
|
|
|
void
|
|
GHOST_WindowSDL::getTitle(STR_String& title) const
|
|
{
|
|
title= SDL_GetWindowTitle(m_sdl_win);
|
|
}
|
|
|
|
|
|
void
|
|
GHOST_WindowSDL::getWindowBounds(GHOST_Rect& bounds) const
|
|
{
|
|
getClientBounds(bounds);
|
|
}
|
|
|
|
|
|
void
|
|
GHOST_WindowSDL::getClientBounds(GHOST_Rect& bounds) const
|
|
{
|
|
int x, y, w, h;
|
|
SDL_GetWindowSize(m_sdl_win, &w, &h);
|
|
SDL_GetWindowPosition(m_sdl_win, &x, &y);
|
|
|
|
bounds.m_l= x;
|
|
bounds.m_r= x + w;
|
|
bounds.m_t= y;
|
|
bounds.m_b= y + h;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::setClientWidth(GHOST_TUns32 width)
|
|
{
|
|
int height;
|
|
SDL_GetWindowSize(m_sdl_win, NULL, &height);
|
|
SDL_SetWindowSize(m_sdl_win, width, height);
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::setClientHeight(GHOST_TUns32 height)
|
|
{
|
|
int width;
|
|
SDL_GetWindowSize(m_sdl_win, &width, NULL);
|
|
SDL_SetWindowSize(m_sdl_win, width, height);
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::setClientSize(GHOST_TUns32 width,
|
|
GHOST_TUns32 height)
|
|
{
|
|
SDL_SetWindowSize(m_sdl_win, width, height);
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
void
|
|
GHOST_WindowSDL::screenToClient( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const
|
|
{
|
|
/* XXXSDL_WEAK_ABS_COORDS */
|
|
int x_win, y_win;
|
|
SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win);
|
|
|
|
outX = inX - x_win;
|
|
outY = inY - y_win;
|
|
}
|
|
void
|
|
GHOST_WindowSDL::clientToScreen( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const
|
|
{
|
|
/* XXXSDL_WEAK_ABS_COORDS */
|
|
int x_win, y_win;
|
|
SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win);
|
|
|
|
outX = inX + x_win;
|
|
outY = inY + y_win;
|
|
}
|
|
|
|
/* mouse cursor */
|
|
static unsigned char sdl_std_cursor_mask_xterm[]= {0xef,0x01,0xff,0x01,0xff,0x01,0x7c,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x7c,0x00,0xff,0x01,0xff,0x01,0xef,0x01,};
|
|
static unsigned char sdl_std_cursor_xterm[]= {0x00,0x77,0x00,0x1c,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x1c,0x00,0x77,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_xterm 9
|
|
#define sdl_std_cursor_HEIGHT_xterm 16
|
|
#define sdl_std_cursor_HOT_X_xterm -3
|
|
#define sdl_std_cursor_HOT_Y_xterm -7
|
|
|
|
static unsigned char sdl_std_cursor_mask_watch[]= {0xfc,0x0f,0xfc,0x0f,0xfc,0x0f,0xfe,0x1f,0xff,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfe,0x1f,0xfc,0x0f,0xfc,0x0f,0xfc,0x0f,};
|
|
static unsigned char sdl_std_cursor_watch[]= {0xf8,0x07,0xf8,0x07,0xf8,0x07,0xfc,0x0f,0x86,0x18,0x83,0x30,0x81,0xe0,0xc1,0xe1,0xc1,0xe1,0x21,0xe0,0x13,0x30,0x06,0x18,0xfc,0x0f,0xf8,0x07,0xf8,0x07,0xf8,0x07,};
|
|
#define sdl_std_cursor_WIDTH_watch 16
|
|
#define sdl_std_cursor_HEIGHT_watch 16
|
|
#define sdl_std_cursor_HOT_X_watch -15
|
|
#define sdl_std_cursor_HOT_Y_watch -7
|
|
|
|
static unsigned char sdl_std_cursor_mask_umbrella[]= {0xe8,0x76,0xfb,0xdf,0xfd,0x3f,0xfe,0xff,0xff,0x3f,0xff,0xff,0xcf,0x79,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x07,0xc0,0x07,0xc0,0x07,0xc0,0x07,0x80,0x03,};
|
|
static unsigned char sdl_std_cursor_umbrella[]= {0x88,0x04,0x20,0x0a,0xc9,0x32,0xf2,0x09,0x4c,0x06,0x43,0x18,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x01,0x40,0x01,0x80,0x00,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_umbrella 16
|
|
#define sdl_std_cursor_HEIGHT_umbrella 16
|
|
#define sdl_std_cursor_HOT_X_umbrella -7
|
|
#define sdl_std_cursor_HOT_Y_umbrella -12
|
|
|
|
static unsigned char sdl_std_cursor_mask_top_side[]= {0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f,0xc0,0x01,0xe0,0x03,0xf0,0x07,0xf8,0x0f,0xdc,0x1d,0xcc,0x19,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,};
|
|
static unsigned char sdl_std_cursor_top_side[]= {0xff,0x1f,0xff,0x1f,0x00,0x00,0x40,0x00,0xe0,0x00,0x50,0x01,0x48,0x02,0x44,0x04,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_top_side 15
|
|
#define sdl_std_cursor_HEIGHT_top_side 16
|
|
#define sdl_std_cursor_HOT_X_top_side -6
|
|
#define sdl_std_cursor_HOT_Y_top_side -14
|
|
|
|
static unsigned char sdl_std_cursor_mask_top_right_corner[]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf0,0xfc,0xf7,0xfc,0xf7,0xfc,0xf7,0xc0,0xf7,0xe0,0xf7,0x70,0xf7,0x38,0xf7,0x1c,0xf7,0x0c,0xf7,0x00,0xf0,0x00,0xf0,};
|
|
static unsigned char sdl_std_cursor_top_right_corner[]= {0xff,0x3f,0xff,0x3f,0x00,0x30,0x00,0x30,0x00,0x30,0xfc,0x31,0x80,0x31,0x40,0x31,0x20,0x31,0x10,0x31,0x08,0x31,0x04,0x31,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_top_right_corner 16
|
|
#define sdl_std_cursor_HEIGHT_top_right_corner 16
|
|
#define sdl_std_cursor_HOT_X_top_right_corner -13
|
|
#define sdl_std_cursor_HOT_Y_top_right_corner -14
|
|
|
|
static unsigned char sdl_std_cursor_mask_top_left_corner[]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0xef,0x3f,0xef,0x3f,0xef,0x3f,0xef,0x03,0xef,0x07,0xef,0x0e,0xef,0x1c,0xef,0x38,0xef,0x30,0x0f,0x00,0x0f,0x00,};
|
|
static unsigned char sdl_std_cursor_top_left_corner[]= {0xff,0x3f,0xff,0x3f,0x03,0x00,0x03,0x00,0x03,0x00,0xe3,0x0f,0x63,0x00,0xa3,0x00,0x23,0x01,0x23,0x02,0x23,0x04,0x23,0x08,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_top_left_corner 16
|
|
#define sdl_std_cursor_HEIGHT_top_left_corner 16
|
|
#define sdl_std_cursor_HOT_X_top_left_corner 0
|
|
#define sdl_std_cursor_HOT_Y_top_left_corner -14
|
|
|
|
static unsigned char sdl_std_cursor_mask_spraycan[]= {0x00,0x0c,0x18,0x0d,0x7c,0x0d,0x7c,0x0d,0x7e,0x0d,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,};
|
|
static unsigned char sdl_std_cursor_spraycan[]= {0x00,0x06,0x80,0x00,0x2c,0x06,0x9e,0x00,0x16,0x06,0x3f,0x00,0x21,0x00,0x27,0x00,0x25,0x00,0x27,0x00,0x25,0x00,0x27,0x00,0x27,0x00,0x21,0x00,0x21,0x00,0x3f,0x00,};
|
|
#define sdl_std_cursor_WIDTH_spraycan 12
|
|
#define sdl_std_cursor_HEIGHT_spraycan 16
|
|
#define sdl_std_cursor_HOT_X_spraycan -9
|
|
#define sdl_std_cursor_HOT_Y_spraycan -14
|
|
|
|
static unsigned char sdl_std_cursor_mask_sb_v_double_arrow[]= {0x38,0x00,0x7c,0x00,0xfe,0x00,0xff,0x01,0xff,0x01,0x7c,0x00,0x7c,0x00,0x7c,0x00,0x7c,0x00,0x7c,0x00,0xff,0x01,0xff,0x01,0xfe,0x00,0x7c,0x00,0x38,0x00,};
|
|
static unsigned char sdl_std_cursor_sb_v_double_arrow[]= {0x10,0x00,0x38,0x00,0x7c,0x00,0xfe,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0xfe,0x00,0x7c,0x00,0x38,0x00,0x10,0x00,};
|
|
#define sdl_std_cursor_WIDTH_sb_v_double_arrow 9
|
|
#define sdl_std_cursor_HEIGHT_sb_v_double_arrow 15
|
|
#define sdl_std_cursor_HOT_X_sb_v_double_arrow -3
|
|
#define sdl_std_cursor_HOT_Y_sb_v_double_arrow -8
|
|
|
|
static unsigned char sdl_std_cursor_mask_sb_h_double_arrow[]= {0x18,0x0c,0x1c,0x1c,0xfe,0x3f,0xff,0x7f,0xff,0x7f,0xff,0x7f,0xfe,0x3f,0x1c,0x1c,0x18,0x0c,};
|
|
static unsigned char sdl_std_cursor_sb_h_double_arrow[]= {0x00,0x00,0x08,0x08,0x0c,0x18,0xfe,0x3f,0x0f,0x78,0xfe,0x3f,0x0c,0x18,0x08,0x08,0x00,0x00};
|
|
#define sdl_std_cursor_WIDTH_sb_h_double_arrow 15
|
|
#define sdl_std_cursor_HEIGHT_sb_h_double_arrow 9
|
|
#define sdl_std_cursor_HOT_X_sb_h_double_arrow -7
|
|
#define sdl_std_cursor_HOT_Y_sb_h_double_arrow -4
|
|
|
|
static unsigned char sdl_std_cursor_mask_right_side[]= {0x00,0xf0,0x00,0xf0,0xc0,0xf0,0xc0,0xf1,0x80,0xf3,0x00,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf7,0x80,0xf3,0xc0,0xf1,0xc0,0xf0,0x00,0xf0,0x00,0xf0,};
|
|
static unsigned char sdl_std_cursor_right_side[]= {0x00,0x30,0x00,0x30,0x40,0x30,0x80,0x30,0x00,0x31,0x00,0x32,0xff,0x37,0x00,0x32,0x00,0x31,0x80,0x30,0x40,0x30,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_right_side 16
|
|
#define sdl_std_cursor_HEIGHT_right_side 15
|
|
#define sdl_std_cursor_HOT_X_right_side -13
|
|
#define sdl_std_cursor_HOT_Y_right_side -7
|
|
|
|
static unsigned char sdl_std_cursor_mask_right_ptr[]= {0x00,0x03,0x80,0x03,0xc0,0x03,0xe0,0x03,0xf0,0x03,0xf8,0x03,0xfc,0x03,0xfe,0x03,0xff,0x03,0xff,0x03,0xf8,0x03,0xbc,0x03,0x3c,0x03,0x1e,0x00,0x1e,0x00,0x0c,0x00,};
|
|
static unsigned char sdl_std_cursor_right_ptr[]= {0x00,0x80,0x00,0xc0,0x00,0xe0,0x00,0xf0,0x00,0xf8,0x00,0xfc,0x00,0xfe,0x00,0xff,0x00,0xf8,0x00,0xd8,0x00,0x8c,0x00,0x0c,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_right_ptr 10
|
|
#define sdl_std_cursor_HEIGHT_right_ptr 16
|
|
#define sdl_std_cursor_HOT_X_right_ptr -7
|
|
#define sdl_std_cursor_HOT_Y_right_ptr -14
|
|
|
|
static unsigned char sdl_std_cursor_mask_question_arrow[]= {0xf8,0x00,0xfc,0x01,0xfe,0x03,0xff,0x07,0x8f,0x07,0x9f,0x07,0xde,0x07,0xfc,0x03,0xf8,0x01,0xf8,0x00,0xf8,0x00,0xfc,0x01,0xfe,0x03,0xfc,0x01,0xf8,0x00,0x70,0x00,};
|
|
static unsigned char sdl_std_cursor_question_arrow[]= {0x7c,0x00,0xfe,0x00,0xc7,0x01,0x83,0x01,0x87,0x01,0xc6,0x01,0xe0,0x00,0x78,0x00,0x38,0x00,0x28,0x00,0x28,0x00,0xee,0x00,0x6c,0x00,0x38,0x00,0x10,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_question_arrow 11
|
|
#define sdl_std_cursor_HEIGHT_question_arrow 16
|
|
#define sdl_std_cursor_HOT_X_question_arrow -4
|
|
#define sdl_std_cursor_HOT_Y_question_arrow -8
|
|
|
|
static unsigned char sdl_std_cursor_mask_pirate[]= {0xf0,0x03,0xf8,0x07,0xfc,0x0f,0xfe,0x1f,0xfe,0x1f,0xfc,0x0f,0xf8,0x07,0xf1,0x83,0xf1,0xe3,0xf3,0xf3,0xef,0x39,0x1e,0x1e,0xe0,0x01,0xfe,0xc7,0xff,0xff,0x0f,0x7c,};
|
|
static unsigned char sdl_std_cursor_pirate[]= {0xe0,0x01,0xf0,0x03,0xf8,0x07,0xcc,0x0c,0xcc,0x0c,0xf8,0x07,0xf0,0x03,0xe0,0x01,0xe1,0x21,0xe1,0x61,0xc2,0x10,0x1c,0x0e,0xe0,0x01,0xf8,0x47,0x0f,0x7c,0x01,0x20,};
|
|
#define sdl_std_cursor_WIDTH_pirate 16
|
|
#define sdl_std_cursor_HEIGHT_pirate 16
|
|
#define sdl_std_cursor_HOT_X_pirate -7
|
|
#define sdl_std_cursor_HOT_Y_pirate -4
|
|
|
|
static unsigned char sdl_std_cursor_mask_left_side[]= {0x0f,0x00,0x0f,0x00,0x0f,0x03,0x8f,0x03,0xcf,0x01,0xef,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x00,0xcf,0x01,0x8f,0x03,0x0f,0x03,0x0f,0x00,0x0f,0x00,};
|
|
static unsigned char sdl_std_cursor_left_side[]= {0x03,0x00,0x03,0x00,0x83,0x00,0x43,0x00,0x23,0x00,0x13,0x00,0xfb,0x3f,0x13,0x00,0x23,0x00,0x43,0x00,0x83,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_left_side 16
|
|
#define sdl_std_cursor_HEIGHT_left_side 15
|
|
#define sdl_std_cursor_HOT_X_left_side 0
|
|
#define sdl_std_cursor_HOT_Y_left_side -7
|
|
|
|
static unsigned char sdl_std_cursor_mask_left_ptr[]= {0x03,0x00,0x07,0x00,0x0f,0x00,0x1f,0x00,0x3f,0x00,0x7f,0x00,0xff,0x00,0xff,0x01,0xff,0x03,0xff,0x03,0x7f,0x00,0xf7,0x00,0xf3,0x00,0xe0,0x01,0xe0,0x01,0xc0,0x00,};
|
|
static unsigned char sdl_std_cursor_left_ptr[]= {0x00,0x00,0x02,0x00,0x06,0x00,0x0e,0x00,0x1e,0x00,0x3e,0x00,0x7e,0x00,0xfe,0x00,0xfe,0x00,0x3e,0x00,0x36,0x00,0x62,0x00,0x60,0x00,0xc0,0x00,0xc0,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_left_ptr 10
|
|
#define sdl_std_cursor_HEIGHT_left_ptr 16
|
|
#define sdl_std_cursor_HOT_X_left_ptr -8
|
|
#define sdl_std_cursor_HOT_Y_left_ptr -14
|
|
|
|
static unsigned char sdl_std_cursor_mask_exchange[]= {0xe3,0x07,0xf7,0x0f,0xff,0x1f,0xff,0x3f,0x3f,0x38,0xff,0x30,0xff,0x00,0xff,0x00,0x00,0xff,0x00,0xff,0x0c,0xfe,0x1c,0xfc,0xfc,0xff,0xf8,0xff,0xf0,0xef,0xe0,0xc7,};
|
|
static unsigned char sdl_std_cursor_exchange[]= {0xf1,0x03,0xfb,0x07,0x1f,0x0c,0x09,0x08,0x19,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x26,0x04,0x24,0x0c,0x3e,0xf8,0x37,0xf0,0x23,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_exchange 16
|
|
#define sdl_std_cursor_HEIGHT_exchange 16
|
|
#define sdl_std_cursor_HOT_X_exchange -6
|
|
#define sdl_std_cursor_HOT_Y_exchange -8
|
|
|
|
static unsigned char sdl_std_cursor_mask_crosshair[]= {0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,};
|
|
static unsigned char sdl_std_cursor_crosshair[]= {0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x7f,0xff,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_crosshair 16
|
|
#define sdl_std_cursor_HEIGHT_crosshair 16
|
|
#define sdl_std_cursor_HOT_X_crosshair -7
|
|
#define sdl_std_cursor_HOT_Y_crosshair -8
|
|
|
|
static unsigned char sdl_std_cursor_mask_bottom_side[]= {0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xcc,0x19,0xdc,0x1d,0xf8,0x0f,0xf0,0x07,0xe0,0x03,0xc0,0x01,0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f,};
|
|
static unsigned char sdl_std_cursor_bottom_side[]= {0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x44,0x04,0x48,0x02,0x50,0x01,0xe0,0x00,0x40,0x00,0x00,0x00,0xff,0x1f,0xff,0x1f,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_bottom_side 15
|
|
#define sdl_std_cursor_HEIGHT_bottom_side 16
|
|
#define sdl_std_cursor_HOT_X_bottom_side -6
|
|
#define sdl_std_cursor_HOT_Y_bottom_side -1
|
|
|
|
static unsigned char sdl_std_cursor_mask_bottom_right_corner[]= {0x00,0xf0,0x00,0xf0,0x0c,0xf7,0x1c,0xf7,0x38,0xf7,0x70,0xf7,0xe0,0xf7,0xc0,0xf7,0xfc,0xf7,0xfc,0xf7,0xfc,0xf7,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,};
|
|
static unsigned char sdl_std_cursor_bottom_right_corner[]= {0x00,0x30,0x00,0x30,0x04,0x31,0x08,0x31,0x10,0x31,0x20,0x31,0x40,0x31,0x80,0x31,0xfc,0x31,0x00,0x30,0x00,0x30,0x00,0x30,0xff,0x3f,0xff,0x3f,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_bottom_right_corner 16
|
|
#define sdl_std_cursor_HEIGHT_bottom_right_corner 16
|
|
#define sdl_std_cursor_HOT_X_bottom_right_corner -13
|
|
#define sdl_std_cursor_HOT_Y_bottom_right_corner -1
|
|
|
|
static unsigned char sdl_std_cursor_mask_bottom_left_corner[]= {0x0f,0x00,0x0f,0x00,0xef,0x30,0xef,0x38,0xef,0x1c,0xef,0x0e,0xef,0x07,0xef,0x03,0xef,0x3f,0xef,0x3f,0xef,0x3f,0x0f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,};
|
|
static unsigned char sdl_std_cursor_bottom_left_corner[]= {0x03,0x00,0x03,0x00,0x23,0x08,0x23,0x04,0x23,0x02,0x23,0x01,0xa3,0x00,0x63,0x00,0xe3,0x0f,0x03,0x00,0x03,0x00,0x03,0x00,0xff,0x3f,0xff,0x3f,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_bottom_left_corner 16
|
|
#define sdl_std_cursor_HEIGHT_bottom_left_corner 16
|
|
#define sdl_std_cursor_HOT_X_bottom_left_corner 0
|
|
#define sdl_std_cursor_HOT_Y_bottom_left_corner -1
|
|
|
|
static unsigned char sdl_std_cursor_mask_arrow[]= {0x00,0xe0,0x00,0xf8,0x00,0xfe,0x80,0x7f,0xe0,0x7f,0xf8,0x3f,0xfc,0x3f,0xfc,0x1f,0xe0,0x1f,0xf0,0x0f,0xf8,0x0f,0x7c,0x07,0x3e,0x07,0x1f,0x02,0x0e,0x00,0x04,0x00,};
|
|
static unsigned char sdl_std_cursor_arrow[]= {0x00,0x30,0x00,0x3c,0x00,0x1f,0xc0,0x1f,0xf0,0x0f,0xfc,0x0f,0xc0,0x07,0xe0,0x07,0x70,0x03,0x38,0x03,0x1c,0x01,0x0e,0x01,0x07,0x00,0x02,0x00,0x00,0x00,0x00,0x00,};
|
|
#define sdl_std_cursor_WIDTH_arrow 16
|
|
#define sdl_std_cursor_HEIGHT_arrow 16
|
|
#define sdl_std_cursor_HOT_X_arrow -13
|
|
#define sdl_std_cursor_HOT_Y_arrow -14
|
|
/* end cursor data */
|
|
|
|
|
|
static SDL_Cursor *sdl_std_cursor_array[(int)GHOST_kStandardCursorNumCursors]= {0};
|
|
|
|
/* utility function mostly a copy of SDL_CreateCursor but allows us to change
|
|
* color and supports blenders flipped bits */
|
|
static SDL_Cursor *
|
|
sdl_ghost_CreateCursor(const Uint8 *data,
|
|
const Uint8 *mask,
|
|
int w,
|
|
int h,
|
|
int hot_x,
|
|
int hot_y)
|
|
{
|
|
SDL_Surface *surface;
|
|
SDL_Cursor *cursor;
|
|
int x, y;
|
|
Uint32 *pixel;
|
|
Uint8 datab= 0, maskb= 0;
|
|
const Uint32 black= 0xFF000000;
|
|
const Uint32 white= 0xFFFFFFFF;
|
|
const Uint32 transparent= 0x00000000;
|
|
|
|
/* Make sure the width is a multiple of 8 */
|
|
w= ((w + 7) & ~7);
|
|
|
|
/* Create the surface from a bitmap */
|
|
surface= SDL_CreateRGBSurface(0, w, h, 32,
|
|
0x00FF0000,
|
|
0x0000FF00,
|
|
0x000000FF,
|
|
0xFF000000);
|
|
if (!surface) {
|
|
return NULL;
|
|
}
|
|
for (y= 0; y < h; ++y) {
|
|
pixel= (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
|
|
for (x= 0; x < w; ++x) {
|
|
if ((x % 8) == 0) {
|
|
datab= *data++;
|
|
maskb= *mask++;
|
|
|
|
/* reverse bit order */
|
|
datab= (datab * 0x0202020202ULL & 0x010884422010ULL) % 1023;
|
|
maskb= (maskb * 0x0202020202ULL & 0x010884422010ULL) % 1023;
|
|
}
|
|
if (maskb & 0x80) {
|
|
*pixel++= (datab & 0x80) ? white : black;
|
|
}
|
|
else {
|
|
*pixel++= (datab & 0x80) ? white : transparent;
|
|
}
|
|
datab <<= 1;
|
|
maskb <<= 1;
|
|
}
|
|
}
|
|
|
|
cursor= SDL_CreateColorCursor(surface, hot_x, hot_y);
|
|
|
|
SDL_FreeSurface(surface);
|
|
|
|
return cursor;
|
|
}
|
|
|
|
/* TODO, this is currently never freed but it wont leak either. */
|
|
static void sdl_cursor_init(void)
|
|
{
|
|
|
|
#define DEF_CURSOR(name, ind) \
|
|
assert(\
|
|
(\
|
|
sdl_std_cursor_array[(int)ind]= \
|
|
sdl_ghost_CreateCursor(sdl_std_cursor_##name, \
|
|
sdl_std_cursor_mask_##name, \
|
|
sdl_std_cursor_WIDTH_##name, \
|
|
sdl_std_cursor_HEIGHT_##name, \
|
|
(sdl_std_cursor_WIDTH_##name + (sdl_std_cursor_HOT_X_##name)) - 1, \
|
|
(sdl_std_cursor_HEIGHT_##name + (sdl_std_cursor_HOT_Y_##name)) - 1) \
|
|
) != NULL) \
|
|
|
|
|
|
DEF_CURSOR(left_ptr, GHOST_kStandardCursorDefault);
|
|
DEF_CURSOR(right_ptr, GHOST_kStandardCursorRightArrow);
|
|
DEF_CURSOR(left_ptr, GHOST_kStandardCursorLeftArrow);
|
|
DEF_CURSOR(umbrella, GHOST_kStandardCursorInfo); // TODO, replace this one.
|
|
DEF_CURSOR(pirate, GHOST_kStandardCursorDestroy);
|
|
DEF_CURSOR(question_arrow, GHOST_kStandardCursorHelp);
|
|
DEF_CURSOR(exchange, GHOST_kStandardCursorCycle);
|
|
DEF_CURSOR(spraycan, GHOST_kStandardCursorSpray);
|
|
DEF_CURSOR(watch, GHOST_kStandardCursorWait);
|
|
DEF_CURSOR(xterm, GHOST_kStandardCursorText);
|
|
DEF_CURSOR(crosshair, GHOST_kStandardCursorCrosshair);
|
|
DEF_CURSOR(sb_v_double_arrow, GHOST_kStandardCursorUpDown);
|
|
DEF_CURSOR(sb_h_double_arrow, GHOST_kStandardCursorLeftRight);
|
|
DEF_CURSOR(top_side, GHOST_kStandardCursorTopSide);
|
|
DEF_CURSOR(bottom_side, GHOST_kStandardCursorBottomSide);
|
|
DEF_CURSOR(left_side, GHOST_kStandardCursorLeftSide);
|
|
DEF_CURSOR(right_side, GHOST_kStandardCursorRightSide);
|
|
DEF_CURSOR(top_left_corner, GHOST_kStandardCursorTopLeftCorner);
|
|
DEF_CURSOR(top_right_corner, GHOST_kStandardCursorTopRightCorner);
|
|
DEF_CURSOR(bottom_right_corner, GHOST_kStandardCursorBottomRightCorner);
|
|
DEF_CURSOR(bottom_left_corner , GHOST_kStandardCursorBottomLeftCorner);
|
|
DEF_CURSOR(arrow , GHOST_kStandardCursorCopy);
|
|
//DEF_CURSOR(arrow, GHOST_kStandardCursorCustom);
|
|
DEF_CURSOR(arrow, GHOST_kStandardCursorPencil);
|
|
|
|
#undef DEF_CURSOR
|
|
|
|
}
|
|
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
|
|
{
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::setWindowCursorShape(GHOST_TStandardCursor shape)
|
|
{
|
|
if(sdl_std_cursor_array[0] == NULL) {
|
|
sdl_cursor_init();
|
|
}
|
|
|
|
SDL_SetCursor(sdl_std_cursor_array[(int)shape]);
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
|
|
GHOST_TUns8 mask[16][2],
|
|
int hotX,
|
|
int hotY)
|
|
{
|
|
return setWindowCustomCursorShape((GHOST_TUns8 *)bitmap,
|
|
(GHOST_TUns8 *)mask,
|
|
16, 16,
|
|
hotX, hotY,
|
|
0, 1);
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
|
|
GHOST_TUns8 *mask,
|
|
int sizex, int sizey,
|
|
int hotX, int hotY,
|
|
int fg_color, int bg_color)
|
|
{
|
|
if(m_sdl_custom_cursor) {
|
|
SDL_FreeCursor(m_sdl_custom_cursor);
|
|
}
|
|
|
|
m_sdl_custom_cursor= sdl_ghost_CreateCursor((const Uint8 *)bitmap,
|
|
(const Uint8 *)mask,
|
|
sizex, sizex,
|
|
hotX, hotY);
|
|
|
|
SDL_SetCursor(m_sdl_custom_cursor);
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowSDL::setWindowCursorVisibility(bool visible)
|
|
{
|
|
SDL_ShowCursor(visible);
|
|
return GHOST_kSuccess;
|
|
}
|