test/testime.c
author Andreas Schiffler <aschiffler@ferzkopp.net>
Mon, 03 Jun 2013 19:24:18 -0700
changeset 7268 b399d0441810
parent 7191 75360622e65f
child 7517 965d57022c01
permissions -rw-r--r--
Add missing VS2012 test projects; update VS2010 and VS2012 solutions; update keybord suite for VS compiler warnings
slouken@5535
     1
/*
slouken@5535
     2
  Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@6251
    12
/* A simple program to test the Input Method support in the SDL library (2.0+) */
slouken@3338
    13
slouken@3280
    14
#include <stdlib.h>
slouken@3280
    15
#include <stdio.h>
slouken@3280
    16
#include <string.h>
slouken@3280
    17
slouken@3280
    18
#include "SDL.h"
slouken@3280
    19
#ifdef HAVE_SDL_TTF
slouken@3280
    20
#include "SDL_ttf.h"
slouken@3280
    21
#endif
slouken@3338
    22
slouken@6785
    23
#include "SDL_test_common.h"
dimitris@6318
    24
slouken@3280
    25
#define DEFAULT_PTSIZE  30
slouken@5150
    26
#define DEFAULT_FONT    "/System/Library/Fonts/华文细黑.ttf"
slouken@3280
    27
#define MAX_TEXT_LENGTH 256
slouken@3280
    28
slouken@6785
    29
static SDLTest_CommonState *state;
dimitris@6318
    30
static SDL_Rect textRect, markedRect;
dimitris@6318
    31
static SDL_Color lineColor = {0,0,0,0};
dimitris@6318
    32
static SDL_Color backColor = {255,255,255,0};
dimitris@6318
    33
static SDL_Color textColor = {0,0,0,0};
dimitris@6318
    34
static char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
dimitris@6318
    35
static int cursor = 0;
slouken@3280
    36
#ifdef HAVE_SDL_TTF
dimitris@6318
    37
static TTF_Font *font;
slouken@3280
    38
#endif
dewyatt@4757
    39
slouken@5150
    40
size_t utf8_length(unsigned char c)
slouken@5150
    41
{
slouken@5150
    42
    c = (unsigned char)(0xff & c);
slouken@5150
    43
    if (c < 0x80)
slouken@5150
    44
        return 1;
slouken@5150
    45
    else if ((c >> 5) ==0x6)
slouken@5150
    46
        return 2;
slouken@5150
    47
    else if ((c >> 4) == 0xe)
slouken@5150
    48
        return 3;
slouken@5150
    49
    else if ((c >> 3) == 0x1e)
slouken@5150
    50
        return 4;
slouken@5150
    51
    else
slouken@5150
    52
        return 0;
slouken@5150
    53
}
slouken@5150
    54
slouken@5150
    55
char *utf8_next(char *p)
slouken@5150
    56
{
slouken@5150
    57
    size_t len = utf8_length(*p);
slouken@5150
    58
    size_t i = 0;
slouken@5150
    59
    if (!len)
slouken@5150
    60
        return 0;
slouken@5150
    61
slouken@5150
    62
    for (; i < len; ++i)
slouken@5150
    63
    {
slouken@5150
    64
        ++p;
slouken@5150
    65
        if (!*p)
slouken@5150
    66
            return 0;
slouken@5150
    67
    }
slouken@5150
    68
    return p;
slouken@5150
    69
}
dewyatt@4757
    70
dewyatt@4757
    71
char *utf8_advance(char *p, size_t distance)
dewyatt@4757
    72
{
dewyatt@4757
    73
    size_t i = 0;
dewyatt@4757
    74
    for (; i < distance && p; ++i)
dewyatt@4757
    75
    {
dewyatt@4757
    76
        p = utf8_next(p);
dewyatt@4757
    77
    }
dewyatt@4757
    78
    return p;
dewyatt@4757
    79
}
slouken@3280
    80
slouken@3280
    81
void usage()
slouken@3280
    82
{
dimitris@6318
    83
    printf("usage: testime [--font fontfile]\n");
slouken@3280
    84
    exit(0);
slouken@3280
    85
}
slouken@3280
    86
dimitris@6318
    87
void InitInput()
slouken@3280
    88
{
dimitris@6318
    89
dimitris@6318
    90
    /* Prepare a rect for text input */
dimitris@6318
    91
    textRect.x = textRect.y = 100;
dimitris@6318
    92
    textRect.w = DEFAULT_WINDOW_WIDTH - 2 * textRect.x;
dimitris@6318
    93
    textRect.h = 50;
dimitris@6318
    94
dimitris@6318
    95
    text[0] = 0;
dimitris@6318
    96
    markedRect = textRect;
dimitris@6318
    97
    markedText[0] = 0;
dimitris@6318
    98
dimitris@6318
    99
    SDL_StartTextInput();
dimitris@6318
   100
}
dimitris@6318
   101
