Commit d4f133c2 authored by Sam Lantinga's avatar Sam Lantinga

Merged a cleaned up version of Jiang's code changes from Google Summer of Code 2009

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403823
parent c03508fe
...@@ -9,4 +9,7 @@ if [ -d $srcdir/.svn ]; then ...@@ -9,4 +9,7 @@ if [ -d $srcdir/.svn ]; then
(svnversion -c 2>/dev/null || svnversion .) | \ (svnversion -c 2>/dev/null || svnversion .) | \
sed -e 's,\([0-9]*\)[A-Z]*,\1,' \ sed -e 's,\([0-9]*\)[A-Z]*,\1,' \
-e 's,[0-9]*:\([0-9]*\)[A-Z]*,\1,' -e 's,[0-9]*:\([0-9]*\)[A-Z]*,\1,'
else
cd $srcdir
git svn info | grep Revision | awk '{ print $2 }'
fi fi
...@@ -60,6 +60,7 @@ typedef enum ...@@ -60,6 +60,7 @@ typedef enum
SDL_WINDOWEVENT, /**< Window state change */ SDL_WINDOWEVENT, /**< Window state change */
SDL_KEYDOWN, /**< Keys pressed */ SDL_KEYDOWN, /**< Keys pressed */
SDL_KEYUP, /**< Keys released */ SDL_KEYUP, /**< Keys released */
SDL_TEXTEDITING, /**< Keyboard text editing (composition) */
SDL_TEXTINPUT, /**< Keyboard text input */ SDL_TEXTINPUT, /**< Keyboard text input */
SDL_MOUSEMOTION, /**< Mouse moved */ SDL_MOUSEMOTION, /**< Mouse moved */
SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */
...@@ -97,6 +98,7 @@ typedef enum ...@@ -97,6 +98,7 @@ typedef enum
SDL_KEYDOWNMASK = SDL_EVENTMASK(SDL_KEYDOWN), SDL_KEYDOWNMASK = SDL_EVENTMASK(SDL_KEYDOWN),
SDL_KEYUPMASK = SDL_EVENTMASK(SDL_KEYUP), SDL_KEYUPMASK = SDL_EVENTMASK(SDL_KEYUP),
SDL_KEYEVENTMASK = SDL_EVENTMASK(SDL_KEYDOWN) | SDL_EVENTMASK(SDL_KEYUP), SDL_KEYEVENTMASK = SDL_EVENTMASK(SDL_KEYDOWN) | SDL_EVENTMASK(SDL_KEYUP),
SDL_TEXTEDITINGMASK = SDL_EVENTMASK(SDL_TEXTEDITING),
SDL_TEXTINPUTMASK = SDL_EVENTMASK(SDL_TEXTINPUT), SDL_TEXTINPUTMASK = SDL_EVENTMASK(SDL_TEXTINPUT),
SDL_MOUSEMOTIONMASK = SDL_EVENTMASK(SDL_MOUSEMOTION), SDL_MOUSEMOTIONMASK = SDL_EVENTMASK(SDL_MOUSEMOTION),
SDL_MOUSEBUTTONDOWNMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN), SDL_MOUSEBUTTONDOWNMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN),
...@@ -148,6 +150,20 @@ typedef struct SDL_KeyboardEvent ...@@ -148,6 +150,20 @@ typedef struct SDL_KeyboardEvent
SDL_keysym keysym; /**< The key that was pressed or released */ SDL_keysym keysym; /**< The key that was pressed or released */
} SDL_KeyboardEvent; } SDL_KeyboardEvent;
/**
* \struct SDL_TextEditingEvent
*
* \brief Keyboard text editing event structure (event.edit.*)
*/
#define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32)
typedef struct SDL_TextEditingEvent
{
Uint8 type; /**< SDL_TEXTEDITING */
char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */
int start; /**< The start cursor of selected editing text */
int length; /**< The length of selected editing text */
} SDL_TextEditingEvent;
/** /**
* \struct SDL_TextInputEvent * \struct SDL_TextInputEvent
* *
...@@ -350,6 +366,7 @@ typedef union SDL_Event ...@@ -350,6 +366,7 @@ typedef union SDL_Event
Uint8 type; /**< Event type, shared with all events */ Uint8 type; /**< Event type, shared with all events */
SDL_WindowEvent window; /**< Window event data */ SDL_WindowEvent window; /**< Window event data */
SDL_KeyboardEvent key; /**< Keyboard event data */ SDL_KeyboardEvent key; /**< Keyboard event data */
SDL_TextEditingEvent edit; /**< Text editing event data */
SDL_TextInputEvent text; /**< Text input event data */ SDL_TextInputEvent text; /**< Text input event data */
SDL_MouseMotionEvent motion; /**< Mouse motion event data */ SDL_MouseMotionEvent motion; /**< Mouse motion event data */
SDL_MouseButtonEvent button; /**< Mouse button event data */ SDL_MouseButtonEvent button; /**< Mouse button event data */
......
...@@ -154,6 +154,34 @@ extern DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_scancode ...@@ -154,6 +154,34 @@ extern DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_scancode
*/ */
extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDLKey key); extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDLKey key);
/**
* \fn void SDL_StartTextInput(void)
*
* \brief Start accepting Unicode text input events.
*
* \sa SDL_StopTextInput()
* \sa SDL_SetTextInputRect()
*/
extern DECLSPEC void SDLCALL SDL_StartTextInput(void);
/**
* \fn void SDL_StopTextInput(void)
*
* \brief Stop receiving any text input events.
*
* \sa SDL_StartTextInput()
*/
extern DECLSPEC void SDLCALL SDL_StopTextInput(void);
/**
* \fn void SDL_SetTextInputRect(SDL_Rect *rect)
*
* \brief Set the rectangle used to type Unicode text inputs.
*
* \sa SDL_StartTextInput()
*/
extern DECLSPEC void SDLCALL SDL_SetTextInputRect(SDL_Rect *rect);
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -40,6 +40,7 @@ static SDL_GLContext *SDL_VideoContext = NULL; ...@@ -40,6 +40,7 @@ static SDL_GLContext *SDL_VideoContext = NULL;
static Uint32 SDL_VideoFlags = 0; static Uint32 SDL_VideoFlags = 0;
static char *wm_title = NULL; static char *wm_title = NULL;
static SDL_Surface *SDL_VideoIcon; static SDL_Surface *SDL_VideoIcon;
static int SDL_enabled_UNICODE = 0;
char * char *
SDL_AudioDriverName(char *namebuf, int maxlen) SDL_AudioDriverName(char *namebuf, int maxlen)
...@@ -1720,7 +1721,19 @@ SDL_GetKeyRepeat(int *delay, int *interval) ...@@ -1720,7 +1721,19 @@ SDL_GetKeyRepeat(int *delay, int *interval)
int int
SDL_EnableUNICODE(int enable) SDL_EnableUNICODE(int enable)
{ {
return SDL_EventState(SDL_TEXTINPUT, enable); int previous = SDL_enabled_UNICODE;
switch (enable) {
case 1:
SDL_enabled_UNICODE = 1;
SDL_StartTextInput();
break;
case 0:
SDL_enabled_UNICODE = 0;
SDL_StopTextInput();
break;
}
return previous;
} }
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -852,6 +852,24 @@ SDL_SendKeyboardText(int index, const char *text) ...@@ -852,6 +852,24 @@ SDL_SendKeyboardText(int index, const char *text)
return (posted); return (posted);
} }
int
SDL_SendEditingText(const char *text, int start, int length)
{
int posted;
/* Post the event, if desired */
posted = 0;
if (SDL_ProcessEvents[SDL_TEXTEDITING] == SDL_ENABLE) {
SDL_Event event;
event.edit.type = SDL_TEXTEDITING;
event.edit.start = start;
event.edit.length = length;
SDL_strlcpy(event.edit.text, text, SDL_arraysize(event.text.text));
posted = (SDL_PushEvent(&event) > 0);
}
return (posted);
}
void void
SDL_KeyboardQuit(void) SDL_KeyboardQuit(void)
{ {
......
...@@ -81,6 +81,9 @@ extern int SDL_SendKeyboardKey(int index, Uint8 state, SDL_scancode scancode); ...@@ -81,6 +81,9 @@ extern int SDL_SendKeyboardKey(int index, Uint8 state, SDL_scancode scancode);
/* Send keyboard text input for a keyboard at an index */ /* Send keyboard text input for a keyboard at an index */
extern int SDL_SendKeyboardText(int index, const char *text); extern int SDL_SendKeyboardText(int index, const char *text);
/* Send editing text for selected range from start to end */
extern int SDL_SendEditingText(const char *text, int start, int end);
/* Shutdown the keyboard subsystem */ /* Shutdown the keyboard subsystem */
extern void SDL_KeyboardQuit(void); extern void SDL_KeyboardQuit(void);
......
...@@ -277,6 +277,11 @@ struct SDL_VideoDevice ...@@ -277,6 +277,11 @@ struct SDL_VideoDevice
/* Suspend the screensaver */ /* Suspend the screensaver */
void (*SuspendScreenSaver) (_THIS); void (*SuspendScreenSaver) (_THIS);
/* Text input */
void (*StartTextInput) (_THIS);
void (*StopTextInput) (_THIS);
void (*SetTextInputRect) (_THIS, SDL_Rect *rect);
/* * * */ /* * * */
/* Data common to all drivers */ /* Data common to all drivers */
SDL_bool suspend_screensaver; SDL_bool suspend_screensaver;
......
...@@ -3233,4 +3233,32 @@ SDL_GetWindowWMInfo(SDL_WindowID windowID, struct SDL_SysWMinfo *info) ...@@ -3233,4 +3233,32 @@ SDL_GetWindowWMInfo(SDL_WindowID windowID, struct SDL_SysWMinfo *info)
return (_this->GetWindowWMInfo(_this, window, info)); return (_this->GetWindowWMInfo(_this, window, info));
} }
void
SDL_StartTextInput(void)
{
if (_this->StartTextInput) {
_this->StartTextInput(_this);
}
SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE);
SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE);
}
void
SDL_StopTextInput(void)
{
if (_this->StopTextInput) {
_this->StopTextInput(_this);
}
SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
}
void
SDL_SetTextInputRect(SDL_Rect *rect)
{
if (_this->SetTextInputRect) {
_this->SetTextInputRect(_this, rect);
}
}
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -193,6 +193,10 @@ Cocoa_PumpEvents(_THIS) ...@@ -193,6 +193,10 @@ Cocoa_PumpEvents(_THIS)
Cocoa_HandleKeyEvent(_this, event); Cocoa_HandleKeyEvent(_this, event);
/* Fall through to pass event to NSApp; er, nevermind... */ /* Fall through to pass event to NSApp; er, nevermind... */
/* FIXME: Find a way to stop the beeping, using delegate */ /* FIXME: Find a way to stop the beeping, using delegate */
/* Add to support system-wide keyboard shortcuts like CMD+Space */
if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged)
[NSApp sendEvent: event];
break; break;
default: default:
[NSApp sendEvent:event]; [NSApp sendEvent:event];
......
...@@ -28,6 +28,10 @@ extern void Cocoa_InitKeyboard(_THIS); ...@@ -28,6 +28,10 @@ extern void Cocoa_InitKeyboard(_THIS);
extern void Cocoa_HandleKeyEvent(_THIS, NSEvent * event); extern void Cocoa_HandleKeyEvent(_THIS, NSEvent * event);
extern void Cocoa_QuitKeyboard(_THIS); extern void Cocoa_QuitKeyboard(_THIS);
extern void Cocoa_StartTextInput(_THIS);
extern void Cocoa_StopTextInput(_THIS);
extern void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect);
#endif /* _SDL_cocoakeyboard_h */ #endif /* _SDL_cocoakeyboard_h */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
//#define DEBUG_IME NSLog
#define DEBUG_IME
#ifndef NX_DEVICERCTLKEYMASK #ifndef NX_DEVICERCTLKEYMASK
#define NX_DEVICELCTLKEYMASK 0x00000001 #define NX_DEVICELCTLKEYMASK 0x00000001
...@@ -54,14 +56,142 @@ ...@@ -54,14 +56,142 @@
#define NX_DEVICERCTLKEYMASK 0x00002000 #define NX_DEVICERCTLKEYMASK 0x00002000
#endif #endif
@interface SDLTranslatorResponder : NSTextView @interface SDLTranslatorResponder : NSView <NSTextInput>
{ {
NSString *_markedText;
NSRange _markedRange;
NSRange _selectedRange;
SDL_Rect _inputRect;
int _keyboard;
} }
- (void) doCommandBySelector:(SEL)myselector; - (void) doCommandBySelector:(SEL)myselector;
- (void) setInputRect:(SDL_Rect *) rect;
- (void) setKeyboard:(int) keyboard;
@end @end
@implementation SDLTranslatorResponder @implementation SDLTranslatorResponder
- (void) doCommandBySelector:(SEL) myselector {}
- (void) setKeyboard:(int) keyboard
{
_keyboard = keyboard;
}
- (void) setInputRect:(SDL_Rect *) rect
{
_inputRect = *rect;
}
- (void) insertText:(id) aString
{
const char *str;
DEBUG_IME(@"insertText: %@", aString);
/* Could be NSString or NSAttributedString, so we have
* to test and convert it before return as SDL event */
if ([aString isKindOfClass: [NSAttributedString class]])
str = [[aString string] UTF8String];
else
str = [aString UTF8String];
SDL_SendKeyboardText(_keyboard, str);
}
- (void) doCommandBySelector:(SEL) myselector
{
[super doCommandBySelector: myselector];
}
- (BOOL) hasMarkedText
{
return _markedText != nil;
}
- (NSRange) markedRange
{
return _markedRange;
}
- (NSRange) selectedRange
{
return _selectedRange;
}
- (void) setMarkedText:(id) aString
selectedRange:(NSRange) selRange
{
if ([aString isKindOfClass: [NSAttributedString class]])
aString = [aString string];
if ([aString length] == 0)
{
[self unmarkText];
return;
}
if (_markedText != aString)
{
[_markedText release];
_markedText = [aString retain];
}
_selectedRange = selRange;
_markedRange = NSMakeRange(0, [aString length]);
SDL_SendEditingText([aString UTF8String], selRange.location, selRange.length);
DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText,
selRange.location, selRange.length);
}
- (void) unmarkText
{
[_markedText release];
_markedText = nil;
}
- (NSRect) firstRectForCharacterRange: (NSRange) theRange
{
float windowHeight = [[self window] frame].size.height;
NSRect rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y - _inputRect.h,
_inputRect.w, _inputRect.h);
DEBUG_IME(@"firstRectForCharacterRange: (%d, %d): windowHeight = %g, rect = %@",
theRange.location, theRange.length, windowHeight,
NSStringFromRect(rect));
rect.origin = [[self window] convertBaseToScreen: rect.origin];
return rect;
}
- (NSAttributedString *) attributedSubstringFromRange: (NSRange) theRange
{
DEBUG_IME(@"attributedSubstringFromRange: (%d, %d)", theRange.location, theRange.length);
return nil;
}
- (NSInteger) conversationIdentifier
{
return (NSInteger) self;
}
// This method returns the index for character that is
// nearest to thePoint. thPoint is in screen coordinate system.
- (NSUInteger) characterIndexForPoint:(NSPoint) thePoint
{
DEBUG_IME(@"characterIndexForPoint: (%g, %g)", thePoint.x, thePoint.y);
return 0;
}
// This method is the key to attribute extension.
// We could add new attributes through this method.
// NSInputServer examines the return value of this
// method & constructs appropriate attributed string.
- (NSArray *) validAttributesForMarkedText
{
return [NSArray array];
}
@end @end
/* This is the original behavior, before support was added for /* This is the original behavior, before support was added for
...@@ -478,11 +608,6 @@ Cocoa_InitKeyboard(_THIS) ...@@ -478,11 +608,6 @@ Cocoa_InitKeyboard(_THIS)
{ {
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
SDL_Keyboard keyboard; SDL_Keyboard keyboard;
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
data->fieldEdit = [[SDLTranslatorResponder alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)];
[pool release];
SDL_zero(keyboard); SDL_zero(keyboard);
data->keyboard = SDL_AddKeyboard(&keyboard, -1); data->keyboard = SDL_AddKeyboard(&keyboard, -1);
...@@ -497,6 +622,47 @@ Cocoa_InitKeyboard(_THIS) ...@@ -497,6 +622,47 @@ Cocoa_InitKeyboard(_THIS)
SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command"); SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command");
} }
void
Cocoa_StartTextInput(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSView *parentView = [[NSApp keyWindow] contentView];
data->fieldEdit = [[SDLTranslatorResponder alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)];
[data->fieldEdit setKeyboard: data->keyboard];
if (! [[data->fieldEdit superview] isEqual: parentView])
{
// DEBUG_IME(@"add fieldEdit to window contentView");
[data->fieldEdit removeFromSuperview];
[parentView addSubview: data->fieldEdit];
[[NSApp keyWindow] makeFirstResponder: data->fieldEdit];
}
[pool release];
}
void
Cocoa_StopTextInput(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[data->fieldEdit removeFromSuperview];
[data->fieldEdit release];
data->fieldEdit = nil;
[pool release];
}
void
Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
[data->fieldEdit setInputRect: rect];
}
void void
Cocoa_HandleKeyEvent(_THIS, NSEvent *event) Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
{ {
...@@ -533,11 +699,13 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event) ...@@ -533,11 +699,13 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
/* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */ /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */
[data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
#if 0
text = [[event characters] UTF8String]; text = [[event characters] UTF8String];
if(text && *text) { if(text && *text) {
SDL_SendKeyboardText(data->keyboard, text); SDL_SendKeyboardText(data->keyboard, text);
[data->fieldEdit setString:@""]; [data->fieldEdit setString:@""];
} }
#endif
} }
break; break;
case NSKeyUp: case NSKeyUp:
...@@ -559,10 +727,6 @@ Cocoa_QuitKeyboard(_THIS) ...@@ -559,10 +727,6 @@ Cocoa_QuitKeyboard(_THIS)
NSAutoreleasePool *pool; NSAutoreleasePool *pool;
SDL_DelKeyboard(data->keyboard); SDL_DelKeyboard(data->keyboard);
pool = [[NSAutoreleasePool alloc] init];
[data->fieldEdit release];
[pool release];
} }
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -250,6 +250,8 @@ Cocoa_SetDisplayMode(_THIS, SDL_DisplayMode * mode) ...@@ -250,6 +250,8 @@ Cocoa_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
CGReleaseDisplayFadeReservation(fade_token); CGReleaseDisplayFadeReservation(fade_token);
} }
[[NSApp mainWindow] makeKeyAndOrderFront: nil];
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
/* /*
There is a bug in Cocoa where NSScreen doesn't synchronize There is a bug in Cocoa where NSScreen doesn't synchronize
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
/* Private display data */ /* Private display data */
@class SDLTranslatorResponder;
typedef struct SDL_VideoData typedef struct SDL_VideoData
{ {
SInt32 osversion; SInt32 osversion;
...@@ -48,7 +50,7 @@ typedef struct SDL_VideoData ...@@ -48,7 +50,7 @@ typedef struct SDL_VideoData
int mouse; int mouse;
int keyboard; int keyboard;
void *key_layout; void *key_layout;
NSText *fieldEdit; SDLTranslatorResponder *fieldEdit;
Uint32 screensaver_activity; Uint32 screensaver_activity;
} SDL_VideoData; } SDL_VideoData;
......
...@@ -102,6 +102,10 @@ Cocoa_CreateDevice(int devindex) ...@@ -102,6 +102,10 @@ Cocoa_CreateDevice(int devindex)
device->GL_DeleteContext = Cocoa_GL_DeleteContext; device->GL_DeleteContext = Cocoa_GL_DeleteContext;
#endif #endif
device->StartTextInput = Cocoa_StartTextInput;
device->StopTextInput = Cocoa_StopTextInput;
device->SetTextInputRect = Cocoa_SetTextInputRect;
device->free = Cocoa_DeleteDevice; device->free = Cocoa_DeleteDevice;
return device; return device;
......
...@@ -7,7 +7,7 @@ EXE = @EXE@ ...@@ -7,7 +7,7 @@ EXE = @EXE@
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
LIBS = @LIBS@ LIBS = @LIBS@
TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testresample$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testpower$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testdyngles$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testgles$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE) testatomic$(EXE) TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testresample$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testpower$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testdyngles$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testgles$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE) testatomic$(EXE) testime$(EXE)
all: Makefile $(TARGETS) all: Makefile $(TARGETS)
...@@ -149,6 +149,9 @@ testmmousetablet$(EXE): $(srcdir)/testmmousetablet.c ...@@ -149,6 +149,9 @@ testmmousetablet$(EXE): $(srcdir)/testmmousetablet.c
testatomic$(EXE): $(srcdir)/testatomic.c testatomic$(EXE): $(srcdir)/testatomic.c
$(CC) -o $@ $? $(CFLAGS) $(LIBS) $(CC) -o $@ $? $(CFLAGS) $(LIBS)
testime$(EXE): $(srcdir)/testime.c
$(CC) -o $@ $? $(CFLAGS) $(LIBS) @SDL_TTF_LIB@
clean: clean:
rm -f $(TARGETS) rm -f $(TARGETS)
......
...@@ -128,5 +128,23 @@ fi ...@@ -128,5 +128,23 @@ fi
AC_SUBST(GLLIB) AC_SUBST(GLLIB)
dnl Check for SDL_ttf
AC_MSG_CHECKING(for SDL_ttf)
have_SDL_ttf=no
AC_TRY_COMPILE([
#include "SDL_ttf.h"
],[
],[
have_SDL_ttf=yes
])
AC_MSG_RESULT($have_SDL_ttf)
if test x$have_SDL_ttf = xyes; then
CFLAGS="$CFLAGS -DHAVE_SDL_TTF"
SDL_TTF_LIB="-lSDL_ttf"
fi
AC_SUBST(SDL_TTF_LIB)
dnl Finally create all the generated files dnl Finally create all the generated files
AC_OUTPUT([Makefile]) AC_OUTPUT([Makefile])
/* A simple program to test the Input Method support in the SDL library (1.3+) */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL.h"
#ifdef HAVE_SDL_TTF
#include "SDL_ttf.h"
#endif
#define DEFAULT_PTSIZE 30
#define DEFAULT_FONT "/System/Library/Fonts/华文细黑.ttf"
#define MAX_TEXT_LENGTH 256
SDL_Surface *screen;
#ifdef HAVE_SDL_TTF
TTF_Font *font;
#endif
SDL_Rect textRect, markedRect;
Uint32 lineColor, backColor;
SDL_Color textColor = { 0, 0, 0 };
char text[MAX_TEXT_LENGTH], *markedText;
void usage()
{
printf("usage: testime [--font fontfile] [--fullscreen]\n");
exit(0);
}
void InitVideo(int argc, char *argv[])
{
int width = 500, height = 250;
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_putenv("SDL_VIDEO_WINDOW_POS=center");
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "Unable to init SDL: %s\n", TTF_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", SDL_GetError());
exit(-1);
}
#endif
printf("Using font: %s\n", fontname);
atexit(SDL_Quit);
if (fullscreen)
{
SDL_DisplayMode mode;
SDL_GetDesktopDisplayMode(&mode);
width = mode.w;
height = mode.h;
fprintf(stderr, "%dx%d\n", width, height);
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.h = 50;
text[0] = 0;
markedRect = textRect;
markedText = NULL;
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)
{
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);
}
#endif
void Redraw()
{
int w = 0, h = textRect.h;
SDL_Rect cursorRect, underlineRect;
SDL_FillRect(screen, &textRect, backColor);
#ifdef HAVE_SDL_TTF
if (strlen(text))
{
RenderText(screen, font, text, textRect.x, textRect.y, textColor);
TTF_SizeUTF8(font, text, &w, &h);
}
#endif
markedRect.x = textRect.x + w;
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;
}
cursorRect = markedRect;
cursorRect.w = 2;
cursorRect.h = h;
SDL_FillRect(screen, &markedRect, backColor);
if (markedText)
{
#ifdef HAVE_SDL_TTF
RenderText(screen, font, markedText, markedRect.x, markedRect.y, textColor);
TTF_SizeUTF8(font, markedText, &w, &h);
#endif
underlineRect = markedRect;
underlineRect.y += (h - 2);
underlineRect.h = 2;
underlineRect.w = w;
cursorRect.x += w + 1;
SDL_FillRect(screen, &underlineRect, lineColor);
}
SDL_FillRect(screen, &cursorRect, lineColor);
SDL_Flip(screen);
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");
}
}
int main(int argc, char *argv[])
{
InitVideo(argc, argv);
InitInput();
Redraw();
SDL_Event event;
int done = 0;
while (! done && SDL_WaitEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) {
done = 1;
break;
}
fprintf(stderr,
"Keyboard %d: scancode 0x%08X = %s, keycode 0x%08X = %s\n",
event.key.which, 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 (strlen(event.text.text) == 0 || event.text.text[0] == '\n' ||
markedRect.w < 0)
break;
fprintf(stderr, "Keyboard %d: text input \"%s\"\n",
event.text.which, event.text.text);
if (strlen(text) + strlen(event.text.text) < sizeof(text))
strcpy(text + strlen(text), event.text.text);
fprintf(stderr, "text inputed: %s\n", text);
// After text inputed, we can clear up markedText because it
// is committed
markedText = NULL;
Redraw();
break;
case SDL_TEXTEDITING:
fprintf(stderr, "text editing \"%s\", selected range (%d, %d)\n",
event.edit.text, event.edit.start, event.edit.length);
markedText = event.edit.text;
Redraw();
break;
case SDL_QUIT:
done = 1;
break;
default:
break;
}
}
CleanupVideo();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment