예제 #1
0
/* Test al_ustr_get on invalid sequences. */
static void t22(void)
{
   ALLEGRO_USTR_INFO info;
   const ALLEGRO_USTR *us;

   /* Empty string. */
   al_set_errno(0);
   CHECK(al_ustr_get(al_ustr_empty_string(), 0) < 0);
   CHECK(al_get_errno() == ERANGE);

   /* 5-byte sequence. */
   us = al_ref_cstr(&info, "\xf8\x88\x80\x80\x80");
   al_set_errno(0);
   CHECK(al_ustr_get(us, 0) < 0);
   CHECK(al_get_errno() == EILSEQ);

   /* Start in trail byte. */
   us = al_ref_cstr(&info, "ð");
   al_set_errno(0);
   CHECK(al_ustr_get(us, 1) < 0);
   CHECK(al_get_errno() == EILSEQ);

   /* Truncated 3-byte sequence. */
   us = al_ref_cstr(&info, "\xEF\xBF");
   al_set_errno(0);
   CHECK(al_ustr_get(us, 0) < 0);
   CHECK(al_get_errno() == EILSEQ);
}
예제 #2
0
/* Test al_ustr_get. */
static void t21(void)
{
   ALLEGRO_USTR_INFO info;
   const ALLEGRO_USTR *us;

   us = al_ref_buffer(&info, "", 1);
   CHECK(al_ustr_get(us, 0) == 0);

   us = al_ref_cstr(&info, "\x7f");
   CHECK(al_ustr_get(us, 0) == 0x7f);

   us = al_ref_cstr(&info, "\xC2\x80");
   CHECK(al_ustr_get(us, 0) == 0x80);

   us = al_ref_cstr(&info, "\xDF\xBf");
   CHECK(al_ustr_get(us, 0) == 0x7ff);

   us = al_ref_cstr(&info, "\xE0\xA0\x80");
   CHECK(al_ustr_get(us, 0) == 0x800);

   us = al_ref_cstr(&info, "\xEF\xBF\xBF");
   CHECK(al_ustr_get(us, 0) == 0xffff);

   us = al_ref_cstr(&info, "\xF0\x90\x80\x80");
   CHECK(al_ustr_get(us, 0) == 0x010000);

   us = al_ref_cstr(&info, "\xF4\x8F\xBF\xBF");
   CHECK(al_ustr_get(us, 0) == 0x10ffff);
}
예제 #3
0
파일: utf8.c 프로젝트: sesc4mt/mvcdecoder
/* Function: al_ustr_find_set
 */
int al_ustr_find_set(const ALLEGRO_USTR *us, int start_pos,
   const ALLEGRO_USTR *accept)
{
   int rc;
   int32_t c, d;
   int pos;
   int set_pos;

   /* Fast path for ASCII characters. */
   if (all_ascii(accept)) {
      rc = _al_binchr(us, start_pos, accept);
      return (rc == _AL_BSTR_ERR) ? -1 : rc;
   }

   /* Non-ASCII. */
   pos = 0;
   while ((c = al_ustr_get(us, pos)) != -1) {
      if (c == -2) {
         /* Invalid byte sequence. */
         pos++;
         continue;
      }

      set_pos = 0;
      while ((d = al_ustr_get_next(accept, &set_pos)) != -1) {
         if (c == d)
            return pos;
      }

      pos += al_utf8_width(c);
   }

   return -1;
}
예제 #4
0
파일: utf8.c 프로젝트: sesc4mt/mvcdecoder
/* Function: al_ustr_set_chr
 */
size_t al_ustr_set_chr(ALLEGRO_USTR *us, int start_pos, int32_t c)
{
   int32_t oldc;
   size_t oldw;
   size_t neww;
   int rc;

   oldc = al_ustr_get(us, start_pos);
   if (oldc == -2)
      return 0;

   oldw = al_utf8_width(oldc);
   neww = al_utf8_width(c);
   if (neww == 0)
      return 0;

   if (oldw > neww)
      rc = _al_bdelete(us, start_pos, oldw - neww);
   else if (neww > oldw)
      rc = _al_binsertch(us, start_pos, neww - oldw, '\0');
   else
      rc = _AL_BSTR_OK;

   if (rc == _AL_BSTR_OK)
      return al_utf8_encode(_al_bdataofs(us, start_pos), c);
   else
      return 0;
}
예제 #5
0
파일: theme.c 프로젝트: beoran/WidgetZ
//return the new start
int wz_find_eol(ALLEGRO_USTR* text, ALLEGRO_FONT* font, float max_width, int start, int* end)
{
	int a, b;
	int first = 1;
	int last = 0;
	a = start;
	
	while(1)
	{
		ALLEGRO_USTR_INFO info;
		ALLEGRO_USTR* token;
		float len;

		/*
		Find the end of current token
		*/
		b = al_ustr_find_set_cstr(text, a, "\t\n ");
		if(b == -1) //found nothing
		{
			b = al_ustr_size(text); //this is the last whole word
			last = 1;
		}
		
		/*
		Check to see if the token fits
		*/
		token = al_ref_ustr(&info, text, start, b);

		len = al_get_ustr_width(font, token);
		if (len < max_width || first)
		{
			if(last)
			{
				*end = b + 1;
				return -1;
			}
		}
		else   //we return the last num
		{
			*end = a - 1;
			return a;
		}
		
		/*
		Check what character we found
		*/
		{
		int character = al_ustr_get(text, b);
		if(character == '\n')
		{
			*end = b;
			return b + 1;
		}
		}
		a = b + 1;
		first = 0;
	}
}
예제 #6
0
파일: utf8.c 프로젝트: sesc4mt/mvcdecoder
/* Function: al_ustr_prev_get
 */
