test/testime.c
author Jjgod Jiang <gzjjgod@gmail.com>
Thu, 12 Aug 2010 16:00:47 +0200
changeset 4637 8c229370ddba
parent 4465 3e69e077cb95
child 4638 08d22c54a21f
permissions -rw-r--r--
Fix for deleting the last uncommit character
slouken@3280
     1
/* A simple program to test the Input Method support in the SDL library (1.3+) */
slouken@3338
     2
slouken@3280
     3
#include <stdlib.h>
slouken@3280
     4
#include <stdio.h>
slouken@3280
     5
#include <string.h>
slouken@3280
     6
slouken@3280
     7
#include "SDL.h"
slouken@3280
     8
#ifdef HAVE_SDL_TTF
slouken@3280
     9
#include "SDL_ttf.h"
slouken@3280
    10
#endif
slouken@3338
    11
slouken@3280
    12
#define DEFAULT_PTSIZE  30
lestat@3478
    13
#ifdef __QNXNTO__
lestat@3478
    14
    #define DEFAULT_FONT    "/usr/photon/font_repository/tt0003m_.ttf"
lestat@3478
    15
#else
lestat@3478
    16
    #define DEFAULT_FONT    "/System/Library/Fonts/华文细黑.ttf"
lestat@3478
    17
#endif
slouken@3280
    18
#define MAX_TEXT_LENGTH 256
slouken@3280
    19
slouken@3280
    20
SDL_Surface *screen;
slouken@3280
    21
slouken@3280
    22
#ifdef HAVE_SDL_TTF
slouken@3280
    23
TTF_Font *font;
slouken@3280
    24
#endif
slouken@3280
    25
SDL_Rect textRect, markedRect;
slouken@3280
    26
Uint32 lineColor, backColor;
slouken@3280
    27
SDL_Color textColor = { 0, 0, 0 };
slouken@3280
    28
char text[MAX_TEXT_LENGTH], *markedText;
slouken@3280
    29
slouken@3280
    30
void usage()
slouken@3280
    31
{
slouken@3280
    32
    printf("usage: testime [--font fontfile] [--fullscreen]\n");
slouken@3280
    33
    exit(0);
slouken@3280
    34
}
slouken@3280
    35
slouken@3280
    36
void InitVideo(int argc, char *argv[])
slouken@3280
    37
{
lestat@3478
    38
    int width = 640, height = 480;
slouken@3280
    39
    int flags = SDL_HWSURFACE;
slouken@3280
    40
    const char *fontname = DEFAULT_FONT;
slouken@3280
    41
    int fullscreen = 0;
slouken@3280
    42
slouken@3280
    43
    for (argc--, argv++; argc > 0; argc--, argv++)
slouken@3280
    44
    {
slouken@3280
    45
        if (strcmp(argv[0], "--help") == 0)
slouken@3280
    46
            usage();
slouken@3280
    47
slouken@3280
    48
        else if (strcmp(argv[0], "--fullscreen") == 0)
slouken@3280
    49
            fullscreen = 1;
slouken@3280
    50
slouken@3280
    51
        else if (strcmp(argv[0], "--font") == 0)
slouken@3280
    52
        {
slouken@3280
    53
            argc--;
slouken@3280
    54
            argv++;
slouken@3280
    55
slouken@3280
    56
            if (argc > 0)
slouken@3280
    57
                fontname = argv[0];
slouken@3280
    58
            else
slouken@3280
    59
                usage();
slouken@3280
    60
        }
slouken@3280
    61
    }
slouken@3280
    62
icculus@3581
    63
    SDL_setenv("SDL_VIDEO_WINDOW_POS", "center", 1);
slouken@3280
    64
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
slouken@3280
    65
    {
bob@3281
    66
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
slouken@3280
    67
        exit(-1);
slouken@3280
    68
    }
slouken@3280
    69
slouken@3280
    70
#ifdef HAVE_SDL_TTF
slouken@3280
    71
    /* Initialize fonts */
slouken@3280
    72
    TTF_Init();
slouken@3280
    73
slouken@3280
    74
    font = TTF_OpenFont(fontname, DEFAULT_PTSIZE);
slouken@3280
    75
    if (! font)
slouken@3280
    76
    {
bob@3281
    77
        fprintf(stderr, "Failed to find font: %s\n", TTF_GetError());
slouken@3280
    78
        exit(-1);
slouken@3280
    79
    }
slouken@3280
    80
#endif
slouken@3280
    81
slouken@3280
    82
    printf("Using font: %s\n", fontname);
slouken@3280
    83
    atexit(SDL_Quit);
slouken@3280
    84
slouken@3280
    85
    if (fullscreen)
slouken@3280
    86
    {
slouken@3280
    87
        SDL_DisplayMode mode;
slouken@3280
    88
        SDL_GetDesktopDisplayMode(&mode);
slouken@3280
    89
slouken@3280
    90
        width = mode.w;
slouken@3280
    91
        height = mode.h;
slouken@3280
    92
        fprintf(stderr, "%dx%d\n", width, height);
slouken@3280
    93
        flags |= SDL_FULLSCREEN;
slouken@3280
    94
    }
slouken@3280
    95
slouken@3280
    96
    /* Create window */
slouken@3280
    97
    screen = SDL_SetVideoMode(width, height, 32, flags);
slouken@3280
    98
    if (screen == NULL)
slouken@3280
    99
    {
slouken@3280
   100
        fprintf(stderr, "Unable to set %dx%d video: %s\n",
slouken@3280
   101
                width, height, SDL_GetError());
slouken@3280
   102
        exit(-1);
slouken@3280
   103
    }
slouken@3280
   104
}
slouken@3280
   105
