From 62f18a8592a4e09a3903e332ffd33280a9f949f2 Mon Sep 17 00:00:00 2001 From: Dimitris Zenios Date: Thu, 31 May 2012 19:23:30 +0300 Subject: [PATCH] 1.Fixed a memory leak inside XInput2 code 2.Replaced XKeycodeToKeysym with XkbKeycodeToKeysym since XKeycodeToKeysym is deprecated in newer X11 version 3.Rewrote testime.c since it was disabled after SDL_compat.c removal 4.Take into account common arguments also in testrelative.c --- configure.in | 1 + include/SDL_config.h.in | 1 + include/SDL_config_macosx.h | 1 + src/video/x11/SDL_x11dyn.h | 4 + src/video/x11/SDL_x11events.c | 6 +- src/video/x11/SDL_x11keyboard.c | 8 + src/video/x11/SDL_x11sym.h | 8 + src/video/x11/SDL_x11xinput2.c | 1 + test/Makefile.in | 4 +- test/testime.c | 424 +++++++++++++++----------------- test/testrelative.c | 3 + 11 files changed, 232 insertions(+), 229 deletions(-) diff --git a/configure.in b/configure.in index 41842b701..0eb81e33b 100644 --- a/configure.in +++ b/configure.in @@ -1111,6 +1111,7 @@ XextAddDisplay(XExtensionInfo* a,Display* b,_Xconst char* c,XExtensionHooks* d,i AC_MSG_RESULT($have_const_param_XextAddDisplay) AC_CHECK_LIB(X11, XGetEventData, AC_DEFINE(SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS, 1, [Have XGenericEvent])) + AC_CHECK_LIB(X11, XkbKeycodeToKeysym, AC_DEFINE(SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM, 1, [Have XkbKeycodeToKeysym])) AC_ARG_ENABLE(video-x11-xcursor, AC_HELP_STRING([--enable-video-x11-xcursor], [enable X11 Xcursor support [[default=yes]]]), diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 12241be21..600dbfb00 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -271,6 +271,7 @@ #undef SDL_VIDEO_DRIVER_X11_XVIDMODE #undef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS #undef SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY +#undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM #undef SDL_VIDEO_RENDER_D3D #undef SDL_VIDEO_RENDER_OGL diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 853730f69..d9d1c1cb6 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -146,6 +146,7 @@ #define SDL_VIDEO_DRIVER_X11_XSHAPE 1 #define SDL_VIDEO_DRIVER_X11_XVIDMODE 1 #define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 +#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 #ifndef SDL_VIDEO_RENDER_OGL #define SDL_VIDEO_RENDER_OGL 1 diff --git a/src/video/x11/SDL_x11dyn.h b/src/video/x11/SDL_x11dyn.h index c3fb75769..5d2d9da16 100755 --- a/src/video/x11/SDL_x11dyn.h +++ b/src/video/x11/SDL_x11dyn.h @@ -27,6 +27,10 @@ #include #include +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +#include +#endif + /* Apparently some X11 systems can't include this multiple times... */ #ifndef SDL_INCLUDED_XLIBINT_H #define SDL_INCLUDED_XLIBINT_H 1 diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index f1d18853c..a85622d2a 100755 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -265,7 +265,11 @@ X11_DispatchEvent(_THIS) if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN) { int min_keycode, max_keycode; XDisplayKeycodes(display, &min_keycode, &max_keycode); +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + keysym = XkbKeycodeToKeysym(display, keycode, 0, 0); +#else keysym = XKeycodeToKeysym(display, keycode, 0); +#endif fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list X11 KeyCode %d (%d), X11 KeySym 0x%lX (%s).\n", keycode, keycode - min_keycode, keysym, @@ -563,7 +567,7 @@ X11_PumpEvents(_THIS) XResetScreenSaver(data->display); data->screensaver_activity = now; } - } + } /* Keep processing pending events */ while (X11_Pending(data->display)) { diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index 3ed61e963..142b96baf 100755 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -151,7 +151,11 @@ X11_KeyCodeToSDLKey(Display *display, KeyCode keycode) unsigned int ucs4; int i; +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + keysym = XkbKeycodeToKeysym(display, keycode, 0, 0); +#else keysym = XKeycodeToKeysym(display, keycode, 0); +#endif if (keysym == NoSymbol) { return SDLK_UNKNOWN; } @@ -232,7 +236,11 @@ X11_InitKeyboard(_THIS) SDL_GetDefaultKeymap(keymap); for (i = min_keycode; i <= max_keycode; ++i) { KeySym sym; +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + sym = XkbKeycodeToKeysym(data->display, i, 0, 0); +#else sym = XKeycodeToKeysym(data->display, i, 0); +#endif if (sym != NoSymbol) { SDL_Keycode key; printf("code = %d, sym = 0x%X (%s) ", i - min_keycode, diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index de0f26714..1e2a6f223 100755 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -132,6 +132,14 @@ SDL_X11_SYM(Bool,XGetEventData,(Display* a,XGenericEventCookie* b),(a,b),return) SDL_X11_SYM(void,XFreeEventData,(Display* a,XGenericEventCookie* b),(a,b),) #endif +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +#if NeedWidePrototypes +SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,unsigned int b,int c,int d),(a,b,c,d),return) +#else +SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,KeyCode b,int c,int d),(a,b,c,d),return) +#endif +#endif + #if NeedWidePrototypes SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return) #else diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index c324bc73d..30742f8d4 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -210,6 +210,7 @@ X11_InitXinput2Multitouch(_THIS) { } } } + XIFreeDeviceInfo(info); #endif } diff --git a/test/Makefile.in b/test/Makefile.in index fe383026d..9afc95524 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -105,8 +105,8 @@ testthread$(EXE): $(srcdir)/testthread.c testiconv$(EXE): $(srcdir)/testiconv.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) -testime$(EXE): $(srcdir)/testime.c - $(CC) -o $@ $? $(CFLAGS) $(LIBS) @SDL_TTF_LIB@ +testime$(EXE): $(srcdir)/testime.c $(srcdir)/common.c + $(CC) -o $@ $(srcdir)/testime.c $(srcdir)/common.c $(CFLAGS) $(LIBS) @SDL_TTF_LIB@ testjoystick$(EXE): $(srcdir)/testjoystick.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) diff --git a/test/testime.c b/test/testime.c index a10390c33..5eead9315 100644 --- a/test/testime.c +++ b/test/testime.c @@ -11,15 +11,6 @@ */ /* A simple program to test the Input Method support in the SDL library (2.0+) */ -#if 1 /* FIXME: Rework this using the 2.0 API */ -#include - -int main(int argc, char *argv[]) -{ - printf("FIXME\n"); - return 0; -} -#else #include #include #include @@ -29,20 +20,22 @@ int main(int argc, char *argv[]) #include "SDL_ttf.h" #endif +#include "common.h" + #define DEFAULT_PTSIZE 30 #define DEFAULT_FONT "/System/Library/Fonts/华文细黑.ttf" #define MAX_TEXT_LENGTH 256 -SDL_Surface *screen; - +static CommonState *state; +static SDL_Rect textRect, markedRect; +static SDL_Color lineColor = {0,0,0,0}; +static SDL_Color backColor = {255,255,255,0}; +static SDL_Color textColor = {0,0,0,0}; +static char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; +static int cursor = 0; #ifdef HAVE_SDL_TTF -TTF_Font *font; +static TTF_Font *font; #endif -SDL_Rect textRect, markedRect; -Uint32 lineColor, backColor; -SDL_Color textColor = { 0, 0, 0 }; -char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; -int cursor = 0; size_t utf8_length(unsigned char c) { @@ -87,94 +80,16 @@ char *utf8_advance(char *p, size_t distance) void usage() { - printf("usage: testime [--font fontfile] [--fullscreen]\n"); + printf("usage: testime [--font fontfile]\n"); exit(0); } -void InitVideo(int argc, char *argv[]) -{ - int width = 640, height = 480; - int flags = SDL_HWSURFACE; - const char *fontname = DEFAULT_FONT; - int fullscreen = 0; - - for (argc--, argv++; argc > 0; argc--, argv++) - { - if (strcmp(argv[0], "--help") == 0) - usage(); - - else if (strcmp(argv[0], "--fullscreen") == 0) - fullscreen = 1; - - else if (strcmp(argv[0], "--font") == 0) - { - argc--; - argv++; - - if (argc > 0) - fontname = argv[0]; - else - usage(); - } - } - - SDL_setenv("SDL_VIDEO_WINDOW_POS", "center", 1); - if (SDL_Init(SDL_INIT_VIDEO) < 0) - { - fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); - exit(-1); - } - -#ifdef HAVE_SDL_TTF - /* Initialize fonts */ - TTF_Init(); - - font = TTF_OpenFont(fontname, DEFAULT_PTSIZE); - if (! font) - { - fprintf(stderr, "Failed to find font: %s\n", TTF_GetError()); - exit(-1); - } -#endif - - printf("Using font: %s\n", fontname); - atexit(SDL_Quit); - - if (fullscreen) - { - /* Use the desktop mode */ - width = 0; - height = 0; - flags |= SDL_FULLSCREEN; - } - - /* Create window */ - screen = SDL_SetVideoMode(width, height, 32, flags); - if (screen == NULL) - { - fprintf(stderr, "Unable to set %dx%d video: %s\n", - width, height, SDL_GetError()); - exit(-1); - } -} - -void CleanupVideo() -{ - SDL_StopTextInput(); -#ifdef HAVE_SDL_TTF - TTF_CloseFont(font); - TTF_Quit(); -#endif -} - void InitInput() { - backColor = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF); - lineColor = SDL_MapRGB(screen->format, 0x0, 0x0, 0x0); /* Prepare a rect for text input */ textRect.x = textRect.y = 100; - textRect.w = screen->w - 2 * textRect.x; + textRect.w = DEFAULT_WINDOW_WIDTH - 2 * textRect.x; textRect.h = 50; text[0] = 0; @@ -184,34 +99,34 @@ void InitInput() SDL_StartTextInput(); } -#ifdef HAVE_SDL_TTF -static void RenderText(SDL_Surface *sur, - TTF_Font *font, - const char *text, - int x, int y, - SDL_Color color) +void CleanupVideo() { - if (text && *text) { - SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, color); - SDL_Rect dest = { x, y, textSur->w, textSur->h }; - - SDL_BlitSurface(textSur, NULL, sur, &dest); - SDL_FreeSurface(textSur); - } -} + SDL_StopTextInput(); +#ifdef HAVE_SDL_TTF + TTF_CloseFont(font); + TTF_Quit(); #endif +} -void Redraw() -{ + +void _Redraw(SDL_Renderer * renderer) { int w = 0, h = textRect.h; SDL_Rect cursorRect, underlineRect; - SDL_FillRect(screen, &textRect, backColor); + SDL_SetRenderDrawColor(renderer, 255,255,255,255); + SDL_RenderFillRect(renderer,&textRect); #ifdef HAVE_SDL_TTF if (*text) { - RenderText(screen, font, text, textRect.x, textRect.y, textColor); + SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, textColor); + SDL_Rect dest = {textRect.x, textRect.y, textSur->w, textSur->h }; + + SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur); + SDL_FreeSurface(textSur); + + SDL_RenderCopy(renderer,texture,NULL,&dest); + SDL_DestroyTexture(texture); TTF_SizeUTF8(font, text, &w, &h); } #endif @@ -220,7 +135,6 @@ void Redraw() markedRect.w = textRect.w - w; if (markedRect.w < 0) { - SDL_Flip(screen); // Stop text input because we cannot hold any more characters SDL_StopTextInput(); return; @@ -234,7 +148,9 @@ void Redraw() cursorRect.w = 2; cursorRect.h = h; - SDL_FillRect(screen, &markedRect, backColor); + SDL_SetRenderDrawColor(renderer, 255,255,255,255); + SDL_RenderFillRect(renderer,&markedRect); + if (markedText[0]) { #ifdef HAVE_SDL_TTF @@ -251,8 +167,14 @@ void Redraw() cursorRect.x += w; *p = c; } - RenderText(screen, font, markedText, markedRect.x, markedRect.y, textColor); + SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, markedText, textColor); + SDL_Rect dest = {markedRect.x, markedRect.y, textSur->w, textSur->h }; TTF_SizeUTF8(font, markedText, &w, &h); + SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur); + SDL_FreeSurface(textSur); + + SDL_RenderCopy(renderer,texture,NULL,&dest); + SDL_DestroyTexture(texture); #endif underlineRect = markedRect; @@ -260,138 +182,188 @@ void Redraw() underlineRect.h = 2; underlineRect.w = w; - SDL_FillRect(screen, &underlineRect, lineColor); + SDL_SetRenderDrawColor(renderer, 0,0,0,0); + SDL_RenderFillRect(renderer,&markedRect); } - SDL_FillRect(screen, &cursorRect, lineColor); - - SDL_Flip(screen); + SDL_SetRenderDrawColor(renderer, 0,0,0,0); + SDL_RenderFillRect(renderer,&cursorRect); SDL_SetTextInputRect(&markedRect); } -void -HotKey_ToggleFullScreen(void) -{ - SDL_Surface *screen; - - screen = SDL_GetVideoSurface(); - if (SDL_WM_ToggleFullScreen(screen)) { - printf("Toggled fullscreen mode - now %s\n", - (screen->flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed"); - } else { - printf("Unable to toggle fullscreen mode\n"); +void Redraw() { + int i; + for (i = 0; i < state->num_windows; ++i) { + SDL_Renderer *renderer = state->renderers[i]; + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + + _Redraw(renderer); + + SDL_RenderPresent(renderer); } } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { + int i, done; SDL_Event event; - int done = 0; - - InitVideo(argc, argv); - InitInput(); - Redraw(); + const char *fontname = DEFAULT_FONT; - while (! done && SDL_WaitEvent(&event)) + /* Initialize test framework */ + state = CommonCreateState(argv, SDL_INIT_VIDEO); + if (!state) { + return 1; + } + for (i = 1; i < argc;i++) { + CommonArg(state, i); + } + for (argc--, argv++; argc > 0; argc--, argv++) { - switch (event.type) - { - case SDL_KEYDOWN: - switch (event.key.keysym.sym) - { - case SDLK_ESCAPE: - done = 1; - break; - case SDLK_RETURN: - text[0]=0x00; - Redraw(); - break; - case SDLK_BACKSPACE: - { - int textlen=SDL_strlen(text); - - do { - if (textlen==0) - { - break; - } - if ((text[textlen-1] & 0x80) == 0x00) - { - /* One byte */ - text[textlen-1]=0x00; - break; - } - if ((text[textlen-1] & 0xC0) == 0x80) - { - /* Byte from the multibyte sequence */ - text[textlen-1]=0x00; - textlen--; - } - if ((text[textlen-1] & 0xC0) == 0xC0) - { - /* First byte of multibyte sequence */ - text[textlen-1]=0x00; - break; - } - } while(1); + if (strcmp(argv[0], "--help") == 0) { + usage(); + return 0; + } - Redraw(); - } - break; - } + else if (strcmp(argv[0], "--font") == 0) + { + argc--; + argv++; - if (done) - { - break; + if (argc > 0) + fontname = argv[0]; + else { + usage(); + return 0; } + } + } + + if (!CommonInit(state)) { + return 2; + } - fprintf(stderr, - "Keyboard: scancode 0x%08X = %s, keycode 0x%08X = %s\n", - event.key.keysym.scancode, - SDL_GetScancodeName(event.key.keysym.scancode), - event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym)); - break; - - case SDL_TEXTINPUT: - if (SDL_strlen(event.text.text) == 0 || event.text.text[0] == '\n' || - markedRect.w < 0) - break; - - fprintf(stderr, "Keyboard: text input \"%s\"\n", event.text.text); - - if (SDL_strlen(text) + SDL_strlen(event.text.text) < sizeof(text)) - SDL_strlcat(text, event.text.text, sizeof(text)); - - fprintf(stderr, "text inputed: %s\n", text); - - // After text inputed, we can clear up markedText because it - // is committed - markedText[0] = 0; - Redraw(); - break; - case SDL_TEXTEDITING: - fprintf(stderr, "text editing \"%s\", selected range (%d, %d)\n", - event.edit.text, event.edit.start, event.edit.length); +#ifdef HAVE_SDL_TTF + /* Initialize fonts */ + TTF_Init(); - strcpy(markedText, event.edit.text); - cursor = event.edit.start; - Redraw(); - break; + font = TTF_OpenFont(fontname, DEFAULT_PTSIZE); + if (! font) + { + fprintf(stderr, "Failed to find font: %s\n", TTF_GetError()); + exit(-1); + } +#endif - case SDL_QUIT: - done = 1; - break; + printf("Using font: %s\n", fontname); + atexit(SDL_Quit); - default: - break; + InitInput(); + /* Create the windows and initialize the renderers */ + for (i = 0; i < state->num_windows; ++i) { + SDL_Renderer *renderer = state->renderers[i]; + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); + SDL_RenderClear(renderer); + } + Redraw(); + /* Main render loop */ + done = 0; + while (!done) { + /* Check for events */ + while (SDL_PollEvent(&event)) { + CommonEvent(state, &event, &done); + switch(event.type) { + case SDL_KEYDOWN: { + switch (event.key.keysym.sym) + { + case SDLK_RETURN: + text[0]=0x00; + Redraw(); + break; + case SDLK_BACKSPACE: + { + int textlen=SDL_strlen(text); + + do { + if (textlen==0) + { + break; + } + if ((text[textlen-1] & 0x80) == 0x00) + { + /* One byte */ + text[textlen-1]=0x00; + break; + } + if ((text[textlen-1] & 0xC0) == 0x80) + { + /* Byte from the multibyte sequence */ + text[textlen-1]=0x00; + textlen--; + } + if ((text[textlen-1] & 0xC0) == 0xC0) + { + /* First byte of multibyte sequence */ + text[textlen-1]=0x00; + break; + } + } while(1); + + Redraw(); + } + break; + } + + if (done) + { + break; + } + + fprintf(stderr, + "Keyboard: scancode 0x%08X = %s, keycode 0x%08X = %s\n", + event.key.keysym.scancode, + SDL_GetScancodeName(event.key.keysym.scancode), + event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym)); + break; + + case SDL_TEXTINPUT: + if (SDL_strlen(event.text.text) == 0 || event.text.text[0] == '\n' || + markedRect.w < 0) + break; + + fprintf(stderr, "Keyboard: text input \"%s\"\n", event.text.text); + + if (SDL_strlen(text) + SDL_strlen(event.text.text) < sizeof(text)) + SDL_strlcat(text, event.text.text, sizeof(text)); + + fprintf(stderr, "text inputed: %s\n", text); + + // After text inputed, we can clear up markedText because it + // is committed + markedText[0] = 0; + Redraw(); + break; + + case SDL_TEXTEDITING: + fprintf(stderr, "text editing \"%s\", selected range (%d, %d)\n", + event.edit.text, event.edit.start, event.edit.length); + + strcpy(markedText, event.edit.text); + cursor = event.edit.start; + Redraw(); + break; + } + break; + + } } } - CleanupVideo(); + CommonQuit(state); return 0; } -#endif + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/test/testrelative.c b/test/testrelative.c index b4592f419..fe83a9748 100644 --- a/test/testrelative.c +++ b/test/testrelative.c @@ -41,6 +41,9 @@ main(int argc, char *argv[]) if (!state) { return 1; } + for (i = 1; i < argc;i++) { + CommonArg(state, i); + } if (!CommonInit(state)) { return 2; }