int32_t al_ustr_prev_get(const ALLEGRO_USTR *us, int *pos)
{
   if (al_ustr_prev(us, pos)) {
      return al_ustr_get(us, *pos);
   }

   /* Past beginning. */
   return -1;
}
예제 #7
0
파일: utf8.c 프로젝트: sesc4mt/mvcdecoder
/* Function: al_ustr_remove_chr
 */
bool al_ustr_remove_chr(ALLEGRO_USTR *us, int pos)
{
   int32_t c;
   size_t w;

   c = al_ustr_get(us, pos);
   if (c < 0)
      return false;

   w = al_utf8_width(c);
   return _al_bdelete(us, pos, w) == _AL_BSTR_OK;
}
예제 #8
0
static ALLEGRO_USTR *create_filter_string(const ALLEGRO_USTR *patterns)
{
   ALLEGRO_USTR *filter = al_ustr_new("");
   bool filter_all = false;
   int start, end;

   if (0 == strcmp(al_cstr(patterns), "*.*")) {
      filter_all = true;
   }
   else {
      al_ustr_append_cstr(filter, "All Supported Files");
      al_ustr_append_chr(filter, '\0');
      start = al_ustr_size(filter);
      al_ustr_append(filter, patterns);

      /* Remove all instances of "*.*", which will be added separately. */
      for (;;) {
         int pos = al_ustr_find_cstr(filter, start, "*.*;");
         if (pos == -1)
            break;
         if (pos == start || al_ustr_get(filter, pos - 1) == ';') {
            filter_all = true;
            al_ustr_remove_range(filter, pos, pos + 4);
            start = pos;
         }
         else {
            start = pos + 4;
         }
      }
      while (al_ustr_has_suffix_cstr(filter, ";*.*")) {
         filter_all = true;
         end = al_ustr_size(filter);
         al_ustr_remove_range(filter, end - 4, end);
      }

      al_ustr_append_chr(filter, '\0');
   }

   if (filter_all) {
      al_ustr_append_cstr(filter, "All Files");
      al_ustr_append_chr(filter, '\0');
      al_ustr_append_cstr(filter, "*.*");
      al_ustr_append_chr(filter, '\0');
   }

   al_ustr_append_chr(filter, '\0');
   return filter;
}
예제 #9
0
파일: utf8.c 프로젝트: sesc4mt/mvcdecoder
/* Function: al_ustr_get_next
 */
int32_t al_ustr_get_next(const ALLEGRO_USTR *us, int *pos)
{
   int32_t c = al_ustr_get(us, *pos);

   if (c >= 0) {
      (*pos) += al_utf8_width(c);
      return c;
   }

   if (c == -1) {
      /* Past end. */
      return c;
   }

   /* Some invalid byte sequence. */
   al_ustr_next(us, pos);
   return c;
}
예제 #10
0
static int ustr_at(ALLEGRO_USTR *string, int index)
{
   return al_ustr_get(string, al_ustr_offset(string, index));
}
예제 #11
0
/* _al_xwin_keyboard_handler:
 *  Keyboard "interrupt" handler.
 */
