Пример #1
0
/** adds or sets a color of a skin.
    @param skin skin to set the color of.
    @param wgt widget name (UTF-8 string).
    @param res resource name (UTF-8 string).
    @param val resource value.
    @return non-zero on success, zero on failure.
 */
int algui_set_skin_color(ALGUI_SKIN *skin, const char *wgt, const char *res, ALLEGRO_COLOR color) {
    ALLEGRO_USTR *temp;
    unsigned char red, green, blue, alpha;
    int result;
    
    //convert the color to a string
    al_unmap_rgba(color, &red, &green, &blue, &alpha);
    temp = al_ustr_newf("%ui, %ui, %ui, %ui", (unsigned int)red, (unsigned int)green, (unsigned int)blue, (unsigned int)alpha);
    
    //set the skin
    result = algui_set_skin_str(skin, wgt, res, al_cstr(temp));
    
    //free the temp string
    al_ustr_free(temp);
    
    return result;
}
Пример #2
0
/* Output message to ANSI log. */
static void wlog_do_append_native_text_log_ansi(ALLEGRO_NATIVE_DIALOG *textlog)
{
   int index;
   CHARFORMATA format;
   memset(&format, 0, sizeof(format));
   format.cbSize      = sizeof(format);
   format.dwMask      = CFM_COLOR;
   format.crTextColor = RGB(128, 255, 128);

   index = GetWindowTextLength(textlog->tl_textview);
   SendMessageA(textlog->tl_textview, EM_SETSEL, (WPARAM)index, (LPARAM)index);
   SendMessageA(textlog->tl_textview, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&format);
   SendMessageA(textlog->tl_textview, EM_REPLACESEL, 0, (LPARAM)al_cstr(textlog->tl_pending_text));

   al_ustr_truncate(textlog->tl_pending_text, 0);
   textlog->tl_have_pending = false;
}
Пример #3
0
static bool ljoy_detect_device_name(int num, ALLEGRO_USTR *device_name)
{
    char key[80];
    const char *value;
    struct stat stbuf;

    al_ustr_truncate(device_name, 0);

    snprintf(key, sizeof(key), "device%d", num);
    value = al_get_config_value(al_get_system_config(), "joystick", key);
    if (value)
        al_ustr_assign_cstr(device_name, value);

    if (al_ustr_size(device_name) == 0)
        al_ustr_appendf(device_name, "/dev/input/event%d", num);

    return (stat(al_cstr(device_name), &stbuf) == 0);
}
Пример #4
0
/* Event callbacks
 * */
void allua_keyboard_event_callback(lua_State * L, ALLEGRO_EVENT * event)
{
   Set_literal("keycode", event->keyboard.keycode, -3);
   allua_pushdisplay(L, event->keyboard.display);
   lua_setfield(L, -2, "display");
   if (event->type == ALLEGRO_EVENT_KEY_CHAR) {
      const char *cstr;
      ALLEGRO_USTR *us = al_ustr_new("");
      al_ustr_append_chr(us, event->keyboard.unichar);
      cstr = al_cstr(us);
      lua_pushstring(L, cstr);
      lua_setfield(L, -2, "string");

      Set_literal("unichar", event->keyboard.unichar, -3);
      Set_literal("modifiers", event->keyboard.modifiers, -3);

      lua_pushboolean(L, event->keyboard.repeat);
      lua_setfield(L, -2, "repeated");
   }
}
Пример #5
0
/* [gtk thread] */
static gboolean create_native_text_log(gpointer data)
{
   Msg *msg = data;
   ALLEGRO_NATIVE_DIALOG *textlog = msg->dialog;

   /* Create a new text log window. */
   GtkWidget *top = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_default_size(GTK_WINDOW(top), 640, 480);
   gtk_window_set_title(GTK_WINDOW(top), al_cstr(textlog->title));

   if (textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE) {
      gtk_window_set_deletable(GTK_WINDOW(top), false);
   }
   else {
      g_signal_connect(G_OBJECT(top), "key-press-event", G_CALLBACK(textlog_key_press), textlog);
   }
   g_signal_connect(G_OBJECT(top), "delete-event", G_CALLBACK(textlog_delete), textlog);
   g_signal_connect(G_OBJECT(top), "destroy", G_CALLBACK(dialog_destroy), textlog);
   GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
   gtk_container_add(GTK_CONTAINER(top), scroll);
   GtkWidget *view = gtk_text_view_new();
   gtk_text_view_set_editable(GTK_TEXT_VIEW(view), false);
   if (textlog->flags & ALLEGRO_TEXTLOG_MONOSPACE) {
      PangoFontDescription *font_desc;
      font_desc = pango_font_description_from_string("Monospace");
      gtk_widget_modify_font(view, font_desc);
      pango_font_description_free(font_desc);
   }
   gtk_container_add(GTK_CONTAINER(scroll), view);
   gtk_widget_show(view);
   gtk_widget_show(scroll);
   gtk_widget_show(top);
   textlog->window = top;
   textlog->tl_textview = view;

   ASSERT(textlog->async_queue);
   g_async_queue_push(textlog->async_queue, ACK_OPENED);
   return FALSE;
}
Пример #6
0
static ALLEGRO_FS_ENTRY *fs_apk_create_entry(const char *path)
{
   ALLEGRO_FS_ENTRY_APK *e;
   ALLEGRO_USTR *us;

   e = al_calloc(1, sizeof *e);
   if (!e)
      return NULL;
   e->fs_entry.vtable = &fs_apk_vtable;

   us = apply_cwd(path);
   e->path = al_create_path(al_cstr(us));
   al_ustr_free(us);
   if (!e->path) {
      al_free(e);
      return NULL;
   }
   e->path_cstr = al_path_cstr(e->path, '/');
   
   return &e->fs_entry;
}
Пример #7
0
/* A helper function for al_clone_menu() and al_clone_menu_for_popup().
 * Note that only the root menu is created as a "popup" (if popup == TRUE).
 */
