FX_ENTRY void FX_CALL grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count, void *pointers, FxU32 stride) { LOG("grDrawVertexArrayContiguous(%d,%d,%d)\r\n", mode, Count, stride); if(nvidia_viewport_hack && !render_to_texture) { glViewport(0, viewport_offset, viewport_width, viewport_height); nvidia_viewport_hack = 0; } if(stride != 156) { LOGINFO("Incompatible stride\n"); } reloadTexture(); if(need_to_compile) compile_shader(); vbo_enable(); switch(mode) { case GR_TRIANGLE_STRIP: vbo_buffer(GL_TRIANGLE_STRIP,0,Count,pointers); break; case GR_TRIANGLE_FAN: vbo_buffer(GL_TRIANGLE_FAN,0,Count,pointers); break; default: display_warning("grDrawVertexArrayContiguous : unknown mode : %x", mode); } }
FX_ENTRY void FX_CALL grCullMode( GrCullMode_t mode ) { LOG("grCullMode(%d)\r\n", mode); static int oldmode = -1, oldinv = -1; culling_mode = mode; if (inverted_culling == oldinv && oldmode == mode) return; oldmode = mode; oldinv = inverted_culling; switch(mode) { case GR_CULL_DISABLE: glDisable(GL_CULL_FACE); break; case GR_CULL_NEGATIVE: if (!inverted_culling) glCullFace(GL_FRONT); else glCullFace(GL_BACK); glEnable(GL_CULL_FACE); break; case GR_CULL_POSITIVE: if (!inverted_culling) glCullFace(GL_BACK); else glCullFace(GL_FRONT); glEnable(GL_CULL_FACE); break; default: display_warning("unknown cull mode : %x", mode); } }
int main() { // declare the required data structures char *word_ptr; bool keep_going = true; // initialize and start the file system data structures startup_memory_system(); display_warning("main: memory manager started"); // accept and process user commands until directed to stop do { keep_going = process_next_command(); } while (keep_going); display_warning("main: memory manager stopped"); return 0; }
FX_ENTRY void FX_CALL grCoordinateSpace( GrCoordinateSpaceMode_t mode ) { LOG("grCoordinateSpace(%d)\r\n", mode); switch(mode) { case GR_WINDOW_COORDS: break; default: display_warning("unknwown coordinate space : %x", mode); } }
FX_ENTRY FxU32 FX_CALL grTexTextureMemRequired( FxU32 evenOdd, GrTexInfo *info ) { int width, height; WriteLog(M64MSG_VERBOSE, "grTextureMemRequired(%d)\r\n", evenOdd); if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexTextureMemRequired : loading more than one LOD"); if (info->aspectRatioLog2 < 0) { height = 1 << info->largeLodLog2; width = height >> -info->aspectRatioLog2; }
FX_ENTRY void FX_CALL grDepthBufferFunction( GrCmpFnc_t function ) { LOG("grDepthBufferFunction(%d)\r\n", function); switch(function) { case GR_CMP_GEQUAL: if (w_buffer_mode) glDepthFunc(GL_LEQUAL); else glDepthFunc(GL_GEQUAL); break; case GR_CMP_LEQUAL: if (w_buffer_mode) glDepthFunc(GL_GEQUAL); else glDepthFunc(GL_LEQUAL); break; case GR_CMP_LESS: if (w_buffer_mode) glDepthFunc(GL_GREATER); else glDepthFunc(GL_LESS); break; case GR_CMP_ALWAYS: glDepthFunc(GL_ALWAYS); break; case GR_CMP_EQUAL: glDepthFunc(GL_EQUAL); break; case GR_CMP_GREATER: if (w_buffer_mode) glDepthFunc(GL_LESS); else glDepthFunc(GL_GREATER); break; case GR_CMP_NEVER: glDepthFunc(GL_NEVER); break; case GR_CMP_NOTEQUAL: glDepthFunc(GL_NOTEQUAL); break; default: display_warning("unknown depth buffer function : %x", function); } }
FX_ENTRY void FX_CALL grVertexLayout(FxU32 param, FxI32 offset, FxU32 mode) { LOG("grVertexLayout(%d,%d,%d)\r\n", param, offset, mode); switch(param) { case GR_PARAM_XY: xy_en = mode; xy_off = offset; break; case GR_PARAM_Z: z_en = mode; z_off = offset; break; case GR_PARAM_Q: q_en = mode; q_off = offset; break; case GR_PARAM_FOG_EXT: fog_ext_en = mode; fog_ext_off = offset; break; case GR_PARAM_PARGB: pargb_en = mode; pargb_off = offset; break; case GR_PARAM_ST0: st0_en = mode; st0_off = offset; break; case GR_PARAM_ST1: st1_en = mode; st1_off = offset; break; default: display_warning("unknown grVertexLayout parameter : %x", param); } }
bool process_next_command() { char command[COMMAND_SIZE + 1]; int pid, address; printf("\nrequest: > "); fgets(command, sizeof command, stdin); // process the entered command if (sscanf(command, "begin p%d", &pid) == 1) { mem_begin(pid); } else if (sscanf(command, "read p%d %d", &pid, &address) == 2) { mem_read(pid, address); } else if (sscanf(command, "write p%d %d", &pid, &address) == 2) { mem_write(pid, address); } else if (sscanf(command, "end p%d", &pid) == 1) { mem_end(pid); } else if (strncmp(command, "view", 4) == 0) { view_memory_system(); } else if (strncmp(command, "warnings", 8) == 0) { if (messages) { printf(" sys !> warnings have been turned off\n"); } else { printf(" sys !> warnings are on\n"); } messages = !messages; } else if (strncmp(command, "stop", 4) == 0) { return false; } else { display_warning("main: unrecognized command"); } return true; }
FX_ENTRY void FX_CALL grDrawVertexArray(FxU32 mode, FxU32 Count, void *pointers2) { void **pointers = (void**)pointers2; LOG("grDrawVertexArray(%d,%d)\r\n", mode, Count); if(nvidia_viewport_hack && !render_to_texture) { glViewport(0, viewport_offset, viewport_width, viewport_height); nvidia_viewport_hack = 0; } reloadTexture(); if(need_to_compile) compile_shader(); if(mode != GR_TRIANGLE_FAN) { display_warning("grDrawVertexArray : unknown mode : %x", mode); } vbo_enable(); vbo_buffer(GL_TRIANGLE_FAN,0,Count,pointers[0]); }
FX_ENTRY void FX_CALL grDepthBufferMode( GrDepthBufferMode_t mode ) { LOG("grDepthBufferMode(%d)\r\n", mode); switch(mode) { case GR_DEPTHBUFFER_DISABLE: glDisable(GL_DEPTH_TEST); w_buffer_mode = 0; return; case GR_DEPTHBUFFER_WBUFFER: case GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS: glEnable(GL_DEPTH_TEST); w_buffer_mode = 1; break; case GR_DEPTHBUFFER_ZBUFFER: case GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS: glEnable(GL_DEPTH_TEST); w_buffer_mode = 0; break; default: display_warning("unknown depth buffer mode : %x", mode); } }
void slide_delete(void) { // Local variables GString *message; // Used to construct message strings GtkTreePath *new_path; // Temporary path gint num_slides; // Number of slides in the whole slide list GtkTreePath *old_path = NULL; // The old path, which we'll free gint slide_position; // Which slide in the slide list we are deleting GtkTreeSelection *film_strip_selector; // GtkTreeIter selection_iter; // undo_history_data *undo_item_data = NULL; // Memory structure undo history items are created in // Are we trying to delete the only slide in the project (not good)? set_slides(g_list_first(get_slides())); num_slides = g_list_length(get_slides()); if (1 == num_slides) { // Yes we are, so give a warning message and don't delete the slide message = g_string_new(NULL); g_string_printf(message, "%s ED462: %s", _("Error"), _("You must leave at least one slide in a project.")); display_warning(message->str); g_string_free(message, TRUE); return; } // Determine where the slide is positioned in the project slide_position = g_list_position(get_slides(), get_current_slide()); // Create and store the undo history item for this slide undo_item_data = g_new0(undo_history_data, 1); undo_item_data->layer_data_new = NULL; // NULL means not set undo_item_data->layer_data_old = NULL; // NULL means not set undo_item_data->position_new = -1; // -1 means not set undo_item_data->position_old = slide_position; undo_item_data->slide_data = get_current_slide_data(); undo_history_add_item(UNDO_DELETE_SLIDE, undo_item_data, TRUE); // Remove the current slide from the slide list set_slides(g_list_remove_link(get_slides(), get_current_slide())); // Remove the current slide from the film strip film_strip_selector = gtk_tree_view_get_selection(GTK_TREE_VIEW(get_film_strip_view())); gtk_tree_selection_get_selected(film_strip_selector, NULL, &selection_iter); gtk_list_store_remove(GTK_LIST_STORE(get_film_strip_store()), &selection_iter); // * Update the currently selected slide to point to the next slide * if (num_slides == (slide_position + 1)) { // If we're deleting the last slide, we'll need to point to the previous one instead slide_position--; } set_current_slide(g_list_nth(get_slides(), slide_position)); // Select the next thumbnail in the film strip and scroll to display it gtk_tree_view_get_cursor(GTK_TREE_VIEW(get_film_strip_view()), &new_path, NULL); if (NULL != new_path) old_path = new_path; // Make a backup of the old path, so we can free it new_path = gtk_tree_path_new_from_indices(slide_position, -1); gtk_tree_view_set_cursor(GTK_TREE_VIEW(get_film_strip_view()), new_path, NULL, FALSE); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(get_film_strip_view()), new_path, NULL, TRUE, 0.5, 0.0); if (NULL != old_path) gtk_tree_path_free(old_path); // Free the old path // Redraw the timeline draw_timeline(); // Redraw the workspace draw_workspace(); // Set the changes made variable set_changes_made(TRUE); // Update the status bar gtk_progress_bar_set_text(GTK_PROGRESS_BAR(get_status_bar()), _(" Slide deleted")); gdk_flush(); }
int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_FONT *font; ALLEGRO_CONFIG *config; ALLEGRO_EVENT_QUEUE *queue; bool write = false; bool flip = false; bool quit; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_font_addon(); al_init_image_addon(); al_install_keyboard(); al_install_mouse(); /* Read parameters from ex_vsync.ini. */ config = al_load_config_file("ex_vsync.ini"); if (!config) { config = al_create_config(); write = true; } /* 0 -> Driver chooses. * 1 -> Force vsync on. * 2 -> Force vsync off. */ vsync = option(config, "vsync", 0); fullscreen = option(config, "fullscreen", 0); frequency = option(config, "frequency", 0); /* Write the file back (so a template is generated on first run). */ if (write) { al_save_config_file("ex_vsync.ini", config); } al_destroy_config(config); /* Vsync 1 means force on, 2 means forced off. */ if (vsync) al_set_new_display_option(ALLEGRO_VSYNC, vsync, ALLEGRO_SUGGEST); /* Force fullscreen mode. */ if (fullscreen) { al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); /* Set a monitor frequency. */ if (frequency) al_set_new_display_refresh_rate(frequency); } display = al_create_display(640, 480); if (!display) { abort_example("Error creating display.\n"); } font = al_load_font("data/a4_font.tga", 0, 0); if (!font) { abort_example("Failed to load a4_font.tga\n"); } 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)); quit = display_warning(queue, font); al_flush_event_queue(queue); while (!quit) { ALLEGRO_EVENT event; /* With vsync, this will appear as a 50% gray screen (maybe * flickering a bit depending on monitor frequency). * Without vsync, there will be black/white shearing all over. */ if (flip) al_clear_to_color(al_map_rgb_f(1, 1, 1)); else al_clear_to_color(al_map_rgb_f(0, 0, 0)); al_flip_display(); flip = !flip; while (al_get_next_event(queue, &event)) { switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: quit = true; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) quit = true; } } /* Let's not go overboard and limit flipping at 1000 Hz. Without * this my system locks up and requires a hard reboot :P */ al_rest(0.001); } al_destroy_font(font); al_destroy_event_queue(queue); return 0; }
FX_ENTRY void FX_CALL grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count, void *pointers, FxU32 stride) { unsigned int i; float *x, *y, *q, *s0, *t0, *s1, *t1, *z, *fog; unsigned char *pargb; LOG("grDrawVertexArrayContiguous(%d,%d,%d)\r\n", mode, Count, stride); if(nvidia_viewport_hack && !render_to_texture) { glViewport(0, viewport_offset, viewport_width, viewport_height); nvidia_viewport_hack = 0; } reloadTexture(); if(need_to_compile) compile_shader(); switch(mode) { case GR_TRIANGLE_STRIP: glBegin(GL_TRIANGLE_STRIP); break; case GR_TRIANGLE_FAN: glBegin(GL_TRIANGLE_FAN); break; default: display_warning("grDrawVertexArrayContiguous : unknown mode : %x", mode); } for (i=0; i<Count; i++) { x = (float*)((unsigned char*)pointers+stride*i) + xy_off/sizeof(float); y = (float*)((unsigned char*)pointers+stride*i) + xy_off/sizeof(float) + 1; z = (float*)((unsigned char*)pointers+stride*i) + z_off/sizeof(float); q = (float*)((unsigned char*)pointers+stride*i) + q_off/sizeof(float); pargb = (unsigned char*)pointers+stride*i + pargb_off; s0 = (float*)((unsigned char*)pointers+stride*i) + st0_off/sizeof(float); t0 = (float*)((unsigned char*)pointers+stride*i) + st0_off/sizeof(float) + 1; s1 = (float*)((unsigned char*)pointers+stride*i) + st1_off/sizeof(float); t1 = (float*)((unsigned char*)pointers+stride*i) + st1_off/sizeof(float) + 1; fog = (float*)((unsigned char*)pointers+stride*i) + fog_ext_off/sizeof(float); //if(*fog == 0.0f) *fog = 1.0f; if (nbTextureUnits > 2) { if (st0_en) glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *s0 / *q / (float)tex1_width, ytex(0, *t0 / *q / (float)tex1_height)); if (st1_en) glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *s1 / *q / (float)tex0_width, ytex(1, *t1 / *q / (float)tex0_height)); } else { if (st0_en) glTexCoord2f(*s0 / *q / (float)tex0_width, ytex(0, *t0 / *q / (float)tex0_height)); } if (pargb_en) glColor4f(pargb[2]/255.0f, pargb[1]/255.0f, pargb[0]/255.0f, pargb[3]/255.0f); if (fog_enabled && fog_coord_support) { if(!fog_ext_en || fog_enabled != 2) glSecondaryColor3f((1.0f / *q) / 255.0f, 0.0f, 0.0f); else glSecondaryColor3f((1.0f / *fog) / 255.0f, 0.0f, 0.0f); } glVertex4f((*x - (float)widtho) / (float)(width/2) / *q, -(*y - (float)heighto) / (float)(height/2) / *q, ZCALC(*z, *q), 1.0f / *q); } glEnd(); }
gboolean working_area_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { // Local variables gint box_height; // Height of the bounding box gint box_width; // Width of the bounding box GList *collision_list = NULL; guint count_int; gint finish_x; // X position at the layer objects finish time gint finish_y; // Y position at the layer objects finish time GList *layer_pointer; GString *message; // Used to construct message strings guint num_collisions; gint onscreen_bottom; // Y coordinate of bounding box bottom gint onscreen_left; // X coordinate of bounding box left gint onscreen_right; // X coordinate of bounding box right gint onscreen_top; // Y coordinate of bounding box top gint pixmap_height; // Height of the front store gint pixmap_width; // Width of the front store gfloat scaled_height_ratio; // Used to calculate a vertical scaling ratio gfloat scaled_width_ratio; // Used to calculate a horizontal scaling ratio gint selected_row; // Holds the number of the row that is selected gint start_x; // X position at the layer objects start time gint start_y; // Y position at the layer objects start time layer *this_layer_data; // Pointer to the data for the selected layer slide *this_slide_data; // Alias to make things easier guint tmp_int; // Temporary integer // Only do this function if we have a front store available and a project loaded if ((NULL == get_front_store()) || (FALSE == get_project_active())) { return TRUE; } // Set the delete key focus to be layers set_delete_focus(FOCUS_LAYER); // Change the focus of the window to be this widget gtk_widget_grab_focus(GTK_WIDGET(widget)); // Initialise some things this_slide_data = get_current_slide_data(); gdk_drawable_get_size(GDK_PIXMAP(get_front_store()), &pixmap_width, &pixmap_height); // Check for primary mouse button click if (1 != event->button) { // Not a primary mouse click, so return return TRUE; } // Reset the mouse drag toggle set_mouse_dragging(FALSE); // Check if this was a double mouse click. If it was, open an edit dialog if (GDK_2BUTTON_PRESS == event->type) { // Open an edit dialog layer_edit(); return TRUE; } // Check if this was a triple mouse click. If it was, ignore it if (GDK_3BUTTON_PRESS == event->type) { return TRUE; } // If we're presently creating a new highlight layer, store the mouse coordinates if (TYPE_HIGHLIGHT == get_new_layer_selected()) { // Save the mouse coordinates set_stored_x(event->x); set_stored_y(event->y); // Reset the invalidation area set_invalidation_end_x(event->x); set_invalidation_end_y(event->y); set_invalidation_start_x(event->x - 1); set_invalidation_start_y(event->y - 1); return TRUE; } // If the user has clicked on the start or end points for the selected layer, we // don't want to do the collision detection below that changes layers if (END_POINTS_INACTIVE == get_end_point_status()) { // * Check if the user is clicking on the layer start or end points * // Calculate the height and width scaling values for the main drawing area at its present size scaled_height_ratio = (gfloat) get_project_height() / (gfloat) pixmap_height; scaled_width_ratio = (gfloat) get_project_width() / (gfloat) pixmap_width; // Determine which row is selected in the time line selected_row = time_line_get_selected_layer_num(this_slide_data->timeline_widget); layer_pointer = g_list_first(this_slide_data->layers); this_layer_data = g_list_nth_data(layer_pointer, selected_row); // If the layer data isn't accessible, then don't run this function if (NULL == this_layer_data) { return TRUE; } // Calculate start and end points finish_x = (this_layer_data->x_offset_finish / scaled_width_ratio) + END_POINT_HORIZONTAL_OFFSET; finish_y = (this_layer_data->y_offset_finish / scaled_height_ratio) + END_POINT_VERTICAL_OFFSET; start_x = (this_layer_data->x_offset_start / scaled_width_ratio) + END_POINT_HORIZONTAL_OFFSET; start_y = (this_layer_data->y_offset_start / scaled_height_ratio) + END_POINT_VERTICAL_OFFSET; // Is the user clicking on an end point? if (((event->x >= start_x) // Start point && (event->x <= start_x + END_POINT_WIDTH) && (event->y >= start_y) && (event->y <= start_y + END_POINT_HEIGHT)) || ((event->x >= finish_x) // End point && (event->x <= finish_x + END_POINT_WIDTH) && (event->y >= finish_y) && (event->y <= finish_y + END_POINT_HEIGHT))) { // Retrieve the layer size information switch (this_layer_data->object_type) { case TYPE_EMPTY: // We can't drag an empty layer, so reset things and return set_mouse_dragging(FALSE); set_end_point_status(END_POINTS_INACTIVE); set_stored_x(-1); set_stored_y(-1); return TRUE; case TYPE_HIGHLIGHT: box_width = ((layer_highlight *) this_layer_data->object_data)->width; box_height = ((layer_highlight *) this_layer_data->object_data)->height; break; case TYPE_GDK_PIXBUF: // If this is the background layer, then we ignore it if (TRUE == this_layer_data->background) { set_mouse_dragging(FALSE); set_end_point_status(END_POINTS_INACTIVE); set_stored_x(-1); set_stored_y(-1); return TRUE; } // No it's not, so process it box_width = ((layer_image *) this_layer_data->object_data)->width; box_height = ((layer_image *) this_layer_data->object_data)->height; break; case TYPE_MOUSE_CURSOR: box_width = ((layer_mouse *) this_layer_data->object_data)->width; box_height = ((layer_mouse *) this_layer_data->object_data)->height; break; case TYPE_TEXT: box_width = ((layer_text *) this_layer_data->object_data)->rendered_width; box_height = ((layer_text *) this_layer_data->object_data)->rendered_height; break; default: message = g_string_new(NULL); g_string_printf(message, "%s ED377: %s", _("Error"), _("Unknown layer type.")); display_warning(message->str); g_string_free(message, TRUE); return TRUE; // Unknown layer type, so no idea how to extract the needed data for the next code } // Work out the bounding box boundaries (scaled) if ((event->x >= start_x) // Left && (event->x <= start_x + END_POINT_WIDTH) // Right && (event->y >= start_y) // Top && (event->y <= start_y + END_POINT_HEIGHT)) // Bottom { // Start point clicked onscreen_left = this_layer_data->x_offset_start / scaled_width_ratio; onscreen_top = this_layer_data->y_offset_start / scaled_width_ratio;; onscreen_right = (this_layer_data->x_offset_start + box_width) / scaled_height_ratio; onscreen_bottom = (this_layer_data->y_offset_start + box_height) / scaled_height_ratio; } else { // End point clicked onscreen_left = this_layer_data->x_offset_finish / scaled_width_ratio; onscreen_top = this_layer_data->y_offset_finish / scaled_width_ratio;; onscreen_right = (this_layer_data->x_offset_finish + box_width) / scaled_height_ratio; onscreen_bottom = (this_layer_data->y_offset_finish + box_height) / scaled_height_ratio; } // Ensure the bounding box doesn't go out of bounds onscreen_left = CLAMP(onscreen_left, 2, pixmap_width - 2); onscreen_top = CLAMP(onscreen_top, 2, pixmap_height - 2); onscreen_right = CLAMP(onscreen_right, 2, pixmap_width - 2); onscreen_bottom = CLAMP(onscreen_bottom, 2, pixmap_height - 2); // Draw a bounding box onscreen draw_bounding_box(onscreen_left, onscreen_top, onscreen_right, onscreen_bottom); // End point clicked, so we return in order to avoid the collision detection return TRUE; } } // * Do collision detection here to determine if the user has clicked on a layer's object * this_slide_data = get_current_slide_data(); calculate_object_boundaries(); collision_list = detect_collisions(collision_list, event->x, event->y); if (NULL == collision_list) { // If there was no collision, then select the background layer time_line_set_selected_layer_num(this_slide_data->timeline_widget, this_slide_data->num_layers - 1); // *Needs* the -1, don't remove // Clear any existing handle box gdk_draw_drawable(GDK_DRAWABLE(get_main_drawing_area()->window), GDK_GC(get_main_drawing_area()->style->fg_gc[GTK_WIDGET_STATE(get_main_drawing_area())]), GDK_PIXMAP(get_front_store()), 0, 0, 0, 0, -1, -1); // Reset the stored mouse coordinates set_stored_x(-1); set_stored_y(-1); // Free the memory allocated during the collision detection g_list_free(collision_list); collision_list = NULL; return TRUE; } // * To get here there must have been at least one collision * // Save the mouse coordinates set_stored_x(event->x); set_stored_y(event->y); // Determine which layer the user has selected in the timeline selected_row = time_line_get_selected_layer_num(this_slide_data->timeline_widget); // Is the presently selected layer in the collision list? collision_list = g_list_first(collision_list); num_collisions = g_list_length(collision_list); for (count_int = 0; count_int < num_collisions; count_int++) { collision_list = g_list_first(collision_list); collision_list = g_list_nth(collision_list, count_int); layer_pointer = g_list_first(this_slide_data->layers); tmp_int = g_list_position(layer_pointer, ((boundary_box *) collision_list->data)->layer_ptr); if (tmp_int == selected_row) { // Return if the presently selected row is in the collision list, as we don't want to change our selected layer return TRUE; } } // * To get here, the presently selected layer wasn't in the collision list * // The presently selected row is not in the collision list, so move the selection row to the first collision collision_list = g_list_first(collision_list); selected_row = g_list_position(this_slide_data->layers, ((boundary_box *) collision_list->data)->layer_ptr); time_line_set_selected_layer_num(this_slide_data->timeline_widget, selected_row); // Draw a handle box around the new selected object draw_handle_box(); // Free the memory allocated during the collision detection g_list_free(collision_list); collision_list = NULL; return TRUE; }
gboolean swf_add_mouse_click(SWFMovie this_movie, gint click_type) { // Local variables gfloat click_duration; guint click_frames; GString *click_name; // The name of the mouse click sound we'll need to play guint i; // Counter GString *message; // Used to construct message strings SWFDisplayItem sound_display_item; FILE *sound_file; // The file we load the sound from SWFMovieClip sound_movie_clip; // Movie clip specifically to hold a sound SWFSoundStream sound_stream; // The sound we use gets loaded into this gchar *sound_pathname = NULL; // Full pathname to a sound file to load is constructed in this SWFAction swf_action; // Used when constructing action script // Initialisation click_name = g_string_new(NULL); // Determine the sound file to load switch (click_type) { case MOUSE_LEFT_ONE: case MOUSE_RIGHT_ONE: case MOUSE_MIDDLE_ONE: // If we've already added the sound to the movie, we don't need to add it again if (FALSE == get_mouse_click_single_added()) { // Single click mouse sound sound_pathname = g_build_path(G_DIR_SEPARATOR_S, SOUND_DIR, "mouse_single_click.mp3", NULL); // Make sure we only add this click sound once set_mouse_click_single_added(TRUE); } click_name = g_string_assign(click_name, "mousesingleclick"); click_duration = 0.5; break; case MOUSE_LEFT_DOUBLE: case MOUSE_RIGHT_DOUBLE: case MOUSE_MIDDLE_DOUBLE: // If we've already added the sound to the movie, we don't need to add it again if (FALSE == get_mouse_click_double_added()) { // Double click mouse sound sound_pathname = g_build_path(G_DIR_SEPARATOR_S, SOUND_DIR, "mouse_double_click.mp3", NULL); // Make sure we only add this click sound once set_mouse_click_double_added(TRUE); } click_name = g_string_assign(click_name, "mousedoubleclick"); click_duration = 0.5; break; case MOUSE_LEFT_TRIPLE: case MOUSE_RIGHT_TRIPLE: case MOUSE_MIDDLE_TRIPLE: // If we've already added the sound to the movie, we don't need to add it again if (FALSE == get_mouse_click_triple_added()) { // Triple click mouse sound sound_pathname = g_build_path(G_DIR_SEPARATOR_S, SOUND_DIR, "mouse_triple_click.mp3", NULL); // Make sure we only add this click sound once set_mouse_click_triple_added(TRUE); } click_name = g_string_assign(click_name, "mousetripleclick"); click_duration = 0.5; break; } if (NULL != sound_pathname) { // Create the sound object we'll be using if (get_debug_level()) printf("%s: '%s'\n", _("Full path name to sound file is"), sound_pathname); // Load the sound file sound_file = fopen(sound_pathname, "rb"); if (NULL == sound_file) { // Something went wrong when loading the sound file, so return message = g_string_new(NULL); g_string_printf(message, "%s ED412: %s", _("Error"), _("Something went wrong when opening a mouse click sound file.")); display_warning(message->str); g_string_free(message, TRUE); return FALSE; } sound_stream = newSWFSoundStream(sound_file); // Create a new movie clip file, containing only the sound sound_movie_clip = newSWFMovieClip(); // Ensure the clip doesn't start out playing nor keep looping swf_action = compileSWFActionCode("this.stop(); "); SWFMovieClip_add(sound_movie_clip, (SWFBlock) swf_action); SWFMovieClip_nextFrame(sound_movie_clip); // Add the sound stream to the sound movie clip SWFMovieClip_setSoundStream(sound_movie_clip, sound_stream, 1); SWFMovieClip_nextFrame(sound_movie_clip); // Add extra frames to allow the click to play it's full length click_frames = roundf(click_duration * get_frames_per_second()); for (i = 0; i < click_frames; i++) { SWFMovieClip_nextFrame(sound_movie_clip); } // Add the sound movie clip to the swf movie sound_display_item = SWFMovie_add(this_movie, (SWFBlock) sound_movie_clip); // Name the display item SWFDisplayItem_setName(sound_display_item, click_name->str); // Ensure the object is at the correct display depth SWFDisplayItem_setDepth(sound_display_item, 1000 + click_type); // Trying to pick a non conflicting depth } // Free the memory allocated in this functions g_string_free(click_name, TRUE); return TRUE; }
layer *read_mouse_layer(xmlDocPtr document, xmlNodePtr this_node) { // Local variables GString *message; // Used to construct message strings layer *tmp_layer; // Temporary layer layer_mouse *tmp_mouse_ob; // Temporary mouse layer object xmlChar *tmp_xmlChar; // Temporary xmlChar pointer gboolean usable_input = TRUE; // Used as a flag to indicate if all validation was successful gfloat *validated_gfloat; // Receives known good gfloat values from the validation function guint *validated_guint; // Receives known good guint values from the validation function GString *validated_string; // Receives known good strings from the validation function // Initialisation message = g_string_new(NULL); // Construct a new mouse pointer layer tmp_mouse_ob = g_new0(layer_mouse, 1); tmp_layer = g_new0(layer, 1); tmp_layer->object_type = TYPE_MOUSE_CURSOR; tmp_layer->object_data = (GObject *) tmp_mouse_ob; tmp_layer->external_link = g_string_new(NULL); tmp_layer->visible = TRUE; tmp_layer->background = FALSE; tmp_layer->external_link_window = g_string_new("_self"); tmp_layer->start_time = 0.0; tmp_layer->transition_in_type = TRANS_LAYER_NONE; tmp_layer->transition_in_duration = 0.0; tmp_layer->duration = get_default_layer_duration(); tmp_layer->transition_out_type = TRANS_LAYER_NONE; tmp_layer->transition_out_duration = 0.0; // Load the highlight layer values while (NULL != this_node) { if ((!xmlStrcmp(this_node->name, (const xmlChar *) "x_offset_start"))) { // Get the starting x offset tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_guint = validate_value(X_OFFSET, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_guint) { g_string_printf(message, "%s ED248: %s", _("Error"), _("There was something wrong with an x offset start value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->x_offset_start = 0; // Fill in the value, just to be safe } else { tmp_layer->x_offset_start = *validated_guint; g_free(validated_guint); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "y_offset_start"))) { // Get the starting y offset tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_guint = validate_value(Y_OFFSET, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_guint) { g_string_printf(message, "%s ED249: %s", _("Error"), _("There was something wrong with a y offset start value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->y_offset_start = 0; // Fill in the value, just to be safe } else { tmp_layer->y_offset_start = *validated_guint; g_free(validated_guint); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "x_offset_finish"))) { // Get the finishing x offset tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_guint = validate_value(X_OFFSET, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_guint) { g_string_printf(message, "%s ED250: %s", _("Error"), _("There was something wrong with an x offset finish value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->x_offset_finish = 0; // Fill in the value, just to be safe } else { tmp_layer->x_offset_finish = *validated_guint; g_free(validated_guint); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "y_offset_finish"))) { // Get the finishing y offset tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_guint = validate_value(Y_OFFSET, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_guint) { g_string_printf(message, "%s ED251: %s", _("Error"), _("There was something wrong with a y offset finish value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->y_offset_finish = 0; // Fill in the value, just to be safe } else { tmp_layer->y_offset_finish = *validated_guint; g_free(validated_guint); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "width"))) { // Get the width tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_guint = validate_value(LAYER_WIDTH, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_guint) { g_string_printf(message, "%s ED252: %s", _("Error"), _("There was something wrong with a layer width value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_mouse_ob->width = 1; // Fill in the value, just to be safe } else { tmp_mouse_ob->width = *validated_guint; g_free(validated_guint); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "height"))) { // Get the height tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_guint = validate_value(LAYER_HEIGHT, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_guint) { g_string_printf(message, "%s ED253: %s", _("Error"), _("There was something wrong with a layer height value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_mouse_ob->height = 1; // Fill in the value, just to be safe } else { tmp_mouse_ob->height = *validated_guint; g_free(validated_guint); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "click"))) { // Get the mouse click type tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_string = validate_value(MOUSE_CLICK, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_string) { g_string_printf(message, "%s ED254: %s", _("Error"), _("There was something wrong with a mouse click value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_mouse_ob->click = MOUSE_NONE; // Fill in the value, just to be safe } else { tmp_mouse_ob->click = MOUSE_NONE; // Set the default if (0 == g_ascii_strncasecmp(validated_string->str, "left_one", 8)) tmp_mouse_ob->click = MOUSE_LEFT_ONE; if (0 == g_ascii_strncasecmp(validated_string->str, "left_double", 11)) tmp_mouse_ob->click = MOUSE_LEFT_DOUBLE; if (0 == g_ascii_strncasecmp(validated_string->str, "left_triple", 11)) tmp_mouse_ob->click = MOUSE_LEFT_TRIPLE; if (0 == g_ascii_strncasecmp(validated_string->str, "right_one", 9)) tmp_mouse_ob->click = MOUSE_RIGHT_ONE; if (0 == g_ascii_strncasecmp(validated_string->str, "right_double", 12)) tmp_mouse_ob->click = MOUSE_RIGHT_DOUBLE; if (0 == g_ascii_strncasecmp(validated_string->str, "right_triple", 12)) tmp_mouse_ob->click = MOUSE_RIGHT_TRIPLE; if (0 == g_ascii_strncasecmp(validated_string->str, "middle_one", 10)) tmp_mouse_ob->click = MOUSE_MIDDLE_ONE; if (0 == g_ascii_strncasecmp(validated_string->str, "middle_double", 13)) tmp_mouse_ob->click = MOUSE_MIDDLE_DOUBLE; if (0 == g_ascii_strncasecmp(validated_string->str, "middle_triple", 13)) tmp_mouse_ob->click = MOUSE_MIDDLE_TRIPLE; g_string_free(validated_string, TRUE); validated_string = NULL; } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "start_time"))) { // Get the start time tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_gfloat = validate_value(LAYER_DURATION, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_gfloat) { g_string_printf(message, "%s ED344: %s", _("Error"), _("There was something wrong with a layer start time value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->start_time = 0; // Fill in the value, just to be safe } else { tmp_layer->start_time = *validated_gfloat; g_free(validated_gfloat); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "duration"))) { // Get the finish frame tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_gfloat = validate_value(LAYER_DURATION, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_gfloat) { g_string_printf(message, "%s ED345: %s", _("Error"), _("There was something wrong with a layer duration value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->duration = 0; // Fill in the value, just to be safe } else { tmp_layer->duration = *validated_gfloat; g_free(validated_gfloat); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "visible"))) { // Get the visibility tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_guint = validate_value(LAYER_VISIBLE, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_guint) { g_string_printf(message, "%s ED257: %s", _("Error"), _("There was something wrong with a layer visibility value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->visible = 0; // Fill in the value, just to be safe } else { tmp_layer->visible = *validated_guint; g_free(validated_guint); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "name"))) { // Get the name of the layer tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_string = validate_value(LAYER_NAME, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_string) { g_string_printf(message, "%s ED258: %s", _("Error"), _("There was something wrong with a layer name value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->name = g_string_new("Empty"); // Fill in the value, just to be safe } else { tmp_layer->name = validated_string; // We keep the validated string instead of copying then freeing it validated_string = NULL; } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "external_link"))) { // Get the URL associated with the layer tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_string = validate_value(EXTERNAL_LINK, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_string) { g_string_printf(message, "%s ED259: %s", _("Error"), _("There was something wrong with an external link value in the project file.")); display_warning(message->str); usable_input = FALSE; } else { tmp_layer->external_link = g_string_assign(tmp_layer->external_link, validated_string->str); g_string_free(validated_string,TRUE); validated_string = NULL; } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "external_link_window"))) { // Get the window to open the URL associated with the layer tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_string = validate_value(EXTERNAL_LINK_WINDOW, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_string) { g_string_printf(message, "%s ED260: %s", _("Error"), _("There was something wrong with an external link target window value in the project file.")); display_warning(message->str); usable_input = FALSE; } else { tmp_layer->external_link_window = g_string_assign(tmp_layer->external_link_window, validated_string->str); g_string_free(validated_string,TRUE); validated_string = NULL; } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "transition_in_type"))) { // Get the type of transition in tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_string = validate_value(TRANSITION_TYPE, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_string) { g_string_printf(message, "%s ED321: %s", _("Error"), _("There was something wrong with a transition in type value in the project file.")); display_warning(message->str); usable_input = FALSE; } else { if (0 == g_ascii_strncasecmp(validated_string->str, "fade", 4)) { tmp_layer->transition_in_type = TRANS_LAYER_FADE; } else { tmp_layer->transition_in_type = TRANS_LAYER_NONE; } g_string_free(validated_string, TRUE); validated_string = NULL; } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "transition_in_duration"))) { // Get the transition in duration tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_gfloat = validate_value(TRANSITION_DURATION, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_gfloat) { g_string_printf(message, "%s ED322: %s", _("Error"), _("There was something wrong with a transition in duration value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->transition_in_duration = 1; // Fill in the value, just to be safe } else { tmp_layer->transition_in_duration = *validated_gfloat; g_free(validated_gfloat); } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "transition_out_type"))) { // Get the type of transition out tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_string = validate_value(TRANSITION_TYPE, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_string) { g_string_printf(message, "%s ED323: %s", _("Error"), _("There was something wrong with a transition out type value in the project file.")); display_warning(message->str); usable_input = FALSE; } else { if (0 == g_ascii_strncasecmp(validated_string->str, "fade", 4)) { tmp_layer->transition_out_type = TRANS_LAYER_FADE; } else { tmp_layer->transition_out_type = TRANS_LAYER_NONE; } g_string_free(validated_string, TRUE); validated_string = NULL; } } if ((!xmlStrcmp(this_node->name, (const xmlChar *) "transition_out_duration"))) { // Get the transition out duration tmp_xmlChar = xmlNodeListGetString(document, this_node->xmlChildrenNode, 1); validated_gfloat = validate_value(TRANSITION_DURATION, V_CHAR, tmp_xmlChar); xmlFree(tmp_xmlChar); if (NULL == validated_gfloat) { g_string_printf(message, "%s ED324: %s", _("Error"), _("There was something wrong with a transition out duration value in the project file.")); display_warning(message->str); usable_input = FALSE; tmp_layer->transition_out_duration = 1; // Fill in the value, just to be safe } else { tmp_layer->transition_out_duration = *validated_gfloat; g_free(validated_gfloat); } } this_node = this_node->next; } // Free memory allocated in this function g_string_free(message, TRUE); // Return the validated mouse layer, or an indicator of failure if (TRUE == usable_input) { return tmp_layer; } else { // Free the newly allocated mouse layer data, as it didn't pass validation, so we won't use it layer_free(tmp_layer); return NULL; } }
void *validate_value(gint value_id, gint input_type, void *value) { // Local variables guint base_type; guint capabilities; gboolean capability_check; gchar *conversion_buffer = NULL; // Used when converting between unicode character types gchar *decimal_point; GString *error_string; gchar input_char; gunichar input_char_unicode; gchar *input_ptr; struct lconv *locale_info; gboolean match_found; gint output_gint; gint *output_gint_ptr; gfloat output_gfloat; gfloat *output_gfloat_ptr; GString *output_gstring; guint output_guint; guint *output_guint_ptr; guint string_counter; gint string_length; gint string_max; guint string_min; gfloat value_max; gfloat value_min; // Initialise various things base_type = get_valid_fields_base_type(value_id); capabilities = get_valid_fields_capabilities(value_id); input_ptr = (gchar *) value; output_gstring = g_string_new(NULL); locale_info = localeconv(); decimal_point = locale_info->decimal_point; switch (base_type) { case V_CHAR: // * We're validating a char or string * // We can only validate string input for this type of value if (V_CHAR != input_type) { return NULL; } // Get the length of the input string string_max = get_valid_fields_max_value(value_id); string_min = get_valid_fields_min_value(value_id); string_length = g_utf8_strlen(input_ptr, -1); // If the length of the string isn't in the acceptable range, return NULL if (string_length < string_min) return NULL; if ((string_length > string_max) && (-1 != string_max)) // -1 for string_max means "no maximum limit" return NULL; if (0 == string_length) { // 0 length string, so we just return it return output_gstring; } // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { // Get the next character input_char_unicode = g_utf8_get_char_validated(input_ptr, -1); if ((gunichar)-1 == input_char_unicode) { // The returned character was not a valid unicode character, so we indicate failure return NULL; } if ((gunichar)-2 == input_char_unicode) { // The returned character was not a valid unicode character, so we indicate failure return NULL; } // Convert the character to UTF-8 so we can process it conversion_buffer = g_ucs4_to_utf8(&input_char_unicode, 1, NULL, NULL, NULL); // Determine which character we're examining if (TRUE == g_unichar_isalnum(input_char_unicode)) { // It's a standard unicode alphanumeric character, so we accept it as is g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); } else { // * The input wasn't a standard alphanumic character, so check if it * // * is one of the characters in the capabilities list for this field * match_found = FALSE; capability_check = V_ANY_UNICHAR & capabilities; if (FALSE != capability_check) { // This field is allowed to have any valid unicode character if (TRUE == g_unichar_validate(input_char_unicode)) { // Yes, this is a valid unicode character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_SPACES & capabilities; if (FALSE != capability_check) { // This field is allowed to have spaces if (0 == g_strcmp0(" ", conversion_buffer)) { // Yes, this is a space character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_FULL_STOP & capabilities; if (FALSE != capability_check) { // This field is allowed to have full stops if (0 == g_strcmp0(".", conversion_buffer)) { // Yes, this is a full stop character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_HYPENS & capabilities; if (FALSE != capability_check) { // This field is allowed to have hypens if (0 == g_strcmp0("-", conversion_buffer)) { // Yes, this is a hypen character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_UNDERSCORES & capabilities; if (FALSE != capability_check) { // This field is allowed to have underscores if (0 == g_strcmp0("_", conversion_buffer)) { // Yes, this is an underscore character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_PATH_SEP & capabilities; if (FALSE != capability_check) { // This field is allowed to have path separator characters ('/', '\') if ((0 == g_strcmp0("/", conversion_buffer)) || (0 == g_strcmp0("\\", conversion_buffer))) { // Yes, this is a path separator character match_found = TRUE; output_gstring = g_string_append_c(output_gstring, G_DIR_SEPARATOR); // Output the OS correct version input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_EQUALS & capabilities; if (FALSE != capability_check) { // This field is allowed to have equals signs if (0 == g_strcmp0("=", conversion_buffer)) { // Yes, this is an equals sign character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_FORWARD_SLASHES & capabilities; if (FALSE != capability_check) { // This field is allowed to have forward slashes if (0 == g_strcmp0("/", conversion_buffer)) { // Yes, this is a forward slash character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_NEW_LINES & capabilities; if (FALSE != capability_check) { // This field is allowed to have new line characters if (0 == g_strcmp0("\n", conversion_buffer)) { // Yes, this is a new line character match_found = TRUE; output_gstring = g_string_append_c(output_gstring, '\n'); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_PLUSES & capabilities; if (FALSE != capability_check) { // This field is allowed to have pluses if (0 == g_strcmp0("+", conversion_buffer)) { // Yes, this is a plus character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_PERCENT & capabilities; if (FALSE != capability_check) { // This field is allowed to have the percent sign if (0 == g_strcmp0("%", conversion_buffer)) { // Yes, this is a percent sign match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_COLON & capabilities; if (FALSE != capability_check) { // This field is allowed to have colons if (0 == g_strcmp0(":", conversion_buffer)) { // Yes, this is a colon character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_AT & capabilities; if (FALSE != capability_check) { // This field is allowed to have the at symbol if (0 == g_strcmp0("@", conversion_buffer)) { // Yes, this is an at character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_QUESTION & capabilities; if (FALSE != capability_check) { // This field is allowed to have the question mark if (0 == g_strcmp0("?", conversion_buffer)) { // Yes, this is a question mark character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_AMPERSAND & capabilities; if (FALSE != capability_check) { // This field is allowed to have the ampersand character if (0 == g_strcmp0("&", conversion_buffer)) { // Yes, this is an ampersand character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } // The character we are checking is not in the list of valid inputs for this field if (FALSE == match_found) { g_free(conversion_buffer); g_string_free(output_gstring, TRUE); return NULL; } } } // Remove any leading and/or trailing white space output_gstring->str = g_strstrip(output_gstring->str); output_gstring->len = strlen(output_gstring->str); // Recheck the length of the output string if (output_gstring->len < string_min) { g_free(conversion_buffer); g_string_free(output_gstring, TRUE); return NULL; } // Free the memory used so far if (0 != string_length) { g_free(conversion_buffer); } // The string seems to be valid, so return it for use return output_gstring; break; case V_FLOAT_UNSIGNED: // * We're validating an unsigned float * // If we're working with string input, we need to convert it to a float first if (V_CHAR == input_type) { // * We're working with string input * // Get the length of the input string string_length = strlen((gchar *) value); // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); } else { // This field is allowed to have full stops. Is this character a full stop? if (0 == g_ascii_strncasecmp(".", &input_char, 1)) { // Yes, this is a full stop character output_gstring = g_string_append_c(output_gstring, *decimal_point); match_found = TRUE; continue; } // This field is allowed to have commas (equiv to full stop in some locales). Is this character a comma? if (0 == g_ascii_strncasecmp(",", &input_char, 1)) { // Yes, this is a comma character output_gstring = g_string_append_c(output_gstring, *decimal_point); match_found = TRUE; continue; } // The character we are checking is not in the list of valid inputs for this field if (FALSE == match_found) { g_string_free(output_gstring, TRUE); return NULL; } } } // Convert the string to a float output_gfloat = (gfloat) g_strtod(output_gstring->str, NULL); } else { // We're working with a float input, so just copy the value directly output_gfloat = *((gfloat *) value); } // Is the float value within the defined bounds? value_max = get_valid_fields_max_value(value_id); value_min = get_valid_fields_min_value(value_id); if ((output_gfloat < value_min) || (output_gfloat > value_max)) { // Value is out of bounds, so fail g_string_free(output_gstring, TRUE); return NULL; } // The value looks ok, so we copy it to newly allocated memory, to pass it back output_gfloat_ptr = g_try_new0(gfloat, 1); if (NULL == output_gfloat_ptr) { // Unable to allocate memory for the new value, so fail g_string_free(output_gstring, TRUE); return NULL; } *output_gfloat_ptr = output_gfloat; // Free the string memory allocated in this function g_string_free(output_gstring, TRUE); return output_gfloat_ptr; case V_INT_UNSIGNED: // * We're validating an unsigned integer * // If we're working with string input, we need to convert it to an integer first if (V_CHAR == input_type) { // * We're working with string input * // Get the length of the input string string_length = strlen((gchar *) value); // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); } else { // This wasn't a valid character g_string_free(output_gstring, TRUE); return NULL; } } // Convert the string to an integer output_guint = atoi(output_gstring->str); } else { // We're working with integer input, so just copy the value directly output_guint = *((guint *) value); } // Is the integer value within the defined bounds? value_max = get_valid_fields_max_value(value_id); value_min = get_valid_fields_min_value(value_id); if ((output_guint < value_min) || (output_guint > value_max)) { // Value is out of bounds, so fail g_string_free(output_gstring, TRUE); return NULL; } // The value looks ok, so we copy it to newly allocated memory, to pass it back output_guint_ptr = g_try_new0(guint, 1); if (NULL == output_guint_ptr) { // Unable to allocate memory for the new value, so fail g_string_free(output_gstring, TRUE); return NULL; } *output_guint_ptr = output_guint; // Free the string memory allocated in this function g_string_free(output_gstring, TRUE); return output_guint_ptr; case V_INT_SIGNED: // * We're validating a signed integer * // If we're working with string input, we need to convert it to an integer first if (V_CHAR == input_type) { // * We're working with string input * // Get the length of the input string string_length = strlen((gchar *) value); // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); } else { // * The input wasn't a standard digit character, so check if it * // * is one of the characters in the capabilities list for this field * match_found = FALSE; capability_check = V_HYPENS & capabilities; if (FALSE != capability_check) { // This field is allowed to have hypens if (0 == g_ascii_strncasecmp("-", &input_char, 1)) { // Yes, this is a hypen character match_found = TRUE; g_string_append_printf(output_gstring, "%s", "-"); } } // The character we are checking is not in the list of valid inputs for this field if (FALSE == match_found) { g_string_free(output_gstring, TRUE); return NULL; } } } // Convert the string to an integer output_gint = atoi(output_gstring->str); } else { // We're working with integer input, so just copy the value directly output_gint = *((gint *) value); } // Is the integer value within the defined bounds? value_max = get_valid_fields_max_value(value_id); value_min = get_valid_fields_min_value(value_id); if ((output_gint < value_min) || (output_gint > value_max)) { // Value is out of bounds, so fail g_string_free(output_gstring, TRUE); return NULL; } // The value looks ok, so we copy it to newly allocated memory, to pass it back output_gint_ptr = g_try_new0(gint, 1); if (NULL == output_gint_ptr) { // Unable to allocate memory for the new value, so fail g_string_free(output_gstring, TRUE); return NULL; } *output_gint_ptr = output_gint; // Free the string memory allocated in this function g_string_free(output_gstring, TRUE); return output_gint_ptr; case V_RESOLUTION: // * We're working with a resolution (text string) input. i.e. '1920x1200 pixels' * // Get the length of the input string string_length = strlen((gchar *) value); string_max = get_valid_fields_max_value(value_id); string_min = get_valid_fields_min_value(value_id); // If the length of the string isn't in the acceptable range, return NULL if ((string_length < string_min) || (string_length > string_max)) return NULL; // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); } else { match_found = FALSE; // This field is allowed to have the ' ' and 'x' characters . Is this character one of those? if (0 == g_ascii_strncasecmp(" ", &input_char, 1)) { // Yes, this is a space character, so we've already collected the required resolution // info and we can just return the resolution part of the string so far // Remove any leading and/or trailing white space output_gstring->str = g_strstrip(output_gstring->str); output_gstring->len = strlen(output_gstring->str); // Recheck the length of the output string if ((string_length < string_min) || (string_length > string_max)) return NULL; // The string seems to be valid, so return it for use return output_gstring; } if (0 == g_ascii_strncasecmp("x", &input_char, 1)) { // Yes, this is a 'x' character output_gstring = g_string_append_c(output_gstring, 'x'); match_found = TRUE; continue; } if (FALSE == match_found) { // This wasn't a valid character g_string_free(output_gstring, TRUE); return NULL; } } } // Remove any leading and/or trailing white space output_gstring->str = g_strstrip(output_gstring->str); output_gstring->len = strlen(output_gstring->str); // Recheck the length of the output string if ((string_length < string_min) || (string_length > string_max)) return NULL; // The string seems to be valid, so return it for use return output_gstring; case V_ZOOM: // * We're working with a zoom level. i.e. "100%" or "Fit to width" * // Get the length of the input string string_length = g_utf8_strlen((gchar *) value, -1); string_max = get_valid_fields_max_value(value_id); string_min = get_valid_fields_min_value(value_id); // If the length of the string isn't in the acceptable range, return NULL if ((string_length < string_min) || (string_length > string_max)) return NULL; // If the string is "Fit to width" or a localised version of it if ((0 == g_strcmp0("Fit to width", (gchar *) value)) || (0 == g_strcmp0(_("Fit to width"), (gchar *) value))) { // Yes, this is the "Fit to width" value output_gstring = g_string_assign(output_gstring, value); return output_gstring; } // * The incoming string isn't the "Fit to width" value, * // * so should only consist of decimal characters and '%' * // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); continue; } // Check for '%' character if (0 == g_ascii_strncasecmp("%", &input_char, 1)) { // Yes, this is a '%' character output_gstring = g_string_append_c(output_gstring, '%'); continue; } // This wasn't a valid character g_string_free(output_gstring, TRUE); return NULL; } return output_gstring; default: // Unknown value type, we should never get here error_string = g_string_new(NULL); g_string_printf(error_string, "%s ED119: %s - '%s'", _("Error"), _("Unknown value passed to validation function"), get_valid_fields_name(value_id)); display_warning(error_string->str); g_string_free(error_string, TRUE); return NULL; } // If we get here, then something went wrong! return NULL; }
GtkTextBuffer *gtk_text_buffer_duplicate(GtkTextBuffer *source_buffer) { // Local variables gchar *conversion_buffer; // Used when converting between unicode character types GtkTextIter end_iter; GtkTextIter end_iter_minus_one; gint end_offset; gint i; guint loop_counter; GtkTextIter loop_iter; GtkTextBuffer *new_text_buffer; guint num_tags; GtkTextIter source_buffer_end; GtkTextIter source_buffer_start; gint start_offset; GSList *tag_list; GtkTextTag *tag_ptr; gunichar temp_char; GString *temp_gstring; // Validate the tags in the source buffer text_layer_dialog_validate_buffer_tag_quantity(GTK_TEXT_BUFFER(source_buffer)); // Initialise various things temp_gstring = g_string_new(NULL); // Create a new text buffer new_text_buffer = gtk_text_buffer_new(get_text_tags_table()); // Get the bounds of the source buffer gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(source_buffer), &source_buffer_start, &source_buffer_end); gtk_text_iter_order(&source_buffer_start, &source_buffer_end); // Scan through the source text buffer one character at a time, getting the character and the tags that apply to it start_offset = gtk_text_iter_get_offset(&source_buffer_start); end_offset = gtk_text_iter_get_offset(&source_buffer_end); for (i = 0; i < end_offset; i++) { // Copy one character from the source text buffer to the new destination text buffer gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(source_buffer), &loop_iter, i); temp_char = gtk_text_iter_get_char(&loop_iter); conversion_buffer = g_ucs4_to_utf8(&temp_char, 1, NULL, NULL, NULL); if (NULL == conversion_buffer) { g_string_printf(temp_gstring, "%s ED441: %s", _("Error"), _("Could not convert unicode character from ucs4 to utf8.")); display_warning(temp_gstring->str); continue; } // Validate the retrieved character if (TRUE != g_unichar_validate(temp_char)) { // Something other than a unicode character was retrieved g_string_printf(temp_gstring, "%s ED442: %s", _("Error"), _("Invalid unicode character found in text.")); display_warning(temp_gstring->str); continue; } gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(new_text_buffer), conversion_buffer, -1); g_free(conversion_buffer); // Copy the tags from the character in the source buffer to the new character in the destination buffer tag_list = gtk_text_iter_get_tags(&loop_iter); num_tags = g_slist_length(tag_list); gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(new_text_buffer), &end_iter); end_iter_minus_one = end_iter; gtk_text_iter_backward_char(&end_iter_minus_one); for (loop_counter = 0; loop_counter < num_tags; loop_counter++) { // Copy each tag from the source text buffer to the destination one tag_ptr = g_slist_nth_data(tag_list, loop_counter); gtk_text_buffer_apply_tag(GTK_TEXT_BUFFER(new_text_buffer), tag_ptr, &end_iter_minus_one, &end_iter); } g_slist_free(tag_list); } g_string_free(temp_gstring, TRUE); // Validate the tags in the duplicated buffer text_layer_dialog_validate_buffer_tag_quantity(GTK_TEXT_BUFFER(new_text_buffer)); // Return the duplicated text buffer return new_text_buffer; }