slouken@3280
   106
void CleanupVideo()
slouken@3280
   107
{
slouken@3280
   108
    SDL_StopTextInput();
slouken@3280
   109
#ifdef HAVE_SDL_TTF
slouken@3280
   110
    TTF_CloseFont(font);
slouken@3280
   111
    TTF_Quit();
slouken@3280
   112
#endif
slouken@3280
   113
}
slouken@3280
   114
slouken@3280
   115
void InitInput()
slouken@3280
   116
{
slouken@3280
   117
    backColor = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF);
slouken@3280
   118
    lineColor = SDL_MapRGB(screen->format, 0x0, 0x0, 0x0);
slouken@3280
   119
slouken@3280
   120
    /* Prepare a rect for text input */
slouken@3280
   121
    textRect.x = textRect.y = 100;
slouken@3280
   122
    textRect.w = screen->w - 2 * textRect.x;
slouken@3280
   123
    textRect.h = 50;
slouken@3280
   124
slouken@3280
   125
    text[0] = 0;
slouken@3280
   126
    markedRect = textRect;
slouken@3280
   127
    markedText = NULL;
slouken@3280
   128
slouken@3280
   129
    SDL_StartTextInput();
slouken@3280
   130
}
slouken@3280
   131
slouken@3280
   132
#ifdef HAVE_SDL_TTF
slouken@3280
   133
static void RenderText(SDL_Surface *sur,
slouken@3280
   134
                        TTF_Font *font,
slouken@3280
   135
                        const char *text,
slouken@3280
   136
                        int x, int y,
slouken@3280
   137
                        SDL_Color color)
slouken@3280
   138
{
gzjjgod@4637
   139
    if (text && strlen(text)) {
gzjjgod@4637
   140
        SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, color);
gzjjgod@4637
   141
        SDL_Rect dest = { x, y, textSur->w, textSur->h };
slouken@3280
   142
gzjjgod@4637
   143
        SDL_BlitSurface(textSur, NULL, sur, &dest);
gzjjgod@4637
   144
        SDL_FreeSurface(textSur);
gzjjgod@4637
   145
    }
slouken@3280
   146
}
slouken@3280
   147
#endif
slouken@3280
   148
slouken@3280
   149