static ALLEGRO_MENU *clone_menu(ALLEGRO_MENU *menu, bool popup)
{
   ALLEGRO_MENU *clone = NULL;
   size_t i;

   if (menu) {
      clone = popup ? al_create_popup_menu() : al_create_menu();
      
      for (i = 0; i < _al_vector_size(&menu->items); ++i) {
         const ALLEGRO_MENU_ITEM *item = *(ALLEGRO_MENU_ITEM **)_al_vector_ref(&menu->items, i);
         ALLEGRO_BITMAP *icon = item->icon;
         
         if (icon)
            icon = al_clone_bitmap(icon);
         
         al_append_menu_item(clone, item->caption ? al_cstr(item->caption) : NULL,
            item->id, item->flags, icon, al_clone_menu(item->popup));
      }
   }

   return clone;
}
Пример #8
0
/* [gtk thread] */
static gboolean create_native_file_dialog(gpointer data)
{
   Msg *msg = data;
   ALLEGRO_DISPLAY *display = msg->display;
   ALLEGRO_NATIVE_DIALOG *fd = msg->dialog;
   GtkWidget *window;

   /* Create a new file selection widget */
   window = gtk_file_selection_new(al_cstr(fd->title));

   make_transient(display, window);

   /* Connect the destroy signal */
   g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(dialog_destroy), fd);

   /* Connect the ok_button */
   g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(window)->ok_button),
                    "clicked", G_CALLBACK(filesel_ok), (gpointer) window);

   /* Connect both buttons to gtk_widget_destroy */
   g_signal_connect_swapped(GTK_FILE_SELECTION(window)->ok_button,
                            "clicked", G_CALLBACK(gtk_widget_destroy), window);
   g_signal_connect_swapped(GTK_FILE_SELECTION(window)->cancel_button,
                            "clicked", G_CALLBACK(gtk_widget_destroy), window);

   g_object_set_data(G_OBJECT(GTK_FILE_SELECTION(window)->ok_button),
      "ALLEGRO_NATIVE_DIALOG", fd);

   if (fd->fc_initial_path) {
      gtk_file_selection_set_filename(GTK_FILE_SELECTION(window),
         al_path_cstr(fd->fc_initial_path, '/'));
   }

   if (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE)
      gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION(window), true);

   gtk_widget_show(window);
   return FALSE;
}
Пример #9
0
/* Test UTF-16 conversion. */
static void t50(void)
{
   ALLEGRO_USTR *us;
   char utf8[] = "⅛-note: 𝅘𝅥𝅮, domino: 🁡";
   uint16_t *utf16;
   size_t s;
   uint16_t little[8];
   /* Only native byte order supported right now, so have to specify
    * elements as uint16_t and not as char.
    */
   uint16_t utf16_ref[] = {
      0x215b, 0x002d, 0x006e, 0x006f, 0x0074,
      0x0065, 0x003a, 0x0020, 0xd834, 0xdd60,
      0x002c, 0x0020, 0x0064, 0x006f, 0x006d,
      0x0069, 0x006e, 0x006f, 0x003a, 0x0020,
      0xd83c, 0xdc61, 0x0000};
   uint16_t truncated[] = {
      0x215b, 0x002d, 0x006e, 0x006f, 0x0074,
      0x0065, 0x003a, 0x0000};

   us = al_ustr_new_from_utf16(utf16_ref);
   CHECK(20 == al_ustr_length(us));
   CHECK(0 == strcmp(utf8, al_cstr(us)));
   al_ustr_free(us);

   us = al_ustr_new(utf8);
   s = al_ustr_size_utf16(us);
   CHECK(46 == s);
   utf16 = malloc(s);
   al_ustr_encode_utf16(us, utf16, s);
   CHECK(0 == memcmp(utf16, utf16_ref, s));
   free(utf16);
   
   s = al_ustr_encode_utf16(us, little, sizeof little);
   CHECK(16 == s);
   CHECK(0 == memcmp(truncated, little, s));
   al_ustr_free(us);
}
Пример #10
0
/* An ALLEGRO_MENU_INFO structure represents a heirarchy of menus. This function 
 * recursively steps through it and builds the entire menu.
 */
static ALLEGRO_MENU_INFO *parse_menu_info(ALLEGRO_MENU *parent, ALLEGRO_MENU_INFO *info)
{
   ASSERT(parent);
   ASSERT(info);

   /* The end of the menu is marked by a NULL caption and an id of 0. */
   while (info->caption || info->id) {
      if (!info->caption) {
         /* A separator */
         al_append_menu_item(parent, NULL, 0, 0, NULL, NULL);
         ++info;
      }
      else if (strlen(info->caption) > 2 &&
         !strncmp("->", info->caption + strlen(info->caption) - 2, 2)) {
         /* An item with a sub-menu has a -> marker as part of its caption.
          * (e.g., "File->"). 
          */
         ALLEGRO_MENU *menu = al_create_menu();
         if (menu) {
            /* Strip the -> mark off the end. */
            ALLEGRO_USTR *s = al_ustr_new(info->caption);
            al_ustr_remove_range(s, al_ustr_size(s) - 2, al_ustr_size(s));
            al_append_menu_item(parent, al_cstr(s), info->id, 0, NULL, menu);
            info = parse_menu_info(menu, info + 1);
            al_ustr_free(s);
         }
      }
      else {
         /* Just ar regular item */
         al_append_menu_item(parent, info->caption, info->id, info->flags, info->icon, NULL);
         ++info;
      }
   }

   return info + 1;
}
Пример #11
0
/* Function: al_is_path_present
 */
