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:
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';
return -1;
}
+ if (0 == i && !strcmp(p0, "q")) {
+ free(buf);
+ return 0;
+ }
+
args[i++] = p0;
p0 = ++p1;
} else
if (ret < 0)
return ret;
- printf("# ");
+ fprintf(stderr, "# ");
}
free(buf);
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},
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));
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)
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;
+}
{
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);
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 { \
#ifndef SES_CORE_H
#define SES_CORE_H
+#include<cairo/cairo.h>
#include"scf_vector.h"
#include"scf_eda_pack.h"
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);
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);
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)
{
#include<cairo/cairo.h>
#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;
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");
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;
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);
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;
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++)
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;
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;
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;
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];
ses_node_t* node;
ses_edge_t* edge;
+ if (nodes->size <= 0)
+ return 0;
+
while (nodes->size > 0) {
node = nodes->data[0];
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;
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;
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",
-#include<cairo/cairo.h>
#include"ses_core.h"
#define SHOW_BITS 1000.0
}
}
-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;
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;
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;
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);
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);
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);
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);
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);
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);
}
}
-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];
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);
}
printf("\n");
+ fflush(stdout);
return 0;
}
}
printf("\n");
+ fflush(stdout);
return 0;
}
}
ctx->i++;
+
+ printf("ok: %d\n", ctx->i);
+ fflush(stdout);
}
return 0;
--- /dev/null
+#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;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface>
+ <requires lib="gtk+" version="3.24"/>
+ <object class="GtkWindow" id="main_window">
+ <property name="can-focus">False</property>
+ <property name="title" translatable="yes">ses电路仿真</property>
+ <property name="default-width">1280</property>
+ <property name="default-height">720</property>
+ <child>
+ <object class="GtkPaned" id="main_log">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="orientation">vertical</property>
+ <property name="position">600</property>
+ <child>
+ <object class="GtkPaned" id="main_menus">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="orientation">vertical</property>
+ <property name="position">63</property>
+ <child>
+ <object class="GtkBox" id="menus_buttons">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkMenuBar">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkMenuItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use-underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkImageMenuItem" id="file_open">
+ <property name="label">gtk-open</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="file_save">
+ <property name="label">gtk-save</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="file_save_as">
+ <property name="label">gtk-save-as</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="use-stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorMenuItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="file_quit">
+ <property name="label">gtk-quit</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use-underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkImageMenuItem" id="help_about">
+ <property name="label">gtk-about</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkButton" id="button_back">
+ <property name="label">gtk-go-back</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_forward">
+ <property name="label">gtk-go-forward</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_undo">
+ <property name="label">gtk-undo</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_redo">
+ <property name="label">gtk-redo</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_zoom_out">
+ <property name="label">gtk-zoom-out</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_zoom_in">
+ <property name="label">gtk-zoom-in</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry_ns">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">6</property>
+ <property name="text" translatable="yes">10</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes"> ns/纳秒 </property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry_count">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">6</property>
+ <property name="text" translatable="yes">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes"> count/次数 </property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_apply">
+ <property name="label">gtk-apply</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_help">
+ <property name="label">gtk-help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-stock">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">11</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkPaned" id="main_buttons">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="position">220</property>
+ <child>
+ <!-- n-columns=3 n-rows=7 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkButton" id="button_R">
+ <property name="label" translatable="yes">R</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_C">
+ <property name="label" translatable="yes">C</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_L">
+ <property name="label" translatable="yes">L</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_D">
+ <property name="label" translatable="yes">D</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_NPN">
+ <property name="label" translatable="yes">NPN</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_PNP">
+ <property name="label" translatable="yes">PNP</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_X">
+ <property name="label" translatable="yes">X</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_op_amp">
+ <property name="label" translatable="yes">AMP</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_Battery">
+ <property name="label" translatable="yes">Battery</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_NAND">
+ <property name="label" translatable="yes">NAND</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_NOR">
+ <property name="label" translatable="yes">NOR</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_AND">
+ <property name="label" translatable="yes">AND</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_OR">
+ <property name="label" translatable="yes">OR</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_NOT">
+ <property name="label" translatable="yes">NOT</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_XOR">
+ <property name="label" translatable="yes">XOR</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkPaned" id="main_VA">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="position">900</property>
+ <child>
+ <object class="GtkGLArea" id="gl_area">
+ <property name="visible">True</property>
+ <property name="app-paintable">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="draw_VA">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTextView" id="text_log">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ </object>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
--- /dev/null
+#ifndef SES_UI_H
+#define SES_UI_H
+
+#include"ses_core.h"
+
+#include<sys/types.h>
+#include<sys/wait.h>
+#include<fcntl.h>
+#include<gtk/gtk.h>
+
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+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
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
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));
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");
}
#define REAL(z,i) ((z)[2*(i)])
#define IMAG(z,i) ((z)[2*(i)+1])
-#define N 1024
+#define N 2048
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);