dimitris@6318
   102
void CleanupVideo()
dimitris@6318
   103
{
dimitris@6318
   104
    SDL_StopTextInput();
dimitris@6318
   105
#ifdef HAVE_SDL_TTF
dimitris@6318
   106
    TTF_CloseFont(font);
dimitris@6318
   107
    TTF_Quit();
dimitris@6318
   108
#endif
dimitris@6318
   109
}
dimitris@6318
   110
dimitris@6318
   111
dimitris@6318
   112
void _Redraw(SDL_Renderer * renderer) {
dimitris@6318
   113
    int w = 0, h = textRect.h;
dimitris@6318
   114
    SDL_Rect cursorRect, underlineRect;
dimitris@6318
   115
dimitris@6318
   116
    SDL_SetRenderDrawColor(renderer, 255,255,255,255);
dimitris@6318
   117
    SDL_RenderFillRect(renderer,&textRect);
dimitris@6318
   118
dimitris@6318
   119
#ifdef HAVE_SDL_TTF
dimitris@6318
   120
    if (*text)
dimitris@6318
   121
    {
dimitris@6318
   122
        SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, textColor);
dimitris@6318
   123
        SDL_Rect dest = {textRect.x, textRect.y, textSur->w, textSur->h };
dimitris@6318
   124
dimitris@6318
   125
        SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur);
dimitris@6318
   126
        SDL_FreeSurface(textSur);
dimitris@6318
   127
dimitris@6318
   128
        SDL_RenderCopy(renderer,texture,NULL,&dest);
dimitris@6318
   129
        SDL_DestroyTexture(texture);
dimitris@6318
   130
        TTF_SizeUTF8(font, text, &w, &h);
dimitris@6318
   131
    }
dimitris@6318
   132
#endif
dimitris@6318
   133
dimitris@6318
   134
    markedRect.x = textRect.x + w;
dimitris@6318
   135
    markedRect.w = textRect.w - w;
dimitris@6318
   136
    if (markedRect.w < 0)
dimitris@6318
   137
    {
dimitris@6318
   138
        // Stop text input because we cannot hold any more characters
dimitris@6318
   139
        SDL_StopTextInput();
dimitris@6318
   140
        return;
dimitris@6318
   141
    }
dimitris@6318
   142
    else
dimitris@6318
   143
    {
dimitris@6318
   144
        SDL_StartTextInput();
dimitris@6318
   145
    }
dimitris@6318
   146
dimitris@6318
   147
    cursorRect = markedRect;
dimitris@6318
   148
    cursorRect.w = 2;
dimitris@6318
   149
    cursorRect.h = h;
dimitris@6318
   150
dimitris@6318
   151
    SDL_SetRenderDrawColor(renderer, 255,255,255,255);
dimitris@6318
   152
    SDL_RenderFillRect(renderer,&markedRect);
dimitris@6318
   153
dimitris@6318
   154
    if (markedText[0])
dimitris@6318
   155
    {
dimitris@6318
   156
#ifdef HAVE_SDL_TTF
dimitris@6318
   157
        if (cursor)
dimitris@6318
   158
        {
dimitris@6318
   159
            char *p = utf8_advance(markedText, cursor);
dimitris@6318
   160
            char c = 0;
dimitris@6318
   161
            if (!p)
dimitris@6318
   162
                p = &markedText[strlen(markedText)];
dimitris@6318
   163
dimitris@6318
   164
            c = *p;
dimitris@6318
   165
            *p = 0;
dimitris@6318
   166
            TTF_SizeUTF8(font, markedText, &w, 0);
dimitris@6318
   167
            cursorRect.x += w;
dimitris@6318
   168
            *p = c;
dimitris@6318
   169
        }
dimitris@6318
   170
        SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, markedText, textColor);
dimitris@6318
   171
        SDL_Rect dest = {markedRect.x, markedRect.y, textSur->w, textSur->h };
dimitris@6318
   172
        TTF_SizeUTF8(font, markedText, &w, &h);
dimitris@6318
   173
        SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur);
dimitris@6318
   174
        SDL_FreeSurface(textSur);
dimitris@6318
   175
dimitris@6318
   176
        SDL_RenderCopy(renderer,texture,NULL,&dest);
dimitris@6318
   177
        SDL_DestroyTexture(texture);
dimitris@6318
   178
#endif
dimitris@6318
   179
dimitris@6318
   180
        underlineRect = markedRect;
dimitris@6318
   181
        underlineRect.y += (h - 2);
dimitris@6318
   182
        underlineRect.h = 2;
dimitris@6318
   183
        underlineRect.w = w;
dimitris@6318
   184
dimitris@6318
   185
        SDL_SetRenderDrawColor(renderer, 0,0,0,0);