bool al_is_path_present(const ALLEGRO_PATH *path)
{
   ALLEGRO_USTR *ustr;
   bool rc;
   ASSERT(path);

   ustr = al_ustr_new("");
   path_to_ustr(path, ALLEGRO_NATIVE_PATH_SEP, ustr);

   /* Windows' stat() doesn't like the slash at the end of the path when
    * the path is pointing to a directory. There are other places which
    * might require the same fix.
    */
#ifdef ALLEGRO_WINDOWS
   if (al_ustr_has_suffix_cstr(ustr, "\\")) {
      al_ustr_truncate(ustr, al_ustr_size(ustr) - 1);
   }
#endif

   rc = al_filename_exists(al_cstr(ustr));
   al_ustr_free(ustr);

   return rc;
}
Пример #12
0
/* [gtk thread] */
static gboolean do_append_native_text_log(gpointer data)
{
   ALLEGRO_NATIVE_DIALOG *textlog = data;
   al_lock_mutex(textlog->tl_text_mutex);

   GtkTextView *tv = GTK_TEXT_VIEW(textlog->tl_textview);
   GtkTextBuffer *buffer = gtk_text_view_get_buffer(tv);
   GtkTextIter iter;
   GtkTextMark *mark;

   gtk_text_buffer_get_end_iter(buffer, &iter);
   gtk_text_buffer_insert(buffer, &iter, al_cstr(textlog->tl_pending_text), -1);

   mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE);
   gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(textlog->tl_textview), mark);
   gtk_text_buffer_delete_mark(buffer, mark);

   al_ustr_truncate(textlog->tl_pending_text, 0);

   textlog->tl_have_pending = false;

   al_unlock_mutex(textlog->tl_text_mutex);
   return FALSE;
}
Пример #13
0
//converts a string to color
static int _string_to_color(const char *str, ALLEGRO_COLOR *color) {
    ALLEGRO_USTR *result[4];
    unsigned int red, green, blue, alpha;
    int count, ok = 0;
    
    //if the string is null, the result is invalid
    if (!str) return 0;
    
    //split the string by ','
    count = _split_string_by_char(str, ',', result, 4);
    
    switch (count) {
        //read red, green, blue
        case 3:
            _string_to_uint(al_cstr(result[0]), &red);
            _string_to_uint(al_cstr(result[1]), &green);
            _string_to_uint(al_cstr(result[2]), &blue);
            *color = al_map_rgb(red, green, blue);
            ok = 1;
            break;
            
        //read red, green, blue, alpha
        case 4:
            _string_to_uint(al_cstr(result[0]), &red);
            _string_to_uint(al_cstr(result[1]), &green);
            _string_to_uint(al_cstr(result[2]), &blue);
            _string_to_uint(al_cstr(result[3]), &alpha);
            *color = al_map_rgba(red, green, blue, alpha);
            ok = 1;
            break;
    }
    
    //free the strings
    _free_string_array(result, count);
    
    return ok;
}
Пример #14
0
/* Test al_ustr_set_chr. */
static void t42(void)
{
   ALLEGRO_USTR *us = al_ustr_new("abcdef");

   /* Same size (ASCII). */
   CHECK(al_ustr_set_chr(us, 1, 'B') == 1);
   CHECK(0 == strcmp(al_cstr(us), "aBcdef"));
   CHECK(6 == al_ustr_size(us));

   /* Enlarge to 2-bytes. */
   CHECK(al_ustr_set_chr(us, 1, U_beta) == 2);
   CHECK(0 == strcmp(al_cstr(us), "aβcdef"));
   CHECK(7 == al_ustr_size(us));

   /* Enlarge to 3-bytes. */
   CHECK(al_ustr_set_chr(us, 5, U_1d08) == 3);
   CHECK(0 == strcmp(al_cstr(us), "aβcdᴈf"));
   CHECK(9 == al_ustr_size(us));

   /* Reduce to 2-bytes. */
   CHECK(al_ustr_set_chr(us, 5, U_schwa) == 2);
   CHECK(0 == strcmp(al_cstr(us), "aβcdəf"));
   CHECK(8 == al_ustr_size(us));

   /* Set at end of string. */
   CHECK(al_ustr_set_chr(us, al_ustr_size(us), U_1ff7) == 3);
   CHECK(0 == strcmp(al_cstr(us), "aβcdəfῷ"));
   CHECK(11 == al_ustr_size(us));

   /* Set past end of string. */
   CHECK(al_ustr_set_chr(us, al_ustr_size(us) + 2, U_2051) == 3);
   CHECK(0 == memcmp(al_cstr(us), "aβcdəfῷ\0\0⁑", 16));
   CHECK(16 == al_ustr_size(us));

   /* Set before start of string (not allowed). */
   CHECK(al_ustr_set_chr(us, -1, U_2051) == 0);
   CHECK(16 == al_ustr_size(us));

   al_ustr_free(us);
}
Пример #15
0
/* [gtk thread] */
static GtkWidget *build_menu_item(ALLEGRO_MENU_ITEM *aitem)
{
   GtkWidget *gitem;
   
   if (!aitem->caption) {
      gitem = gtk_separator_menu_item_new();
   }
   else {
      ALLEGRO_USTR *caption = al_ustr_dup(aitem->caption);
      
      /* convert & to _ using unprintable chars as placeholders */
      al_ustr_find_replace_cstr(caption, 0, "_", "\x01\x02");
      al_ustr_find_replace_cstr(caption, 0, "&", "_");
      al_ustr_find_replace_cstr(caption, 0, "\x01\x02", "__");
      
      if (aitem->flags & ALLEGRO_MENU_ITEM_CHECKBOX) {
         gitem = gtk_check_menu_item_new_with_mnemonic(al_cstr(caption));
         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gitem), aitem->flags & ALLEGRO_MENU_ITEM_CHECKED);
         g_signal_connect_swapped (gitem, "toggled", G_CALLBACK(checkbox_on_toggle),
            (gpointer) aitem);
      }
      else {
         /* always create an image menu item, in case the user ever sets an icon */
         gitem = gtk_image_menu_item_new_with_mnemonic(al_cstr(caption));
         
         if (aitem->icon) {
            const int w = al_get_bitmap_width(aitem->icon), h = al_get_bitmap_height(aitem->icon);
            const int stride = w * 4;
            int x, y, i;
            GdkPixbuf *pixbuf;
            uint8_t *data = al_malloc(stride * h);
            
            if (data) {
               for (y = 0, i = 0; y < h; ++y) {
                  for (x = 0; x < w; ++x, i += 4) {
                     al_unmap_rgba(al_get_pixel(aitem->icon, x, y),
                        &data[i],
                        &data[i + 1],
                        &data[i + 2],
                        &data[i + 3]
                     );
                  }
               }
               
               pixbuf = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, TRUE, 8,
                  w, h, stride, destroy_pixbuf, NULL);
               
               aitem->extra2 = gtk_image_new_from_pixbuf(pixbuf);
               
               gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(gitem), aitem->extra2);
               
               /* Subtract the main reference. the image still holds a reference, so the
                * pixbuf won't be destroyed until the image itself is. */
               g_object_unref(pixbuf);
            }
         }
      }
      
      al_ustr_free(caption);
      
      gtk_widget_set_sensitive(gitem, !(aitem->flags & ALLEGRO_MENU_ITEM_DISABLED));
      
      aitem->extra1 = gitem;
      
      if (aitem->popup) {
         GtkWidget *gsubmenu = gtk_menu_new();
         build_menu(gsubmenu, aitem->popup);
         aitem->popup->extra1 = gsubmenu;
         gtk_widget_show(gsubmenu);
         gtk_menu_item_set_submenu(GTK_MENU_ITEM(gitem), gsubmenu);
      }
      else if (aitem->id) {
         g_signal_connect_swapped (gitem, "activate",
            G_CALLBACK(menuitem_response), (gpointer) aitem);
      }
   }
      
   gtk_widget_show(gitem);
   
   return gitem;
}
Пример #16
0
void TextEdit::EventOccured( Event* e )
{
	UString keyname;

	Control::EventOccured( e );

	if( e->Type == EVENT_FORM_INTERACTION )
	{
		if( e->Data.Forms.RaisedBy == this )
		{
			if( e->Data.Forms.EventFlag == FormEventType::GotFocus || e->Data.Forms.EventFlag == FormEventType::MouseClick || e->Data.Forms.EventFlag == FormEventType::KeyDown )
			{
				editting = true;
				//e->Handled = true;
			}
			if( e->Data.Forms.EventFlag == FormEventType::LostFocus )
			{
				editting = false;
				RaiseEvent( FormEventType::TextEditFinish );
				//e->Handled = true;
			}
		} else if( e->Data.Forms.EventFlag == FormEventType::MouseClick ) {
			editting = false;
			RaiseEvent( FormEventType::TextEditFinish );
		}

		if( e->Data.Forms.EventFlag == FormEventType::KeyPress && editting )
		{
			switch( e->Data.Forms.KeyInfo.KeyCode )
			{
				case ALLEGRO_KEY_BACKSPACE:
					if( SelectionStart > 0 )
					{
						text.remove(SelectionStart, 1);
						SelectionStart--;
						RaiseEvent( FormEventType::TextChanged );
					}
					e->Handled = true;
					break;
				case ALLEGRO_KEY_DELETE:
					if( SelectionStart < text.length() )
					{
						text.remove(SelectionStart+1, 1);
						RaiseEvent( FormEventType::TextChanged );
					}
					e->Handled = true;
					break;
				case ALLEGRO_KEY_LEFT:
					if( SelectionStart > 0 )
					{
						SelectionStart--;
					}
					e->Handled = true;
					break;
				case ALLEGRO_KEY_RIGHT:
					if( SelectionStart < text.length() )
					{
						SelectionStart++;
					}
					e->Handled = true;
					break;
				case ALLEGRO_KEY_LSHIFT:
				case ALLEGRO_KEY_RSHIFT:
					editShift = true;
					break;
				case ALLEGRO_KEY_ALTGR:
					editAltGr = true;
					break;

				case ALLEGRO_KEY_HOME:
					SelectionStart = 0;
					e->Handled = true;
					break;
				case ALLEGRO_KEY_END:
					SelectionStart = text.length();
					e->Handled = true;
					break;

				case ALLEGRO_KEY_ENTER:
					editting = false;
					RaiseEvent( FormEventType::TextEditFinish );
					break;

				default:
					ALLEGRO_USTR* convert = al_ustr_new("");
					al_ustr_append_chr( convert, e->Data.Forms.KeyInfo.UniChar );
					if( convert->slen == 1 && al_cstr(convert)[0] != 0 )
					{
						text.insert( SelectionStart, al_cstr(convert) );
						SelectionStart++;
						RaiseEvent( FormEventType::TextChanged );
					}
			}
		}

		if( e->Data.Forms.EventFlag == FormEventType::KeyUp && editting )
		{

			switch( e->Data.Forms.KeyInfo.KeyCode )
			{
				case ALLEGRO_KEY_LSHIFT:
				case ALLEGRO_KEY_RSHIFT:
					editShift = false;
					e->Handled = true;
					break;
				case ALLEGRO_KEY_ALTGR:
					editAltGr = false;
					e->Handled = true;
					break;
			}
		}
	}

}
Пример #17
0
static void t2(void)
{
   CHECK(0 == al_ustr_size(al_ustr_empty_string()));
   CHECK(0 == strcmp(al_cstr(al_ustr_empty_string()), ""));
}
Пример #18
0
/** returns the current filename of a skin.    
    @param skin skin to get the filename of.
    @return the filename of a skin; a pointer to the internal character buffer (UTF-8 string).
 */