void Redraw()
slouken@3280
   150
{
slouken@3280
   151
    int w = 0, h = textRect.h;
slouken@3280
   152
    SDL_Rect cursorRect, underlineRect;
slouken@3280
   153
slouken@3280
   154
    SDL_FillRect(screen, &textRect, backColor);
slouken@3280
   155
slouken@3280
   156
#ifdef HAVE_SDL_TTF
slouken@3280
   157
    if (strlen(text))
slouken@3280
   158
    {
slouken@3280
   159
        RenderText(screen, font, text, textRect.x, textRect.y, textColor);
slouken@3280
   160
        TTF_SizeUTF8(font, text, &w, &h);
slouken@3280
   161
    }
slouken@3280
   162
#endif
slouken@3280
   163
slouken@3280
   164
    markedRect.x = textRect.x + w;
slouken@3280
   165
    markedRect.w = textRect.w - w;
slouken@3280
   166
    if (markedRect.w < 0)
slouken@3280
   167
    {
slouken@3280
   168
        SDL_Flip(screen);
slouken@3280
   169
        // Stop text input because we cannot hold any more characters
slouken@3280
   170
        SDL_StopTextInput();
slouken@3280
   171
        return;
slouken@3280
   172
    }
lestat@3478
   173
    else
lestat@3478
   174
    {
lestat@3478
   175
        SDL_StartTextInput();
lestat@3478
   176
    }
slouken@3280
   177
slouken@3280
   178
    cursorRect = markedRect;
slouken@3280
   179
    cursorRect.w = 2;
slouken@3280
   180
    cursorRect.h = h;
slouken@3280
   181
slouken@3280
   182
    SDL_FillRect(screen, &markedRect, backColor);
slouken@3280
   183
    if (markedText)
slouken@3280
   184
    {
slouken@3280
   185
#ifdef HAVE_SDL_TTF
slouken@3280
   186
        RenderText(screen, font, markedText, markedRect.x, markedRect.y, textColor);
slouken@3280
   187
        TTF_SizeUTF8(font, markedText, &w, &h);
slouken@3280
   188
#endif
slouken@3280
   189
slouken@3280
   190
        underlineRect = markedRect;
slouken@3280
   191
        underlineRect.y += (h - 2);
slouken@3280
   192
        underlineRect.h = 2;
slouken@3280
   193
        underlineRect.w = w;
slouken@3280
   194
slouken@3280
   195
        cursorRect.x += w + 1;
slouken@3280
   196
slouken@3280
   197
        SDL_FillRect(screen, &underlineRect, lineColor);
slouken@3280
   198
    }
slouken@3280
   199
slouken@3280
   200
    SDL_FillRect(screen, &cursorRect, lineColor);
slouken@3280
   201
slouken@3280
   202
    SDL_Flip(screen);
slouken@3280
   203
slouken@3280
   204
    SDL_SetTextInputRect(&markedRect);
slouken@3280
   205
}
slouken@3280
   206
slouken@3280
   207
void
slouken@3280
   208