dimitris@6318
   186
        SDL_RenderFillRect(renderer,&markedRect);
dimitris@6318
   187
    }
dimitris@6318
   188
dimitris@6318
   189
    SDL_SetRenderDrawColor(renderer, 0,0,0,0);
dimitris@6318
   190
    SDL_RenderFillRect(renderer,&cursorRect);
dimitris@6318
   191
dimitris@6318
   192
    SDL_SetTextInputRect(&markedRect);
dimitris@6318
   193
}
dimitris@6318
   194
dimitris@6318
   195
void Redraw() {
dimitris@6318
   196
    int i;
dimitris@6318
   197
    for (i = 0; i < state->num_windows; ++i) {
dimitris@6318
   198
        SDL_Renderer *renderer = state->renderers[i];
dimitris@6318
   199
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
dimitris@6318
   200
        SDL_RenderClear(renderer);
dimitris@6318
   201
dimitris@6318
   202
        _Redraw(renderer);
dimitris@6318
   203
dimitris@6318
   204
        SDL_RenderPresent(renderer);
dimitris@6318
   205
    }
dimitris@6318
   206
}
dimitris@6318
   207
dimitris@6318
   208
int main(int argc, char *argv[]) {
dimitris@6318
   209
    int i, done;
dimitris@6318
   210
    SDL_Event event;
slouken@3280
   211
    const char *fontname = DEFAULT_FONT;
slouken@3280
   212
dimitris@6318
   213
    /* Initialize test framework */
slouken@6785
   214
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
dimitris@6318
   215
    if (!state) {
dimitris@6318
   216
        return 1;
dimitris@6318
   217
    }
dimitris@6318
   218
    for (i = 1; i < argc;i++) {
slouken@6785
   219
        SDLTest_CommonArg(state, i);
dimitris@6318
   220
    }
slouken@3280
   221
    for (argc--, argv++; argc > 0; argc--, argv++)
slouken@3280
   222
    {
dimitris@6318
   223
        if (strcmp(argv[0], "--help") == 0) {
slouken@3280
   224
            usage();
dimitris@6318
   225
            return 0;
dimitris@6318
   226
        }
slouken@3280
   227
slouken@3280
   228
        else if (strcmp(argv[0], "--font") == 0)
slouken@3280
   229
        {
slouken@3280
   230
            argc--;
slouken@3280
   231
            argv++;
slouken@3280
   232
slouken@3280
   233
            if (argc > 0)
slouken@3280
   234
                fontname = argv[0];
dimitris@6318
   235
            else {
slouken@3280
   236
                usage();
dimitris@6318
   237
                return 0;
dimitris@6318
   238
            }
slouken@3280
   239
        }
slouken@3280
   240
    }
slouken@7191
   241
slouken@6785
   242
    if (!SDLTest_CommonInit(state)) {
dimitris@6318
   243
        return 2;
dimitris@6318
   244
    }
slouken@3280
   245
slouken@3280
   246
slouken@3280
   247
#ifdef HAVE_SDL_TTF
slouken@3280
   248
    /* Initialize fonts */
slouken@3280
   249
    TTF_Init();
slouken@3280
   250
slouken@3280
   251
    font = TTF_OpenFont(fontname, DEFAULT_PTSIZE);
slouken@3280
   252
    if (! font)
slouken@3280
   253
    {
bob@3281
   254
        fprintf(stderr, "Failed to find font: %s\n", TTF_GetError());
slouken@3280
   255
        exit(-1);
slouken@3280
   256
    }
slouken@3280
   257
#endif
slouken@3280
   258
slouken@3280
   259
    printf("Using font: %s\n", fontname);
slouken@3280
   260
    atexit(SDL_Quit);
slouken@3280
   261
dimitris@6318
   262
    InitInput();
dimitris@6318
   263
    /* Create the windows and initialize the renderers */
dimitris@6318
   264
    for (i = 0; i < state->num_windows; ++i) {
dimitris@6318
   265
        SDL_Renderer *renderer = state->renderers[i];
dimitris@6318
   266
        SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
dimitris@6318
   267
        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
dimitris@6318
   268
        SDL_RenderClear(renderer);
slouken@3280
   269
    }
slouken@7191
   270
    Redraw();
dimitris@6318
   271
    /* Main render loop */
dimitris@6318
   272
    done = 0;
dimitris@6318
   273
    while (!done) {
dimitris@6318
   274
        /* Check for events */
dimitris@6318
   275
        while (SDL_PollEvent(&event)) {
slouken@6785
   276
            SDLTest_CommonEvent(state, &event, &done);
dimitris@6318
   277
            switch(event.type) {
dimitris@6318
   278
                case SDL_KEYDOWN: {
dimitris@6318
   279
                    switch (event.key.keysym.sym)
dimitris@6318
   280
                    {
dimitris@6318
   281
                        case SDLK_RETURN:
dimitris@6318
   282
                             text[0]=0x00;
dimitris@6318
   283
                             Redraw();
dimitris@6318
   284
                             break;
dimitris@6318
   285
                        case SDLK_BACKSPACE:
dimitris@6318
   286
                             {
dimitris@6318
   287
                                 int textlen=SDL_strlen(text);
slouken@3280
   288
dimitris@6318
   289
                                 do {
dimitris@6318
   290
                                     if (textlen==0)
dimitris@6318
   291
                                     {
dimitris@6318
   292
                                         break;
dimitris@6318
   293
                                     }
dimitris@6318
   294
                                     if ((text[textlen-1] & 0x80) == 0x00)
dimitris@6318
   295
                                     {
dimitris@6318
   296
                                         /* One byte */
dimitris@6318
   297
                                         text[textlen-1]=0x00;
dimitris@6318
   298
                                         break;
dimitris@6318
   299
                                     }
dimitris@6318
   300
                                     if ((text[textlen-1] & 0xC0) == 0x80)
dimitris@6318
   301
                                     {
dimitris@6318
   302
                                         /* Byte from the multibyte sequence */
dimitris@6318
   303
                                         text[textlen-1]=0x00;
dimitris@6318
   304
                                         textlen--;
dimitris@6318
   305
                                     }
dimitris@6318
   306
                                     if ((text[textlen-1] & 0xC0) == 0xC0)
dimitris@6318
   307
                                     {
dimitris@6318
   308
                                         /* First byte of multibyte sequence */
dimitris@6318
   309
                                         text[textlen-1]=0x00;
dimitris@6318
   310
                                         break;
dimitris@6318
   311
                                     }
dimitris@6318
   312
                                 } while(1);
dimitris@6318
   313
dimitris@6318
   314
                                 Redraw();
dimitris@6318
   315
                             }
dimitris@6318
   316
                             break;
dimitris@6318
   317
                    }
dimitris@6318
   318
dimitris@6318
   319
                    if (done)
dimitris@6318
   320
                    {
dimitris@6318
   321
                        break;
dimitris@6318
   322
                    }
dimitris@6318
   323
dimitris@6318
   324
                    fprintf(stderr,
dimitris@6318
   325
                            "Keyboard: scancode 0x%08X = %s, keycode 0x%08X = %s\n",
dimitris@6318
   326
                            event.key.keysym.scancode,
dimitris@6318
   327
                            SDL_GetScancodeName(event.key.keysym.scancode),
dimitris@6318
   328
                            event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym));
dimitris@6318
   329
                    break;
dimitris@6318
   330
dimitris@6318
   331
                case SDL_TEXTINPUT:
dimitris@6318
   332
                    if (SDL_strlen(event.text.text) == 0 || event.text.text[0] == '\n' ||
dimitris@6318
   333
                        markedRect.w < 0)
dimitris@6318
   334
                        break;
dimitris@6318
   335
dimitris@6318
   336
                    fprintf(stderr, "Keyboard: text input \"%s\"\n", event.text.text);
dimitris@6318
   337
dimitris@6318
   338
                    if (SDL_strlen(text) + SDL_strlen(event.text.text) < sizeof(text))
dimitris@6318
   339
                        SDL_strlcat(text, event.text.text, sizeof(text));
dimitris@6318
   340
dimitris@6318
   341
                    fprintf(stderr, "text inputed: %s\n", text);
dimitris@6318
   342
dimitris@6318
   343
                    // After text inputed, we can clear up markedText because it
dimitris@6318
   344
                    // is committed
dimitris@6318
   345
                    markedText[0] = 0;
dimitris@6318
   346
                    Redraw();
dimitris@6318
   347
                    break;
dimitris@6318
   348
dimitris@6318
   349
                case SDL_TEXTEDITING:
dimitris@6318
   350
                    fprintf(stderr, "text editing \"%s\", selected range (%d, %d)\n",
dimitris@6318
   351
                            event.edit.text, event.edit.start, event.edit.length);
dimitris@6318
   352
dimitris@6318
   353
                    strcpy(markedText, event.edit.text);
dimitris@6318
   354
                    cursor = event.edit.start;
dimitris@6318
   355
                    Redraw();
dimitris@6318
   356
                    break;
dimitris@6318
   357
                }
dimitris@6318
   358
                break;
slouken@7191
   359
dimitris@6318
   360
            }
dimitris@6318
   361
        }
slouken@3280
   362
    }
dimitris@6318
   363
    CleanupVideo();
slouken@6785
   364
    SDLTest_CommonQuit(state);
dimitris@6318
   365
    return 0;
slouken@3280
   366
}
slouken@3280
   367
slouken@5244
   368
slouken@5244
   369
/* vi: set ts=4 sw=4 expandtab: */