void _al_xwin_keyboard_handler(XKeyEvent *event, ALLEGRO_DISPLAY *display)
{
    int keycode;

    if (!xkeyboard_installed)
        return;

    keycode = keycode_to_scancode[event->keycode];
    if (keycode == -1)
        keycode = find_unknown_key_assignment(event->keycode);

    update_shifts(event);

    /* Special case the pause key. */
    if (keycode == ALLEGRO_KEY_PAUSE) {
        /* Allegro ignore's releasing of the pause key. */
        if (event->type == KeyRelease)
            return;
        if (pause_key) {
            event->type = KeyRelease;
            pause_key = 0;
        }
        else {
            pause_key = 1;
        }
    }

    if (event->type == KeyPress) { /* Key pressed.  */
        int len;
        char buffer[16];
        int unicode = 0;
        int filtered = 0;

#if defined (ALLEGRO_XWINDOWS_WITH_XIM) && defined(X_HAVE_UTF8_STRING)
        if (xic) {
            len = Xutf8LookupString(xic, event, buffer, sizeof buffer, NULL, NULL);
        }
        else
#endif
        {
            /* XLookupString is supposed to only use ASCII. */
            len = XLookupString(event, buffer, sizeof buffer, NULL, NULL);
        }
        buffer[len] = '\0';
        ALLEGRO_USTR_INFO info;
        const ALLEGRO_USTR *ustr = al_ref_cstr(&info, buffer);
        unicode = al_ustr_get(ustr, 0);
        if (unicode < 0)
            unicode = 0;

#ifdef ALLEGRO_XWINDOWS_WITH_XIM
        ALLEGRO_DISPLAY_XGLX *glx = (void *)display;
        filtered = XFilterEvent((XEvent *)event, glx->window);
#endif
        if (keycode || unicode) {
            handle_key_press(keycode, unicode, filtered, _key_shifts, display);
        }
    }
    else { /* Key release. */
        /* HACK:
         * Detect key repeat by looking forward to see if this release is
         * followed by a press event, in which case we assume that this release
         * event was generated in response to that key press event. Events are
         * simultaneous if they are separated by less than 4 ms (a value that
         * worked well on one machine where this hack was needed).
         *
         * This is unnecessary on systems where XkbSetDetectableAutorepeat works.
         */
        if (XPending(event->display) > 0) {
            ALLEGRO_KEY_REPEAT_DATA d;
            XEvent dummy;
            d.event = event;
            d.found = false;
            XCheckIfEvent(event->display, &dummy, check_for_repeat, (XPointer)&d);
            if (d.found) {
                return;
            }
        }
        handle_key_release(keycode, display);
    }
}
예제 #12
0
파일: path.c 프로젝트: sesc4mt/mvcdecoder
/* parse_path_string:
 *
 * Parse a path string according to the following grammar.  The last
 * component, if it is not followed by a directory separator, is interpreted
 * as the filename component, unless it is "." or "..".
 *
 * GRAMMAR
 *
 * path     ::=   "//" c+ "/" nonlast        [Windows only]
 *            |   c ":" nonlast              [Windows only]
 *            |   nonlast
 *
 * nonlast  ::=   c* "/" nonlast
 *            |   last
 *
 * last     ::=   "."
 *            |   ".."
 *            |   filename
 *
 * filename ::=   c*                         [but not "." and ".."]
 *
 * c        ::=   any character but '/'
 */
