--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <SDL.h>
+#include <SDL_him.h>
+#include <SDL_ttf.h>
+
+static SDL_Surface *screen;
+static TTF_Font* font;
+static char text[100] = { '\0' };
+static char editing[100] = { '\0' };
+static char temp[100];
+static int cursor = 0;
+static SDL_Color back_color = { 255, 255, 255 };
+static SDL_Color text_color = { 0, 0, 0 };
+static SDL_Color editing_color = { 125, 125, 125 };
+unsigned int him_flags = HIM_MODE_FULL | HIM_MODE_MULTILINE | HIM_MODE_AUTOCAP | HIM_MODE_DICTIONARY;
+
+#define HIM_EVENT (SDL_USEREVENT + 1)
+
+static void draw()
+{
+ SDL_Surface *text_surface;
+ char in_cursor;
+ int res;
+ unsigned int cursor_x, cursor_h, after_x;
+
+ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,
+ back_color.r, back_color.g, back_color.b));
+
+ cursor_h = 22; /* Sane default */
+
+ /* Render everything before cursor */
+ in_cursor = text[cursor];
+ text[cursor] = '\0';
+ if (text[0]) {
+ text_surface = TTF_RenderUTF8_Shaded(font, text, text_color, back_color);
+ assert(text_surface != NULL);
+ res = SDL_BlitSurface(text_surface, NULL, screen, NULL);
+ assert(res == 0);
+ cursor_x = text_surface->w;
+ cursor_h = text_surface->h;
+ SDL_FreeSurface(text_surface);
+ } else {
+ cursor_x = 0;
+ }
+ text[cursor] = in_cursor;
+
+ /* Render editing text, if any */
+ if (editing[0]) {
+ SDL_Rect rect = {cursor_x, 0, 0, 0};
+ text_surface = TTF_RenderUTF8_Shaded(font, editing, editing_color, back_color);
+ assert(text_surface != NULL);
+ res = SDL_BlitSurface(text_surface, NULL, screen, &rect);
+ assert(res == 0);
+ after_x = cursor_x + text_surface->w;
+ cursor_h = text_surface->h;
+ SDL_FreeSurface(text_surface);
+ } else {
+ after_x = cursor_x;
+ }
+
+ /* Render everything after the cursor */
+ if (in_cursor) {
+ SDL_Rect rect = {after_x, 0, 0, 0};
+ text_surface = TTF_RenderUTF8_Shaded(font, &text[cursor], text_color, back_color);
+ assert(text_surface != NULL);
+ res = SDL_BlitSurface(text_surface, NULL, screen, &rect);
+ assert(res == 0);
+ cursor_h = text_surface->h;
+ SDL_FreeSurface(text_surface);
+ }
+
+ /* Draw the cursor */
+ {
+ SDL_Rect rect = {cursor_x, 0, 4, cursor_h};
+ SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format,
+ text_color.r, text_color.g, text_color.b));
+ }
+
+ SDL_Flip(screen);
+}
+
+static void toggle_fullscreen()
+{
+ unsigned int flags;
+ unsigned short x, y;
+ if (screen->flags & SDL_FULLSCREEN) {
+ flags = screen->flags & ~SDL_FULLSCREEN;
+ x = 720; y = 420;
+ } else {
+ flags = screen->flags | SDL_FULLSCREEN;
+ x = 800; y = 480;
+ }
+
+ HIM_Disable();
+ screen = SDL_SetVideoMode(x, y, 16, flags);
+ HIM_Enable(him_flags);
+
+ draw();
+}
+
+static void handle_special_key(SDLKey key) {
+ switch(key) {
+ case SDLK_BACKSPACE:
+ if (cursor > 0) {
+ cursor--;
+ strcpy(&text[cursor], &text[cursor+1]);
+ }
+ draw();
+ break;
+ case SDLK_SPACE:
+ text[cursor++] = ' ';
+ break;
+ case SDLK_LEFT:
+ if (cursor > 0) {
+ cursor--;
+ draw();
+ }
+ break;
+ case SDLK_RIGHT:
+ if (cursor < strlen(text)) {
+ cursor++;
+ draw();
+ }
+ break;
+ case SDLK_F6:
+ toggle_fullscreen();
+ break;
+ default:
+ /* blah */
+ break;
+ }
+}
+
+int main()
+{
+ int res;
+ res = SDL_Init(SDL_INIT_VIDEO);
+ assert(res == 0);
+
+ screen = SDL_SetVideoMode(720, 420, 16, SDL_SWSURFACE | SDL_RESIZABLE);
+ assert(screen != NULL);
+
+ res = HIM_Init(0, HIM_EVENT);
+ assert(res == 0);
+
+ res = TTF_Init();
+ assert(res == 0);
+
+ font = TTF_OpenFont("/usr/share/fonts/nokia/nosnr.ttf", 26);
+ assert(font != NULL);
+
+ draw();
+
+ HIM_Enable(him_flags);
+
+ SDL_Event event;
+ while (SDL_WaitEvent(&event)) {
+ if (HIM_FilterEvent(&event)) continue;
+ switch (event.type) {
+ case SDL_QUIT:
+ goto quit;
+ case SDL_VIDEOEXPOSE:
+ draw();
+ break;
+ case SDL_VIDEORESIZE:
+ printf("New screen size %dx%d\n", event.resize.w, event.resize.h);
+ screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16, screen->flags);
+ draw();
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ HIM_ShowKeyboard(HIM_TRIGGER_FINGER);
+ break;
+ case SDL_KEYDOWN:
+ printf("Key Down: %s (unicode=%x)\n",
+ SDL_GetKeyName(event.key.keysym.sym),
+ event.key.keysym.unicode);
+ handle_special_key(event.key.keysym.sym);
+ break;
+ case SDL_KEYUP:
+ printf("Key Up: %s\n", SDL_GetKeyName(event.key.keysym.sym));
+ break;
+ case HIM_EVENT:
+ switch (((HIM_TextEvent*)&event)->code) {
+ case HIM_TEXTINPUTEVENT:
+ printf("Text Input Event: %s\n",
+ ((HIM_TextInputEvent*)&event)->text);
+ strcpy(temp, &text[cursor]);
+ strcpy(&text[cursor], ((HIM_TextInputEvent*)&event)->text);
+ strcat(&text[cursor], temp);
+ cursor+=strlen(((HIM_TextInputEvent*)&event)->text);
+ editing[0] = '\0'; /* On input, clear the preedit area. */
+ draw();
+ break;
+ case HIM_TEXTEDITINGEVENT:
+ printf("Text Editing Event: %s\n",
+ ((HIM_TextEditingEvent*)&event)->text);
+ strcpy(editing, ((HIM_TextEditingEvent*)&event)->text);
+ draw();
+ break;
+ case HIM_SPECIALKEYEVENT:
+ printf("Special Key: %s\n", SDL_GetKeyName(
+ ((HIM_SpecialKeyEvent*)&event)->sym));
+ handle_special_key(((HIM_SpecialKeyEvent*)&event)->sym);
+ break;
+ case HIM_CURSORMOVEEVENT:
+ printf("Cursor Move (%s): %d\n",
+ ((HIM_CursorMoveEvent*)&event)->relative ? "relative" : "absolute",
+ ((HIM_CursorMoveEvent*)&event)->offset);
+ if (((HIM_CursorMoveEvent*)&event)->relative) {
+ cursor += ((HIM_CursorMoveEvent*)&event)->offset;
+ }
+ draw();
+ break;
+ case HIM_REQUESTSURROUNDINGEVENT:
+ printf("Surrounding Request\n");
+ HIM_SendSurrounding(text, cursor);
+ break;
+ case HIM_CLIPBOARDEVENT:
+ switch (((HIM_ClipboardEvent*)&event)->action) {
+ case HIM_CLIPBOARD_CUT:
+ printf("Clipboard Cut\n");
+ break;
+ case HIM_CLIPBOARD_COPY:
+ printf("Clipboard Copy\n");
+ break;
+ case HIM_CLIPBOARD_PASTE:
+ printf("Clipboard Paste\n");
+ break;
+ case HIM_CLIPBOARD_REQUEST_SELECTION:
+ printf("Clipboard Request Selection\n");
+ HIM_SendSelection("Selected");
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ }
+
+quit:
+ HIM_Quit();
+ TTF_CloseFont(font);
+ TTF_Quit();
+ SDL_Quit();
+ return 0;
+}