From ce44c12bddf7a2dbdef5172befebd1a76ff30439 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Sun, 8 Jun 2025 12:50:13 +0800 Subject: [PATCH] add UI with GTK to make the electronic circuit easy --- Makefile | 11 + main.c | 11 +- scf_eda_pack.c | 98 ++++- scf_eda_pack.h | 9 +- ses_core.h | 15 +- ses_layout.c | 111 +----- ses_layout_function.c | 34 +- ses_node_analysis.c | 10 + ses_step_battery.c | 6 +- ses_step_draw.c | 784 +++++++++++++++++++++----------------- ses_ui.c | 854 ++++++++++++++++++++++++++++++++++++++++++ ses_ui.glade | 596 +++++++++++++++++++++++++++++ ses_ui.h | 79 ++++ ses_ui_gl.c | 152 ++++++++ ses_ui_render.c | 113 ++++++ ses_utils.c | 19 +- test/fft.c | 4 +- 17 files changed, 2405 insertions(+), 501 deletions(-) create mode 100644 ses_ui.c create mode 100644 ses_ui.glade create mode 100644 ses_ui.h create mode 100644 ses_ui_gl.c create mode 100644 ses_ui_render.c diff --git a/Makefile b/Makefile index d6d3cba..bb305d9 100644 --- a/Makefile +++ b/Makefile @@ -35,12 +35,23 @@ CFILES += ses_step_draw.c CFLAGS += -g -D_GNU_SOURCE #-Wunused-variable CFLAGS += -I./ CFLAGS += -I./pack +CFLAGS += `pkg-config --cflags gtk+-3.0` LDFLAGS += -lm LDFLAGS += -lcairo LDFLAGS += -lgsl #-lgslcblas +LDFLAGS += -lGL +LDFLAGS += `pkg-config --libs gtk+-3.0` + +UI += ses_ui.c +UI += ses_ui_gl.c +UI += ses_ui_render.c +UI += ses_step_draw.c +UI += scf_eda_pack.c +UI += ./pack/scf_pack.c all: + gcc $(CFLAGS) $(UI) $(LDFLAGS) -o ses_ui gcc $(CFLAGS) $(CFILES) $(LDFLAGS) -o ses clean: diff --git a/main.c b/main.c index 5b00d39..fdfcc34 100644 --- a/main.c +++ b/main.c @@ -478,13 +478,15 @@ int main(int argc, char* argv[]) char* args[256]; usage(); - printf("# "); + fprintf(stderr, "# "); while ((ret = getline(&buf, &len, stdin)) != -1) { char* p0 = buf; char* p1 = p0; int i = 0; + scf_logi("%s\n", buf); + while (*p1) { if (' ' == *p1 || '\n' == *p1 || '\r' == *p1 || '\t' == *p1) { *p1 = '\0'; @@ -500,6 +502,11 @@ int main(int argc, char* argv[]) return -1; } + if (0 == i && !strcmp(p0, "q")) { + free(buf); + return 0; + } + args[i++] = p0; p0 = ++p1; } else @@ -515,7 +522,7 @@ int main(int argc, char* argv[]) if (ret < 0) return ret; - printf("# "); + fprintf(stderr, "# "); } free(buf); diff --git a/scf_eda_pack.c b/scf_eda_pack.c index c689c0e..eaadc2e 100644 --- a/scf_eda_pack.c +++ b/scf_eda_pack.c @@ -418,7 +418,7 @@ static ScfEops __741_op_amp_ops = static ScfEdata component_datas[] = { {SCF_EDA_None, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL}, - {SCF_EDA_Battery, 0, 0, 0, 0, 1e-9, 1e9, 0, 0, 0, NULL, NULL, NULL}, + {SCF_EDA_Battery, 0, 0, 5, 0, 1e-9, 1e9, 0, 0, 0, NULL, NULL, NULL}, {SCF_EDA_Signal, 0, 0, 0, 0, 1e-9, 1e9, 0, 0, 0, NULL, NULL, NULL}, {SCF_EDA_Resistor, 0, 0, 0, 0, 1e4, 0, 0, 0, 0, NULL, NULL, NULL}, @@ -568,12 +568,6 @@ int scf_eline__add_line(ScfEline* el, ScfLine* l) if (el->lines[i] == l) return 0; - - if (el->lines[i]->x0 == l->x0 - && el->lines[i]->y0 == l->y0 - && el->lines[i]->x1 == l->x1 - && el->lines[i]->y1 == l->y1) - return 0; } void* p = realloc(el->lines, sizeof(ScfLine*) * (el->n_lines + 1)); @@ -721,9 +715,11 @@ int scf_eline__del_conn(ScfEline* el, ScfEconn* ec) ScfEpin* scf_epin__alloc() { - ScfEpin* pin = calloc(1, sizeof(ScfEpin)); + ScfEpin* p = calloc(1, sizeof(ScfEpin)); + if (p) + p->lid = -1; - return pin; + return p; } int scf_epin__add_component(ScfEpin* pin, uint64_t cid, uint64_t pid) @@ -1322,3 +1318,87 @@ next: return 0; } + +void scf_efunction_find_pin(ScfEfunction* f, ScfEcomponent** pc, ScfEpin** pp, int x, int y) +{ + ScfEcomponent* c; + ScfEpin* p; + + long i; + long j; + + for (i = 0; i < f->n_components; i++) { + c = f->components[i]; + + scf_logd("c%ld, c->x: %d, c->y: %d, c->w: %d, c->h: %d, x: %d, y: %d\n", c->id, c->x, c->y, c->w, c->y, x, y); + if (x > c->x - c->w / 2 + && x < c->x + c->w / 2 + && y > c->y - c->h / 2 + && y < c->y + c->h / 2) { + *pc = c; + *pp = NULL; + + scf_logd("c%ld, %d,%d, x: %d, y: %d\n", c->id, c->x, c->y, x, y); + return; + } + + for (j = 0; j < c->n_pins; j++) { + p = c->pins[j]; + + if (x > p->x - 5 + && x < p->x + 5 + && y > p->y - 5 + && y < p->y + 5) { + *pc = c; + *pp = p; + + scf_logi("c%ldp%ld, %d,%d, x: %d, y: %d\n", c->id, p->id, p->x, p->y, x, y); + return; + } + } + } +} + +void scf_efunction_find_eline(ScfEfunction* f, ScfEline** pel, ScfLine** pl, int x, int y) +{ + ScfEline* el; + ScfLine* l; + + long i; + long j; + + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; + + for (j = el->n_lines - 1; j >= 0; j--) { + l = el->lines[j]; + + if (x > l->x0 - 5 + && x < l->x1 + 5 + && y > l->y0 - 5 + && y < l->y1 + 5) { + + scf_logi("j: %ld, (%d, %d)-->(%d, %d), x: %d, y: %d\n", j, l->x0, l->y0, l->x1, l->y1, x, y); + + *pel = el; + *pl = l; + return; + } + } + } +} + +long scf_find_eline_index(ScfEfunction* f, int64_t lid) +{ + ScfEline* el; + long j; + + for (j = 0; j < f->n_elines; j++) { + el = f->elines[j]; + + if (el->id == lid) + return j; + } + + return -1; +} diff --git a/scf_eda_pack.h b/scf_eda_pack.h index 3e2c027..eb0866b 100644 --- a/scf_eda_pack.h +++ b/scf_eda_pack.h @@ -340,7 +340,7 @@ struct scf_epin_s { SCF_PACK_DEF_VAR(uint64_t, id); SCF_PACK_DEF_VAR(uint64_t, cid); - SCF_PACK_DEF_VAR(uint64_t, lid); + SCF_PACK_DEF_VAR(int64_t, lid); SCF_PACK_DEF_VAR(uint64_t, flags); SCF_PACK_DEF_VARS(uint64_t, tos); SCF_PACK_DEF_VAR(uint64_t, c_lid); @@ -597,7 +597,12 @@ ScfEboard* scf_eboard__alloc(); int scf_eboard__add_function(ScfEboard* b, ScfEfunction* f); int scf_eboard__del_function(ScfEboard* b, ScfEfunction* f); -int scf_pins_same_line(ScfEfunction* f); +int scf_pins_same_line (ScfEfunction* f); + +long scf_find_eline_index(ScfEfunction* f, int64_t lid); + +void scf_efunction_find_pin (ScfEfunction* f, ScfEcomponent** pc, ScfEpin** pp, int x, int y); +void scf_efunction_find_eline(ScfEfunction* f, ScfEline** pel, ScfLine** pl, int x, int y); #define EDA_INST_ADD_COMPONENT(_ef, _c, _type) \ do { \ diff --git a/ses_core.h b/ses_core.h index 412a083..2bf98dc 100644 --- a/ses_core.h +++ b/ses_core.h @@ -1,6 +1,7 @@ #ifndef SES_CORE_H #define SES_CORE_H +#include #include"scf_vector.h" #include"scf_eda_pack.h" @@ -156,6 +157,7 @@ ses_node_t* ses_node_alloc(); void ses_node_free (ses_node_t* node); void ses_node_print(ses_node_t* node); +void ses_edges_print(scf_vector_t* edges); void ses_nodes_free (scf_vector_t* nodes); void ses_nodes_print(scf_vector_t* nodes); void ses_paths_print(scf_vector_t* paths); @@ -181,8 +183,6 @@ int ses_steps_analyse(ScfEboard* b, ScfEfunction* f, int64_t ps, int64_t count, int ses_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t ps, int64_t count); -int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ps, int64_t count); - int __ses_nodes_paths (ScfEfunction* f, scf_vector_t* paths, scf_vector_t** pnodes, scf_vector_t** pedges); int __ses_nodes_paths_solve(ScfEfunction* f, scf_vector_t* paths, int* changed, int64_t ps, int64_t count); @@ -194,6 +194,17 @@ void __ses_path_lc(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv, int __ses_path_pos(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN); int __ses_path_neg(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN); +void __ses_draw_components(cairo_t* cr, ScfEfunction* f); +void __ses_draw_elines (cairo_t* cr, ScfEfunction* f, int64_t count); + +void __ses_draw_battery (cairo_t* cr, ScfEcomponent* c); +void __ses_draw_resistor (cairo_t* cr, ScfEcomponent* c); +void __ses_draw_capacitor(cairo_t* cr, ScfEcomponent* c); +void __ses_draw_inductor (cairo_t* cr, ScfEcomponent* c); +void __ses_draw_crystal (cairo_t* cr, ScfEcomponent* c); +void __ses_draw_diode (cairo_t* cr, ScfEcomponent* c); +void __ses_draw_npn (cairo_t* cr, ScfEcomponent* c); +void __ses_draw_pnp (cairo_t* cr, ScfEcomponent* c); static inline ScfEline* ses_top_line(ScfEline* el) { diff --git a/ses_layout.c b/ses_layout.c index 62402d3..6b806ef 100644 --- a/ses_layout.c +++ b/ses_layout.c @@ -1,8 +1,6 @@ #include #include"ses_core.h" -void __ses_function_draw(ScfEfunction* f, cairo_t* cr); - int ses_layout_draw(ScfEboard* b, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh) { ScfEfunction* f; @@ -30,113 +28,8 @@ int ses_layout_draw(ScfEboard* b, uint32_t bx, uint32_t by, uint32_t bw, uint32_ for (i = 0; i < b->n_functions; i++) { f = b->functions[i]; - for (j = 0; j < f->n_elines; j++) { - el = f->elines[j]; - - if (SCF_EDA_PIN_POS & el->flags) - SHOW_COLOR(cr, 1, 0, 0); - - else if (SCF_EDA_PIN_NEG & el->flags) - SHOW_COLOR(cr, 0, 0, 1); - - else if (SCF_EDA_PIN_IN0 & el->flags) - SHOW_COLOR(cr, 0.8, 0, 0); - - else if (SCF_EDA_PIN_IN & el->flags) - SHOW_COLOR(cr, 0.07, 0.6, 1.0); - - else if (SCF_EDA_PIN_DIV0 & el->flags) - SHOW_COLOR(cr, 0, 1, 0); - - else if (SCF_EDA_PIN_OUT & el->flags) - SHOW_COLOR(cr, 1, 0, 1); - - else if (SCF_EDA_PIN_SHIFT & el->flags) - SHOW_COLOR(cr, 0.5, 0, 0.5); - - else if (SCF_EDA_PIN_CF & el->flags) - SHOW_COLOR(cr, 0.8, 0, 0.8); - - else if (SCF_EDA_PIN_GND & el->flags) - SHOW_COLOR(cr, 0.0, 0, 0.5); - else - SHOW_COLOR(cr, 1, 0.5, 0.1); - - uint8_t text[64]; - - cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size (cr, 22); - - ScfLine* prev = NULL; - - for (k = 0; k < el->n_lines; k++) { - l = el->lines[k]; - - if (l->x0 > l->x1) - continue; - - if (!prev) { - int n = snprintf(text, sizeof(text) - 1, "%ld", el->id); - - cairo_move_to (cr, l->x0 - 8 - n * 12, l->y0 + 12); - cairo_show_text(cr, text); - cairo_stroke(cr); - - if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_OUT | SCF_EDA_PIN_DIV0 | SCF_EDA_PIN_SHIFT)) { - cairo_set_font_size(cr, 16); - - if (el->flags & SCF_EDA_PIN_DIV0) - n = snprintf(text, sizeof(text) - 1, "DIV0"); - - else if (el->flags & SCF_EDA_PIN_SHIFT) - n = snprintf(text, sizeof(text) - 1, "T%ld", el->io_lid); - else - n = snprintf(text, sizeof(text) - 1, "B%ld", el->io_lid); - - cairo_move_to (cr, l->x0 - 2 - n * 10, l->y0 + 28); - cairo_show_text(cr, text); - cairo_stroke(cr); - } - - if (el->flags & SCF_EDA_PIN_GND) { - cairo_move_to(cr, l->x0, l->y0); - cairo_line_to(cr, l->x0, l->y0 + 8); - cairo_move_to(cr, l->x0 - 6, l->y0 + 8); - cairo_line_to(cr, l->x0 + 6, l->y0 + 8); - cairo_move_to(cr, l->x0 - 4, l->y0 + 12); - cairo_line_to(cr, l->x0 + 4, l->y0 + 12); - cairo_move_to(cr, l->x0 - 2, l->y0 + 16); - cairo_line_to(cr, l->x0 + 2, l->y0 + 16); - cairo_stroke(cr); - } - } - - cairo_set_line_width(cr, 3); - cairo_move_to(cr, l->x0, l->y0); - cairo_line_to(cr, l->x1, l->y1); - cairo_stroke(cr); - - if (prev) { - if (!(el->flags & SCF_EDA_PIN_BORDER)) - cairo_set_line_width(cr, 1.5); - - cairo_move_to(cr, prev->x0, prev->y0); - cairo_line_to(cr, l->x0, l->y0); - cairo_stroke(cr); - } - - prev = l; - } - cairo_stroke(cr); - } - } - - cairo_set_line_width(cr, 2.5); - - for (i = 0; i < b->n_functions; i++) { - f = b->functions[i]; - - __ses_function_draw(f, cr); + __ses_draw_elines (cr, f, -1); + __ses_draw_components(cr, f); } cairo_surface_write_to_png(surface, "./2.png"); diff --git a/ses_layout_function.c b/ses_layout_function.c index 58410fb..b9e4565 100644 --- a/ses_layout_function.c +++ b/ses_layout_function.c @@ -133,22 +133,6 @@ int ecomponent_cmp_cx(const void* v0, const void* v1) return 0; } -static inline int __ses_find_eline_index(ScfEfunction* f, uint64_t lid) -{ - ScfEline* el; - size_t j; - - for (j = 0; j < f->n_elines; j++) { - el = f->elines[j]; - - if (el->id == lid) - break; - } - assert(j < f->n_elines); - - return j; -} - int ses_lines_same_components(ScfEfunction* f) { ScfEline* el0; @@ -285,7 +269,7 @@ static void __ses_layout_path2(ScfEfunction* f, ses_path_t* path, ses_path_t* ba long __n; bp = base->pins->data[base->pins->size - 1]; - __n = __ses_find_eline_index(f, bp->lid); + __n = scf_find_eline_index(f, bp->lid); scf_logd("path: %d, __n: %ld, l%ld\n", path->index, __n, f->elines[__n]->id); @@ -298,14 +282,14 @@ static void __ses_layout_path2(ScfEfunction* f, ses_path_t* path, ses_path_t* ba bp = base->pins->data[k]; if (p->lid == bp->lid) { - __n = __ses_find_eline_index(f, bp->lid); + __n = scf_find_eline_index(f, bp->lid); scf_logd("__n: %ld, l%ld\n\n", __n, f->elines[__n]->id); break; } } - n = __ses_find_eline_index(f, p->lid); + n = scf_find_eline_index(f, p->lid); if (!f->elines[n]->vflag) { f->elines[n]->vflag = 1; @@ -380,13 +364,13 @@ static int __ses_layout_lines4(ScfEfunction* f) for (j = 0; j < base->pins->size; j += 2) { p = base->pins->data[j]; - n = __ses_find_eline_index(f, p->lid); + n = scf_find_eline_index(f, p->lid); SCF_XCHG(f->elines[n], f->elines[j / 2]); } p = base->pins->data[j - 1]; - n = __ses_find_eline_index(f, p->lid); + n = scf_find_eline_index(f, p->lid); SCF_XCHG(f->elines[n], f->elines[j / 2]); for (i = 0; i < f->n_elines; i++) @@ -433,7 +417,7 @@ static void __ses_layout_key_components(ScfEfunction* f) for (j = LAYOUT_P0(c); j < c->n_pins; j++) { p = c->pins[j]; - n = __ses_find_eline_index(f, p->lid); + n = scf_find_eline_index(f, p->lid); if (!(f->elines[n]->flags & SCF_EDA_PIN_POS)) break; @@ -445,7 +429,7 @@ static void __ses_layout_key_components(ScfEfunction* f) for (++j; j < c->n_pins; j++) { p = c->pins[j]; - k = __ses_find_eline_index(f, p->lid); + k = scf_find_eline_index(f, p->lid); if (f->elines[k]->flags & SCF_EDA_PIN_POS) continue; @@ -489,7 +473,7 @@ static int __ses_layout_lines2(ScfEfunction* f) for (j = 0; j < el0->n_conns; j++) { - int k = __ses_find_eline_index(f, el0->conns[j]->lid); + int k = scf_find_eline_index(f, el0->conns[j]->lid); if (max < k) { max = k; lid = el0->conns[j]->lid; @@ -503,7 +487,7 @@ static int __ses_layout_lines2(ScfEfunction* f) for (j = i + 1; j < f->n_elines; j++) f->elines[j - 1] = f->elines[j]; - j = __ses_find_eline_index(f, lid); + j = scf_find_eline_index(f, lid); el1 = f->elines[j]; diff --git a/ses_node_analysis.c b/ses_node_analysis.c index b9328ad..3bac660 100644 --- a/ses_node_analysis.c +++ b/ses_node_analysis.c @@ -1066,6 +1066,9 @@ static int __ses_nodes_split(scf_vector_t* groups, scf_vector_t* nodes, scf_vect ses_node_t* node; ses_edge_t* edge; + if (nodes->size <= 0) + return 0; + while (nodes->size > 0) { node = nodes->data[0]; @@ -1159,6 +1162,13 @@ int __ses_nodes_paths_solve(ScfEfunction* f, scf_vector_t* paths, int* changed, if (ret < 0) goto error; + if (0 == nodes->size) { + ses_edges_print(edges); + + ret = __ses_nodes_solve(f, nodes, edges, changed, ps, count); + goto error; + } + ret = __ses_nodes_split(groups, nodes, edges); if (ret < 0) goto error; diff --git a/ses_step_battery.c b/ses_step_battery.c index e6388b7..7ab6b14 100644 --- a/ses_step_battery.c +++ b/ses_step_battery.c @@ -30,6 +30,9 @@ static int _battery_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_ LP = f->elines[Bp->lid]; LN = f->elines[Bn->lid]; + LP->flags |= SCF_EDA_PIN_POS; + LN->flags |= SCF_EDA_PIN_NEG; + if (!LP->vconst) { if (!LN->vconst) { Bp->v = c->v; @@ -55,7 +58,8 @@ static int _battery_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_ LN->vconst = 1; - LP->flags |= SCF_EDA_PIN_GND; + LP->flags &= ~(SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG); + LP->flags |= SCF_EDA_PIN_GND; } else if (LP->v - LN->v != c->v) { scf_loge("Battery '%lgV' connected between line '%lgV' and '%lgV', diff: %lgV\n", diff --git a/ses_step_draw.c b/ses_step_draw.c index 001a967..83ca723 100644 --- a/ses_step_draw.c +++ b/ses_step_draw.c @@ -1,4 +1,3 @@ -#include #include"ses_core.h" #define SHOW_BITS 1000.0 @@ -68,7 +67,371 @@ static void ses_text_v(cairo_t* cr, int x, int y, double v) } } -void __ses_function_draw(ScfEfunction* f, cairo_t* cr) +void __ses_draw_battery(cairo_t* cr, ScfEcomponent* c) +{ + ScfEpin* p = c->pins[SCF_EDA_Battery_POS]; + + if (p->y < c->y) { + cairo_move_to(cr, c->x - 12, c->y - 5); + cairo_line_to(cr, c->x + 12, c->y - 5); + + cairo_move_to(cr, c->x, c->y - 5); + cairo_line_to(cr, p->x, p->y); + + cairo_move_to(cr, c->x - 8, c->y + 5); + cairo_line_to(cr, c->x + 8, c->y + 5); + + p = c->pins[SCF_EDA_Battery_NEG]; + cairo_move_to(cr, c->x, c->y + 5); + cairo_line_to(cr, p->x, p->y); + + } else { + cairo_move_to(cr, c->x - 12, c->y + 5); + cairo_line_to(cr, c->x + 12, c->y + 5); + + cairo_move_to(cr, c->x, c->y + 5); + cairo_line_to(cr, p->x, p->y); + + cairo_move_to(cr, c->x - 8, c->y - 5); + cairo_line_to(cr, c->x + 8, c->y - 5); + + p = c->pins[SCF_EDA_Battery_NEG]; + cairo_move_to(cr, c->x, c->y - 5); + cairo_line_to(cr, p->x, p->y); + } + + cairo_stroke(cr); +} + +void __ses_draw_crystal(cairo_t* cr, ScfEcomponent* c) +{ + ScfEpin* p0 = c->pins[0]; + ScfEpin* p1 = c->pins[1]; + + cairo_rectangle(cr, c->x - 8, c->y - 3, 16, 6); + cairo_fill(cr); + cairo_stroke(cr); + + if (p0->y < c->y) { + cairo_move_to(cr, p0->x, p0->y); + cairo_line_to(cr, c->x, c->y - 6); + + cairo_move_to(cr, p1->x, p1->y); + cairo_line_to(cr, c->x, c->y + 6); + + cairo_move_to(cr, c->x - 6, c->y + 6); + cairo_line_to(cr, c->x + 6, c->y + 6); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.0, 0.0, 0.8); + cairo_move_to(cr, c->x - 6, c->y - 6); + cairo_line_to(cr, c->x + 6, c->y - 6); + cairo_stroke(cr); + } else { + cairo_move_to(cr, p0->x, p0->y); + cairo_line_to(cr, c->x, c->y + 6); + + cairo_move_to(cr, p1->x, p1->y); + cairo_line_to(cr, c->x, c->y - 6); + + cairo_move_to(cr, c->x - 6, c->y - 6); + cairo_line_to(cr, c->x + 6, c->y - 6); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.0, 0.0, 0.8); + cairo_move_to(cr, c->x - 6, c->y + 6); + cairo_line_to(cr, c->x + 6, c->y + 6); + cairo_stroke(cr); + } +} + +void __ses_draw_capacitor(cairo_t* cr, ScfEcomponent* c) +{ + ScfEpin* p; + + SHOW_COLOR(cr, 0.8, 0.0, 0.0); + p = c->pins[SCF_EDA_Battery_POS]; + if (p->y < c->y) { + cairo_move_to(cr, c->x - 8, c->y - 5); + cairo_line_to(cr, c->x + 8, c->y - 5); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.6, 0.6, 0.0); + cairo_move_to(cr, c->x, c->y - 5); + } else { + cairo_move_to(cr, c->x - 8, c->y + 5); + cairo_line_to(cr, c->x + 8, c->y + 5); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.6, 0.6, 0.0); + cairo_move_to(cr, c->x, c->y + 5); + } + cairo_line_to(cr, p->x, p->y); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.0, 0.0, 0.8); + p = c->pins[SCF_EDA_Battery_NEG]; + if (p->y < c->y) { + cairo_move_to(cr, c->x - 8, c->y - 5); + cairo_line_to(cr, c->x + 8, c->y - 5); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.6, 0.6, 0.0); + cairo_move_to(cr, c->x, c->y - 5); + } else { + cairo_move_to(cr, c->x - 8, c->y + 5); + cairo_line_to(cr, c->x + 8, c->y + 5); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.6, 0.6, 0.0); + cairo_move_to(cr, c->x, c->y + 5); + } + cairo_line_to(cr, p->x, p->y); + cairo_stroke(cr); +} + +void __ses_draw_inductor(cairo_t* cr, ScfEcomponent* c) +{ + ScfEpin* p; + + SHOW_COLOR(cr, 0.8, 0.0, 0.0); + p = c->pins[SCF_EDA_Battery_POS]; +#define DRAW_Inductor() \ + do { \ + if (p->y < c->y) { \ + cairo_arc(cr, c->x + 1, c->y - 15, 5, M_PI * 0.45, M_PI * 1.55); \ + cairo_stroke(cr); \ + cairo_arc(cr, c->x + 1, c->y - 5, 5, M_PI * 0.45, M_PI * 1.55); \ + cairo_stroke(cr); \ + SHOW_COLOR(cr, 0.6, 0.6, 0.0); \ + cairo_move_to(cr, c->x, c->y - 19); \ + } else { \ + cairo_arc(cr, c->x + 1, c->y + 15, 5, M_PI * 0.45, M_PI * 1.55); \ + cairo_stroke(cr); \ + cairo_arc(cr, c->x + 1, c->y + 5, 5, M_PI * 0.45, M_PI * 1.55); \ + cairo_stroke(cr); \ + SHOW_COLOR(cr, 0.6, 0.6, 0.0); \ + cairo_move_to(cr, c->x, c->y + 19); \ + } \ + cairo_line_to(cr, p->x, p->y); \ + } while (0) + + DRAW_Inductor(); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.0, 0.0, 0.8); + p = c->pins[SCF_EDA_Battery_NEG]; + DRAW_Inductor(); + cairo_stroke(cr); +} + +void __ses_draw_resistor(cairo_t* cr, ScfEcomponent* c) +{ + ScfEpin* p = c->pins[0]; + + int dx0; + int dx1; + int dy0; + int dy1; + + vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 6); + forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 12); + + cairo_move_to(cr, p->x, p->y); + cairo_line_to(cr, c->x - dx1, c->y - dy1); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.0, 0.0, 0.8); + + cairo_move_to (cr, c->x - dx1 + dx0, c->y - dy1 + dy0); + cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + cairo_stroke(cr); + + SHOW_COLOR(cr, 0.6, 0.6, 0.0); + + cairo_move_to (cr, c->x - dx1 - dx0, c->y - dy1 - dy0); + cairo_rel_line_to(cr, dx1 * 2, dy1 * 2); + cairo_rel_line_to(cr, dx0 * 2, dy0 * 2); + cairo_rel_line_to(cr, -dx1 * 2, -dy1 * 2); + + p = c->pins[1]; + cairo_move_to(cr, p->x, p->y); + cairo_line_to(cr, c->x + dx1, c->y + dy1); + cairo_stroke(cr); +} + +void __ses_draw_diode(cairo_t* cr, ScfEcomponent* c) +{ + ScfEpin* p = c->pins[SCF_EDA_Diode_POS]; + + int dx0; + int dx1; + int dy0; + int dy1; + + vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 8); + forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 8); + + cairo_move_to(cr, p->x, p->y); + cairo_line_to(cr, c->x - dx1, c->y - dy1); + + cairo_rel_move_to(cr, dx0, dy0); + cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + cairo_line_to (cr, c->x + dx1, c->y + dy1); + cairo_line_to (cr, c->x + dx0 - dx1, c->y + dy0 - dy1); + + p = c->pins[SCF_EDA_Diode_NEG]; + + cairo_move_to (cr, p->x, p->y); + cairo_line_to (cr, c->x + dx1, c->y + dy1); + cairo_rel_move_to(cr, dx0, dy0); + cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + cairo_stroke(cr); +} + +void __ses_draw_npn(cairo_t* cr, ScfEcomponent* c) +{ + ScfEpin* pb = c->pins[SCF_EDA_NPN_B]; + ScfEpin* pc = c->pins[SCF_EDA_NPN_C]; + ScfEpin* pe = c->pins[SCF_EDA_NPN_E]; + + int dx0; + int dy0; + int dx1; + int dy1; + + int dx3; + int dy3; + int dx4; + int dy4; + + vertical(&dx0, &dy0, c->x - pb->x, c->y - pb->y, 8); + forward (&dx3, &dy3, c->x - pb->x, c->y - pb->y, 8); + + cairo_arc(cr, c->x - dx3 / 2, c->y - dy3 / 2, 12, 0, 2 * M_PI); + + cairo_move_to (cr, pb->x, pb->y); + cairo_line_to (cr, c->x - dx3, c->y - dy3); + cairo_rel_move_to(cr, dx0, dy0); + cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + cairo_stroke(cr); + + if ((c->x + dx3 + dx0 > c->x + dx3 - dx0 && pe->x > pc->x) + || (c->x + dx3 + dx0 < c->x + dx3 - dx0 && pe->x < pc->x)) { + + cairo_move_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); + cairo_line_to(cr, pe->x, c->y + dy3 + dy0); + cairo_line_to(cr, pe->x, pe->y); + + vertical(&dx1, &dy1, dx3 * 2 + dx0, dy3 * 2 + dy0, 3); + forward (&dx4, &dy4, dx3 * 2 + dx0, dy3 * 2 + dy0, 8); + + cairo_move_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); + cairo_line_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); + cairo_move_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); + cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); + cairo_stroke(cr); + + cairo_move_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); + cairo_line_to(cr, pc->x, c->y + dy3 - dy0); + cairo_line_to(cr, pc->x, pc->y); + cairo_stroke(cr); + } else { + cairo_move_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); + cairo_line_to(cr, pc->x, c->y + dy3 + dy0); + cairo_line_to(cr, pc->x, pc->y); + cairo_stroke(cr); + + cairo_move_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); + cairo_line_to(cr, pe->x, c->y + dy3 - dy0); + cairo_line_to(cr, pe->x, pe->y); + + vertical(&dx1, &dy1, dx3 * 2 - dx0, dy3 * 2 - dy0, 3); + forward (&dx4, &dy4, dx3 * 2 - dx0, dy3 * 2 - dy0, 8); + + cairo_move_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); + cairo_line_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); + cairo_move_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); + cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); + cairo_stroke(cr); + } +} + +void __ses_draw_pnp(cairo_t* cr, ScfEcomponent* c) +{ + ScfEpin* pb = c->pins[SCF_EDA_PNP_B]; + ScfEpin* pc = c->pins[SCF_EDA_PNP_C]; + ScfEpin* pe = c->pins[SCF_EDA_PNP_E]; + + int dx0; + int dy0; + int dx1; + int dy1; + + int dx3; + int dy3; + int dx4; + int dy4; + + vertical(&dx0, &dy0, c->x - pb->x, c->y - pb->y, 8); + forward (&dx3, &dy3, c->x - pb->x, c->y - pb->y, 8); + + cairo_arc(cr, c->x - dx3 / 2, c->y - dy3 / 2, 12, 0, 2 * M_PI); + + cairo_move_to (cr, pb->x, pb->y); + cairo_line_to (cr, c->x - dx3, c->y - dy3); + cairo_rel_move_to(cr, dx0, dy0); + cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + cairo_stroke(cr); + + if ((c->x + dx3 + dx0 > c->x + dx3 - dx0 && pe->x > pc->x) + || (c->x + dx3 + dx0 < c->x + dx3 - dx0 && pe->x < pc->x)) { + + cairo_move_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); + cairo_line_to(cr, pe->x, c->y + dy3 + dy0); + cairo_line_to(cr, pe->x, pe->y); + + vertical(&dx1, &dy1, dx3 * 2 + dx0, dy3 * 2 + dy0, 4); + forward (&dx4, &dy4, dx3 * 2 + dx0, dy3 * 2 + dy0, 12); + + cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); + cairo_line_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); + cairo_stroke(cr); + + cairo_move_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); + cairo_line_to(cr, pc->x, c->y + dy3 - dy0); + cairo_line_to(cr, pc->x, pc->y); + cairo_stroke(cr); + } else { + cairo_move_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); + cairo_line_to(cr, pc->x, c->y + dy3 + dy0); + cairo_line_to(cr, pc->x, pc->y); + cairo_stroke(cr); + + cairo_move_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); + cairo_line_to(cr, pe->x, c->y + dy3 - dy0); + cairo_line_to(cr, pe->x, pe->y); + + vertical(&dx1, &dy1, dx3 * 2 - dx0, dy3 * 2 - dy0, 4); + forward (&dx4, &dy4, dx3 * 2 - dx0, dy3 * 2 - dy0, 12); + + cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); + cairo_line_to(cr, c->x - dx3, c->y - dy3); + cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); + cairo_stroke(cr); + } +} + +void __ses_draw_components(cairo_t* cr, ScfEfunction* f) { ScfEcomponent* c; ScfEpin* p; @@ -98,7 +461,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) switch (c->type) { case SCF_EDA_Resistor: n = snprintf(text, sizeof(text) - 1, "R%ld", c->id); - + cairo_move_to(cr, c->x + 10, c->y + 8); break; @@ -206,14 +569,15 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) for (k = 0; k < c->n_pins; k++) { p = c->pins[k]; - cairo_arc (cr, p->x, p->y, 4, 0, 2 * M_PI); - cairo_fill(cr); + if (p->lid >= 0) { + cairo_arc (cr, p->x, p->y, 4, 0, 2 * M_PI); + cairo_fill(cr); + } } cairo_stroke(cr); int dx0; int dy0; - int dx1; int dy1; @@ -225,79 +589,15 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) switch (c->type) { case SCF_EDA_Battery: - p = c->pins[SCF_EDA_Battery_POS]; - - if (p->y < c->y) { - cairo_move_to(cr, c->x - 12, c->y - 5); - cairo_line_to(cr, c->x + 12, c->y - 5); - - cairo_move_to(cr, c->x, c->y - 5); - cairo_line_to(cr, p->x, p->y); - - cairo_move_to(cr, c->x - 8, c->y + 5); - cairo_line_to(cr, c->x + 8, c->y + 5); + __ses_draw_battery(cr, c); - p = c->pins[SCF_EDA_Battery_NEG]; - cairo_move_to(cr, c->x, c->y + 5); - cairo_line_to(cr, p->x, p->y); - - } else { - cairo_move_to(cr, c->x - 12, c->y + 5); - cairo_line_to(cr, c->x + 12, c->y + 5); - - cairo_move_to(cr, c->x, c->y + 5); - cairo_line_to(cr, p->x, p->y); - - cairo_move_to(cr, c->x - 8, c->y - 5); - cairo_line_to(cr, c->x + 8, c->y - 5); - - p = c->pins[SCF_EDA_Battery_NEG]; - cairo_move_to(cr, c->x, c->y - 5); - cairo_line_to(cr, p->x, p->y); - } + cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - cairo_stroke(cr); + ses_text_v(cr, c->x + 12, c->y + 8, c->v); break; case SCF_EDA_Crystal: - cairo_rectangle(cr, c->x - 8, c->y - 3, 16, 6); - cairo_fill(cr); - cairo_stroke(cr); - - p0 = c->pins[0]; - p1 = c->pins[1]; - - if (p0->y < c->y) { - cairo_move_to(cr, p0->x, p0->y); - cairo_line_to(cr, c->x, c->y - 6); - - cairo_move_to(cr, p1->x, p1->y); - cairo_line_to(cr, c->x, c->y + 6); - - cairo_move_to(cr, c->x - 6, c->y + 6); - cairo_line_to(cr, c->x + 6, c->y + 6); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.0, 0.0, 0.8); - cairo_move_to(cr, c->x - 6, c->y - 6); - cairo_line_to(cr, c->x + 6, c->y - 6); - cairo_stroke(cr); - } else { - cairo_move_to(cr, p0->x, p0->y); - cairo_line_to(cr, c->x, c->y + 6); - - cairo_move_to(cr, p1->x, p1->y); - cairo_line_to(cr, c->x, c->y - 6); - - cairo_move_to(cr, c->x - 6, c->y - 6); - cairo_line_to(cr, c->x + 6, c->y - 6); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.0, 0.0, 0.8); - cairo_move_to(cr, c->x - 6, c->y + 6); - cairo_line_to(cr, c->x + 6, c->y + 6); - cairo_stroke(cr); - } + __ses_draw_crystal(cr, c); cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); @@ -318,46 +618,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) break; case SCF_EDA_Capacitor: - SHOW_COLOR(cr, 0.8, 0.0, 0.0); - - p = c->pins[SCF_EDA_Battery_POS]; - if (p->y < c->y) { - cairo_move_to(cr, c->x - 8, c->y - 5); - cairo_line_to(cr, c->x + 8, c->y - 5); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.6, 0.6, 0.0); - cairo_move_to(cr, c->x, c->y - 5); - } else { - cairo_move_to(cr, c->x - 8, c->y + 5); - cairo_line_to(cr, c->x + 8, c->y + 5); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.6, 0.6, 0.0); - cairo_move_to(cr, c->x, c->y + 5); - } - cairo_line_to(cr, p->x, p->y); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.0, 0.0, 0.8); - p = c->pins[SCF_EDA_Battery_NEG]; - if (p->y < c->y) { - cairo_move_to(cr, c->x - 8, c->y - 5); - cairo_line_to(cr, c->x + 8, c->y - 5); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.6, 0.6, 0.0); - cairo_move_to(cr, c->x, c->y - 5); - } else { - cairo_move_to(cr, c->x - 8, c->y + 5); - cairo_line_to(cr, c->x + 8, c->y + 5); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.6, 0.6, 0.0); - cairo_move_to(cr, c->x, c->y + 5); - } - cairo_line_to(cr, p->x, p->y); - cairo_stroke(cr); + __ses_draw_capacitor(cr, c); cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); @@ -379,35 +640,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) break; case SCF_EDA_Inductor: - SHOW_COLOR(cr, 0.8, 0.0, 0.0); - p = c->pins[SCF_EDA_Battery_POS]; -#define DRAW_Inductor() \ - do { \ - if (p->y < c->y) { \ - cairo_arc(cr, c->x + 1, c->y - 15, 5, M_PI * 0.45, M_PI * 1.55); \ - cairo_stroke(cr); \ - cairo_arc(cr, c->x + 1, c->y - 5, 5, M_PI * 0.45, M_PI * 1.55); \ - cairo_stroke(cr); \ - SHOW_COLOR(cr, 0.6, 0.6, 0.0); \ - cairo_move_to(cr, c->x, c->y - 19); \ - } else { \ - cairo_arc(cr, c->x + 1, c->y + 15, 5, M_PI * 0.45, M_PI * 1.55); \ - cairo_stroke(cr); \ - cairo_arc(cr, c->x + 1, c->y + 5, 5, M_PI * 0.45, M_PI * 1.55); \ - cairo_stroke(cr); \ - SHOW_COLOR(cr, 0.6, 0.6, 0.0); \ - cairo_move_to(cr, c->x, c->y + 19); \ - } \ - cairo_line_to(cr, p->x, p->y); \ - } while (0) - - DRAW_Inductor(); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.0, 0.0, 0.8); - p = c->pins[SCF_EDA_Battery_NEG]; - DRAW_Inductor(); - cairo_stroke(cr); + __ses_draw_inductor(cr, c); cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); @@ -431,32 +664,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) break; case SCF_EDA_Resistor: - p = c->pins[0]; - - vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 6); - forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 12); - - cairo_move_to(cr, p->x, p->y); - cairo_line_to(cr, c->x - dx1, c->y - dy1); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.0, 0.0, 0.8); - - cairo_move_to (cr, c->x - dx1 + dx0, c->y - dy1 + dy0); - cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); - cairo_stroke(cr); - - SHOW_COLOR(cr, 0.6, 0.6, 0.0); - - cairo_move_to (cr, c->x - dx1 - dx0, c->y - dy1 - dy0); - cairo_rel_line_to(cr, dx1 * 2, dy1 * 2); - cairo_rel_line_to(cr, dx0 * 2, dy0 * 2); - cairo_rel_line_to(cr, -dx1 * 2, -dy1 * 2); - - p = c->pins[1]; - cairo_move_to (cr, p->x, p->y); - cairo_line_to (cr, c->x + dx1, c->y + dy1); - cairo_stroke(cr); + __ses_draw_resistor(cr, c); cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); @@ -476,92 +684,20 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) break; case SCF_EDA_Diode: - p = c->pins[SCF_EDA_Diode_POS]; - - vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 8); - forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 8); - - cairo_move_to(cr, p->x, p->y); - cairo_line_to(cr, c->x - dx1, c->y - dy1); - - cairo_rel_move_to(cr, dx0, dy0); - cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); - cairo_line_to (cr, c->x + dx1, c->y + dy1); - cairo_line_to (cr, c->x + dx0 - dx1, c->y + dy0 - dy1); - - p = c->pins[SCF_EDA_Diode_NEG]; - - cairo_move_to (cr, p->x, p->y); - cairo_line_to (cr, c->x + dx1, c->y + dy1); - cairo_rel_move_to(cr, dx0, dy0); - cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); - cairo_stroke(cr); + __ses_draw_diode(cr, c); ses_text_a(cr, c->x + 10, c->y + 25, c->a); cairo_stroke(cr); break; case SCF_EDA_NPN: - pb = c->pins[SCF_EDA_NPN_B]; - pc = c->pins[SCF_EDA_NPN_C]; - pe = c->pins[SCF_EDA_NPN_E]; - - vertical(&dx0, &dy0, c->x - pb->x, c->y - pb->y, 8); - forward (&dx3, &dy3, c->x - pb->x, c->y - pb->y, 8); - - cairo_arc(cr, c->x - dx3 / 2, c->y - dy3 / 2, 12, 0, 2 * M_PI); - - cairo_move_to (cr, pb->x, pb->y); - cairo_line_to (cr, c->x - dx3, c->y - dy3); - cairo_rel_move_to(cr, dx0, dy0); - cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); - cairo_stroke(cr); + __ses_draw_npn(cr, c); cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - if ((c->x + dx3 + dx0 > c->x + dx3 - dx0 && pe->x > pc->x) - || (c->x + dx3 + dx0 < c->x + dx3 - dx0 && pe->x < pc->x)) { - - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); - cairo_line_to(cr, pe->x, c->y + dy3 + dy0); - cairo_line_to(cr, pe->x, pe->y); - - vertical(&dx1, &dy1, dx3 * 2 + dx0, dy3 * 2 + dy0, 3); - forward (&dx4, &dy4, dx3 * 2 + dx0, dy3 * 2 + dy0, 8); - - cairo_move_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); - cairo_line_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); - cairo_move_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); - cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); - cairo_stroke(cr); - - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); - cairo_line_to(cr, pc->x, c->y + dy3 - dy0); - cairo_line_to(cr, pc->x, pc->y); - cairo_stroke(cr); - } else { - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); - cairo_line_to(cr, pc->x, c->y + dy3 + dy0); - cairo_line_to(cr, pc->x, pc->y); - cairo_stroke(cr); - - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); - cairo_line_to(cr, pe->x, c->y + dy3 - dy0); - cairo_line_to(cr, pe->x, pe->y); - - vertical(&dx1, &dy1, dx3 * 2 - dx0, dy3 * 2 - dy0, 3); - forward (&dx4, &dy4, dx3 * 2 - dx0, dy3 * 2 - dy0, 8); - - cairo_move_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); - cairo_line_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); - cairo_move_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); - cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); - cairo_stroke(cr); - } + pb = c->pins[SCF_EDA_NPN_B]; + pc = c->pins[SCF_EDA_NPN_C]; + pe = c->pins[SCF_EDA_NPN_E]; if (pb->y > c->y) { ses_text_a(cr, c->x + 2, c->y + 32, pb->a); @@ -588,65 +724,14 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) break; case SCF_EDA_PNP: + __ses_draw_pnp(cr, c); + + cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + pb = c->pins[SCF_EDA_PNP_B]; pc = c->pins[SCF_EDA_PNP_C]; pe = c->pins[SCF_EDA_PNP_E]; - vertical(&dx0, &dy0, c->x - pb->x, c->y - pb->y, 8); - forward (&dx3, &dy3, c->x - pb->x, c->y - pb->y, 8); - - cairo_arc(cr, c->x - dx3 / 2, c->y - dy3 / 2, 12, 0, 2 * M_PI); - - cairo_move_to (cr, pb->x, pb->y); - cairo_line_to (cr, c->x - dx3, c->y - dy3); - cairo_rel_move_to(cr, dx0, dy0); - cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); - cairo_stroke(cr); - - if ((c->x + dx3 + dx0 > c->x + dx3 - dx0 && pe->x > pc->x) - || (c->x + dx3 + dx0 < c->x + dx3 - dx0 && pe->x < pc->x)) { - - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); - cairo_line_to(cr, pe->x, c->y + dy3 + dy0); - cairo_line_to(cr, pe->x, pe->y); - - vertical(&dx1, &dy1, dx3 * 2 + dx0, dy3 * 2 + dy0, 4); - forward (&dx4, &dy4, dx3 * 2 + dx0, dy3 * 2 + dy0, 12); - - cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); - cairo_line_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); - cairo_stroke(cr); - - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); - cairo_line_to(cr, pc->x, c->y + dy3 - dy0); - cairo_line_to(cr, pc->x, pc->y); - cairo_stroke(cr); - } else { - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); - cairo_line_to(cr, pc->x, c->y + dy3 + dy0); - cairo_line_to(cr, pc->x, pc->y); - cairo_stroke(cr); - - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); - cairo_line_to(cr, pe->x, c->y + dy3 - dy0); - cairo_line_to(cr, pe->x, pe->y); - - vertical(&dx1, &dy1, dx3 * 2 - dx0, dy3 * 2 - dy0, 4); - forward (&dx4, &dy4, dx3 * 2 - dx0, dy3 * 2 - dy0, 12); - - cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); - cairo_line_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); - cairo_stroke(cr); - } - - cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - if (pb->y > c->y) { ses_text_a(cr, c->x + 2, c->y + 32, pb->a); @@ -1363,51 +1448,15 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) } } -int ses_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t ps, int64_t count) +void __ses_draw_elines(cairo_t* cr, ScfEfunction* f, int64_t count) { - ScfEcomponent* B; - ScfEline* el; - ScfLine* l; - - cairo_surface_t* surface; - cairo_t* cr; - - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, bx + bw, by + bh); - cr = cairo_create (surface); - - cairo_set_line_width(cr, 2); - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_rectangle (cr, 0, 0, bx + bw, by + bh); - cairo_fill(cr); - cairo_stroke(cr); - - cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size (cr, 20); - cairo_set_source_rgb(cr, 0, 0, 0); - - if (count >= 0) { - int64_t t = ps * count; - int64_t s = t / (1000000LL * 1000000LL); - t %= 1000000LL * 1000000LL; - int64_t ms = t / (1000000LL * 1000LL); - t %= 1000000LL * 1000LL; - int64_t us = t / 1000000; - t %= 1000000; - int64_t ns = t / 1000; - t %= 1000; - - uint8_t time[512]; - snprintf(time, sizeof(time) - 1, "%03ld,%03ld,%03ld,%03ld,%03ldps", s, ms, us, ns, t); - cairo_move_to (cr, 10, 20); - cairo_show_text(cr, time); - cairo_stroke(cr); - } + ScfEcomponent* B = f->components[0]; + ScfEline* el; + ScfLine* l; long j; long k; - B = f->components[0]; - for (j = 0; j < f->n_elines; j++) { el = f->elines[j]; @@ -1531,16 +1580,58 @@ int ses_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32 cairo_set_font_size(cr, 18); if (prev->x1 == prev->x0) - cairo_move_to(cr, prev->x1 + 4, prev->y0 - 5); + cairo_move_to(cr, prev->x1 + 4, prev->y1 - 5); else - cairo_move_to(cr, prev->x1 - 12 - n * 10, prev->y0 - 5); + cairo_move_to(cr, prev->x1 - 12 - n * 10, prev->y1 - 5); cairo_show_text(cr, text); cairo_stroke(cr); } } +} + +int ses_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t ps, int64_t count) +{ + ScfEcomponent* B; + ScfEline* el; + ScfLine* l; + + cairo_surface_t* surface; + cairo_t* cr; - __ses_function_draw(f, cr); + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, bx + bw, by + bh); + cr = cairo_create (surface); + + cairo_set_line_width(cr, 2); + cairo_set_source_rgb(cr, 1, 1, 1); + cairo_rectangle (cr, 0, 0, bx + bw, by + bh); + cairo_fill(cr); + cairo_stroke(cr); + + cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size (cr, 20); + cairo_set_source_rgb(cr, 0, 0, 0); + + if (count >= 0) { + int64_t t = ps * count; + int64_t s = t / (1000000LL * 1000000LL); + t %= 1000000LL * 1000000LL; + int64_t ms = t / (1000000LL * 1000LL); + t %= 1000000LL * 1000LL; + int64_t us = t / 1000000; + t %= 1000000; + int64_t ns = t / 1000; + t %= 1000; + + uint8_t time[512]; + snprintf(time, sizeof(time) - 1, "%03ld,%03ld,%03ld,%03ld,%03ldps", s, ms, us, ns, t); + cairo_move_to (cr, 10, 20); + cairo_show_text(cr, time); + cairo_stroke(cr); + } + + __ses_draw_elines (cr, f, count); + __ses_draw_components(cr, f); cairo_surface_write_to_png(surface, file); @@ -1686,6 +1777,7 @@ static int print_a(ScfEfunction* f, ses_ctx_t* ctx) } printf("\n"); + fflush(stdout); return 0; } @@ -1751,6 +1843,7 @@ static int print_v(ScfEfunction* f, ses_ctx_t* ctx) } printf("\n"); + fflush(stdout); return 0; } @@ -1774,6 +1867,9 @@ static int _draw_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_t* } ctx->i++; + + printf("ok: %d\n", ctx->i); + fflush(stdout); } return 0; diff --git a/ses_ui.c b/ses_ui.c new file mode 100644 index 0000000..c641e73 --- /dev/null +++ b/ses_ui.c @@ -0,0 +1,854 @@ +#include"ses_ui.h" + +static void resize(GtkGLArea* self, gint width, gint height, gpointer user_data) +{ + GdkGLContext *context; + + gtk_gl_area_make_current(self); + + if (gtk_gl_area_get_error(self) != NULL) { + scf_loge("\n"); + return; + } + + scf_logi("width: %d, height: %d\n", width, height); + + context = gtk_gl_area_get_context(self); + + if (gdk_gl_context_get_use_es(context)) + scf_logi("gles\n"); + else + scf_logi("gl\n"); +} + +static void unrealize(GtkWidget *widget) +{ + scf_logi("\n"); +} + +static gboolean render(GtkGLArea* self, GdkGLContext* context, gpointer user_data) +{ + if (gtk_gl_area_get_error(self) != NULL) + return FALSE; + + ses_ui_t* ui = user_data; + + int width = gtk_widget_get_allocated_width (GTK_WIDGET(self)); + int height = gtk_widget_get_allocated_height(GTK_WIDGET(self)); + + scf_logd("width: %d, height: %d\n\n", width, height); + + glViewport(0, 0, width, height); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + if ((ui->width != width || ui->height != height) && SES_UI_EDIT == ui->status) { + ui->width = width; + ui->height = height; + + if (ui->bgra) { + cairo_destroy(ui->cr); + cairo_surface_destroy(ui->surface); + free(ui->bgra); + + ui->bgra = NULL; + ui->surface = NULL; + ui->cr = NULL; + } + + ui->bgra = calloc(1, width * height * 4); + if (!ui->bgra) + return TRUE; + + ui->surface = cairo_image_surface_create_for_data(ui->bgra, CAIRO_FORMAT_ARGB32, width, height, width * 4); + if (!ui->surface) { + free(ui->bgra); + return TRUE; + } + + ui->cr = cairo_create(ui->surface); + if (!ui->cr) { + cairo_surface_destroy(ui->surface); + free(ui->bgra); + return TRUE; + } + + cairo_set_line_width(ui->cr, 2); + cairo_set_source_rgb(ui->cr, 1, 1, 1); + + cairo_rectangle(ui->cr, 0, 0, width, height); + cairo_fill(ui->cr); + cairo_stroke(ui->cr); + } + + if (ui->f) { + int ret = ses_gl_render(ui, width, height, 0, 0, width, height); + } + + glFlush(); + return TRUE; +} + +static int button_2pins_clicked(ses_ui_t* ui, int type) +{ + ScfEcomponent* B; + ScfEcomponent* c; + + if (!ui->f) { + ui->f = scf_efunction__alloc("tmp"); + if (!ui->f) + return 0; + + EDA_INST_ADD_COMPONENT(ui->f, B, SCF_EDA_Battery); + B->x = 100; + B->y = 100; + B->w = 16; + B->h = 10; + + B->pins[0]->x = B->x; + B->pins[1]->x = B->x; + + B->pins[0]->y = B->y + 50; + B->pins[1]->y = B->y - 50; + } + + EDA_INST_ADD_COMPONENT(ui->f, c, type); + c->x = 200 + rand() % 100; + c->y = 200 + rand() % 100; + c->w = 12; + c->h = 24; + + c->pins[0]->x = c->x; + c->pins[1]->x = c->x; + + c->pins[0]->y = c->y + 50; + c->pins[1]->y = c->y - 50; + return 0; +} + +static int button_transistor_clicked(ses_ui_t* ui, int type) +{ + ScfEcomponent* B; + ScfEcomponent* c; + + if (!ui->f) { + ui->f = scf_efunction__alloc("tmp"); + if (!ui->f) + return 0; + + EDA_INST_ADD_COMPONENT(ui->f, B, SCF_EDA_Battery); + B->x = 100; + B->y = 100; + B->w = 16; + B->h = 10; + + B->pins[0]->x = B->x; + B->pins[1]->x = B->x; + + B->pins[0]->y = B->y + 50; + B->pins[1]->y = B->y - 50; + } + + EDA_INST_ADD_COMPONENT(ui->f, c, type); + c->x = 200 + rand() % 100; + c->y = 200 + rand() % 100; + c->w = 12; + c->h = 24; + + c->pins[SCF_EDA_NPN_B]->x = c->x; + c->pins[SCF_EDA_NPN_B]->y = c->y - 50; + + c->pins[SCF_EDA_NPN_C]->x = c->x - 100 * 7 / 8; + c->pins[SCF_EDA_NPN_C]->y = c->y + 50; + + c->pins[SCF_EDA_NPN_E]->x = c->x + 100 * 7 / 8; + c->pins[SCF_EDA_NPN_E]->y = c->y + 50; + return 0; +} + +static void button_R_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + ui->status = SES_UI_EDIT; + + button_2pins_clicked(ui, SCF_EDA_Resistor); + gtk_gl_area_queue_render(ui->gl_area); +} + +static void button_C_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + ui->status = SES_UI_EDIT; + + button_2pins_clicked(ui, SCF_EDA_Capacitor); + gtk_gl_area_queue_render(ui->gl_area); +} + +static void button_L_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + ui->status = SES_UI_EDIT; + + button_2pins_clicked(ui, SCF_EDA_Inductor); + gtk_gl_area_queue_render(ui->gl_area); +} + +static void button_B_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + ui->status = SES_UI_EDIT; + + button_2pins_clicked(ui, SCF_EDA_Battery); + gtk_gl_area_queue_render(ui->gl_area); +} + +static void button_D_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + ui->status = SES_UI_EDIT; + + button_2pins_clicked(ui, SCF_EDA_Diode); + gtk_gl_area_queue_render(ui->gl_area); +} + +static void button_X_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + ui->status = SES_UI_EDIT; + + button_2pins_clicked(ui, SCF_EDA_Crystal); + gtk_gl_area_queue_render(ui->gl_area); +} + +static void button_NPN_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + ui->status = SES_UI_EDIT; + + button_transistor_clicked(ui, SCF_EDA_NPN); + gtk_gl_area_queue_render(ui->gl_area); +} + +static void button_PNP_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + ui->status = SES_UI_EDIT; + + button_transistor_clicked(ui, SCF_EDA_PNP); + gtk_gl_area_queue_render(ui->gl_area); +} + +static int button_add_line(ScfEline* el, ScfLine** pl, int x0, int y0, int x1, int y1) +{ + ScfLine* l = calloc(1, sizeof(ScfLine)); + if (!l) + return -ENOMEM; + + l->x0 = x0; + l->y0 = y0; + l->x1 = x1; + l->y1 = y1; + + int ret = scf_eline__add_line(el, l); + if (ret < 0) { + free(l); + return ret; + } + + *pl = l; + return 0; +} + +static int button_add_eline(ses_ui_t* ui, ScfEline** pel, ScfLine** pl, int x0, int y0, int x1, int y1) +{ + ScfLine* l = NULL; + ScfEline* el = scf_eline__alloc(); + if (!el) + return -ENOMEM; + + int ret = button_add_line(el, &l, x0, y0, x1, y1); + if (ret < 0) { + ScfEline_free(el); + return ret; + } + + ret = scf_efunction__add_eline(ui->f, el); + if (ret < 0) { + ScfEline_free(el); + return ret; + } + + el->id = ui->f->n_elines - 1; + + *pel = el; + *pl = l; + return 0; +} + +static int button_connect_pin(ses_ui_t* ui, ScfEpin* p0, ScfEpin* p1) +{ + ScfEline* el = NULL; + ScfLine* l = NULL; + + int ret; + + scf_efunction_find_eline(ui->f, &el, &l, p0->x, p0->y); + if (!el) { + ret = button_add_eline(ui, &el, &l, p0->x, p0->y, p1->x, p1->y); + if (ret < 0) + return ret; + + ret = scf_eline__add_pin(el, p0->cid, p0->id); + if (ret < 0) + return ret; + + p0->lid = el->id; + } else { + ret = button_add_line(el, &l, p0->x, p0->y, p1->x, p1->y); + if (ret < 0) + return ret; + } + + ret = scf_eline__add_pin(el, p1->cid, p1->id); + if (ret < 0) + return ret; + + scf_logi("\033[32m el%ld add c%ldp%ld, c%ldp%ld\033[0m\n", el->id, p0->cid, p0->id, p1->cid, p1->id); + + p1->lid = el->id; + return 0; +} + +static int button_connect_pins(ses_ui_t* ui) +{ + ScfEpin* p; + long i; + long j; + + for (i = 0; i < ui->c->n_pins; i++) { + p = ui->c->pins[i]; + + int x = p->x; + int y = p->y; + + p->x = 0; + p->y = 0; + + ScfEcomponent* c2 = NULL; + ScfEpin* p2 = NULL; + ScfEline* el = NULL; + ScfLine* l = NULL; + + scf_efunction_find_pin(ui->f, &c2, &p2, x, y); + p->x = x; + p->y = y; + + if (p2) { + scf_logi("\033[33m c%ldp%ld, c%ldp%ld\033[0m\n", p->cid, p->id, p2->cid, p2->id); + + scf_efunction_find_eline(ui->f, &el, &l, x, y); + if (!el) { + scf_efunction_find_eline(ui->f, &el, &l, p2->x, p2->y); + if (!el) { + int ret = button_add_eline(ui, &el, &l, x, y, x, y); + if (ret < 0) + return ret; + } + } + + int ret = scf_eline__add_pin(el, p->cid, p->id); + if (ret < 0) + return ret; + + ret = scf_eline__add_pin(el, p2->cid, p2->id); + if (ret < 0) + return ret; + + scf_logi("\033[32m el%ld add c%ldp%ld, c%ldp%ld\033[0m\n", el->id, p->cid, p->id, p2->cid, p2->id); + + p ->lid = el->id; + p2->lid = el->id; + + } else { + scf_efunction_find_eline(ui->f, &el, &l, x, y); + if (!el) { + j = scf_find_eline_index(ui->f, p->lid); + + if (j >= 0) { + el = ui->f->elines[j]; + + assert(0 == scf_eline__del_pin(el, p->cid, p->id)); + p->lid = -1; + + scf_logi("\033[31m el%ld del c%ldp%ld\033[0m\n", el->id, p->cid, p->id); + + if (2 == el->n_pins) { + c2 = ui->f->components[el->pins[0]]; + p2 = c2->pins [el->pins[1]]; + + assert(0 == scf_eline__del_pin(el, p2->cid, p2->id)); + p2->lid = -1; + + scf_logi("\033[31m el%ld del c%ldp%ld\033[0m\n", el->id, p2->cid, p2->id); + + assert(0 == scf_efunction__del_eline(ui->f, el)); + ScfEline_free(el); + el = NULL; + } + } + } + } + } + + return 0; +} + +static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpointer user_data) +{ + ses_ui_t* ui = user_data; + ScfEline* el = NULL; + ScfLine* l = NULL; + + if (gtk_widget_get_window(GTK_WIDGET(ui->gl_area)) == event->window) { + ui->status = SES_UI_EDIT; + + scf_logi("x: %f, y: %f", event->x, event->y); + + if (ui->f) { + ui->c = NULL; + ui->p = NULL; + + scf_efunction_find_pin (ui->f, &ui->c, &ui->p, event->x, event->y); + scf_efunction_find_eline(ui->f, &el, &l, event->x, event->y); + + ui->press_x = event->x; + ui->press_y = event->y; + + if (ui->c) { + fprintf(stderr, ", c%ld", ui->c->id); + if (ui->p) + fprintf(stderr, "p%ld", ui->p->id); + } + + if (el) + fprintf(stderr, ", el%ld", el->id); + } + fprintf(stderr, "\n"); + } + + return TRUE; +} + +static gboolean button_release_event(GtkWidget* self, GdkEventButton* event, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + if (gtk_widget_get_window(GTK_WIDGET(ui->gl_area)) == event->window) { + ui->status = SES_UI_EDIT; + + scf_logw("x: %f, y: %f\n", event->x, event->y); + + if (ui->c) { + if (!ui->p) { + button_connect_pins(ui); + } else { + ScfEpin* p = ui->p; + + ui->c = NULL; + ui->p = NULL; + + scf_efunction_find_pin(ui->f, &ui->c, &ui->p, event->x, event->y); + if (ui->p) + button_connect_pin(ui, p, ui->p); + } + + ui->c = NULL; + ui->p = NULL; + + ui->press_x = 0; + ui->press_y = 0; + ui->move_x = 0; + ui->move_y = 0; + } + } + + return TRUE; +} + +static gboolean button_move_event(GtkWidget* self, GdkEventMotion* event, gpointer user_data) +{ + ses_ui_t* ui = user_data; + ScfEpin* p; + long i; + + if (ui->c) { + scf_logd("event x: %f, y: %f, c%ld\n", event->x, event->y, ui->c->id); + + if (!ui->p) { + int dx = event->x - ui->c->x; + int dy = event->y - ui->c->y; + + for (i = 0; i < ui->c->n_pins; i++) { + p = ui->c->pins[i]; + + p->x += dx; + p->y += dy; + } + + ui->c->x += dx; + ui->c->y += dy; + } else { + ui->move_x = event->x; + ui->move_y = event->y; + } + + gtk_gl_area_queue_render(ui->gl_area); + } + + return TRUE; +} + +static void apply_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + ScfEboard* b = scf_eboard__alloc(); + if (!b) + return; + + if (scf_eboard__add_function(b, ui->f) < 0) { + ScfEboard_free(b); + return; + } + + ui->f->x = 0; + ui->f->y = 0; + ui->f->w = ui->width; + ui->f->h = ui->height; + + uint8_t* buf = NULL; + long len = 0; + long ret = ScfEboard_pack(b, &buf, &len); + + assert(0 == scf_eboard__del_function(b, ui->f)); + + ScfEboard_free(b); + b = NULL; + if (ret < 0) + return; + + FILE* fp = fopen("./tmp.cpk", "wb"); + if (!fp) + return; + + fwrite(buf, len, 1, fp); + fclose(fp); + fp = NULL; + + free(buf); + buf = NULL; + + float ns = atof(gtk_entry_get_text(ui->entry_ns)); + int count = atoi(gtk_entry_get_text(ui->entry_count)); + + printf("./ses ./tmp.cpk -l 0 -t %fns -c %d\n", ns, count); + fflush(stdout); + + ui->apply_index = -1; + ui->show_index = -1; + + ui->status = SES_UI_RUN; +} + +static gboolean key_press_event(GtkWidget* self, GdkEventKey* event, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + scf_logi("event keyval: %c, %d\n", event->keyval, event->keyval); + + switch (event->keyval) { + case GDK_KEY_BackSpace: + case GDK_KEY_Delete: + break; + default: + break; + }; + + return TRUE; +} + +static int load_png(ses_ui_t* ui) +{ + if (ui->apply_index <= 0 + || ui->show_index < 0 + || ui->show_index >= ui->apply_index) + return -1; + + char file[128]; + snprintf(file, sizeof(file) - 1, "./draw_%d.png", ui->show_index); + + cairo_surface_t* tmp = cairo_image_surface_create_from_png(file); + + if (CAIRO_STATUS_SUCCESS == cairo_surface_status(tmp)) { + int width = cairo_image_surface_get_width(tmp); + int height = cairo_image_surface_get_height(tmp); + int stride = cairo_image_surface_get_stride(tmp); + + int format = cairo_image_surface_get_format(tmp); + char* data = cairo_image_surface_get_data (tmp); + + assert(CAIRO_FORMAT_ARGB32 == format || CAIRO_FORMAT_RGB24 == format); + + scf_logi("apply_index: %d, show_index: %d, %dx%d, %s\n", ui->apply_index, ui->show_index, width, height, file); + + uint8_t* bgra = malloc(width * height * 4); + if (bgra) { + int i; + int j; + + for (i = 0; i < height; i++) { + uint8_t* dst = bgra + i * width * 4; + uint8_t* src = data + i * stride; + + for (j = 0; j < width; j++) { + dst[j * 4 ] = src[j * 4 ]; + dst[j * 4 + 1] = src[j * 4 + 1]; + dst[j * 4 + 2] = src[j * 4 + 2]; + dst[j * 4 + 3] = src[j * 4 + 3]; + } + } + + cairo_surface_t* surface; + cairo_t* cr; + + surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, width, height, width * 4); + if (surface) { + cr = cairo_create(surface); + + if (cr) { + if (ui->bgra) { + cairo_destroy(ui->cr); + cairo_surface_destroy(ui->surface); + free(ui->bgra); + } + + ui->cr = cr; + ui->surface = surface; + ui->bgra = bgra; + + ui->width = width; + ui->height = height; + } else { + cairo_surface_destroy(surface); + free(bgra); + surface = NULL; + bgra = NULL; + } + } else { + free(bgra); + bgra = NULL; + } + } + } + + cairo_surface_destroy(tmp); + return 0; +} + +static void forward_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + if (ui->show_index < ui->apply_index - 1) + ui->show_index++; + + load_png(ui); + gtk_gl_area_queue_render(ui->gl_area); +} + +static void back_clicked(GtkButton* self, gpointer user_data) +{ + ses_ui_t* ui = user_data; + + if (ui->show_index > 0) + ui->show_index--; + + load_png(ui); + gtk_gl_area_queue_render(ui->gl_area); +} + +static gboolean timer_handler(gpointer user_data) +{ + ses_ui_t* ui = user_data; + + if (SES_UI_EDIT == ui->status) { + gtk_gl_area_queue_render(ui->gl_area); + return TRUE; + } + + char buf[PIPE_BUF]; + + int ret = read(0, buf, PIPE_BUF); + if (ret <= 0) { + gtk_gl_area_queue_render(ui->gl_area); + return TRUE; + } + + if (!strncmp(buf, "ok: ", 3)) + ui->apply_index = atol(buf + 4); + + if (ui->show_index < 0 && ui->apply_index > 0) { + ui->show_index = 0; + load_png(ui); + } + + gtk_gl_area_queue_render(ui->gl_area); + return TRUE; +} + +int main(int argc, char* argv[]) +{ + int rfd[2]; + int wfd[2]; + + if (-1 == pipe2(rfd, O_DIRECT)) + return -1; + if (-1 == pipe2(wfd, O_DIRECT)) + return -1; + + pid_t cpid = fork(); + + if (cpid < 0) { + scf_loge("\n"); + return -1; + + } else if (0 == cpid) { + close(rfd[0]); + close(wfd[1]); + + dup2(rfd[1], 1); + dup2(wfd[0], 0); + + close(rfd[1]); + close(wfd[0]); + + char* argv[] = {"./ses", NULL}; + + execve(argv[0], argv, NULL); + exit(-1); + + } else { + close(rfd[1]); + close(wfd[0]); + + dup2(rfd[0], 0); + dup2(wfd[1], 1); + + close(rfd[0]); + close(wfd[1]); + + int flags = fcntl(0, F_GETFL); + flags |= O_NONBLOCK; + fcntl(0, F_SETFL, flags); + } + + ses_ui_t ui = SES_UI_INIT(); + + GtkBuilder* builder; + GObject* window; + GObject* gl_area; + GError* error = NULL; + + gtk_init(&argc, &argv); + + builder = gtk_builder_new(); + + if (gtk_builder_add_from_file(builder, "ses_ui.glade", &error) == 0) { + g_printerr("Error loading file: %s\n", error->message); + g_clear_error(&error); + return 1; + } + + window = gtk_builder_get_object(builder, "main_window"); + gl_area = gtk_builder_get_object(builder, "gl_area"); + + ui.builder = builder; + ui.gl_area = GTK_GL_AREA(gl_area); + ui.entry_ns = GTK_ENTRY(gtk_builder_get_object(builder, "entry_ns")); + ui.entry_count = GTK_ENTRY(gtk_builder_get_object(builder, "entry_count")); + + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(gl_area, "resize", G_CALLBACK(resize), NULL); + g_signal_connect(gl_area, "unrealize", G_CALLBACK(unrealize), NULL); + g_signal_connect(gl_area, "render", G_CALLBACK(render), &ui); + + gtk_widget_add_events(GTK_WIDGET(gl_area), GDK_POINTER_MOTION_MASK); + + g_signal_connect(gl_area, "key-press-event", G_CALLBACK(key_press_event), &ui); + g_signal_connect(window, "button-press-event", G_CALLBACK(button_press_event), &ui); + g_signal_connect(window, "button-release-event", G_CALLBACK(button_release_event), &ui); + g_signal_connect(window, "motion-notify-event", G_CALLBACK(button_move_event), &ui); + + GObject* back = gtk_builder_get_object(builder, "button_back"); + GObject* forward = gtk_builder_get_object(builder, "button_forward"); + GObject* undo = gtk_builder_get_object(builder, "button_undo"); + GObject* redo = gtk_builder_get_object(builder, "button_redo"); + GObject* zoom_in = gtk_builder_get_object(builder, "button_zoom_in"); + GObject* zoom_out = gtk_builder_get_object(builder, "button_zoom_out"); + GObject* apply = gtk_builder_get_object(builder, "button_apply"); + + g_signal_connect(forward, "clicked", G_CALLBACK(forward_clicked), &ui); + g_signal_connect(back, "clicked", G_CALLBACK(back_clicked), &ui); + g_signal_connect(apply, "clicked", G_CALLBACK(apply_clicked), &ui); + + GObject* button_B = gtk_builder_get_object(builder, "button_Battery"); + GObject* button_R = gtk_builder_get_object(builder, "button_R"); + GObject* button_C = gtk_builder_get_object(builder, "button_C"); + GObject* button_L = gtk_builder_get_object(builder, "button_L"); + GObject* button_X = gtk_builder_get_object(builder, "button_X"); + GObject* button_D = gtk_builder_get_object(builder, "button_D"); + GObject* button_NPN = gtk_builder_get_object(builder, "button_NPN"); + GObject* button_PNP = gtk_builder_get_object(builder, "button_PNP"); + + g_signal_connect(button_B, "clicked", G_CALLBACK(button_B_clicked), &ui); + g_signal_connect(button_R, "clicked", G_CALLBACK(button_R_clicked), &ui); + g_signal_connect(button_C, "clicked", G_CALLBACK(button_C_clicked), &ui); + g_signal_connect(button_L, "clicked", G_CALLBACK(button_L_clicked), &ui); + g_signal_connect(button_X, "clicked", G_CALLBACK(button_X_clicked), &ui); + g_signal_connect(button_D, "clicked", G_CALLBACK(button_D_clicked), &ui); + g_signal_connect(button_NPN, "clicked", G_CALLBACK(button_NPN_clicked), &ui); + g_signal_connect(button_PNP, "clicked", G_CALLBACK(button_PNP_clicked), &ui); + + g_timeout_add(1, timer_handler, &ui); + + gtk_widget_show_all(GTK_WIDGET(window)); + + gtk_main(); +#if 0 + printf("./ses examples/sin_oscillator.cpk -t 1us -V v4\n"); + fflush(stdout); + + char* buf = NULL; + long len = 0; + + if (getline(&buf, &len, stdin) != -1) + scf_logw("parent pid %d: %s\n", getpid(), buf); +#endif + printf("q\n"); + fflush(stdout); + + int status = 0; + wait(&status); + + scf_logi("main ok\n"); + return 0; +} diff --git a/ses_ui.glade b/ses_ui.glade new file mode 100644 index 0000000..2931598 --- /dev/null +++ b/ses_ui.glade @@ -0,0 +1,596 @@ + + + + + + False + ses电路仿真 + 1280 + 720 + + + True + True + vertical + 600 + + + True + True + vertical + 63 + + + True + False + vertical + + + True + False + + + True + False + + + True + False + _File + True + + + True + False + + + gtk-open + True + False + True + True + True + + + + + gtk-save + True + False + True + True + True + + + + + gtk-save-as + True + False + True + True + + + + + True + False + + + + + gtk-quit + True + False + True + True + True + + + + + + + + + True + False + _Help + True + + + True + False + + + gtk-about + True + False + True + True + True + + + + + + + + + False + True + 0 + + + + + + + + + + + False + True + 0 + + + + + True + False + + + gtk-go-back + True + True + True + True + True + + + False + True + 0 + + + + + gtk-go-forward + True + True + True + True + True + + + False + True + 1 + + + + + gtk-undo + True + True + True + True + True + + + False + True + 2 + + + + + gtk-redo + True + True + True + True + True + + + False + True + 3 + + + + + gtk-zoom-out + True + True + True + True + True + + + False + True + 4 + + + + + gtk-zoom-in + True + True + True + True + True + + + False + True + 5 + + + + + True + True + 6 + 10 + + + False + True + 6 + + + + + True + False + ns/纳秒 + + + False + True + 7 + + + + + True + True + 6 + 1 + + + False + True + 8 + + + + + True + False + count/次数 + + + False + True + 9 + + + + + gtk-apply + True + True + True + True + True + + + False + True + 10 + + + + + gtk-help + True + True + True + True + True + + + False + True + 11 + + + + + False + True + 1 + + + + + False + True + + + + + True + True + 220 + + + + True + False + + + R + True + True + True + + + 0 + 0 + + + + + C + True + True + True + + + 1 + 0 + + + + + L + True + True + True + + + 2 + 0 + + + + + D + True + True + True + + + 0 + 1 + + + + + NPN + True + True + True + + + 1 + 1 + + + + + PNP + True + True + True + + + 2 + 1 + + + + + X + True + True + True + + + 1 + 2 + + + + + AMP + True + True + True + + + 2 + 2 + + + + + Battery + True + True + True + + + 0 + 2 + + + + + NAND + True + True + True + + + 0 + 3 + + + + + NOR + True + True + True + + + 1 + 3 + + + + + AND + True + True + True + + + 0 + 4 + + + + + OR + True + True + True + + + 1 + 4 + + + + + NOT + True + True + True + + + 2 + 4 + + + + + XOR + True + True + True + + + 2 + 3 + + + + + + + + + + + + + + + + + + + + + + + False + True + + + + + True + True + 900 + + + True + True + False + + + False + True + + + + + True + False + + + True + True + + + + + True + True + + + + + True + True + + + + + False + True + + + + + True + True + + + True + True + + + + + + diff --git a/ses_ui.h b/ses_ui.h new file mode 100644 index 0000000..c6927b9 --- /dev/null +++ b/ses_ui.h @@ -0,0 +1,79 @@ +#ifndef SES_UI_H +#define SES_UI_H + +#include"ses_core.h" + +#include +#include +#include +#include + +#define GL_GLEXT_PROTOTYPES +#include +#include + +typedef struct ses_ui_s ses_ui_t; + +struct ses_ui_s +{ + GtkBuilder* builder; + GtkGLArea* gl_area; + + GtkEntry* entry_ns; + GtkEntry* entry_count; + + cairo_surface_t* surface; + cairo_t* cr; + uint8_t* bgra; + + ScfEfunction* f; + ScfEcomponent* c; + ScfEpin* p; + + int press_x; + int press_y; + int move_x; + int move_y; + + int width; + int height; + + int x; + int y; + int w; + int h; + + int apply_index; + int show_index; +#define SES_UI_EDIT 0 +#define SES_UI_RUN 1 + int status; +}; + +#define SES_UI_INIT() {NULL,NULL, NULL,NULL, NULL,NULL,NULL, NULL,NULL,NULL, 0,0,0,0, 0,0, 0,0,0,0, -1,-1, 0} + +static const GLfloat vert_array[] = { + -1.0f, -1.0f, + 1.0f, -1.0f, + -1.0f, 1.0f, + 1.0f, 1.0f +}; + +static const GLfloat texture_array[] = { + 0.0f, 1.0f, + 1.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, +}; + +void __compute_mvp(float *res, float phi, float theta, float psi); + +int __init_texture(GLuint* ptex, GLenum format, int w, int h, uint8_t* data); + +int __init_program(GLuint* pprog, const char* vert_shader, const char* frag_shader); + +int __init_buffers(GLuint* vao, GLuint buffers[2]); + +int ses_gl_render(ses_ui_t* ui, int width, int height, int x, int y, int w, int h); + +#endif diff --git a/ses_ui_gl.c b/ses_ui_gl.c new file mode 100644 index 0000000..f2607ad --- /dev/null +++ b/ses_ui_gl.c @@ -0,0 +1,152 @@ +#include"ses_ui.h" + +void __compute_mvp(float *res, float phi, float theta, float psi) +{ + float x = phi * (M_PI / 180.f); + float y = theta * (M_PI / 180.f); + float z = psi * (M_PI / 180.f); + float c1 = cosf (x), s1 = sinf (x); + float c2 = cosf (y), s2 = sinf (y); + float c3 = cosf (z), s3 = sinf (z); + float c3c2 = c3 * c2; + float s3c1 = s3 * c1; + float c3s2s1 = c3 * s2 * s1; + float s3s1 = s3 * s1; + float c3s2c1 = c3 * s2 * c1; + float s3c2 = s3 * c2; + float c3c1 = c3 * c1; + float s3s2s1 = s3 * s2 * s1; + float c3s1 = c3 * s1; + float s3s2c1 = s3 * s2 * c1; + float c2s1 = c2 * s1; + float c2c1 = c2 * c1; + + /* initialize to the identity matrix */ + res[0] = 1.f; res[4] = 0.f; res[8] = 0.f; res[12] = 0.f; + res[1] = 0.f; res[5] = 1.f; res[9] = 0.f; res[13] = 0.f; + res[2] = 0.f; res[6] = 0.f; res[10] = 1.f; res[14] = 0.f; + res[3] = 0.f; res[7] = 0.f; res[11] = 0.f; res[15] = 1.f; + + /* apply all three rotations using the three matrices: + * + * ⎡ c3 s3 0 ⎤ ⎡ c2 0 -s2 ⎤ ⎡ 1 0 0 ⎤ + * ⎢ -s3 c3 0 ⎥ ⎢ 0 1 0 ⎥ ⎢ 0 c1 s1 ⎥ + * ⎣ 0 0 1 ⎦ ⎣ s2 0 c2 ⎦ ⎣ 0 -s1 c1 ⎦ + */ + res[0] = c3c2; res[4] = s3c1 + c3s2s1; res[8] = s3s1 - c3s2c1; res[12] = 0.f; + res[1] = -s3c2; res[5] = c3c1 - s3s2s1; res[9] = c3s1 + s3s2c1; res[13] = 0.f; + res[2] = s2; res[6] = -c2s1; res[10] = c2c1; res[14] = 0.f; + res[3] = 0.f; res[7] = 0.f; res[11] = 0.f; res[15] = 1.f; +} + +int __init_texture(GLuint* ptex, GLenum format, int w, int h, uint8_t* data) +{ + GLuint tex; + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, data); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glBindTexture(GL_TEXTURE_2D, 0); + + *ptex = tex; + return 0; +} + +int __init_buffers(GLuint* vao, GLuint buffers[2]) +{ + glGenBuffers(2, buffers); + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vert_array), vert_array, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, buffers[1]); + glBufferData(GL_ARRAY_BUFFER, sizeof(texture_array), texture_array, GL_STATIC_DRAW); + + glGenVertexArrays(1, vao); + glBindVertexArray(*vao); + + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); + + glBindBuffer(GL_ARRAY_BUFFER, buffers[1]); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0); + + glBindVertexArray(0); + return 0; +} + +int __init_program(GLuint* pprog, const char* vert_shader, const char* frag_shader) +{ + GLint status = 0; + GLint len = 0; + + GLuint vshader = glCreateShader(GL_VERTEX_SHADER); + + glShaderSource (vshader, 1, &vert_shader, NULL); + glCompileShader(vshader); + glGetShaderiv (vshader, GL_COMPILE_STATUS, &status); + + if (!status) { + glGetShaderiv(vshader, GL_INFO_LOG_LENGTH, &len); + + char* log = calloc(1, len + 1); + if (!log) + return -ENOMEM; + + glGetShaderInfoLog(vshader, len, NULL, log); + + scf_loge("%s\n", log); + free(log); + log = NULL; + } + + GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); + + glShaderSource (fshader, 1, &frag_shader, NULL); + glCompileShader(fshader); + glGetShaderiv (fshader, GL_COMPILE_STATUS, &status); + + if (!status) { + glGetShaderiv(fshader, GL_INFO_LOG_LENGTH, &len); + + char* log = calloc(1, len + 1); + if (!log) + return -ENOMEM; + + glGetShaderInfoLog(fshader, len, NULL, log); + + scf_loge("%s\n", log); + free(log); + log = NULL; + } + + GLuint program = glCreateProgram(); + + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram (program); + glGetProgramiv(program, GL_LINK_STATUS, &status); + + if (!status) { + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len); + + char* log = calloc(1, len + 1); + if (!log) + return -ENOMEM; + + glGetProgramInfoLog(program, len, NULL, log); + + scf_loge("%s\n", log); + free(log); + log = NULL; + } + + *pprog = program; + return 0; +} diff --git a/ses_ui_render.c b/ses_ui_render.c new file mode 100644 index 0000000..127faa3 --- /dev/null +++ b/ses_ui_render.c @@ -0,0 +1,113 @@ +#include"ses_ui.h" + +static const char* vert_shader = + "#version 330 core\n" + "layout(location = 0) in vec4 position; \n" + "layout(location = 1) in vec2 a_texCoord; \n" + "out vec2 v_texCoord; \n" + "uniform mat4 mvp; \n" + "void main() { \n" + "gl_Position = mvp * position; \n" + "v_texCoord = a_texCoord; \n" + "} \n"; + +static const char* frag_shader = + "#version 330 core\n" + "in vec2 v_texCoord; \n" + "out vec4 outputColor; \n" + "uniform sampler2D tex_rgba; \n" + "void main() { \n" + " vec2 xy = v_texCoord; \n" + " vec4 v = texture2D(tex_rgba, xy).rgba; \n" + " outputColor = vec4(v.b, v.g, v.r, 1.0); \n" + "} \n"; + + +static GLuint program = 0; + +static GLuint vao = 0; +static GLuint buffers[2] = {0}; +static GLuint texture_rgba = 0; + +static GLuint uniform_mvp; +static GLuint uniform_rgba; + + +int ses_gl_render(ses_ui_t* ui, int width, int height, int x, int y, int w, int h) +{ + if (0 == program) + __init_program(&program, vert_shader, frag_shader); + + if (0 == vao) + __init_buffers(&vao, buffers); + + if (0 == texture_rgba) + __init_texture(&texture_rgba, GL_RGBA, ui->width, ui->height, NULL); + + float mvp[16]; + __compute_mvp(mvp, 0, 0, 0); + + if (SES_UI_EDIT == ui->status) { + cairo_set_line_width(ui->cr, 2); + cairo_set_source_rgb(ui->cr, 1, 1, 1); + + cairo_rectangle(ui->cr, 0, 0, width, height); + cairo_fill(ui->cr); + cairo_stroke(ui->cr); + + __ses_draw_elines (ui->cr, ui->f, -1); + __ses_draw_components(ui->cr, ui->f); + + if (ui->press_x > 0 + && ui->press_y > 0 + && ui->move_x > 0 + && ui->move_y > 0) { + cairo_set_source_rgb(ui->cr, 1, 0.5, 0.1); + + cairo_move_to(ui->cr, ui->press_x, ui->press_y); + cairo_line_to(ui->cr, ui->move_x, ui->move_y); + cairo_stroke(ui->cr); + } + } + + cairo_surface_write_to_png(ui->surface, "tmp.png"); + + GLfloat vert_update[] = + { + 2.0 * x / (float)width - 1.0, + -2.0 * (y + h) / (float)height + 1.0, + + 2.0 * (x + w) / (float)width - 1.0, + -2.0 * (y + h) / (float)height + 1.0, + + 2.0 * x / (float)width - 1.0, + -2.0 * y / (float)height + 1.0, + + 2.0 * (x + w) / (float)width - 1.0, + -2.0 * y / (float)height + 1.0, + }; + + glUseProgram(program); + uniform_rgba = glGetUniformLocation(program, "tex_rgba"); + uniform_mvp = glGetUniformLocation(program, "mvp"); + + glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp); + + // board + glActiveTexture(GL_TEXTURE0); + glBindTexture (GL_TEXTURE_2D, texture_rgba); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, ui->width, ui->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ui->bgra); + glUniform1i(uniform_rgba, 0); + + // draw + glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update); + + glBindVertexArray(vao); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glBindVertexArray(0); + glUseProgram(0); + return 0; +} diff --git a/ses_utils.c b/ses_utils.c index 4d04a95..b499863 100644 --- a/ses_utils.c +++ b/ses_utils.c @@ -94,6 +94,19 @@ void ses_edge_print(ses_edge_t* edge) fprintf(stderr, "; "); } +void ses_edges_print(scf_vector_t* edges) +{ + if (!edges) + return; + + int i; + for (i = 0; i < edges->size; i++) { + + ses_edge_print(edges->data[i]); + } + fprintf(stderr, "\n"); +} + ses_node_t* ses_node_alloc() { ses_node_t* node = calloc(1, sizeof(ses_node_t)); @@ -136,12 +149,8 @@ void ses_node_print(ses_node_t* node) fprintf(stderr, "node %d: \n", node->index); - for (i = 0; i < node->edges->size; i++) { - edge = node->edges->data[i]; + ses_edges_print(node->edges); - ses_edge_print(edge); - fprintf(stderr, "\n"); - } fprintf(stderr, "\n"); } diff --git a/test/fft.c b/test/fft.c index 44c3310..1bfb3a3 100644 --- a/test/fft.c +++ b/test/fft.c @@ -9,7 +9,7 @@ #define REAL(z,i) ((z)[2*(i)]) #define IMAG(z,i) ((z)[2*(i)+1]) -#define N 1024 +#define N 2048 int main() { @@ -117,7 +117,7 @@ int main() printf("%d, %lg %lg\n", i, REAL(data, i) / sqrt(N), IMAG(data, i) / sqrt(N)); } - double f = 2000.0 * 1e6 * imax / N; + double f = 1000.0 * 1e6 * imax / N; printf("avg: %lg, Zmax: %lg, imax: %d, f: %lg\n", sum / (N - 1), Zmax, imax, f); -- 2.25.1