static bool parse_path_string(const ALLEGRO_USTR *str, ALLEGRO_PATH *path)
{
   ALLEGRO_USTR_INFO    dot_info;
   ALLEGRO_USTR_INFO    dotdot_info;
   const ALLEGRO_USTR *  dot = al_ref_cstr(&dot_info, ".");
   const ALLEGRO_USTR *  dotdot = al_ref_cstr(&dotdot_info, "..");

   ALLEGRO_USTR *piece = al_ustr_new("");
   int pos = 0;
   bool on_windows;

   /* We compile the drive handling code on non-Windows platforms to prevent
    * it becoming broken.
    */
#ifdef ALLEGRO_WINDOWS
   on_windows = true;
#else
   on_windows = false;
#endif
   if (on_windows) {
      /* UNC \\server\share name */
      if (al_ustr_has_prefix_cstr(str, "//")) {
         int slash = al_ustr_find_chr(str, 2, '/');
         if (slash == -1 || slash == 2) {
            /* Missing slash or server component is empty. */
            goto Error;
         }
         al_ustr_assign_substr(path->drive, str, pos, slash);
         pos = slash + 1;
      }
      else {
         /* Drive letter. */
         int colon = al_ustr_offset(str, 1);
         if (colon > -1 && al_ustr_get(str, colon) == ':') {
            /* Include the colon in the drive string. */
            al_ustr_assign_substr(path->drive, str, 0, colon + 1);
            pos = colon + 1;
         }
      }
   }

   for (;;) {
      int slash = al_ustr_find_chr(str, pos, '/');

      if (slash == -1) {
         /* Last component. */
         al_ustr_assign_substr(piece, str, pos, al_ustr_size(str));
         if (al_ustr_equal(piece, dot) || al_ustr_equal(piece, dotdot)) {
            al_append_path_component(path, al_cstr(piece));
         }
         else {
            /* This might be an empty string, but that's okay. */
            al_ustr_assign(path->filename, piece);
         }
         break;
      }

      /* Non-last component. */
      al_ustr_assign_substr(piece, str, pos, slash);
      al_append_path_component(path, al_cstr(piece));
      pos = slash + 1;
   }

   al_ustr_free(piece);
   return true;

Error:

   al_ustr_free(piece);
   return false;
}
예제 #13
0
/* [nd_gtk thread] */
static gboolean create_gtk_file_dialog(gpointer data)
{
   GTK_FILE_DIALOG_MESSAGE *msg = data;
   ALLEGRO_DISPLAY *display = msg->display;
   ALLEGRO_NATIVE_DIALOG *fd = msg->dialog;
   bool save = fd->flags & ALLEGRO_FILECHOOSER_SAVE;
   gint result;

   GtkWidget *window;

   window =
      gtk_file_chooser_dialog_new(al_cstr(fd->title),
                                  NULL,
                                  save ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN,
                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                  save ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);

   _al_gtk_make_transient(display, window);

   if (fd->fc_initial_path) {
      gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(window),
         al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP));
   }

   if (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE)
      gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(window), true);

   /* FIXME: Move all this filter parsing stuff into a common file. */
   if (al_ustr_size(fd->fc_patterns) > 0) {
      GtkFileFilter* filter = gtk_file_filter_new();
      int start = 0;
      int end = 0;
      bool is_mime_type = false;
      while (true) {
         int32_t c = al_ustr_get(fd->fc_patterns, end);
         if (c < 0 || c == ';') {
            if (end - start > 0) {
               ALLEGRO_USTR* pattern = al_ustr_dup_substr(fd->fc_patterns, start, end);
               if (is_mime_type) {
                  gtk_file_filter_add_mime_type(filter, al_cstr(pattern));
               }
               else {
                  gtk_file_filter_add_pattern(filter, al_cstr(pattern));
               }
               al_ustr_free(pattern);
            }
            start = end + 1;
            is_mime_type = false;
         }
         if (c == '/')
            is_mime_type = true;
         if (c < 0)
            break;
         end += al_utf8_width(c);
      }

      gtk_file_filter_set_name(filter, "All supported files");
      gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(window), filter);
   }

   result = gtk_dialog_run(GTK_DIALOG(window));
   if (result == GTK_RESPONSE_ACCEPT) {
      GSList* filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(window));
      int i;
      GSList* iter;

      fd->fc_path_count = g_slist_length(filenames);
      fd->fc_paths = al_malloc(fd->fc_path_count * sizeof(void *));
      for (i = 0, iter = filenames; i < (int)fd->fc_path_count; i++, iter = g_slist_next(iter)) {
         fd->fc_paths[i] = al_create_path((const char*)iter->data);
         g_free(iter->data);
      }
      g_slist_free(filenames);
   }

   gtk_widget_destroy(window);

   ASSERT(fd->async_queue);
   g_async_queue_push(fd->async_queue, ACK_CLOSED);

   return FALSE;
}
예제 #14
0
/* Get more ideas for tests from
 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
 */
static void t23(void)
{
   ALLEGRO_USTR_INFO info;
   const ALLEGRO_USTR *us;

   /* Examples of an overlong ASCII character */
   us = al_ref_cstr(&info, "\xc0\xaf");
   CHECK(al_ustr_get(us, 0) < 0);
   us = al_ref_cstr(&info, "\xe0\x80\xaf");
   CHECK(al_ustr_get(us, 0) < 0);
   us = al_ref_cstr(&info, "\xf0\x80\x80\xaf");
   CHECK(al_ustr_get(us, 0) < 0);
   us = al_ref_cstr(&info, "\xf8\x80\x80\x80\xaf");
   CHECK(al_ustr_get(us, 0) < 0);
   us = al_ref_cstr(&info, "\xfc\x80\x80\x80\x80\xaf");
   CHECK(al_ustr_get(us, 0) < 0);

   /* Maximum overlong sequences */
   us = al_ref_cstr(&info, "\xc1\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xe0\x9f\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xf0\x8f\xbf\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xf8\x87\xbf\xbf\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xfc\x83\xbf\xbf\xbf\xbf");
   CHECK(al_ustr_get(us, 0) < 0);

   /* Overlong representation of the NUL character */
   us = al_ref_cstr(&info, "\xc0\x80");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xe0\x80\x80");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xf0\x80\x80");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xf8\x80\x80\x80");
   CHECK(al_ustr_get(us, 0) < 0);

   us = al_ref_cstr(&info, "\xfc\x80\x80\x80\x80");
   CHECK(al_ustr_get(us, 0) < 0);
}