test/testime.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 09 May 2010 20:47:22 -0700
changeset 4465 3e69e077cb95
parent 3581 15eea7a1fa97
child 4637 8c229370ddba
child 4756 b99b1024607a
permissions -rw-r--r--
Removed multi-mouse / multi-keyboard support in anticipation of a real multi-mouse and multi-touch API.

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