|
|
@@ -32,8 +32,7 @@
|
|
|
#include "polycode/core/PolyBasicFileProvider.h"
|
|
|
#include "polycode/core/PolyPhysFSFileProvider.h"
|
|
|
|
|
|
-#include <SDL/SDL.h>
|
|
|
-#include <SDL/SDL_syswm.h>
|
|
|
+#include <SDL2/SDL.h>
|
|
|
#include <stdio.h>
|
|
|
#include <limits.h>
|
|
|
#include <dirent.h>
|
|
|
@@ -46,27 +45,6 @@
|
|
|
#include <sys/wait.h>
|
|
|
#include <pwd.h>
|
|
|
|
|
|
-#ifdef USE_X11
|
|
|
- // SDL scrap
|
|
|
- #define T(A, B, C, D) (int)((A<<24)|(B<<16)|(C<<8)|(D<<0))
|
|
|
-
|
|
|
- int init_scrap(void);
|
|
|
- int lost_scrap(void);
|
|
|
- void put_scrap(int type, int srclen, const char *src);
|
|
|
- void get_scrap(int type, int *dstlen, char **dst);
|
|
|
- // end SDL scrap
|
|
|
-
|
|
|
-// X11 cursor
|
|
|
-#include <X11/cursorfont.h>
|
|
|
-
|
|
|
-namespace {
|
|
|
- void set_cursor(int cursorType);
|
|
|
- void free_cursors();
|
|
|
-} // namespace
|
|
|
-// end X11 cursor
|
|
|
-
|
|
|
-#endif
|
|
|
-
|
|
|
using namespace Polycode;
|
|
|
using std::vector;
|
|
|
|
|
|
@@ -85,11 +63,13 @@ long getThreadID() {
|
|
|
}
|
|
|
|
|
|
void Core::getScreenInfo(int *width, int *height, int *hz) {
|
|
|
- SDL_Init(SDL_INIT_VIDEO); // Or GetVideoInfo will not work
|
|
|
- const SDL_VideoInfo *video = SDL_GetVideoInfo();
|
|
|
- if (width) *width = video->current_w;
|
|
|
- if (height) *height = video->current_h;
|
|
|
- if (hz) *hz = 0;
|
|
|
+ SDL_DisplayMode current;
|
|
|
+
|
|
|
+ SDL_GetCurrentDisplayMode(0, ¤t);
|
|
|
+
|
|
|
+ if (width) *width = current.w;
|
|
|
+ if (height) *height = current.h;
|
|
|
+ if (hz) *hz = current.refresh_rate;
|
|
|
}
|
|
|
|
|
|
SDLCore::SDLCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen, bool vSync, int aaLevel, int anisotropyLevel, int frameRate, int monitorIndex, bool retinaSupport) : Core(_xRes, _yRes, fullScreen, vSync, aaLevel, anisotropyLevel, frameRate, monitorIndex) {
|
|
|
@@ -115,16 +95,14 @@ SDLCore::SDLCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen, bool
|
|
|
setenv("SDL_VIDEO_CENTERED", "1", 1);
|
|
|
}
|
|
|
|
|
|
+ sdlContext = nullptr;
|
|
|
+ sdlWindow = nullptr;
|
|
|
+
|
|
|
int sdlerror = SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
|
|
|
if(sdlerror < 0) {
|
|
|
Logger::log("SDL_Init failed! Code: %d, %s\n", sdlerror, SDL_GetError());
|
|
|
}
|
|
|
|
|
|
- SDL_Surface* icon = SDL_LoadBMP("icon.bmp");
|
|
|
- if(icon){
|
|
|
- SDL_WM_SetIcon(icon, NULL);
|
|
|
- }
|
|
|
-
|
|
|
eventMutex = createMutex();
|
|
|
|
|
|
renderer = new Renderer();
|
|
|
@@ -134,11 +112,6 @@ SDLCore::SDLCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen, bool
|
|
|
services->setRenderer(renderer);
|
|
|
setVideoMode(xRes, yRes, fullScreen, vSync, aaLevel, anisotropyLevel, retinaSupport);
|
|
|
|
|
|
- SDL_WM_SetCaption(windowTitle->c_str(), windowTitle->c_str());
|
|
|
-
|
|
|
- SDL_EnableUNICODE(1);
|
|
|
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
|
|
-
|
|
|
SDL_JoystickEventState(SDL_ENABLE);
|
|
|
|
|
|
int numJoysticks = SDL_NumJoysticks();
|
|
|
@@ -152,13 +125,6 @@ SDLCore::SDLCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen, bool
|
|
|
|
|
|
lastMouseX = 0;
|
|
|
lastMouseY = 0;
|
|
|
-
|
|
|
-#ifdef USE_X11
|
|
|
- // Start listening to clipboard events.
|
|
|
- // (Yes on X11 you need to actively listen to
|
|
|
- // clipboard events and respond to them)
|
|
|
- init_scrap();
|
|
|
-#endif // USE_X11
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -186,32 +152,55 @@ void SDLCore::handleVideoModeChange(VideoModeChangeInfo* modeInfo){
|
|
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
|
|
}
|
|
|
|
|
|
- flags = SDL_OPENGL;
|
|
|
+ flags = SDL_WINDOW_OPENGL;
|
|
|
|
|
|
if(fullScreen) {
|
|
|
- flags |= SDL_FULLSCREEN;
|
|
|
+ flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
|
|
}
|
|
|
|
|
|
if(resizableWindow) {
|
|
|
- flags |= SDL_RESIZABLE;
|
|
|
+ flags |= SDL_WINDOW_RESIZABLE;
|
|
|
}
|
|
|
|
|
|
-// if(modeInfo->retinaSupport) {
|
|
|
-// flags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
|
|
-// }
|
|
|
-/*
|
|
|
- if(vSync) {
|
|
|
- flags |= SDL_DOUBLEBUF;
|
|
|
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
|
- SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
|
|
|
+ if(modeInfo->retinaSupport) {
|
|
|
+ flags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(vSync){
|
|
|
+ if(SDL_GL_SetSwapInterval(-1) == -1){
|
|
|
+ SDL_GL_SetSwapInterval(1);
|
|
|
+ }
|
|
|
} else {
|
|
|
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
|
|
|
- - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
|
|
|
+ SDL_GL_SetSwapInterval(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!sdlWindow) {
|
|
|
+ sdlWindow = SDL_CreateWindow(windowTitle->c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, xRes, yRes, flags);
|
|
|
+ sdlContext = SDL_GL_CreateContext(sdlWindow);
|
|
|
+ SDL_Surface* icon = SDL_LoadBMP("icon.bmp");
|
|
|
+ if(icon){
|
|
|
+ SDL_SetWindowIcon(sdlWindow, icon);
|
|
|
+ } else {
|
|
|
+ Logger::log("icon error: %s\n",SDL_GetError());
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ SDL_SetWindowSize(sdlWindow, xRes, yRes);
|
|
|
}
|
|
|
-*/
|
|
|
-
|
|
|
- SDL_SetVideoMode(xRes, yRes, 0, flags);
|
|
|
|
|
|
+ int x, y;
|
|
|
+ SDL_GL_GetDrawableSize(sdlWindow, &x, &y);
|
|
|
+ if(x >= xRes){
|
|
|
+ backingX = x;
|
|
|
+ }else{
|
|
|
+ backingX = xRes;
|
|
|
+ }
|
|
|
+ if(y >= yRes){
|
|
|
+ backingY = y;
|
|
|
+ }else{
|
|
|
+ backingY = yRes;
|
|
|
+ }
|
|
|
+
|
|
|
int glewcode = glewInit();
|
|
|
if (glewcode != GLEW_OK){
|
|
|
Logger::log("glewInit failed! code: %d, %s\n", glewcode, glewGetErrorString(glewcode));
|
|
|
@@ -224,12 +213,12 @@ void SDLCore::handleVideoModeChange(VideoModeChangeInfo* modeInfo){
|
|
|
vector<Polycode::Rectangle> SDLCore::getVideoModes() {
|
|
|
vector<Polycode::Rectangle> retVector;
|
|
|
|
|
|
- SDL_Rect **modes;
|
|
|
- modes=SDL_ListModes(NULL, SDL_FULLSCREEN);
|
|
|
- for(int i=0;modes[i];++i) {
|
|
|
+ SDL_DisplayMode modes;
|
|
|
+ for(int i=0;i<SDL_GetNumDisplayModes(0);++i) {
|
|
|
+ SDL_GetDisplayMode(0, i, &modes);
|
|
|
Rectangle res;
|
|
|
- res.w = modes[i]->w;
|
|
|
- res.h = modes[i]->h;
|
|
|
+ res.w = modes.w;
|
|
|
+ res.h = modes.h;
|
|
|
retVector.push_back(res);
|
|
|
}
|
|
|
|
|
|
@@ -240,6 +229,8 @@ SDLCore::~SDLCore() {
|
|
|
#ifdef USE_X11
|
|
|
free_cursors();
|
|
|
#endif // USE_X11
|
|
|
+ SDL_GL_DeleteContext(sdlContext);
|
|
|
+ SDL_DestroyWindow(sdlWindow);
|
|
|
SDL_Quit();
|
|
|
}
|
|
|
|
|
|
@@ -285,7 +276,7 @@ int SDLThreadFunc(void *data) {
|
|
|
}
|
|
|
|
|
|
void SDLCore::createThread(Threaded *target) {
|
|
|
- SDL_CreateThread(SDLThreadFunc, (void*)target);
|
|
|
+ SDL_CreateThread(SDLThreadFunc, "PolycodeThread", (void*)target);
|
|
|
}
|
|
|
|
|
|
unsigned int SDLCore::getTicks() {
|
|
|
@@ -295,19 +286,17 @@ unsigned int SDLCore::getTicks() {
|
|
|
void SDLCore::enableMouse(bool newval) {
|
|
|
if(newval) {
|
|
|
SDL_ShowCursor(1);
|
|
|
- //SDL_WM_GrabInput(SDL_GRAB_OFF);
|
|
|
} else {
|
|
|
SDL_ShowCursor(0);
|
|
|
- //SDL_WM_GrabInput(SDL_GRAB_ON);
|
|
|
}
|
|
|
Core::enableMouse(newval);
|
|
|
}
|
|
|
|
|
|
void SDLCore::captureMouse(bool newval) {
|
|
|
if(newval) {
|
|
|
- SDL_WM_GrabInput(SDL_GRAB_ON);
|
|
|
+ SDL_SetWindowGrab(sdlWindow, SDL_TRUE);
|
|
|
} else {
|
|
|
- SDL_WM_GrabInput(SDL_GRAB_OFF);
|
|
|
+ SDL_SetWindowGrab(sdlWindow, SDL_FALSE);
|
|
|
}
|
|
|
Core::captureMouse(newval);
|
|
|
}
|
|
|
@@ -354,7 +343,7 @@ void SDLCore::Render() {
|
|
|
}
|
|
|
|
|
|
void SDLCore::flushRenderContext(){
|
|
|
- SDL_GL_SwapBuffers();
|
|
|
+ SDL_GL_SwapWindow(sdlWindow);
|
|
|
}
|
|
|
|
|
|
bool SDLCore::systemUpdate() {
|
|
|
@@ -370,26 +359,41 @@ bool SDLCore::systemUpdate() {
|
|
|
case SDL_QUIT:
|
|
|
running = false;
|
|
|
break;
|
|
|
- case SDL_VIDEORESIZE:
|
|
|
- if(resizableWindow) {
|
|
|
- unsetenv("SDL_VIDEO_CENTERED");
|
|
|
- } else {
|
|
|
- setenv("SDL_VIDEO_CENTERED", "1", 1);
|
|
|
- }
|
|
|
- this->xRes = event.resize.w;
|
|
|
- this->yRes = event.resize.h;
|
|
|
- SDL_SetVideoMode(xRes, yRes, 0, flags);
|
|
|
- dispatchEvent(new Event(), EVENT_CORE_RESIZE);
|
|
|
- break;
|
|
|
- case SDL_ACTIVEEVENT:
|
|
|
- if(event.active.state == SDL_APPINPUTFOCUS){
|
|
|
- if(event.active.gain == 1){
|
|
|
+ case SDL_WINDOWEVENT:
|
|
|
+ switch(event.window.event){
|
|
|
+ case SDL_WINDOWEVENT_RESIZED:
|
|
|
+ if(resizableWindow) {
|
|
|
+ unsetenv("SDL_VIDEO_CENTERED");
|
|
|
+ } else {
|
|
|
+ setenv("SDL_VIDEO_CENTERED", "1", 1);
|
|
|
+ }
|
|
|
+ this->xRes = event.window.data1;
|
|
|
+ this->yRes = event.window.data2;
|
|
|
+
|
|
|
+ SDL_SetWindowSize(sdlWindow, xRes, yRes);
|
|
|
+
|
|
|
+ int x, y;
|
|
|
+ SDL_GL_GetDrawableSize(sdlWindow, &x, &y);
|
|
|
+ if(x >= xRes){
|
|
|
+ backingX = x;
|
|
|
+ }else{
|
|
|
+ backingX = xRes;
|
|
|
+ }
|
|
|
+ if(y >= yRes){
|
|
|
+ backingY = y;
|
|
|
+ }else{
|
|
|
+ backingY = yRes;
|
|
|
+ }
|
|
|
+
|
|
|
+ dispatchEvent(new Event(), EVENT_CORE_RESIZE);
|
|
|
+ break;
|
|
|
+ case SDL_WINDOWEVENT_FOCUS_GAINED:
|
|
|
gainFocus();
|
|
|
- } else {
|
|
|
+ break;
|
|
|
+ case SDL_WINDOWEVENT_FOCUS_LOST:
|
|
|
loseFocus();
|
|
|
- }
|
|
|
+ break;
|
|
|
}
|
|
|
- break;
|
|
|
case SDL_JOYAXISMOTION:
|
|
|
input->joystickAxisMoved(event.jaxis.axis, ((Number)event.jaxis.value)/32767.0, event.jaxis.which);
|
|
|
break;
|
|
|
@@ -401,29 +405,30 @@ bool SDLCore::systemUpdate() {
|
|
|
break;
|
|
|
case SDL_KEYDOWN:
|
|
|
if(!checkSpecialKeyEvents((PolyKEY)(event.key.keysym.sym))) {
|
|
|
- input->setKeyState((PolyKEY)(event.key.keysym.sym), event.key.keysym.unicode, true, getTicks());
|
|
|
+ input->setKeyState((PolyKEY)(event.key.keysym.sym), event.key.keysym.sym, true, getTicks());
|
|
|
}
|
|
|
break;
|
|
|
case SDL_KEYUP:
|
|
|
- input->setKeyState((PolyKEY)(event.key.keysym.sym), event.key.keysym.unicode, false, getTicks());
|
|
|
+ input->setKeyState((PolyKEY)(event.key.keysym.sym), event.key.keysym.sym, false, getTicks());
|
|
|
break;
|
|
|
- case SDL_MOUSEBUTTONDOWN:
|
|
|
- if(event.button.button == SDL_BUTTON_WHEELUP){
|
|
|
+ case SDL_MOUSEWHEEL:
|
|
|
+ if(event.wheel.y > 0) {
|
|
|
input->mouseWheelUp(getTicks());
|
|
|
- } else if (event.button.button == SDL_BUTTON_WHEELDOWN){
|
|
|
+ } else if(event.wheel.y < 0) {
|
|
|
input->mouseWheelDown(getTicks());
|
|
|
- } else {
|
|
|
- switch(event.button.button) {
|
|
|
- case SDL_BUTTON_LEFT:
|
|
|
- input->setMouseButtonState(CoreInput::MOUSE_BUTTON1, true, getTicks());
|
|
|
- break;
|
|
|
- case SDL_BUTTON_RIGHT:
|
|
|
- input->setMouseButtonState(CoreInput::MOUSE_BUTTON2, true, getTicks());
|
|
|
- break;
|
|
|
- case SDL_BUTTON_MIDDLE:
|
|
|
- input->setMouseButtonState(CoreInput::MOUSE_BUTTON3, true, getTicks());
|
|
|
- break;
|
|
|
- }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_MOUSEBUTTONDOWN:
|
|
|
+ switch(event.button.button) {
|
|
|
+ case SDL_BUTTON_LEFT:
|
|
|
+ input->setMouseButtonState(CoreInput::MOUSE_BUTTON1, true, getTicks());
|
|
|
+ break;
|
|
|
+ case SDL_BUTTON_RIGHT:
|
|
|
+ input->setMouseButtonState(CoreInput::MOUSE_BUTTON2, true, getTicks());
|
|
|
+ break;
|
|
|
+ case SDL_BUTTON_MIDDLE:
|
|
|
+ input->setMouseButtonState(CoreInput::MOUSE_BUTTON3, true, getTicks());
|
|
|
+ break;
|
|
|
}
|
|
|
break;
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
@@ -459,22 +464,11 @@ void SDLCore::setCursor(int cursorType) {
|
|
|
}
|
|
|
|
|
|
void SDLCore::warpCursor(int x, int y) {
|
|
|
- SDL_WarpMouse(x, y);
|
|
|
+ SDL_WarpMouseInWindow(sdlWindow, x, y);
|
|
|
lastMouseX = x;
|
|
|
lastMouseY = y;
|
|
|
}
|
|
|
|
|
|
-/*void SDLCore::lockMutex(CoreMutex *mutex) {
|
|
|
- SDLCoreMutex *smutex = (SDLCoreMutex*)mutex;
|
|
|
- SDL_mutexP(smutex->pMutex);
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-void SDLCore::unlockMutex(CoreMutex *mutex) {
|
|
|
- SDLCoreMutex *smutex = (SDLCoreMutex*)mutex;
|
|
|
- SDL_mutexV(smutex->pMutex);
|
|
|
-}*/
|
|
|
-
|
|
|
CoreMutex *SDLCore::createMutex() {
|
|
|
SDLCoreMutex *mutex = new SDLCoreMutex();
|
|
|
mutex->pMutex = SDL_CreateMutex();
|
|
|
@@ -482,29 +476,17 @@ CoreMutex *SDLCore::createMutex() {
|
|
|
}
|
|
|
|
|
|
void SDLCore::copyStringToClipboard(const String& str) {
|
|
|
-#ifdef USE_X11
|
|
|
- put_scrap(T('T', 'E', 'X', 'T'), str.size(), str.c_str());
|
|
|
-#endif
|
|
|
-// SDL_SetClipboardText(str.c_str());
|
|
|
+ SDL_SetClipboardText(str.c_str());
|
|
|
}
|
|
|
|
|
|
String SDLCore::getClipboardString() {
|
|
|
-#ifdef USE_X11
|
|
|
- int dstlen;
|
|
|
- char* buffer;
|
|
|
- get_scrap(T('T', 'E', 'X', 'T'), &dstlen, &buffer);
|
|
|
-
|
|
|
- String rval(buffer, dstlen);
|
|
|
- free(buffer);
|
|
|
+ String rval;
|
|
|
+ if(SDL_HasClipboardText() ==SDL_TRUE){
|
|
|
+ rval=SDL_GetClipboardText();
|
|
|
+ } else {
|
|
|
+ rval="";
|
|
|
+ }
|
|
|
return rval;
|
|
|
- #endif
|
|
|
-// String rval;
|
|
|
-// if(SDL_HasClipboardText() ==SDL_TRUE){
|
|
|
-// rval=SDL_GetClipboardText();
|
|
|
-// } else {
|
|
|
-// rval="";
|
|
|
-// }
|
|
|
-// return rval;
|
|
|
}
|
|
|
|
|
|
void SDLCore::createFolder(const String& folderPath) {
|
|
|
@@ -582,442 +564,10 @@ bool SDLCore::systemParseFolder(const String& pathString, bool showHidden, vecto
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-#ifdef USE_X11
|
|
|
-// SDL_scrap.c
|
|
|
-// Credits to Sam Lantinga for making this
|
|
|
-// Changes include:
|
|
|
-// - All non-X11 stuff was removed
|
|
|
-// - Uses the X11 CLIPBOARD atom in addition to PRIMARY
|
|
|
-// =======================================
|
|
|
-
|
|
|
-
|
|
|
-/* Handle clipboard text and data in arbitrary formats */
|
|
|
-
|
|
|
-/* Miscellaneous defines */
|
|
|
-#define PUBLIC
|
|
|
-#define PRIVATE static
|
|
|
-
|
|
|
-#define X11_SCRAP
|
|
|
-
|
|
|
-typedef Atom scrap_type;
|
|
|
-
|
|
|
-static Display *SDL_Display;
|
|
|
-static Window SDL_Window;
|
|
|
-static void (*Lock_Display)(void);
|
|
|
-static void (*Unlock_Display)(void);
|
|
|
-
|
|
|
-#define FORMAT_PREFIX "SDL_scrap_0x"
|
|
|
-
|
|
|
-PRIVATE scrap_type
|
|
|
-convert_format(int type)
|
|
|
-{
|
|
|
- switch (type)
|
|
|
- {
|
|
|
-
|
|
|
- case T('T', 'E', 'X', 'T'):
|
|
|
- return XA_STRING;
|
|
|
-
|
|
|
- default:
|
|
|
- {
|
|
|
- char format[sizeof(FORMAT_PREFIX)+8+1];
|
|
|
-
|
|
|
- sprintf(format, "%s%08lx", FORMAT_PREFIX, (unsigned long)type);
|
|
|
-
|
|
|
- return XInternAtom(SDL_Display, format, False);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/* Convert internal data to scrap format */
|
|
|
-PRIVATE int
|
|
|
-convert_data(int type, char *dst, const char *src, int srclen)
|
|
|
-{
|
|
|
- int dstlen;
|
|
|
-
|
|
|
- dstlen = 0;
|
|
|
- switch (type)
|
|
|
- {
|
|
|
- case T('T', 'E', 'X', 'T'):
|
|
|
- if ( dst )
|
|
|
- {
|
|
|
- while ( --srclen >= 0 )
|
|
|
- {
|
|
|
- if ( *src == '\r' )
|
|
|
- {
|
|
|
- *dst++ = '\n';
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- *dst++ = *src;
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- ++src;
|
|
|
- }
|
|
|
- *dst = '\0';
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- while ( --srclen >= 0 )
|
|
|
- {
|
|
|
- if ( *src == '\r' )
|
|
|
- {
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- ++src;
|
|
|
- }
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- if ( dst )
|
|
|
- {
|
|
|
- *(int *)dst = srclen;
|
|
|
- dst += sizeof(int);
|
|
|
- memcpy(dst, src, srclen);
|
|
|
- }
|
|
|
- dstlen = sizeof(int)+srclen;
|
|
|
- break;
|
|
|
- }
|
|
|
- return(dstlen);
|
|
|
-}
|
|
|
-
|
|
|
-/* Convert scrap data to internal format */
|
|
|
-PRIVATE int
|
|
|
-convert_scrap(int type, char *dst, char *src, int srclen)
|
|
|
-{
|
|
|
- int dstlen;
|
|
|
-
|
|
|
- dstlen = 0;
|
|
|
- switch (type)
|
|
|
- {
|
|
|
- case T('T', 'E', 'X', 'T'):
|
|
|
- {
|
|
|
- if ( srclen == 0 )
|
|
|
- srclen = strlen(src);
|
|
|
- if ( dst )
|
|
|
- {
|
|
|
- while ( --srclen >= 0 )
|
|
|
- {
|
|
|
- if ( *src == '\n' )
|
|
|
- {
|
|
|
- *dst++ = '\r';
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- *dst++ = *src;
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- ++src;
|
|
|
- }
|
|
|
- *dst = '\0';
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- while ( --srclen >= 0 )
|
|
|
- {
|
|
|
- ++dstlen;
|
|
|
- ++src;
|
|
|
- }
|
|
|
- ++dstlen;
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- dstlen = *(int *)src;
|
|
|
- if ( dst )
|
|
|
- {
|
|
|
- if ( srclen == 0 )
|
|
|
- memcpy(dst, src+sizeof(int), dstlen);
|
|
|
- else
|
|
|
- memcpy(dst, src+sizeof(int), srclen-sizeof(int));
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- return dstlen;
|
|
|
-}
|
|
|
-
|
|
|
-/* The system message filter function -- handle clipboard messages */
|
|
|
-PRIVATE int clipboard_filter(const SDL_Event *event);
|
|
|
-
|
|
|
-PUBLIC int
|
|
|
-init_scrap(void)
|
|
|
-{
|
|
|
- SDL_SysWMinfo info;
|
|
|
- int retval;
|
|
|
-
|
|
|
- /* Grab the window manager specific information */
|
|
|
- retval = -1;
|
|
|
- SDL_SetError("SDL is not running on known window manager");
|
|
|
-
|
|
|
- SDL_VERSION(&info.version);
|
|
|
- if ( SDL_GetWMInfo(&info) )
|
|
|
- {
|
|
|
- /* Save the information for later use */
|
|
|
-/* * */
|
|
|
- if ( info.subsystem == SDL_SYSWM_X11 )
|
|
|
- {
|
|
|
- SDL_Display = info.info.x11.display;
|
|
|
- SDL_Window = info.info.x11.window;
|
|
|
- Lock_Display = info.info.x11.lock_func;
|
|
|
- Unlock_Display = info.info.x11.unlock_func;
|
|
|
-
|
|
|
- /* Enable the special window hook events */
|
|
|
- SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
|
|
|
- SDL_SetEventFilter(clipboard_filter);
|
|
|
-
|
|
|
- retval = 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- SDL_SetError("SDL is not running on X11");
|
|
|
- }
|
|
|
- }
|
|
|
- return(retval);
|
|
|
-}
|
|
|
-
|
|
|
-PUBLIC int
|
|
|
-lost_scrap(void)
|
|
|
-{
|
|
|
- int retval;
|
|
|
-
|
|
|
-/* * */
|
|
|
- Lock_Display();
|
|
|
- retval = ( XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window );
|
|
|
- Unlock_Display();
|
|
|
-
|
|
|
- return(retval);
|
|
|
-}
|
|
|
-
|
|
|
-PUBLIC void
|
|
|
-put_scrap(int type, int srclen, const char *src)
|
|
|
-{
|
|
|
- scrap_type format;
|
|
|
- int dstlen;
|
|
|
- char *dst;
|
|
|
-
|
|
|
- format = convert_format(type);
|
|
|
- dstlen = convert_data(type, NULL, src, srclen);
|
|
|
-
|
|
|
-/* * */
|
|
|
- dst = (char *)malloc(dstlen);
|
|
|
- if ( dst != NULL )
|
|
|
- {
|
|
|
- Lock_Display();
|
|
|
- convert_data(type, dst, src, srclen);
|
|
|
- XChangeProperty(SDL_Display, DefaultRootWindow(SDL_Display),
|
|
|
- XA_CUT_BUFFER0, format, 8, PropModeReplace, (unsigned char*) dst, dstlen);
|
|
|
- free(dst);
|
|
|
- Atom XA_CLIPBOARD = XInternAtom(SDL_Display, "CLIPBOARD", 0);
|
|
|
- if ( lost_scrap() ) {
|
|
|
- XSetSelectionOwner(SDL_Display, XA_PRIMARY, SDL_Window, CurrentTime);
|
|
|
- XSetSelectionOwner(SDL_Display, XA_CLIPBOARD, SDL_Window, CurrentTime);
|
|
|
- }
|
|
|
- Unlock_Display();
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-PUBLIC void
|
|
|
-get_scrap(int type, int *dstlen, char **dst)
|
|
|
-{
|
|
|
- scrap_type format;
|
|
|
-
|
|
|
- *dstlen = 0;
|
|
|
- format = convert_format(type);
|
|
|
-
|
|
|
-/* * */
|
|
|
- {
|
|
|
- Window owner;
|
|
|
- Atom selection;
|
|
|
- Atom seln_type;
|
|
|
- int seln_format;
|
|
|
- unsigned long nbytes;
|
|
|
- unsigned long overflow;
|
|
|
- char *src;
|
|
|
-
|
|
|
- Lock_Display();
|
|
|
- Atom XA_CLIPBOARD = XInternAtom(SDL_Display, "CLIPBOARD", 0);
|
|
|
- owner = XGetSelectionOwner(SDL_Display, XA_PRIMARY);
|
|
|
- Unlock_Display();
|
|
|
- if ( (owner == None) || (owner == SDL_Window) )
|
|
|
- {
|
|
|
- owner = DefaultRootWindow(SDL_Display);
|
|
|
- selection = XA_CUT_BUFFER0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- int selection_response = 0;
|
|
|
- SDL_Event event;
|
|
|
-
|
|
|
- owner = SDL_Window;
|
|
|
- Lock_Display();
|
|
|
- selection = XInternAtom(SDL_Display, "SDL_SELECTION", False);
|
|
|
- XConvertSelection(SDL_Display, XA_PRIMARY, format,
|
|
|
- selection, owner, CurrentTime);
|
|
|
- XConvertSelection(SDL_Display, XA_CLIPBOARD, format,
|
|
|
- selection, owner, CurrentTime);
|
|
|
- Unlock_Display();
|
|
|
- while ( ! selection_response )
|
|
|
- {
|
|
|
- SDL_WaitEvent(&event);
|
|
|
- if ( event.type == SDL_SYSWMEVENT )
|
|
|
- {
|
|
|
- XEvent xevent = event.syswm.msg->event.xevent;
|
|
|
-
|
|
|
- if ( (xevent.type == SelectionNotify) &&
|
|
|
- (xevent.xselection.requestor == owner) )
|
|
|
- selection_response = 1;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- Lock_Display();
|
|
|
- if ( XGetWindowProperty(SDL_Display, owner, selection, 0, INT_MAX/4,
|
|
|
- False, format, &seln_type, &seln_format,
|
|
|
- &nbytes, &overflow, (unsigned char **)&src) == Success )
|
|
|
- {
|
|
|
- if ( seln_type == format )
|
|
|
- {
|
|
|
- *dstlen = convert_scrap(type, NULL, src, nbytes);
|
|
|
- *dst = (char *)malloc(*dstlen);
|
|
|
- if ( *dst == NULL )
|
|
|
- *dstlen = 0;
|
|
|
- else
|
|
|
- convert_scrap(type, *dst, src, nbytes);
|
|
|
- }
|
|
|
- XFree(src);
|
|
|
- }
|
|
|
- }
|
|
|
- Unlock_Display();
|
|
|
-}
|
|
|
-
|
|
|
-PRIVATE int clipboard_filter(const SDL_Event *event)
|
|
|
-{
|
|
|
- /* Post all non-window manager specific events */
|
|
|
- if ( event->type != SDL_SYSWMEVENT ) {
|
|
|
- return(1);
|
|
|
- }
|
|
|
-
|
|
|
- /* Handle window-manager specific clipboard events */
|
|
|
- switch (event->syswm.msg->event.xevent.type) {
|
|
|
- /* Copy the selection from XA_CUT_BUFFER0 to the requested property */
|
|
|
- case SelectionRequest: {
|
|
|
- XSelectionRequestEvent *req;
|
|
|
- XEvent sevent;
|
|
|
- int seln_format;
|
|
|
- unsigned long nbytes;
|
|
|
- unsigned long overflow;
|
|
|
- unsigned char *seln_data;
|
|
|
-
|
|
|
- req = &event->syswm.msg->event.xevent.xselectionrequest;
|
|
|
- sevent.xselection.type = SelectionNotify;
|
|
|
- sevent.xselection.display = req->display;
|
|
|
- sevent.xselection.selection = req->selection;
|
|
|
- sevent.xselection.target = None;
|
|
|
- sevent.xselection.property = None;
|
|
|
- sevent.xselection.requestor = req->requestor;
|
|
|
- sevent.xselection.time = req->time;
|
|
|
- if ( XGetWindowProperty(SDL_Display, DefaultRootWindow(SDL_Display),
|
|
|
- XA_CUT_BUFFER0, 0, INT_MAX/4, False, req->target,
|
|
|
- &sevent.xselection.target, &seln_format,
|
|
|
- &nbytes, &overflow, &seln_data) == Success )
|
|
|
- {
|
|
|
- if ( sevent.xselection.target == req->target )
|
|
|
- {
|
|
|
- if ( sevent.xselection.target == XA_STRING )
|
|
|
- {
|
|
|
- if ( seln_data[nbytes-1] == '\0' )
|
|
|
- --nbytes;
|
|
|
- }
|
|
|
- XChangeProperty(SDL_Display, req->requestor, req->property,
|
|
|
- sevent.xselection.target, seln_format, PropModeReplace,
|
|
|
- seln_data, nbytes);
|
|
|
- sevent.xselection.property = req->property;
|
|
|
- }
|
|
|
- XFree(seln_data);
|
|
|
- }
|
|
|
- XSendEvent(SDL_Display,req->requestor,False,0,&sevent);
|
|
|
- XSync(SDL_Display, False);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- /* Post the event for X11 clipboard reading above */
|
|
|
- return(1);
|
|
|
-}
|
|
|
-
|
|
|
-// X11 cursor
|
|
|
-
|
|
|
-namespace {
|
|
|
-
|
|
|
-// WARNING: These functions rely on the SDL_Display and SDL_Window previously initialized by init_scrap
|
|
|
-
|
|
|
-const int CURSOR_COUNT = 7;
|
|
|
-Cursor defined_cursors[CURSOR_COUNT] = {0};
|
|
|
-
|
|
|
-void set_cursor(int cursorType) {
|
|
|
- Cursor cursor = 0;
|
|
|
-
|
|
|
- if(cursorType >= 0 && cursorType < CURSOR_COUNT) {
|
|
|
- cursor = defined_cursors[cursorType];
|
|
|
- if(!cursor) {
|
|
|
- switch(cursorType) {
|
|
|
- case Polycode::Core::CURSOR_TEXT:
|
|
|
- cursor = XCreateFontCursor (SDL_Display, XC_xterm);
|
|
|
- break;
|
|
|
- case Polycode::Core::CURSOR_POINTER:
|
|
|
- cursor = XCreateFontCursor (SDL_Display, XC_hand1);
|
|
|
- break;
|
|
|
- case Polycode::Core::CURSOR_CROSSHAIR:
|
|
|
- cursor = XCreateFontCursor (SDL_Display, XC_crosshair);
|
|
|
- break;
|
|
|
- case Polycode::Core::CURSOR_RESIZE_LEFT_RIGHT:
|
|
|
- cursor = XCreateFontCursor (SDL_Display, XC_sb_h_double_arrow);
|
|
|
- break;
|
|
|
- case Polycode::Core::CURSOR_RESIZE_UP_DOWN:
|
|
|
- cursor = XCreateFontCursor (SDL_Display, XC_sb_v_double_arrow);
|
|
|
- break;
|
|
|
- case Polycode::Core::CURSOR_OPEN_HAND:
|
|
|
- cursor = XCreateFontCursor (SDL_Display, XC_fleur);
|
|
|
- break;
|
|
|
- case Polycode::Core::CURSOR_ARROW:
|
|
|
- cursor = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- defined_cursors[cursorType] = cursor;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(!cursor) {
|
|
|
- // Restore the normal cursor.
|
|
|
- XUndefineCursor(SDL_Display, SDL_Window);
|
|
|
- } else {
|
|
|
- XDefineCursor(SDL_Display, SDL_Window, cursor);
|
|
|
- }
|
|
|
-
|
|
|
- XFlush(SDL_Display);
|
|
|
-}
|
|
|
-
|
|
|
-void free_cursors() {
|
|
|
- XUndefineCursor(SDL_Display, SDL_Window);
|
|
|
- for(int i = 0; i < CURSOR_COUNT; i++) {
|
|
|
- if(defined_cursors[i]) {
|
|
|
- XFreeCursor(SDL_Display, defined_cursors[i]);
|
|
|
- defined_cursors[i] = 0;
|
|
|
- }
|
|
|
- }
|
|
|
+Number SDLCore::getBackingXRes() {
|
|
|
+ return backingX;
|
|
|
}
|
|
|
-} // namespace
|
|
|
-// end X11 cursor
|
|
|
|
|
|
-#endif // USE_X11
|
|
|
+Number SDLCore::getBackingYRes() {
|
|
|
+ return backingY;
|
|
|
+}
|