From e245c772f1f540d175a5463d3e2b4a2ab1b3a537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Thu, 10 May 2018 00:14:00 +0200 Subject: [PATCH] Implemented open file dialog --- gdsparse.c | 535 ++++++++++++++++++++++++----------------------- glade/main.glade | 2 +- main.c | 77 +++++-- 3 files changed, 333 insertions(+), 281 deletions(-) diff --git a/gdsparse.c b/gdsparse.c index 477e5af..b2780d2 100644 --- a/gdsparse.c +++ b/gdsparse.c @@ -1,3 +1,22 @@ +/* + * GDSII converter + * Copyright (C) 2018 Mario Hüttel + * + * This file is part of GDSII-Converter. + * + * GDSII-Converter is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License. + * + * GDSII-converter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + /* * What's missing? - A lot: * Support for Boxes @@ -312,11 +331,9 @@ int parse_gds_from_file(const char *filename, GList **library_list) struct gds_cell *current_cell = NULL; struct gds_graphics *current_graphics = NULL; struct gds_cell_instance *current_s_reference = NULL; + int x, y; //////////// GList *lib_list; - GList *lib_ptr; - GList *cell_ptr; - GList *cell_ref_ptr; lib_list = *library_list; @@ -329,275 +346,271 @@ int parse_gds_from_file(const char *filename, GList **library_list) /* Record parser */ while (run == 1) { - switch (state) { - case PARSING_LENGTH: - rec_type = INVALID; - read = fread(workbuff, sizeof(char), 2, gds_file); - if (read != 2 && (current_cell != NULL || - current_graphics != NULL || - current_lib != NULL || - current_s_reference != NULL)) { - GDS_ERROR("End of File. with openend structs/libs"); - run = -2; - break; - } else if (read != 2) { - /* EOF */ - run = 0; - break; - } - - rec_data_length = (uint16_t)((((uint16_t)(workbuff[0])) << 8) | - (uint16_t)(workbuff[1])); - - if (rec_data_length < 4) { - /* Possible Zero-Padding: */ - run = 0; - GDS_WARN("Zero Padding detected!"); - if (current_cell != NULL || - current_graphics != NULL || - current_lib != NULL || - current_s_reference != NULL) { - GDS_ERROR("Not all structures closed"); - run = -2; - } - break; - } - rec_data_length -= 4; - state = PARSING_TYPE; + rec_type = INVALID; + read = fread(workbuff, sizeof(char), 2, gds_file); + if (read != 2 && (current_cell != NULL || + current_graphics != NULL || + current_lib != NULL || + current_s_reference != NULL)) { + GDS_ERROR("End of File. with openend structs/libs"); + run = -2; break; - case PARSING_TYPE: - read = fread(workbuff, sizeof(char), 2, gds_file); - if (read != 2) { + } else if (read != 2) { + /* EOF */ + run = 0; + break; + } + + rec_data_length = (uint16_t)((((uint16_t)(workbuff[0])) << 8) | + (uint16_t)(workbuff[1])); + + if (rec_data_length < 4) { + /* Possible Zero-Padding: */ + run = 0; + GDS_WARN("Zero Padding detected!"); + if (current_cell != NULL || + current_graphics != NULL || + current_lib != NULL || + current_s_reference != NULL) { + GDS_ERROR("Not all structures closed"); run = -2; - GDS_ERROR("Unexpected end of file"); - break; - } - rec_type = (uint16_t)((((uint16_t)(workbuff[0])) << 8) | - (uint16_t)(workbuff[1])); - state = PARSING_DAT; - - /* if begin: Allocate structures */ - switch (rec_type) { - case BGNLIB: - lib_list = append_library(lib_list); - if (lib_list == NULL) { - GDS_ERROR("Allocating memory failed"); - run = -3; - break; - - } - printf("Entering Lib\n"); - current_lib = (struct gds_library *)g_list_last(lib_list)->data; - break; - case ENDLIB: - if (current_lib == NULL) { - run = -4; - GDS_ERROR("Closing Library with no opened library"); - break; - } - - /* Check for open Cells */ - if (current_cell != NULL) { - run = -4; - GDS_ERROR("Closing Library with opened cells"); - break; - } - current_lib = NULL; - printf("Leaving Library\n"); - break; - case BGNSTR: - current_lib->cells = append_cell(current_lib->cells); - if (current_lib->cells == NULL) { - GDS_ERROR("Allocating memory failed"); - run = -3; - break; - } - printf("Entering Cell\n"); - current_cell = (struct gds_cell *)g_list_last(current_lib->cells)->data; - break; - case ENDSTR: - if (current_cell == NULL) { - run = -4; - GDS_ERROR("Closing cell with no opened cell"); - break; - } - /* Check for open Elements */ - if (current_graphics != NULL || current_s_reference != NULL) { - run = -4; - GDS_ERROR("Closing cell with opened Elements"); - break; - } - current_cell = NULL; - printf("Leaving Cell\n"); - break; - //case BOX: - case BOUNDARY: - if (current_cell == NULL) { - GDS_ERROR("Boundary outside of cell"); - run = -3; - break; - } - current_cell->graphic_objs = append_graphics(current_cell->graphic_objs, GRAPHIC_POLYGON); - if (current_cell->graphic_objs == NULL) { - GDS_ERROR("Memory allocation failed"); - run = -4; - break; - } - current_graphics = (struct gds_graphics *) g_list_last(current_cell->graphic_objs)->data; - printf("\tEntering boundary\n"); - break; - case SREF: - if (current_cell == NULL) { - GDS_ERROR("Path outside of cell"); - run = -3; - break; - } - current_cell->child_cells = append_cell_ref(current_cell->child_cells); - if (current_cell->child_cells == NULL) { - GDS_ERROR("Memory allocation failed"); - run = -4; - break; - } - - current_s_reference = (struct gds_cell_instance *) g_list_last(current_cell->child_cells)->data; - printf("\tEntering reference\n"); - break; - case PATH: - if (current_cell == NULL) { - GDS_ERROR("Path outside of cell"); - run = -3; - break; - } - current_cell->graphic_objs = append_graphics(current_cell->graphic_objs, GRAPHIC_PATH); - if (current_cell->graphic_objs == NULL) { - GDS_ERROR("Memory allocation failed"); - run = -4; - break; - } - current_graphics = (struct gds_graphics *) g_list_last(current_cell->graphic_objs)->data; - printf("\tEntering Path\n"); - break; - case ENDEL: - if (current_graphics != NULL) { - - printf("\tLeaving %s\n", (current_graphics->type == GRAPHIC_POLYGON ? "boundary" : "path")); - current_graphics = NULL; - } - if (current_s_reference != NULL) { - printf("\tLeaving Reference\n"); - current_s_reference = NULL; - } - break; - case XY: - if (current_graphics) { - - } else if (current_s_reference) { - if (rec_data_length != 8) { - GDS_WARN("Instance has weird coordinates. Rendered output might be screwed!"); - } - } - - break; - case MAG: - break; - case ANGLE: - break; - case STRANS: - break; - default: - //GDS_WARN("Record: %04x, len: %u", (unsigned int)rec_type, (unsigned int)rec_data_length); - break; } break; + } + rec_data_length -= 4; + read = fread(workbuff, sizeof(char), 2, gds_file); + if (read != 2) { + run = -2; + GDS_ERROR("Unexpected end of file"); + break; + } + rec_type = (uint16_t)((((uint16_t)(workbuff[0])) << 8) | + (uint16_t)(workbuff[1])); + state = PARSING_DAT; - case PARSING_DAT: - read = fread(workbuff, sizeof(char), rec_data_length, gds_file); - state = PARSING_LENGTH; - - if (read != rec_data_length) { - GDS_ERROR("Could not read enough data"); - run = -5; - break; - } - /* No Data -> No Processing */ - if (!read) break; - - switch (rec_type) { - case LIBNAME: - name_library(current_lib, read, workbuff); - break; - case STRNAME: - name_cell(current_cell, read, workbuff, current_lib); - break; - case XY: - if (current_s_reference) { - /* Get origin of reference */ - current_s_reference->origin.x = gds_convert_signed_int(workbuff); - current_s_reference->origin.y = gds_convert_signed_int(&workbuff[4]); - } else if (current_graphics) { - for (i = 0; i < read/8; i++) { - // printf("coords: %d/%d", gds_convert_signed_int(&workbuff[i*8]), gds_convert_signed_int(&workbuff[i*8+4])); - current_graphics->vertices = append_vertex(current_graphics->vertices, - gds_convert_signed_int(&workbuff[i*8]), - gds_convert_signed_int(&workbuff[i*8])); - - } - } - break; - case STRANS: - if (!current_s_reference) { - GDS_ERROR("Transformation defined outside of instance"); - break; - } - current_s_reference->flipped = ((workbuff[0] & 0x80) ? 1 : 0); - break; - - case SNAME: - name_cell_ref(current_s_reference, read, workbuff); - break; - case LAYER: - if (!current_graphics) { - GDS_WARN("Layer has to be defined inside graphics object. Probably unknown object. Implement it yourself!"); - break; - } - current_graphics->layer = gds_convert_signed_int16(workbuff); - printf("\t\tAdded layer %d\n", (int)current_graphics->layer); - break; - case MAG: - if (rec_data_length != 8) { - GDS_WARN("Magnification is not an 8 byte real. Results may be wrong"); - } - if (current_graphics != NULL && current_s_reference != NULL) { - GDS_ERROR("Open Graphics and Cell Reference\n\tMissing ENDEL?"); - run = -6; - break; - } - if (current_s_reference != NULL) { - current_s_reference->magnification = gds_convert_double(workbuff); - printf("\t\tMagnification defined: %lf\n", current_s_reference->magnification); - } - break; - case ANGLE: - if (rec_data_length != 8) { - GDS_WARN("Angle is not an 8 byte real. Results may be wrong"); - } - if (current_graphics != NULL && current_s_reference != NULL) { - GDS_ERROR("Open Graphics and Cell Reference\n\tMissing ENDEL?"); - run = -6; - break; - } - if (current_s_reference != NULL) { - current_s_reference->angle = gds_convert_double(workbuff); - printf("\t\tAngle defined: %lf\n", current_s_reference->angle); - } + /* if begin: Allocate structures */ + switch (rec_type) { + case BGNLIB: + lib_list = append_library(lib_list); + if (lib_list == NULL) { + GDS_ERROR("Allocating memory failed"); + run = -3; break; } - break; /* PARSING_DAT */ + printf("Entering Lib\n"); + current_lib = (struct gds_library *)g_list_last(lib_list)->data; + break; + case ENDLIB: + if (current_lib == NULL) { + run = -4; + GDS_ERROR("Closing Library with no opened library"); + break; + } + + /* Check for open Cells */ + if (current_cell != NULL) { + run = -4; + GDS_ERROR("Closing Library with opened cells"); + break; + } + current_lib = NULL; + printf("Leaving Library\n"); + break; + case BGNSTR: + current_lib->cells = append_cell(current_lib->cells); + if (current_lib->cells == NULL) { + GDS_ERROR("Allocating memory failed"); + run = -3; + break; + } + printf("Entering Cell\n"); + current_cell = (struct gds_cell *)g_list_last(current_lib->cells)->data; + break; + case ENDSTR: + if (current_cell == NULL) { + run = -4; + GDS_ERROR("Closing cell with no opened cell"); + break; + } + /* Check for open Elements */ + if (current_graphics != NULL || current_s_reference != NULL) { + run = -4; + GDS_ERROR("Closing cell with opened Elements"); + break; + } + current_cell = NULL; + printf("Leaving Cell\n"); + break; + //case BOX: + case BOUNDARY: + if (current_cell == NULL) { + GDS_ERROR("Boundary outside of cell"); + run = -3; + break; + } + current_cell->graphic_objs = append_graphics(current_cell->graphic_objs, GRAPHIC_POLYGON); + if (current_cell->graphic_objs == NULL) { + GDS_ERROR("Memory allocation failed"); + run = -4; + break; + } + current_graphics = (struct gds_graphics *) g_list_last(current_cell->graphic_objs)->data; + printf("\tEntering boundary\n"); + break; + case SREF: + if (current_cell == NULL) { + GDS_ERROR("Path outside of cell"); + run = -3; + break; + } + current_cell->child_cells = append_cell_ref(current_cell->child_cells); + if (current_cell->child_cells == NULL) { + GDS_ERROR("Memory allocation failed"); + run = -4; + break; + } + + current_s_reference = (struct gds_cell_instance *) g_list_last(current_cell->child_cells)->data; + printf("\tEntering reference\n"); + break; + case PATH: + if (current_cell == NULL) { + GDS_ERROR("Path outside of cell"); + run = -3; + break; + } + current_cell->graphic_objs = append_graphics(current_cell->graphic_objs, GRAPHIC_PATH); + if (current_cell->graphic_objs == NULL) { + GDS_ERROR("Memory allocation failed"); + run = -4; + break; + } + current_graphics = (struct gds_graphics *) g_list_last(current_cell->graphic_objs)->data; + printf("\tEntering Path\n"); + break; + case ENDEL: + if (current_graphics != NULL) { + + printf("\tLeaving %s\n", (current_graphics->type == GRAPHIC_POLYGON ? "boundary" : "path")); + current_graphics = NULL; + } + if (current_s_reference != NULL) { + printf("\tLeaving Reference\n"); + current_s_reference = NULL; + } + break; + case XY: + if (current_graphics) { + + } else if (current_s_reference) { + if (rec_data_length != 8) { + GDS_WARN("Instance has weird coordinates. Rendered output might be screwed!"); + } + } + + break; + case MAG: + break; + case ANGLE: + break; + case STRANS: + break; + default: + //GDS_WARN("Record: %04x, len: %u", (unsigned int)rec_type, (unsigned int)rec_data_length); + break; + } /* switch(rec_type) */ + + + /* No Data -> No Processing, go back to top */ + if (!rec_data_length) continue; + + read = fread(workbuff, sizeof(char), rec_data_length, gds_file); + state = PARSING_LENGTH; + + if (read != rec_data_length) { + GDS_ERROR("Could not read enough data"); + run = -5; + break; + } + + switch (rec_type) { + case LIBNAME: + name_library(current_lib, read, workbuff); + break; + case STRNAME: + name_cell(current_cell, read, workbuff, current_lib); + break; + case XY: + if (current_s_reference) { + /* Get origin of reference */ + current_s_reference->origin.x = gds_convert_signed_int(workbuff); + current_s_reference->origin.y = gds_convert_signed_int(&workbuff[4]); + printf("\t\tSet origin to: %d/%d\n", current_s_reference->origin.x, + current_s_reference->origin.y); + } else if (current_graphics) { + for (i = 0; i < read/8; i++) { + x = gds_convert_signed_int(&workbuff[i*8]); + y = gds_convert_signed_int(&workbuff[i*8]); + current_graphics->vertices = + append_vertex(current_graphics->vertices, x, y); + printf("\t\tSet coordinate: %d/%d\n", x, y); + + } + } + break; + case STRANS: + if (!current_s_reference) { + GDS_ERROR("Transformation defined outside of instance"); + break; + } + current_s_reference->flipped = ((workbuff[0] & 0x80) ? 1 : 0); + break; + + case SNAME: + name_cell_ref(current_s_reference, read, workbuff); + break; + case LAYER: + if (!current_graphics) { + GDS_WARN("Layer has to be defined inside graphics object. Probably unknown object. Implement it yourself!"); + break; + } + current_graphics->layer = gds_convert_signed_int16(workbuff); + printf("\t\tAdded layer %d\n", (int)current_graphics->layer); + break; + case MAG: + if (rec_data_length != 8) { + GDS_WARN("Magnification is not an 8 byte real. Results may be wrong"); + } + if (current_graphics != NULL && current_s_reference != NULL) { + GDS_ERROR("Open Graphics and Cell Reference\n\tMissing ENDEL?"); + run = -6; + break; + } + if (current_s_reference != NULL) { + current_s_reference->magnification = gds_convert_double(workbuff); + printf("\t\tMagnification defined: %lf\n", current_s_reference->magnification); + } + break; + case ANGLE: + if (rec_data_length != 8) { + GDS_WARN("Angle is not an 8 byte real. Results may be wrong"); + } + if (current_graphics != NULL && current_s_reference != NULL) { + GDS_ERROR("Open Graphics and Cell Reference\n\tMissing ENDEL?"); + run = -6; + break; + } + if (current_s_reference != NULL) { + current_s_reference->angle = gds_convert_double(workbuff); + printf("\t\tAngle defined: %lf\n", current_s_reference->angle); + } + break; } - } + + } /* while(run == 1) */ fclose(gds_file); diff --git a/glade/main.glade b/glade/main.glade index ac561d3..c4fd288 100644 --- a/glade/main.glade +++ b/glade/main.glade @@ -2,7 +2,7 @@ - + True False diff --git a/main.c b/main.c index fdc8122..4b34be7 100644 --- a/main.c +++ b/main.c @@ -3,15 +3,16 @@ #include enum cell_store_columns { -LIBRARY, -CELL, -STORE_COLUMN + LIBRARY, + CELL, + STORE_COLUMN }; struct open_button_data { - GList **list_ptr; - GtkTreeStore *cell_store; + GtkWindow *main_window; + GList **list_ptr; + GtkTreeStore *cell_store; }; @@ -36,24 +37,62 @@ void on_load_gds(gpointer button, gpointer user) struct gds_cell *gds_c; struct open_button_data *ptr = (struct open_button_data *)user; GtkTreeStore *store = ptr->cell_store; + GtkWidget *open_dialog; + GtkFileChooser *file_chooser; + GtkFileFilter *filter; + GtkStyleContext *button_style; + gint dialog_result; + int gds_result; + char *filename; - gtk_tree_store_clear(store); + open_dialog = gtk_file_chooser_dialog_new("Open GDSII File", ptr->main_window, GTK_FILE_CHOOSER_ACTION_OPEN, + "Cancel", GTK_RESPONSE_CANCEL, "Open GDSII", GTK_RESPONSE_ACCEPT, NULL); + file_chooser = GTK_FILE_CHOOSER(open_dialog); + /* Add GDS II Filter */ + filter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(filter, "*.gds"); + gtk_file_filter_set_name(filter, "GDSII-Files"); + gtk_file_chooser_add_filter(file_chooser, filter); - clear_lib_list(ptr->list_ptr); - parse_gds_from_file("/home/mari/Desktop/test.gds", ptr->list_ptr); + dialog_result = gtk_dialog_run(GTK_DIALOG(open_dialog)); - for (lib = *(ptr->list_ptr); lib != NULL; lib = lib->next) { - gds_lib = (struct gds_library *)lib->data; - /* Create top level iter */ - gtk_tree_store_append (store, &libiter, NULL); - gtk_tree_store_set (store, &libiter, LIBRARY, gds_lib->name, -1); - for (cell = gds_lib->cells; cell != NULL; cell = cell->next) { - gds_c = (struct gds_cell *)cell->data; - gtk_tree_store_append (store, &celliter, &libiter); - gtk_tree_store_set (store, &celliter, CELL, gds_c->name, -1); + if (dialog_result == GTK_RESPONSE_ACCEPT) { + + /* Get File name */ + filename = gtk_file_chooser_get_filename(file_chooser); + + /* Clear Display */ + gtk_tree_store_clear(store); + /* Delete parsed GDS data */ + clear_lib_list(ptr->list_ptr); + + /* Parse new GDSII file */ + gds_result = parse_gds_from_file(filename, ptr->list_ptr); + + /* Delete file name afterwards */ + g_free(filename); + if (gds_result) + goto end_destroy; + + /* remove suggested action from Open button */ + button_style = gtk_widget_get_style_context(GTK_WIDGET(button)); + gtk_style_context_remove_class(button_style, "suggested-action"); + + for (lib = *(ptr->list_ptr); lib != NULL; lib = lib->next) { + gds_lib = (struct gds_library *)lib->data; + /* Create top level iter */ + gtk_tree_store_append (store, &libiter, NULL); + gtk_tree_store_set (store, &libiter, LIBRARY, gds_lib->name, -1); + for (cell = gds_lib->cells; cell != NULL; cell = cell->next) { + gds_c = (struct gds_cell *)cell->data; + gtk_tree_store_append (store, &celliter, &libiter); + gtk_tree_store_set (store, &celliter, CELL, gds_c->name, -1); + } } } +end_destroy: + gtk_widget_destroy(open_dialog); } void on_convert_clicked(gpointer button, gpointer user) @@ -66,7 +105,6 @@ static GtkTreeStore * setup_cell_selector(GtkTreeView* view) GtkTreeStore *cell_store; GtkCellRenderer *render; - GtkCellRenderer *render2; GtkTreeViewColumn *column; cell_store = gtk_tree_store_new(STORE_COLUMN, G_TYPE_STRING, G_TYPE_STRING); @@ -75,7 +113,7 @@ static GtkTreeStore * setup_cell_selector(GtkTreeView* view) render = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Library", render, "text", LIBRARY, NULL); gtk_tree_view_append_column(view, column); - //g_object_unref(column); + column = gtk_tree_view_column_new_with_attributes("Cell", render, "text", CELL, NULL); gtk_tree_view_append_column(view, column); @@ -103,6 +141,7 @@ int main(int argc, char **argv) open_data.cell_store = cell_store; open_data.list_ptr = &gds_libs; + open_data.main_window = GTK_WINDOW(gtk_builder_get_object(main_builder, "main-window")); g_signal_connect(GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds")), "clicked", G_CALLBACK(on_load_gds), (gpointer)&open_data);