const char *algui_get_skin_filename(ALGUI_SKIN *skin) {
    assert(skin);
    return al_cstr(skin->filename);
}
Пример #19
0
/* 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;
}
Пример #20
0
/* Function: al_get_path_filename
 */
const char *al_get_path_filename(const ALLEGRO_PATH *path)
{
   ASSERT(path);

   return al_cstr(path->filename);
}
/* _find_executable_file:
 *  Helper function: searches path and current directory for executable.
 *  Returns 1 on succes, 0 on failure.
 */
static ALLEGRO_PATH *_find_executable_file(const char *filename)
{
   char *env;

   /* If filename has an explicit path, search current directory */
   if (strchr(filename, '/')) {
      if (filename[0] == '/') {
         /* Full path; done */
         return al_create_path(filename);
      }
      else {
         struct stat finfo;
         char *cwd;

         /* Prepend current directory */
         cwd = al_get_current_directory();
         if (cwd) {
            ALLEGRO_PATH *path = al_create_path_for_directory(cwd);
            al_free(cwd);
            al_set_path_filename(path, filename);

            if (stat(al_path_cstr(path, '/'), &finfo) == 0
                  && !S_ISDIR(finfo.st_mode)) {
               return path;
            }

            al_destroy_path(path);
         }
      }
   }
   /* If filename has no explicit path, but we do have $PATH, search
    * there
    */
   else if ((env = getenv("PATH"))) {
      struct stat finfo;
      ALLEGRO_USTR *us = al_ustr_new(env);
      int start_pos = 0;
      while (start_pos >= 0) {
         int next_start_pos = al_ustr_find_chr(us, start_pos + 1, ':');
         int end_pos = next_start_pos;
         if (next_start_pos < 0)
            end_pos = al_ustr_size(us);
         ALLEGRO_USTR_INFO info;
         const ALLEGRO_USTR *sub = al_ref_ustr(&info, us, start_pos, end_pos);

         ALLEGRO_PATH *path = al_create_path_for_directory(al_cstr(sub));
         al_set_path_filename(path, filename);

         if (stat(al_path_cstr(path, '/'), &finfo) == 0 &&
            !S_ISDIR (finfo.st_mode)) {
            return path;
         }

         al_destroy_path(path);

         start_pos = next_start_pos;
      }
   }

   return NULL;
}
Пример #22
0
bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
   ALLEGRO_NATIVE_DIALOG *fd)
{
   OPENFILENAME ofn;
   ALLEGRO_DISPLAY_WIN *win_display;
   int flags = 0;
   bool ret;
   char buf[4096] = "";
   ALLEGRO_USTR *filter_string = NULL;

   win_display = (ALLEGRO_DISPLAY_WIN *)display;

   if (fd->flags & ALLEGRO_FILECHOOSER_FOLDER) {
      return select_folder(win_display, fd);
   }

   /* Selecting a file. */
   memset(&ofn, 0, sizeof(OPENFILENAME));
   ofn.lStructSize = sizeof(OPENFILENAME);
   ofn.hwndOwner = (win_display) ? win_display->window : NULL;

   /* Create filter string. */
   if (fd->fc_patterns) {
      filter_string = create_filter_string(fd->fc_patterns);
      ofn.lpstrFilter = al_cstr(filter_string);
   }
   else {
      /* List all files by default. */
      ofn.lpstrFilter = "All Files\0*.*\0\0";
   }

   ofn.lpstrFile = buf;
   ofn.nMaxFile = sizeof(buf);

   if (fd->fc_initial_path) {
      ofn.lpstrInitialDir =
         al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
   }

   if (fd->title)
      ofn.lpstrTitle = al_cstr(fd->title);

   flags |= OFN_NOCHANGEDIR | OFN_EXPLORER;
   if (fd->flags & ALLEGRO_FILECHOOSER_SAVE) {
      flags |= OFN_OVERWRITEPROMPT;
   }
   else {
      flags |= (fd->flags & ALLEGRO_FILECHOOSER_FILE_MUST_EXIST) ? OFN_FILEMUSTEXIST : 0;
   }
   flags |= (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE) ? OFN_ALLOWMULTISELECT : 0;
   flags |= (fd->flags & ALLEGRO_FILECHOOSER_SHOW_HIDDEN) ? 0x10000000 : 0; // NOTE: 0x10000000 is FORCESHOWHIDDEN
   ofn.Flags = flags;

   if (flags & OFN_OVERWRITEPROMPT) {
      ret = GetSaveFileName(&ofn);
   }
   else {
      ret = GetOpenFileName(&ofn);
   }

   al_ustr_free(filter_string);

   if (!ret) {
      DWORD err = GetLastError();
      if (err != ERROR_SUCCESS) {
         char buf[1000];
         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, sizeof(buf), NULL);
         ALLEGRO_ERROR("al_show_native_file_dialog failed: %s\n", buf);
      }
      return false;
   }

   if (flags & OFN_ALLOWMULTISELECT) {
      int i;
      /* Count number of file names in buf. */
      fd->fc_path_count = 0;
      i = skip_nul_terminated_string(buf);
      while (1) {
         if (buf[i] == '\0') {
            fd->fc_path_count++;
            if (buf[i+1] == '\0')
               break;
         }
         i++;
      }
   }
   else {
      fd->fc_path_count = 1;
   }

   if (fd->fc_path_count == 1) {
      fd->fc_paths = al_malloc(sizeof(void *));
      fd->fc_paths[0] = al_create_path(buf);
   }
   else {
      int i, p;
      /* If multiple files were selected, the first string in buf is the
       * directory name, followed by each of the file names terminated by NUL.
       */
      fd->fc_paths = al_malloc(fd->fc_path_count * sizeof(void *));
      i = skip_nul_terminated_string(buf);
      for (p = 0; p < (int)fd->fc_path_count; p++) {
         fd->fc_paths[p] = al_create_path_for_directory(buf);
         al_set_path_filename(fd->fc_paths[p], buf+i);
         i += skip_nul_terminated_string(buf+i);
      }
   }

   return true;
}
Пример #23
0
bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog)
{
   LPCSTR font_name;
   HWND hWnd;
   HWND hLog;
   WNDCLASSA text_log_class;
   RECT client_rect;
   HFONT hFont;
   MSG msg;
   BOOL ret;

   al_lock_mutex(textlog->tl_text_mutex);

   /* Prepare text log class info. */
   if (!wlog_class_registered) {
      memset(&text_log_class, 0, sizeof(text_log_class));
      text_log_class.hInstance      = (HINSTANCE)GetModuleHandle(NULL);
      text_log_class.lpszClassName  = "Allegro Text Log";
      text_log_class.lpfnWndProc    = wlog_text_log_callback;
      text_log_class.hIcon          = NULL;
      text_log_class.hCursor        = NULL;
      text_log_class.lpszMenuName   = NULL;
      text_log_class.hbrBackground  = (HBRUSH)GetStockObject(GRAY_BRUSH);

      if (RegisterClassA(&text_log_class) == 0) {
         /* Failure, window class is a basis and we do not have one. */
         al_unlock_mutex(textlog->tl_text_mutex);
         return false;
      }

      wlog_class_registered++;
   }

   /* Load RichEdit control. */
   if (!wlog_rich_edit_module) {
      if ((wlog_rich_edit_module = _al_open_library("msftedit.dll"))) {
         /* 4.1 and emulation of 3.0, 2.0, 1.0 */
         wlog_edit_control = L"RICHEDIT50W"; /*MSFTEDIT_CLASS*/
         wlog_unicode      = true;
      }
      else if ((wlog_rich_edit_module = _al_open_library("riched20.dll"))) {
         /* 3.0, 2.0 */
         wlog_edit_control = L"RichEdit20W"; /*RICHEDIT_CLASS*/
         wlog_unicode      = true;
      }
      else if ((wlog_rich_edit_module = _al_open_library("riched32.dll"))) {
         /* 1.0 */
         wlog_edit_control = L"RichEdit"; /*RICHEDIT_CLASS*/
         wlog_unicode      = false;
      }
      else {
         wlog_edit_control = L"EDIT";
         wlog_unicode      = false;
      }
   }

   /* Create text log window. */
   hWnd = CreateWindowA("Allegro Text Log", al_cstr(textlog->title),
      WS_CAPTION | WS_SIZEBOX | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU,
      CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL,
      (HINSTANCE)GetModuleHandle(NULL), textlog);
   if (!hWnd) {
      if (wlog_rich_edit_module) {
         _al_close_library(wlog_rich_edit_module);
         wlog_rich_edit_module = NULL;
      }
      UnregisterClassA("Allegro Text Log", (HINSTANCE)GetModuleHandle(NULL));
      al_unlock_mutex(textlog->tl_text_mutex);
      return false;
   }

   /* Get client area of the log window. */
   GetClientRect(hWnd, &client_rect);

   /* Create edit control. */
   hLog = CreateWindowW(wlog_edit_control, NULL,
      WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_READONLY,
      client_rect.left, client_rect.top, client_rect.right - client_rect.left, client_rect.bottom - client_rect.top,
      hWnd, NULL, (HINSTANCE)GetModuleHandle(NULL), NULL);
   if (!hLog) {
      if (wlog_rich_edit_module) {
         _al_close_library(wlog_rich_edit_module);
         wlog_rich_edit_module = NULL;
      }
      DestroyWindow(hWnd);
      UnregisterClassA("Allegro Text Log", (HINSTANCE)GetModuleHandle(NULL));
      al_unlock_mutex(textlog->tl_text_mutex);
      return false;
   }

   /* Enable double-buffering. */
   SetWindowLong(hLog, GWL_EXSTYLE, GetWindowLong(hLog, GWL_EXSTYLE) | 0x02000000L/*WS_EX_COMPOSITED*/);

   /* Select font name. */
   if (textlog->flags & ALLEGRO_TEXTLOG_MONOSPACE)
      font_name = "Courier New";
   else
      font_name = "Arial";

   /* Create font and set font. */
   hFont = CreateFont(-11, 0, 0, 0, FW_LIGHT, 0, 0,
      0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
      FF_MODERN | FIXED_PITCH, font_name);

   /* Assign font to the text log. */
   if (hFont) {
      SendMessage(hLog, WM_SETFONT, (WPARAM)hFont, 0);
   }

   /* Set background color of RichEdit control. */
   if (wlog_rich_edit_module) {
      SendMessage(hLog, EM_SETBKGNDCOLOR, 0, (LPARAM)RGB(16, 16, 16));
   }

   /* We are ready to show our window. */
   ShowWindow(hWnd, SW_NORMAL);

   /* Save handles for future use. */
   textlog->window    = hWnd;
   textlog->tl_textview  = hLog;
   textlog->is_active = true;

   /* Now notify al_show_native_textlog that the text log is ready. */
   textlog->tl_done = true;
   al_signal_cond(textlog->tl_text_cond);
   al_unlock_mutex(textlog->tl_text_mutex);

   /* Process messages. */
   while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0) {
      if (ret != -1 && msg.message != WM_QUIT) {
         /* Intercept child window key down messages. Needed to track
          * hit of ESCAPE key while text log have focus. */
         if (msg.hwnd != textlog->window && msg.message == WM_KEYDOWN) {
            PostMessage(textlog->window, WM_KEYDOWN, msg.wParam, msg.lParam);
         }
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
      else
         break;
   }

   /* Close window. Should be already closed, this is just sanity. */
   if (IsWindow(textlog->window)) {
      DestroyWindow(textlog->window);
   }

   /* Release font. We don't want to leave any garbage. */
   DeleteObject(hFont);

   /* Release RichEdit module. */
   if (wlog_rich_edit_module) {
      _al_close_library(wlog_rich_edit_module);
      wlog_rich_edit_module = NULL;
   }

   /* Unregister window class. */
   if (--wlog_class_registered == 0) {
      UnregisterClassA("Allegro Text Log", (HINSTANCE)GetModuleHandle(NULL));
   }

   /* Notify everyone that we're gone. */
   al_lock_mutex(textlog->tl_text_mutex);
   textlog->tl_done = true;
   al_signal_cond(textlog->tl_text_cond);
   al_unlock_mutex(textlog->tl_text_mutex);

   return true;
}
Пример #24
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;
}
Пример #25
0
int main(void)
{
   ALLEGRO_DISPLAY *display;
   ALLEGRO_TIMER *timer;
   ALLEGRO_EVENT_QUEUE *queue;
   int redraw = 0, i;
   bool quit = false;

   if (!al_init()) {
      abort_example("Could not initialise Allegro\n");
      return 1;
   }
   al_init_primitives_addon();
   al_install_mouse();
   al_init_image_addon();
   al_init_font_addon();
   al_init_ttf_addon();
   srand(time(NULL));

   white = al_map_rgba_f(1, 1, 1, 1);

   display = al_create_display(640, 480);
   if (!display) {
      abort_example("Could not create display\n");
      return 1;
   }
   al_set_window_title(display, "Allegro Logo Generator");
   al_install_keyboard();

   /* Read logo parameters from logo.ini (if it exists). */
   config = al_load_config_file("logo.ini");
   if (!config)
      config = al_create_config();
   for (i = 0; param_names[i]; i++) {
      char const *value = al_get_config_value(config, "logo", param_names[i]);
      if (value)
         strncpy(param_values[i], value, sizeof(param_values[i]));
   }

   font = al_load_font("data/DejaVuSans.ttf", 12, 0);
   if (!font) {
      abort_example("Could not load font\n");
      return 1;
   }

   timer = al_create_timer(1.0 / 60);

   queue = al_create_event_queue();
   al_register_event_source(queue, al_get_keyboard_event_source());
   al_register_event_source(queue, al_get_mouse_event_source());
   al_register_event_source(queue, al_get_display_event_source(display));
   al_register_event_source(queue, al_get_timer_event_source(timer));

   al_start_timer(timer);
   while (!quit) {
      ALLEGRO_EVENT event;
      al_wait_for_event(queue, &event);
      if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
         break;
      if (event.type == ALLEGRO_EVENT_KEY_CHAR) {
         if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
            quit = true;
         }
         else if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) {
            if (editing) {
               regenerate = true;
               editing = false;
            }
            else {
               cursor = 0;
               editing = true;
            }
         }
         else if (event.keyboard.keycode == ALLEGRO_KEY_UP) {
            if (selection > 0) {
               selection--;
               cursor = 0;
               editing = false;
            }
         }
         else if (event.keyboard.keycode == ALLEGRO_KEY_DOWN) {
            if (param_names[selection + 1]) {
               selection++;
               cursor = 0;
               editing = false;
            }
         }
         else {
            int c = event.keyboard.unichar;
            if (editing) {
               if (c >= 32) {
                  ALLEGRO_USTR *u = al_ustr_new(param_values[selection]);
                  al_ustr_set_chr(u, cursor, c);
                  cursor++;
                  al_ustr_set_chr(u, cursor, 0);
                  strncpy(param_values[selection], al_cstr(u),
                     sizeof param_values[selection]);
                  al_ustr_free(u);
               }
            }
            else {
               if (c == 'r')
                  randomize();
               if (c == 's')
                  save();
            }
         }
      }
      if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) {
         if (event.mouse.button == 1) {
            mouse_click(event.mouse.x, event.mouse.y);
         }
      }
      if (event.type == ALLEGRO_EVENT_TIMER)
         redraw++;

      if (redraw && al_is_event_queue_empty(queue)) {
         redraw = 0;

         render();

         al_flip_display();
      }
   }

   /* Write modified parameters back to logo.ini. */
   for (i = 0; param_names[i]; i++) {
      al_set_config_value(config, "logo", param_names[i],
         param_values[i]);
   }
   al_save_config_file("logo.ini", config);
   al_destroy_config(config);

   return 0;
}
Пример #26
0
/* Function: al_path_cstr
 */
