test/testime.c
author Jiang Jiang <gzjjgod@gmail.com>
Thu, 06 Aug 2009 08:59:53 +0000
branchgsoc2009_IME
changeset 3136 962357f325e1
parent 3134 f896821736fb
child 3137 311c678f3b2e
permissions -rw-r--r--
Further polish API, fix crash in test program.
gzjjgod@3131
     1
/* A simple program to test the Input Method support in the SDL library (1.3+) */
gzjjgod@3131
     2
 
gzjjgod@3131
     3
#include <stdlib.h>
gzjjgod@3131
     4
#include <stdio.h>
gzjjgod@3131
     5
#include <string.h>
gzjjgod@3131
     6
gzjjgod@3131
     7
#include "SDL.h"
gzjjgod@3131
     8
#include <SDL/SDL_ttf.h>
gzjjgod@3131
     9
 
gzjjgod@3131
    10
#define DEFAULT_PTSIZE  30
gzjjgod@3131
    11
#define DEFAULT_FONT    "DroidSansFallback.ttf"
gzjjgod@3131
    12
#define MAX_TEXT_LENGTH 256
gzjjgod@3131
    13
gzjjgod@3134
    14
SDL_Surface *screen;
gzjjgod@3134
    15
TTF_Font *font;
gzjjgod@3134
    16
SDL_Rect textRect, markedRect;
gzjjgod@3134
    17
Uint32 lineColor, backColor;
gzjjgod@3134
    18
SDL_Color textColor = { 0, 0, 0 };
gzjjgod@3134
    19
char text[MAX_TEXT_LENGTH], *markedText;
gzjjgod@3134
    20
gzjjgod@3134
    21
void InitVideo(int argc, char *argv[])
gzjjgod@3131
    22
{
gzjjgod@3134
    23
    int width = 500, height = 250;
gzjjgod@3131
    24
gzjjgod@3131
    25
    SDL_putenv("SDL_VIDEO_WINDOW_POS=center");
gzjjgod@3131
    26
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
gzjjgod@3131
    27
    {
gzjjgod@3131
    28
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
gzjjgod@3134
    29
        exit(-1);
gzjjgod@3131
    30
    }
gzjjgod@3131
    31
gzjjgod@3131
    32
    /* Initialize fonts */
gzjjgod@3131
    33
    TTF_Init();
gzjjgod@3131
    34
gzjjgod@3131
    35
    font = TTF_OpenFont(DEFAULT_FONT, DEFAULT_PTSIZE);
gzjjgod@3131
    36
    if (! font)
gzjjgod@3131
    37
    {
gzjjgod@3131
    38
        fprintf(stderr, "Failed to find font: %s\n", SDL_GetError());
gzjjgod@3131
    39
        exit(-1);
gzjjgod@3131
    40
    }
gzjjgod@3131
    41
gzjjgod@3131
    42
    atexit(SDL_Quit);
gzjjgod@3131
    43
gzjjgod@3134
    44
    int flags = SDL_HWSURFACE;
gzjjgod@3134
    45
    if (argc > 1 && strcmp(argv[1], "--fullscreen") == 0)
gzjjgod@3134
    46
    {
gzjjgod@3134
    47
        SDL_DisplayMode mode;
gzjjgod@3134
    48
        SDL_GetDesktopDisplayMode(&mode);
gzjjgod@3134
    49
gzjjgod@3134
    50
        width = mode.w;
gzjjgod@3134
    51
        height = mode.h;
gzjjgod@3134
    52
        fprintf(stderr, "%dx%d\n", width, height);
gzjjgod@3134
    53
        flags |= SDL_FULLSCREEN;
gzjjgod@3134
    54
    }
gzjjgod@3134
    55
gzjjgod@3131
    56
    /* Create window */
gzjjgod@3134
    57
    screen = SDL_SetVideoMode(width, height, 32, flags);
gzjjgod@3131
    58
    if (screen == NULL)
gzjjgod@3131
    59
    {
gzjjgod@3131
    60
        fprintf(stderr, "Unable to set %dx%d video: %s\n",
gzjjgod@3131
    61
                width, height, SDL_GetError());
gzjjgod@3134
    62
        exit(-1);
gzjjgod@3134
    63
    }
gzjjgod@3134
    64
}
gzjjgod@3134
    65
gzjjgod@3134
    66
void CleanupVideo()
gzjjgod@3134
    67
{
gzjjgod@3136
    68
    SDL_StopTextInput();
gzjjgod@3134
    69
    TTF_CloseFont(font);
gzjjgod@3134
    70
    TTF_Quit();
gzjjgod@3134
    71
}
gzjjgod@3134
    72
