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