const char *al_path_cstr(const ALLEGRO_PATH *path, char delim)
{
   path_to_ustr(path, delim, path->full_string);
   return al_cstr(path->full_string);
}
Пример #27
0
const char *TextEntry::get_text()
{
   return al_cstr(text);
}
Пример #28
0
/* get_segment_cstr:
 *  Return the i'th directory component of a path as a C string.
 */
static const char *get_segment_cstr(const ALLEGRO_PATH *path, unsigned i)
{
   return al_cstr(get_segment(path, i));
}
Пример #29
0
static void ljoy_scan(bool configure)
{
    int fd;
    ALLEGRO_JOYSTICK_LINUX *joy, **joypp;
    int num;
    ALLEGRO_USTR *device_name;
    unsigned i;

    /* Clear mark bits. */
    for (i = 0; i < _al_vector_size(&joysticks); i++) {
        joypp = _al_vector_ref(&joysticks, i);
        joy = *joypp;
        joy->marked = false;
    }

    device_name = al_ustr_new("");

    /* This is a big number, but there can be gaps and other unrelated event
     * device files.  Perhaps it would be better to use glob() here.
     */
    for (num = 0; num < 32; num++) {
        if (!ljoy_detect_device_name(num, device_name))
            continue;

        joy = ljoy_by_device_name(device_name);
        if (joy) {
            ALLEGRO_DEBUG("Device %s still exists\n", al_cstr(device_name));
            joy->marked = true;
            continue;
        }

        /* Try to open the device. The device must be opened in O_RDWR mode to
         * allow writing of haptic effects! The haptic driver for linux
         * reuses the joystick driver's fd.
         */
        fd = open(al_cstr(device_name), O_RDWR|O_NONBLOCK);
        if (fd == -1) {
            ALLEGRO_WARN("Failed to open device %s\n", al_cstr(device_name));
            continue;
        }

        /* The device must have at least one joystick-related axis, and one
         * joystick-related button.  Some devices, such as mouse pads, have ABS_X
         * and ABS_Y axes like a joystick but not joystick-related buttons.  By
         * checking for both axes and buttons, such devices can be excluded.
         */
        if (!have_joystick_button(fd) || !have_joystick_axis(fd)) {
            ALLEGRO_DEBUG("Device %s not a joystick\n", al_cstr(device_name));
            close(fd);
            continue;
        }

        ALLEGRO_DEBUG("Device %s is new\n", al_cstr(device_name));

        joy = ljoy_allocate_structure();
        joy->fd = fd;
        joy->device_name = al_ustr_dup(device_name);
        joy->config_state = LJOY_STATE_BORN;
        joy->marked = true;
        config_needs_merging = true;

        if (ioctl(fd, EVIOCGNAME(sizeof(joy->name)), joy->name) < 0)
            strcpy(joy->name, "Unknown");

        /* Map Linux input API axis and button numbers to ours, and fill in
         * information.
         */
        if (!fill_joystick_axes(joy, fd) || !fill_joystick_buttons(joy, fd)) {
            ALLEGRO_ERROR("fill_joystick_info failed %s\n", al_cstr(device_name));
            inactivate_joy(joy);
            close(fd);
            continue;
        }

        /* Register the joystick with the fdwatch subsystem.  */
        _al_unix_start_watching_fd(joy->fd, ljoy_process_new_data, joy);
    }

    al_ustr_free(device_name);

    /* Schedule unmarked structures to be inactivated. */
    for (i = 0; i < _al_vector_size(&joysticks); i++) {
        joypp = _al_vector_ref(&joysticks, i);
        joy = *joypp;

        if (joy->config_state == LJOY_STATE_ALIVE && !joy->marked) {
            ALLEGRO_DEBUG("Device %s to be inactivated\n",
                          al_cstr(joy->device_name));
            joy->config_state = LJOY_STATE_DYING;
            config_needs_merging = true;
        }
    }

    /* Generate a configure event if necessary.
     * Even if we generated one before that the user hasn't responded to,
     * we don't know if the user received it so always generate it.
     */
    if (config_needs_merging && configure) {
        ljoy_generate_configure_event();
    }
}
Пример #30
0
/* Function: al_get_path_drive
 */
const char *al_get_path_drive(const ALLEGRO_PATH *path)
{
   ASSERT(path);

   return al_cstr(path->drive);
}