Implemented open file dialog
This commit is contained in:
		
							
								
								
									
										535
									
								
								gdsparse.c
									
									
									
									
									
								
							
							
						
						
									
										535
									
								
								gdsparse.c
									
									
									
									
									
								
							@@ -1,3 +1,22 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * GDSII converter
 | 
				
			||||||
 | 
					 * Copyright (C) 2018  Mario Hüttel <mario.huettel@gmx.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * What's missing? - A lot:
 | 
					 * What's missing? - A lot:
 | 
				
			||||||
 * Support for Boxes
 | 
					 * 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_cell *current_cell = NULL;
 | 
				
			||||||
	struct gds_graphics *current_graphics = NULL;
 | 
						struct gds_graphics *current_graphics = NULL;
 | 
				
			||||||
	struct gds_cell_instance *current_s_reference = NULL;
 | 
						struct gds_cell_instance *current_s_reference = NULL;
 | 
				
			||||||
 | 
						int x, y;
 | 
				
			||||||
	////////////
 | 
						////////////
 | 
				
			||||||
	GList *lib_list;
 | 
						GList *lib_list;
 | 
				
			||||||
	GList *lib_ptr;
 | 
					 | 
				
			||||||
	GList *cell_ptr;
 | 
					 | 
				
			||||||
	GList *cell_ref_ptr;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lib_list = *library_list;
 | 
						lib_list = *library_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -329,275 +346,271 @@ int parse_gds_from_file(const char *filename, GList **library_list)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Record parser */
 | 
						/* Record parser */
 | 
				
			||||||
	while (run == 1) {
 | 
						while (run == 1) {
 | 
				
			||||||
		switch (state) {
 | 
							rec_type = INVALID;
 | 
				
			||||||
		case PARSING_LENGTH:
 | 
							read = fread(workbuff, sizeof(char), 2, gds_file);
 | 
				
			||||||
			rec_type = INVALID;
 | 
							if (read != 2 && (current_cell != NULL ||
 | 
				
			||||||
			read = fread(workbuff, sizeof(char), 2, gds_file);
 | 
									  current_graphics != NULL ||
 | 
				
			||||||
			if (read != 2 && (current_cell != NULL ||
 | 
									  current_lib != NULL ||
 | 
				
			||||||
					  current_graphics != NULL ||
 | 
									  current_s_reference != NULL)) {
 | 
				
			||||||
					  current_lib != NULL ||
 | 
								GDS_ERROR("End of File. with openend structs/libs");
 | 
				
			||||||
					  current_s_reference != NULL)) {
 | 
								run = -2;
 | 
				
			||||||
				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;
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case PARSING_TYPE:
 | 
							} else if (read != 2) {
 | 
				
			||||||
			read = fread(workbuff, sizeof(char), 2, gds_file);
 | 
								/* EOF */
 | 
				
			||||||
			if (read != 2) {
 | 
								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;
 | 
									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;
 | 
								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:
 | 
							/* if begin: Allocate structures */
 | 
				
			||||||
			read = fread(workbuff, sizeof(char), rec_data_length, gds_file);
 | 
							switch (rec_type) {
 | 
				
			||||||
			state = PARSING_LENGTH;
 | 
							case BGNLIB:
 | 
				
			||||||
 | 
								lib_list = append_library(lib_list);
 | 
				
			||||||
			if (read != rec_data_length) {
 | 
								if (lib_list == NULL) {
 | 
				
			||||||
				GDS_ERROR("Could not read enough data");
 | 
									GDS_ERROR("Allocating memory failed");
 | 
				
			||||||
				run = -5;
 | 
									run = -3;
 | 
				
			||||||
				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);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				break;
 | 
									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);
 | 
						fclose(gds_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
<!-- Generated with glade 3.22.1 -->
 | 
					<!-- Generated with glade 3.22.1 -->
 | 
				
			||||||
<interface>
 | 
					<interface>
 | 
				
			||||||
  <requires lib="gtk+" version="3.20"/>
 | 
					  <requires lib="gtk+" version="3.20"/>
 | 
				
			||||||
  <object class="GtkWindow">
 | 
					  <object class="GtkWindow" id="main-window">
 | 
				
			||||||
    <property name="visible">True</property>
 | 
					    <property name="visible">True</property>
 | 
				
			||||||
    <property name="can_focus">False</property>
 | 
					    <property name="can_focus">False</property>
 | 
				
			||||||
    <signal name="delete-event" handler="on_window_close" swapped="no"/>
 | 
					    <signal name="delete-event" handler="on_window_close" swapped="no"/>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										77
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								main.c
									
									
									
									
									
								
							@@ -3,15 +3,16 @@
 | 
				
			|||||||
#include <gtk/gtk.h>
 | 
					#include <gtk/gtk.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum cell_store_columns {
 | 
					enum cell_store_columns {
 | 
				
			||||||
LIBRARY,
 | 
						LIBRARY,
 | 
				
			||||||
CELL,
 | 
						CELL,
 | 
				
			||||||
STORE_COLUMN
 | 
						STORE_COLUMN
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct open_button_data {
 | 
					struct open_button_data {
 | 
				
			||||||
	GList **list_ptr;
 | 
							GtkWindow *main_window;
 | 
				
			||||||
	GtkTreeStore *cell_store;
 | 
							GList **list_ptr;
 | 
				
			||||||
 | 
							GtkTreeStore *cell_store;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,24 +37,62 @@ void on_load_gds(gpointer button, gpointer user)
 | 
				
			|||||||
	struct gds_cell *gds_c;
 | 
						struct gds_cell *gds_c;
 | 
				
			||||||
	struct open_button_data *ptr = (struct open_button_data *)user;
 | 
						struct open_button_data *ptr = (struct open_button_data *)user;
 | 
				
			||||||
	GtkTreeStore *store = ptr->cell_store;
 | 
						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);
 | 
						dialog_result = gtk_dialog_run(GTK_DIALOG(open_dialog));
 | 
				
			||||||
	parse_gds_from_file("/home/mari/Desktop/test.gds", ptr->list_ptr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (lib = *(ptr->list_ptr); lib != NULL; lib = lib->next) {
 | 
						if (dialog_result == GTK_RESPONSE_ACCEPT) {
 | 
				
			||||||
		gds_lib = (struct gds_library *)lib->data;
 | 
					
 | 
				
			||||||
		/* Create top level iter */
 | 
							/* Get File name */
 | 
				
			||||||
		gtk_tree_store_append (store, &libiter, NULL);
 | 
							filename = gtk_file_chooser_get_filename(file_chooser);
 | 
				
			||||||
		gtk_tree_store_set (store, &libiter, LIBRARY, gds_lib->name, -1);
 | 
					
 | 
				
			||||||
		for (cell = gds_lib->cells; cell != NULL; cell = cell->next) {
 | 
							/* Clear Display */
 | 
				
			||||||
			gds_c = (struct gds_cell *)cell->data;
 | 
							gtk_tree_store_clear(store);
 | 
				
			||||||
			gtk_tree_store_append (store, &celliter, &libiter);
 | 
							/* Delete parsed GDS data */
 | 
				
			||||||
			gtk_tree_store_set (store, &celliter, CELL, gds_c->name, -1);
 | 
							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)
 | 
					void on_convert_clicked(gpointer button, gpointer user)
 | 
				
			||||||
@@ -66,7 +105,6 @@ static GtkTreeStore * setup_cell_selector(GtkTreeView* view)
 | 
				
			|||||||
	GtkTreeStore *cell_store;
 | 
						GtkTreeStore *cell_store;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GtkCellRenderer *render;
 | 
						GtkCellRenderer *render;
 | 
				
			||||||
	GtkCellRenderer *render2;
 | 
					 | 
				
			||||||
	GtkTreeViewColumn *column;
 | 
						GtkTreeViewColumn *column;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cell_store = gtk_tree_store_new(STORE_COLUMN, G_TYPE_STRING, G_TYPE_STRING);
 | 
						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();
 | 
						render = gtk_cell_renderer_text_new();
 | 
				
			||||||
	column = gtk_tree_view_column_new_with_attributes("Library", render, "text", LIBRARY, NULL);
 | 
						column = gtk_tree_view_column_new_with_attributes("Library", render, "text", LIBRARY, NULL);
 | 
				
			||||||
	gtk_tree_view_append_column(view, column);
 | 
						gtk_tree_view_append_column(view, column);
 | 
				
			||||||
	//g_object_unref(column);
 | 
					
 | 
				
			||||||
	column = gtk_tree_view_column_new_with_attributes("Cell", render, "text", CELL, NULL);
 | 
						column = gtk_tree_view_column_new_with_attributes("Cell", render, "text", CELL, NULL);
 | 
				
			||||||
	gtk_tree_view_append_column(view, column);
 | 
						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.cell_store = cell_store;
 | 
				
			||||||
	open_data.list_ptr = &gds_libs;
 | 
						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")),
 | 
						g_signal_connect(GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds")),
 | 
				
			||||||
			 "clicked", G_CALLBACK(on_load_gds), (gpointer)&open_data);
 | 
								 "clicked", G_CALLBACK(on_load_gds), (gpointer)&open_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user