HotKey_ToggleFullScreen(void)
slouken@3280
   209
{
slouken@3280
   210
    SDL_Surface *screen;
slouken@3280
   211
slouken@3280
   212
    screen = SDL_GetVideoSurface();
slouken@3280
   213
    if (SDL_WM_ToggleFullScreen(screen)) {
slouken@3280
   214
        printf("Toggled fullscreen mode - now %s\n",
slouken@3280
   215
               (screen->flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed");
slouken@3280
   216
    } else {
slouken@3280
   217
        printf("Unable to toggle fullscreen mode\n");
slouken@3280
   218
    }
slouken@3280
   219
}
slouken@3280
   220
slouken@3280
   221
int main(int argc, char *argv[])
slouken@3280
   222
{
slouken@3338
   223
    SDL_Event event;
slouken@3338
   224
    int done = 0;
slouken@3338
   225
slouken@3280
   226
    InitVideo(argc, argv);
slouken@3280
   227
    InitInput();
slouken@3280
   228
    Redraw();
slouken@3280
   229
slouken@3280
   230
    while (! done && SDL_WaitEvent(&event))
slouken@3280
   231
    {
slouken@3280
   232
        switch (event.type)
slouken@3280
   233
        {
slouken@3280
   234
        case SDL_KEYDOWN:
lestat@3478
   235
            switch (event.key.keysym.sym)
lestat@3478
   236
            {
lestat@3478
   237
                case SDLK_ESCAPE:
lestat@3478
   238
                     done = 1;
lestat@3478
   239
                     break;
lestat@3478
   240
                case SDLK_RETURN:
lestat@3478
   241
                     text[0]=0x00;
lestat@3478
   242
                     Redraw();
lestat@3478
   243
                     break;
lestat@3478
   244
                case SDLK_BACKSPACE:
lestat@3478
   245
                     {
lestat@3478
   246
                         int textlen=SDL_strlen(text);
lestat@3478
   247
lestat@3478
   248
                         do {
lestat@3478
   249
                             if (textlen==0)
lestat@3478
   250
                             {
lestat@3478
   251
                                 break;
lestat@3478
   252
                             }
lestat@3478
   253
                             if ((text[textlen-1] & 0x80) == 0x00)
lestat@3478
   254
                             {
lestat@3478
   255
                                 /* One byte */
lestat@3478
   256
                                 text[textlen-1]=0x00;
lestat@3478
   257
                                 break;
lestat@3478
   258
                             }
lestat@3478
   259
                             if ((text[textlen-1] & 0xC0) == 0x80)
lestat@3478
   260
                             {
lestat@3478
   261
                                 /* Byte from the multibyte sequence */
lestat@3478
   262
                                 text[textlen-1]=0x00;
lestat@3478
   263
                                 textlen--;
lestat@3478
   264
                             }
lestat@3478
   265
                             if ((text[textlen-1] & 0xC0) == 0xC0)
lestat@3478
   266
                             {
lestat@3478
   267
                                 /* First byte of multibyte sequence */
lestat@3478
   268
                                 text[textlen-1]=0x00;
lestat@3478
   269
                                 break;
lestat@3478
   270
                             }
lestat@3478
   271
                         } while(1);
lestat@3478
   272
lestat@3478
   273
                         Redraw();
lestat@3478
   274
                     }
lestat@3478
   275
                     break;
lestat@3478
   276
            }
lestat@3478
   277
lestat@3478
   278
            if (done)
lestat@3478
   279
            {
slouken@3280
   280
                break;
slouken@3280
   281
            }
slouken@3280
   282
slouken@3280
   283
            fprintf(stderr,
slouken@4465
   284
                    "Keyboard: scancode 0x%08X = %s, keycode 0x%08X = %s\n",
slouken@4465
   285
                    event.key.keysym.scancode,
slouken@3280
   286
                    SDL_GetScancodeName(event.key.keysym.scancode),
slouken@3280
   287
                    event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym));
slouken@3280
   288
            break;
slouken@3280
   289
slouken@3280
   290
        case SDL_TEXTINPUT:
lestat@3478
   291
            if (SDL_strlen(event.text.text) == 0 || event.text.text[0] == '\n' ||
slouken@3280
   292
                markedRect.w < 0)
slouken@3280
   293
                break;
slouken@3280
   294
slouken@4465
   295
            fprintf(stderr, "Keyboard: text input \"%s\"\n", event.text.text);
slouken@3280
   296
lestat@3478
   297
            if (SDL_strlen(text) + SDL_strlen(event.text.text) < sizeof(text))
lestat@3478
   298
                strcpy(text + SDL_strlen(text), event.text.text);
slouken@3280
   299
slouken@3280
   300
            fprintf(stderr, "text inputed: %s\n", text);
slouken@3280
   301
slouken@3280
   302
            // After text inputed, we can clear up markedText because it
slouken@3280
   303
            // is committed
slouken@3280
   304
            markedText = NULL;
slouken@3280
   305
            Redraw();
slouken@3280
   306
            break;
slouken@3280
   307
slouken@3280
   308
        case SDL_TEXTEDITING:
slouken@3280
   309
            fprintf(stderr, "text editing \"%s\", selected range (%d, %d)\n",
slouken@3280
   310
                    event.edit.text, event.edit.start, event.edit.length);
slouken@3280
   311
slouken@3280
   312
            markedText = event.edit.text;
slouken@3280
   313
            Redraw();
slouken@3280
   314
            break;
slouken@3280
   315
slouken@3280
   316
        case SDL_QUIT:
slouken@3280
   317
            done = 1;
slouken@3280
   318
            break;
slouken@3280
   319
slouken@3280
   320
        default:
slouken@3280
   321
            break;
slouken@3280
   322
        }
slouken@3280
   323
    }
slouken@3280
   324
slouken@3280
   325
    CleanupVideo();
slouken@3280
   326
    return 0;
slouken@3280
   327
}