//returns the filepath of a resource static ALLEGRO_USTR *_get_resource_filepath(const ALLEGRO_USTR *skin_filepath, const char *resource_filename) { ALLEGRO_USTR *result; int pos, end_pos; ALLEGRO_USTR *temp; ALLEGRO_USTR_INFO temp_info; //duplicate the resource filepath in order to replace '\' by '/' result = al_ustr_dup(skin_filepath); //replace '\' with '/' al_ustr_find_replace_cstr(result, 0, "\\", "/"); //find the end of the string end_pos = al_ustr_size(result); //find the last occurrence of '/' pos = al_ustr_rfind_chr(result, end_pos, '/'); //find the position after the '/' pos += al_utf8_width('/'); //the replace function needs a ustr temp = al_ref_cstr(&temp_info, resource_filename); //replace the string after the '/' with the resource filename al_ustr_replace_range(result, pos, end_pos, temp); return result; }
/* Test al_ustr_dup. */ static void t6(void) { ALLEGRO_USTR *us1 = al_ustr_new("aábdðeéfghiíjklmnoóprstuúvxyýþæö"); ALLEGRO_USTR *us2 = al_ustr_dup(us1); CHECK(al_ustr_size(us1) == al_ustr_size(us2)); CHECK(0 == memcmp(al_cstr(us1), al_cstr(us2), al_ustr_size(us1))); al_ustr_free(us1); al_ustr_free(us2); }
/* Title: Text Box Section: Internal Function: wz_textbox_proc See also: <wz_widget_proc> */ int wz_textbox_proc(WZ_WIDGET* wgt, ALLEGRO_EVENT* event) { int ret = 1; WZ_TEXTBOX* box = (WZ_TEXTBOX*)wgt; switch (event->type) { case WZ_DRAW: { if (wgt->flags & WZ_STATE_HIDDEN) { ret = 0; } else { int flags = (wgt->flags & WZ_STATE_DISABLED) ? WZ_STYLE_DISABLED : 0; wgt->theme->draw_textbox(wgt->theme, wgt->local_x, wgt->local_y, wgt->w, wgt->h, box->h_align, box->v_align, box->text, flags); } break; } case WZ_DESTROY: { if(box->own) al_ustr_free(box->text); ret = 0; break; } case WZ_SET_TEXT: { if(box->own) { al_ustr_free(box->text); box->text = al_ustr_dup((ALLEGRO_USTR*)event->user.data3); } else { box->text = (ALLEGRO_USTR*)event->user.data3; } break; } default: ret = 0; } if (ret == 0) ret = wz_widget_proc(wgt, event); return ret; }
/* Test al_ustr_equal. */ static void t10(void) { ALLEGRO_USTR *us1; ALLEGRO_USTR *us2; const ALLEGRO_USTR *us3; ALLEGRO_USTR_INFO us3_info; const char us3_data[] = "aábdð\0eéfgh"; us1 = al_ustr_new("aábdð"); us2 = al_ustr_dup(us1); us3 = al_ref_buffer(&us3_info, us3_data, sizeof(us3_data)); CHECK(al_ustr_equal(us1, us2)); CHECK(!al_ustr_equal(us1, al_ustr_empty_string())); /* Check comparison doesn't stop at embedded NUL. */ CHECK(!al_ustr_equal(us1, us3)); al_ustr_free(us1); al_ustr_free(us2); }
/* Function: al_clone_path */ ALLEGRO_PATH *al_clone_path(const ALLEGRO_PATH *path) { ALLEGRO_PATH *clone; unsigned int i; ASSERT(path); clone = al_create_path(NULL); if (!clone) { return NULL; } al_ustr_assign(clone->drive, path->drive); al_ustr_assign(clone->filename, path->filename); for (i = 0; i < _al_vector_size(&path->segments); i++) { ALLEGRO_USTR **slot = _al_vector_alloc_back(&clone->segments); (*slot) = al_ustr_dup(get_segment(path, i)); } return clone; }
/* Title: Button Section: Internal Function: wz_button_proc See also: <wz_widget_proc> */ int wz_button_proc(WZ_WIDGET* wgt, const ALLEGRO_EVENT* event) { int ret = 1; WZ_BUTTON* but = (WZ_BUTTON*)wgt; float x, y; switch(event->type) { case WZ_LOSE_FOCUS: { ret = 0; break; } case WZ_DRAW: { if(wgt->flags & WZ_STATE_HIDDEN) { ret = 0; } else { int flags = 0; if(wgt->flags & WZ_STATE_DISABLED) flags |= WZ_STYLE_DISABLED; else if (wgt->flags & WZ_STATE_HAS_FOCUS) flags |= WZ_STYLE_FOCUSED; if(but->down) flags |= WZ_STYLE_DOWN; wgt->theme->draw_button(wgt->theme, wgt->local_x, wgt->local_y, wgt->w, wgt->h, but->text, flags); } break; } #if (ALLEGRO_SUB_VERSION > 0) case ALLEGRO_EVENT_TOUCH_MOVE: x = event->touch.x; y = event->touch.y; #endif case ALLEGRO_EVENT_MOUSE_AXES: { if(event->type == ALLEGRO_EVENT_MOUSE_AXES) { x = event->mouse.x; y = event->mouse.y; } if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if((event->mouse.dx != 0 || event->mouse.dy != 0) && wz_widget_rect_test(wgt, x, y) && !(wgt->flags & WZ_STATE_HAS_FOCUS)) { wz_ask_parent_for_focus(wgt); } else { ret = 0; } break; } #if (ALLEGRO_SUB_VERSION > 0) case ALLEGRO_EVENT_TOUCH_BEGIN: x = event->touch.x; y = event->touch.y; #endif case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: { if(event->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { x = event->mouse.x; y = event->mouse.y; } if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if(wz_widget_rect_test(wgt, x, y)) { wz_ask_parent_for_focus(wgt); but->down = 1; wgt->hold_focus = 1; } else ret = 0; break; } case ALLEGRO_EVENT_KEY_DOWN: { switch(event->keyboard.keycode) { case ALLEGRO_KEY_ENTER: { if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if(wgt->flags & WZ_STATE_HAS_FOCUS) { but->down = 1; } else ret = 0; break; } default: ret = 0; } break; } case ALLEGRO_EVENT_KEY_UP: { switch(event->keyboard.keycode) { case ALLEGRO_KEY_ENTER: { if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if(wgt->flags & WZ_STATE_HAS_FOCUS) { wz_trigger(wgt); } else ret = 0; break; } default: ret = 0; } break; } case WZ_HANDLE_SHORTCUT: { if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else { if(!(wgt->flags & WZ_STATE_HAS_FOCUS)) { wz_ask_parent_for_focus(wgt); } wz_trigger(wgt); } break; } #if (ALLEGRO_SUB_VERSION > 0) case ALLEGRO_EVENT_TOUCH_END: x = event->touch.x; y = event->touch.y; #endif case ALLEGRO_EVENT_MOUSE_BUTTON_UP: { if(event->type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { x = event->mouse.x; y = event->mouse.y; } if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if(but->down == 1) { if(wz_widget_rect_test(wgt, x, y)) wz_trigger(wgt); but->down = 0; wgt->hold_focus = 0; } else { ret = 0; } break; } case WZ_DESTROY: { if(but->own) al_ustr_free(but->text); ret = 0; break; } case WZ_SET_TEXT: { if(but->own) { al_ustr_free(but->text); but->text = al_ustr_dup((ALLEGRO_USTR*)event->user.data3); } else { but->text = (ALLEGRO_USTR*)event->user.data3; } break; } case WZ_TRIGGER: { ALLEGRO_EVENT ev; but->down = 0; wz_craft_event(&ev, WZ_BUTTON_PRESSED, wgt, 0); al_emit_user_event(wgt->source, &ev, 0); break; } default: ret = 0; } if(ret == 0) ret = wz_widget_proc(wgt, event); return ret; }
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(); } }
/* [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; }