gzjjgod@3134
    73
void InitInput()
gzjjgod@3134
    74
{
gzjjgod@3134
    75
    backColor = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF);
gzjjgod@3134
    76
    lineColor = SDL_MapRGB(screen->format, 0x0, 0x0, 0x0);
gzjjgod@3134
    77
gzjjgod@3134
    78
    /* Prepare a rect for text input */
gzjjgod@3134
    79
    textRect.x = textRect.y = 100;
gzjjgod@3134
    80
    textRect.w = screen->w - 2 * textRect.x;
gzjjgod@3134
    81
    textRect.h = 50;
gzjjgod@3134
    82
gzjjgod@3134
    83
    text[0] = 0;
gzjjgod@3134
    84
    markedRect = textRect;
gzjjgod@3134
    85
    markedText = NULL;
gzjjgod@3136
    86
gzjjgod@3136
    87
    SDL_StartTextInput();
gzjjgod@3134
    88
}
gzjjgod@3134
    89
gzjjgod@3134
    90
static void RenderText(SDL_Surface *sur,
gzjjgod@3134
    91
                        TTF_Font *font,
gzjjgod@3134
    92
                        const char *text,
gzjjgod@3134
    93
                        int x, int y,
gzjjgod@3134
    94
                        SDL_Color color)
gzjjgod@3134
    95
{
gzjjgod@3134
    96
    SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, color);
gzjjgod@3134
    97
    SDL_Rect dest = { x, y, textSur->w, textSur->h };
gzjjgod@3134
    98
gzjjgod@3134
    99
    SDL_BlitSurface(textSur, NULL, sur, &dest);
gzjjgod@3134
   100
    SDL_FreeSurface(textSur);
gzjjgod@3134
   101
}
gzjjgod@3134
   102
gzjjgod@3134
   103
void Redraw()
gzjjgod@3134
   104
{
gzjjgod@3134
   105
    int w = 0, h = textRect.h;
gzjjgod@3134
   106
    SDL_Rect cursorRect, underlineRect;
gzjjgod@3134
   107
gzjjgod@3134
   108
    SDL_FillRect(screen, &textRect, backColor);
gzjjgod@3134
   109
gzjjgod@3134
   110
    if (strlen(text))
gzjjgod@3134
   111
    {
gzjjgod@3134
   112
        RenderText(screen, font, text, textRect.x, textRect.y, textColor);
gzjjgod@3134
   113
        TTF_SizeUTF8(font, text, &w, &h);
gzjjgod@3131
   114
    }
gzjjgod@3131
   115
gzjjgod@3134
   116
    markedRect.x = textRect.x + w;
gzjjgod@3134
   117
    markedRect.w = textRect.w - w;
gzjjgod@3134
   118
    if (markedRect.w < 0)
gzjjgod@3134
   119
    {
gzjjgod@3134
   120
        SDL_Flip(screen);
gzjjgod@3136
   121
        // Stop text input because we cannot hold any more characters
gzjjgod@3136
   122
        SDL_StopTextInput();
gzjjgod@3134
   123
        return;
gzjjgod@3134
   124
    }
gzjjgod@3131
   125
gzjjgod@3134
   126
    SDL_FillRect(screen, &markedRect, backColor);
gzjjgod@3134
   127
gzjjgod@3134
   128
    if (markedText)
gzjjgod@3134
   129
    {
gzjjgod@3134
   130
        RenderText(screen, font, markedText, markedRect.x, markedRect.y, textColor);
gzjjgod@3134
   131
        TTF_SizeUTF8(font, markedText, &w, &h);
gzjjgod@3134
   132
gzjjgod@3134
   133
        underlineRect = markedRect;
gzjjgod@3134
   134
        underlineRect.y += (h - 2);
gzjjgod@3134
   135
        underlineRect.h = 2;
gzjjgod@3134
   136
        underlineRect.w = w;
gzjjgod@3134
   137
        SDL_FillRect(screen, &underlineRect, lineColor);
gzjjgod@3134
   138
    }
gzjjgod@3134
   139
gzjjgod@3134
   140
    cursorRect = markedRect;
gzjjgod@3134
   141
    cursorRect.w = 2;
gzjjgod@3134
   142
    cursorRect.h = h;
gzjjgod@3134
   143
    SDL_FillRect(screen, &cursorRect, lineColor);
gzjjgod@3131
   144
gzjjgod@3131
   145
    SDL_Flip(screen);
gzjjgod@3131
   146
gzjjgod@3136
   147
    SDL_SetTextInputRect(&markedRect);
gzjjgod@3134
   148
}
gzjjgod@3134
   149
gzjjgod@3134
   150
void
gzjjgod@3134
   151
HotKey_ToggleFullScreen(void)
gzjjgod@3134
   152
{
gzjjgod@3134
   153
    SDL_Surface *screen;
gzjjgod@3134
   154
gzjjgod@3134
   155
    screen = SDL_GetVideoSurface();
gzjjgod@3134
   156
    if (SDL_WM_ToggleFullScreen(screen)) {
gzjjgod@3134
   157
        printf("Toggled fullscreen mode - now %s\n",
gzjjgod@3134
   158
               (screen->flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed");
gzjjgod@3134
   159
    } else {
gzjjgod@3134
   160
        printf("Unable to toggle fullscreen mode\n");
gzjjgod@3134
   161
    }
gzjjgod@3134
   162
}
gzjjgod@3134
   163
gzjjgod@3134
   164
int main(int argc, char *argv[])
gzjjgod@3134
   165
{
gzjjgod@3134
   166
    InitVideo(argc, argv);
gzjjgod@3134
   167
    InitInput();
gzjjgod@3134
   168
    Redraw();
gzjjgod@3134
   169
gzjjgod@3131
   170
    SDL_Event event;
gzjjgod@3134
   171
    int done = 0;
gzjjgod@3131
   172
gzjjgod@3131
   173
    while (! done && SDL_WaitEvent(&event))
gzjjgod@3131
   174
    {
gzjjgod@3131
   175
        switch (event.type)
gzjjgod@3131
   176
        {
gzjjgod@3131
   177
        case SDL_KEYDOWN:
gzjjgod@3134
   178
            if (event.key.keysym.sym == SDLK_ESCAPE) {
gzjjgod@3134
   179
                done = 1;
gzjjgod@3134
   180
                break;
gzjjgod@3134
   181
            }
gzjjgod@3134
   182
gzjjgod@3131
   183
            fprintf(stderr,
gzjjgod@3131
   184
                    "Keyboard %d: scancode 0x%08X = %s, keycode 0x%08X = %s\n",
gzjjgod@3131
   185
                    event.key.which, event.key.keysym.scancode,
gzjjgod@3131
   186
                    SDL_GetScancodeName(event.key.keysym.scancode),
gzjjgod@3131
   187
                    event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym));
gzjjgod@3131
   188
            break;
gzjjgod@3131
   189
gzjjgod@3131
   190
        case SDL_TEXTINPUT:
gzjjgod@3134
   191
            if (strlen(event.text.text) == 0 || event.text.text[0] == '\n' ||
gzjjgod@3134
   192
                markedRect.w < 0)
gzjjgod@3134
   193
                break;
gzjjgod@3134
   194
gzjjgod@3131
   195
            fprintf(stderr, "Keyboard %d: text input \"%s\"\n",
gzjjgod@3131
   196
                    event.text.which, event.text.text);
gzjjgod@3131
   197
gzjjgod@3134
   198
            if (strlen(text) + strlen(event.text.text) < sizeof(text))
gzjjgod@3134
   199
                strcpy(text + strlen(text), event.text.text);
gzjjgod@3131
   200
gzjjgod@3131
   201
            fprintf(stderr, "text inputed: %s\n", text);
gzjjgod@3131
   202
gzjjgod@3134
   203
            // After text inputed, we can clear up markedText because it
gzjjgod@3134
   204
            // is committed
gzjjgod@3134
   205
            markedText = NULL;
gzjjgod@3134
   206
            Redraw();
gzjjgod@3131
   207
            break;
gzjjgod@3131
   208
gzjjgod@3132
   209
        case SDL_TEXTEDITING:
gzjjgod@3132
   210
            fprintf(stderr, "text editing \"%s\", selected range (%d, %d)\n",
gzjjgod@3132
   211
                    event.edit.text, event.edit.start, event.edit.length);
gzjjgod@3132
   212
gzjjgod@3134
   213
            markedText = event.edit.text;
gzjjgod@3134
   214
            Redraw();
gzjjgod@3132
   215
            break;
gzjjgod@3132
   216
gzjjgod@3131
   217
        case SDL_QUIT:
gzjjgod@3131
   218
            done = 1;
gzjjgod@3131
   219
            break;
gzjjgod@3131
   220
gzjjgod@3131
   221
        default:
gzjjgod@3131
   222
            break;
gzjjgod@3131
   223
        }
gzjjgod@3131
   224
    }
gzjjgod@3131
   225
gzjjgod@3134
   226
    CleanupVideo();
gzjjgod@3131
   227
    return 0;
gzjjgod@3131
   228
}
gzjjgod@3131
   229