--- /dev/null
+<html>
+<title>test</title>
+<body>
+
+<form action="/" method="post">
+
+<label for="name">用户:</label>
+<input type="text" id="name" name="name">
+<br>
+
+<label for="password">密码:</label>
+<input type="password" id="password" name="password">
+<br>
+
+<input type="submit" value="提交">
+</form>
+
+</body>
+</html>
char* name;
char* value;
int type;
+ int flags;
} html_attr_t;
typedef struct {
static html_attr_t h1_attrs[] =
{
- {"font", "SimHei", ABC_HTML_ATTR_FONT},
- {"font-size", "40", ABC_HTML_ATTR_FONT_SIZE},
+ {"font", "SimHei", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "40", ABC_HTML_ATTR_FONT_SIZE, 0},
};
static html_attr_t h2_attrs[] =
{
- {"font", "SimHei", ABC_HTML_ATTR_FONT},
- {"font-size", "32", ABC_HTML_ATTR_FONT_SIZE},
+ {"font", "SimHei", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "32", ABC_HTML_ATTR_FONT_SIZE, 0},
};
static html_attr_t h3_attrs[] =
{
- {"font", "SimHei", ABC_HTML_ATTR_FONT},
- {"font-size", "28", ABC_HTML_ATTR_FONT_SIZE},
+ {"font", "SimHei", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "28", ABC_HTML_ATTR_FONT_SIZE, 0},
};
static html_attr_t h4_attrs[] =
{
- {"font", "SimHei", ABC_HTML_ATTR_FONT},
- {"font-size", "24", ABC_HTML_ATTR_FONT_SIZE},
+ {"font", "SimHei", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "24", ABC_HTML_ATTR_FONT_SIZE, 0},
};
static html_attr_t h5_attrs[] =
{
- {"font", "SimHei", ABC_HTML_ATTR_FONT},
- {"font-size", "20", ABC_HTML_ATTR_FONT_SIZE},
+ {"font", "SimHei", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "20", ABC_HTML_ATTR_FONT_SIZE, 0},
};
static html_attr_t h6_attrs[] =
{
- {"font", "SimHei", ABC_HTML_ATTR_FONT},
- {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE},
+ {"font", "SimHei", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE, 0},
};
static html_attr_t p_attrs[] =
{
- {"font", "SimSong", ABC_HTML_ATTR_FONT},
- {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE},
+ {"font", "SimSong", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE, 0},
};
static html_attr_t a_attrs[] =
{
- {"href", "", ABC_HTML_ATTR_HREF},
- {"font", "SimHei", ABC_HTML_ATTR_FONT},
- {"font-size", "24", ABC_HTML_ATTR_FONT_SIZE},
- {"font-color", "blue", ABC_HTML_ATTR_FONT_COLOR},
+ {"href", "", ABC_HTML_ATTR_HREF, ABC_HTML_FLAG_SHOW},
+ {"font", "SimHei", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "24", ABC_HTML_ATTR_FONT_SIZE, 0},
+ {"font-color", "blue", ABC_HTML_ATTR_FONT_COLOR, 0},
};
static html_attr_t img_attrs[] =
{
- {"src", "", ABC_HTML_ATTR_SRC},
- {"width", "100", ABC_HTML_ATTR_WIDTH},
- {"height", "100", ABC_HTML_ATTR_HEIGHT},
+ {"src", "", ABC_HTML_ATTR_SRC, ABC_HTML_FLAG_SHOW},
+ {"width", "100", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW},
+ {"height", "100", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW},
+};
+
+static html_attr_t input_attrs[] =
+{
+ {"type", "text", ABC_HTML_ATTR_TYPE, ABC_HTML_FLAG_SHOW},
+ {"id", "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW},
+ {"name", "", ABC_HTML_ATTR_NAME, ABC_HTML_FLAG_SHOW},
+ {"value", "", ABC_HTML_ATTR_VALUE, ABC_HTML_FLAG_SHOW},
+
+ {"font", "SimSong", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE, 0},
+};
+
+static html_attr_t label_attrs[] =
+{
+ {"for", "", ABC_HTML_ATTR_FOR, ABC_HTML_FLAG_SHOW},
+
+ {"font", "SimSong", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE, 0},
+};
+
+static html_attr_t form_attrs[] =
+{
+ {"action", "/", ABC_HTML_ATTR_ACTION, ABC_HTML_FLAG_SHOW},
+ {"method", "post", ABC_HTML_ATTR_METHOD, ABC_HTML_FLAG_SHOW},
+
+ {"font", "SimSong", ABC_HTML_ATTR_FONT, 0},
+ {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE, 0},
};
static html_label_t html_labels[] =
{"div", ABC_HTML_DIV, 0, NULL, ABC_HTML_FLAG_CLOSE},
- {"h1", ABC_HTML_H1, abc_number_of(h1_attrs), h1_attrs, ABC_HTML_FLAG_CLOSE},
- {"h2", ABC_HTML_H2, abc_number_of(h2_attrs), h2_attrs, ABC_HTML_FLAG_CLOSE},
- {"h3", ABC_HTML_H3, abc_number_of(h3_attrs), h3_attrs, ABC_HTML_FLAG_CLOSE},
- {"h4", ABC_HTML_H4, abc_number_of(h4_attrs), h4_attrs, ABC_HTML_FLAG_CLOSE},
- {"h5", ABC_HTML_H5, abc_number_of(h5_attrs), h5_attrs, ABC_HTML_FLAG_CLOSE},
- {"h6", ABC_HTML_H6, abc_number_of(h6_attrs), h6_attrs, ABC_HTML_FLAG_CLOSE},
+ {"h1", ABC_HTML_H1, abc_number_of(h1_attrs), h1_attrs, ABC_HTML_FLAG_CLOSE},
+ {"h2", ABC_HTML_H2, abc_number_of(h2_attrs), h2_attrs, ABC_HTML_FLAG_CLOSE},
+ {"h3", ABC_HTML_H3, abc_number_of(h3_attrs), h3_attrs, ABC_HTML_FLAG_CLOSE},
+ {"h4", ABC_HTML_H4, abc_number_of(h4_attrs), h4_attrs, ABC_HTML_FLAG_CLOSE},
+ {"h5", ABC_HTML_H5, abc_number_of(h5_attrs), h5_attrs, ABC_HTML_FLAG_CLOSE},
+ {"h6", ABC_HTML_H6, abc_number_of(h6_attrs), h6_attrs, ABC_HTML_FLAG_CLOSE},
+
+ {"p", ABC_HTML_P, abc_number_of(p_attrs), p_attrs, ABC_HTML_FLAG_CLOSE},
+ {"br", ABC_HTML_BR, 0, NULL, ABC_HTML_FLAG_OPEN},
- {"p", ABC_HTML_P, abc_number_of(p_attrs), p_attrs, ABC_HTML_FLAG_CLOSE},
- {"br", ABC_HTML_BR, 0, NULL, ABC_HTML_FLAG_OPEN},
+ {"a", ABC_HTML_A, abc_number_of(a_attrs), a_attrs, ABC_HTML_FLAG_CLOSE},
+ {"img", ABC_HTML_IMG, abc_number_of(img_attrs), img_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE},
- {"a", ABC_HTML_A, abc_number_of(a_attrs), a_attrs, ABC_HTML_FLAG_CLOSE},
- {"img", ABC_HTML_IMG, abc_number_of(img_attrs), img_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE},
+ {"form", ABC_HTML_FORM, abc_number_of(form_attrs), form_attrs, ABC_HTML_FLAG_CLOSE},
+ {"input", ABC_HTML_INPUT, abc_number_of(input_attrs), input_attrs, ABC_HTML_FLAG_OPEN},
+ {"label", ABC_HTML_LABEL, abc_number_of(label_attrs), label_attrs, ABC_HTML_FLAG_CLOSE},
};
static int __html_parse_obj(abc_html_t* html, abc_char_t* c);
return NULL;
}
-static int __html_add_attr(abc_obj_t* obj, int type, const char* name, const char* value)
+static int __html_add_attr(abc_obj_t* obj, int type, const char* name, const char* value, int flags)
{
abc_obj_t* attr = abc_obj_alloc(NULL, 0, 0, type);
if (!attr)
return -ENOMEM;
}
+ attr->flags = flags;
+
scf_list_add_tail(&obj->attrs, &attr->list);
return 0;
}
if (attrs && n_attrs > 0) {
for (i = 0; i < n_attrs; i++) {
- ret = __html_add_attr(obj, attrs[i].type, attrs[i].name, attrs[i].value);
+ ret = __html_add_attr(obj, attrs[i].type, attrs[i].name, attrs[i].value, attrs[i].flags);
if (ret < 0)
return ret;
}
for (l = scf_list_head(&obj->parent->attrs); l != scf_list_sentinel(&obj->parent->attrs); l = scf_list_next(l)) {
attr = scf_list_data(l, abc_obj_t, list);
- ret = __html_add_attr(obj, attr->type, attr->key->data, attr->value->data);
+ ret = __html_add_attr(obj, attr->type, attr->key->data, attr->value->data, 0);
if (ret < 0)
return ret;
}
text = NULL;
- if (ABC_HTML_BR == obj->type) { // single label
+ if (ABC_HTML_FLAG_OPEN == (obj->flags & 0x1)) { // single labels
+
__html_push_char(html, c);
c = NULL;
return 0;
- }
+ };
html->pos++;
free(c);
return;
if (obj->value)
- printf(" %s=%s", obj->key->data, obj->value->data);
+ printf(" %s=\"%s\"", obj->key->data, obj->value->data);
else if (obj->key)
printf("<%s", obj->key->data);
- if (ABC_HTML_FLAG_CLOSE & obj->flags) {
-
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
+ for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
+ attr = scf_list_data(l, abc_obj_t, list);
+ if (ABC_HTML_FLAG_SHOW & attr->flags)
abc_obj_print(attr);
- }
}
if (!obj->value) {
// 15
ABC_HTML_IMG,
+ ABC_HTML_FORM,
+ ABC_HTML_LABEL,
+ ABC_HTML_INPUT,
+
ABC_HTML_NB, // total HTML objects
ABC_HTML_ATTR_ID,
+ ABC_HTML_ATTR_TYPE,
+ ABC_HTML_ATTR_NAME,
+ ABC_HTML_ATTR_VALUE,
+
ABC_HTML_ATTR_HREF,
ABC_HTML_ATTR_SRC,
+ ABC_HTML_ATTR_FOR,
+
+ ABC_HTML_ATTR_ACTION,
+ ABC_HTML_ATTR_METHOD,
+
ABC_HTML_ATTR_FONT,
ABC_HTML_ATTR_FONT_SIZE,
ABC_HTML_ATTR_FONT_COLOR,
#define ABC_HTML_FLAG_OPEN 0
#define ABC_HTML_FLAG_CLOSE 1
#define ABC_HTML_FLAG_SINGLE 2
+#define ABC_HTML_FLAG_SHOW 4
uint32_t flags;
int x;
int w;
int h;
+ int progress;
+ uint32_t jiffies; // timeout numbers of sys timer
+
scf_string_t* key;
scf_string_t* value;
scf_string_t* text;
scf_string_t* file; // file name
int line; // line
int pos; // position
+
+ uint32_t clicked:1;
};
abc_obj_t* abc_obj_alloc(scf_string_t* file, int line, int pos, int type);
CFILES += abc_layout_h1.c
CFILES += abc_layout_a.c
CFILES += abc_layout_img.c
+CFILES += abc_layout_form.c
+CFILES += abc_layout_label.c
+CFILES += abc_layout_input.c
CFILES += abc_render.c
CFILES += abc_render_html.c
CFILES += abc_render_a.c
CFILES += abc_render_a_href.c
CFILES += abc_render_img.c
+CFILES += abc_render_form.c
+CFILES += abc_render_label.c
+CFILES += abc_render_input.c
CFILES += ../html/abc_html.c
CFILES += ../html/abc_html_util.c
struct abc_ctx_s
{
- scf_list_t html_list;
- abc_html_t* current;
+ scf_list_t html_list;
+ abc_html_t* current;
- GtkBuilder* builder;
+ GtkBuilder* builder;
- GtkGLArea* gl_area;
+ GtkGLArea* gl_area;
- GtkButton* back;
- GtkButton* forward;
- GtkButton* refresh;
+ GtkButton* back;
+ GtkButton* forward;
+ GtkButton* refresh;
+
+ GtkIMContext* im;
};
#define ABC_CTX_INIT(__ctx) {SCF_LIST_INIT((__ctx).html_list), NULL, NULL, NULL, NULL, NULL, NULL}
int abc_layout_a (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
int abc_layout_img (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+int abc_layout_form (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+int abc_layout_label(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+int abc_layout_input(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+
static abc_layout_pt abc_layouts[ABC_HTML_NB] =
{
- abc_layout_html,
- abc_layout_title,
- abc_layout_head,
- abc_layout_body,
-
- // 4
- abc_layout_div,
-
- // 5
- abc_layout_h1,
- abc_layout_h1,
- abc_layout_h1,
- abc_layout_h1,
- abc_layout_h1,
- abc_layout_h1,
-
- // 11
- abc_layout_h1, // <p>
- abc_layout_h1, // <br>
- abc_layout_a,
- NULL,
-
- abc_layout_img,
+ [ABC_HTML] = abc_layout_html,
+ [ABC_HTML_TITLE] = abc_layout_title,
+ [ABC_HTML_HEAD] = abc_layout_head,
+ [ABC_HTML_BODY] = abc_layout_body,
+ [ABC_HTML_DIV] = abc_layout_div,
+
+ [ABC_HTML_H1] = abc_layout_h1,
+ [ABC_HTML_H2] = abc_layout_h1,
+ [ABC_HTML_H3] = abc_layout_h1,
+ [ABC_HTML_H4] = abc_layout_h1,
+ [ABC_HTML_H5] = abc_layout_h1,
+ [ABC_HTML_H6] = abc_layout_h1,
+
+ [ABC_HTML_P] = abc_layout_h1,
+ [ABC_HTML_BR] = abc_layout_h1,
+
+ [ABC_HTML_A] = abc_layout_a,
+ [ABC_HTML_IMG] = abc_layout_img,
+
+ [ABC_HTML_FORM] = abc_layout_form,
+ [ABC_HTML_LABEL] = abc_layout_label,
+ [ABC_HTML_INPUT] = abc_layout_input,
};
int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
};
if (child->key)
- scf_logi("key: %s, x: %d, y: %d, w: %d, h: %d\n\n", child->key->data, child->x, child->y, child->w, child->h);
+ scf_logd("key: %s, x: %d, y: %d, w: %d, h: %d\n\n", child->key->data, child->x, child->y, child->w, child->h);
if (__w < child->x + child->w)
__w = child->x + child->w;
root->h = __h;
if (root->key)
- scf_logi("key: %s, x: %d, y: %d, w: %d, h: %d\n", root->key->data, root->x, root->y, root->w, root->h);
+ scf_logd("key: %s, x: %d, y: %d, w: %d, h: %d\n", root->key->data, root->x, root->y, root->w, root->h);
return 0;
}
--- /dev/null
+#include"abc.h"
+
+int abc_layout_form(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+{
+ abc_obj_t* attr;
+ cairo_text_extents_t extents;
+ cairo_surface_t* surface;
+ cairo_t* cr;
+
+ if (!obj->text)
+ return 0;
+
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create(surface);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
+ if (attr)
+ cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
+ if (attr)
+ cairo_set_font_size(cr, atoi(attr->value->data));
+
+ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_text_extents(cr, obj->text->data, &extents);
+
+ obj->x = 4;
+ obj->y = 4;
+ obj->w = extents.width + extents.x_bearing;
+ obj->h = extents.height + extents.height / 2;
+
+ obj->w = (obj->w + 3) & ~0x3;
+ obj->h = (obj->h + 3) & ~0x3;
+
+ scf_logi("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n",
+ obj->text->data, obj->w, obj->h,
+ extents.x_bearing, extents.y_bearing, extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ return 0;
+}
--- /dev/null
+#include"abc.h"
+
+int abc_layout_input(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+{
+ abc_obj_t* attr;
+ cairo_text_extents_t extents;
+ cairo_surface_t* surface;
+ cairo_t* cr;
+
+ char* text = "Hello HTML INPUT";
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_TYPE);
+
+ if (!strcmp(attr->value->data, "submit")) {
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_VALUE);
+
+ if (attr && attr->value && attr->value->len > 0)
+ text = attr->value->data;
+ else
+ text = "submit";
+ }
+
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create(surface);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
+ if (attr)
+ cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
+ if (attr)
+ cairo_set_font_size(cr, atoi(attr->value->data));
+
+ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_text_extents(cr, text, &extents);
+
+ obj->x = 4;
+ obj->y = 4;
+ obj->w = extents.width + extents.x_bearing;
+ obj->h = extents.height;
+
+ obj->w = ((obj->w + 3) & ~0x3) + 8;
+ obj->h = ((obj->h + 3) & ~0x3) + 8;
+
+ scf_logd("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n",
+ text, obj->w, obj->h,
+ extents.x_bearing, extents.y_bearing, extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ return 0;
+}
--- /dev/null
+#include"abc.h"
+
+int abc_layout_label(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+{
+ abc_obj_t* attr;
+ cairo_text_extents_t extents;
+ cairo_surface_t* surface;
+ cairo_t* cr;
+
+ if (!obj->text)
+ return 0;
+
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create(surface);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
+ if (attr)
+ cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
+ if (attr)
+ cairo_set_font_size(cr, atoi(attr->value->data));
+
+ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_text_extents(cr, obj->text->data, &extents);
+
+ obj->x = 4;
+ obj->y = 4;
+ obj->w = extents.width + extents.x_bearing;
+ obj->h = extents.height;
+
+ obj->w = ((obj->w + 3) & ~0x3) + 4;
+ obj->h = ((obj->h + 3) & ~0x3) + 4;
+
+ scf_logd("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n",
+ obj->text->data, obj->w, obj->h,
+ extents.x_bearing, extents.y_bearing, extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ return 0;
+}
extern abc_render_t abc_render_a_href;
extern abc_render_t abc_render_img;
+extern abc_render_t abc_render_form;
+extern abc_render_t abc_render_label;
+extern abc_render_t abc_render_input;
+
static abc_render_t* abc_renders[ABC_HTML_NB] =
{
- &abc_render_html,
- &abc_render_title,
- &abc_render_head,
- &abc_render_body,
-
- // 4
- &abc_render_div,
-
- &abc_render_h1,
- &abc_render_h1,
- &abc_render_h1,
- &abc_render_h1,
- &abc_render_h1,
- &abc_render_h1,
-
- // 11
- &abc_render_h1, // <p>
- &abc_render_h1, // <br>
- &abc_render_a,
- &abc_render_a_href,
-
- &abc_render_img,
+ [ABC_HTML] = &abc_render_html,
+ [ABC_HTML_TITLE] = &abc_render_title,
+ [ABC_HTML_HEAD] = &abc_render_head,
+ [ABC_HTML_BODY] = &abc_render_body,
+ [ABC_HTML_DIV] = &abc_render_div,
+
+ [ABC_HTML_H1] = &abc_render_h1,
+ [ABC_HTML_H2] = &abc_render_h1,
+ [ABC_HTML_H3] = &abc_render_h1,
+ [ABC_HTML_H4] = &abc_render_h1,
+ [ABC_HTML_H5] = &abc_render_h1,
+ [ABC_HTML_H6] = &abc_render_h1,
+
+ [ABC_HTML_P] = &abc_render_h1,
+ [ABC_HTML_BR] = &abc_render_h1,
+
+ [ABC_HTML_A] = &abc_render_a,
+ [ABC_HTML_A_HREF] = &abc_render_a_href,
+ [ABC_HTML_IMG] = &abc_render_img,
+
+ [ABC_HTML_FORM] = &abc_render_form,
+ [ABC_HTML_LABEL] = &abc_render_label,
+ [ABC_HTML_INPUT] = &abc_render_input,
};
int abc_renders_fini()
}
}
- scf_logi("-----------------\n\n");
+ scf_logd("-----------------\n\n");
return 0;
}
--- /dev/null
+#include"abc.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;
+
+
+static int _render_fini_form(abc_render_t* render)
+{
+ return 0;
+}
+
+static int _render_draw_form(abc_render_t* render, abc_obj_t* obj, int width, int height)
+{
+ if (!obj->text)
+ return 0;
+
+ 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, obj->w, obj->h, NULL);
+
+ abc_obj_t* attr;
+ cairo_text_extents_t extents;
+ cairo_surface_t* surface;
+ cairo_t* cr;
+
+ uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
+ if (!bgra)
+ return -ENOMEM;
+
+ surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4);
+ cr = cairo_create(surface);
+
+ cairo_set_line_width(cr, 1);
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, 0, obj->w, obj->h);
+ cairo_fill(cr);
+ cairo_stroke(cr);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
+ if (attr)
+ cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
+ if (attr)
+ cairo_set_font_size(cr, atoi(attr->value->data));
+
+ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_text_extents(cr, obj->text->data, &extents);
+
+ cairo_move_to (cr, extents.x_bearing, -extents.y_bearing);
+ cairo_show_text(cr, obj->text->data);
+
+// cairo_surface_write_to_png(surface, "tmp.png");
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ surface = NULL;
+ cr = NULL;
+
+ float mvp[16];
+ __compute_mvp(mvp, 0, 0, 0);
+
+ scf_logi("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
+
+ GLfloat vert_update[] =
+ {
+ 2.0 * obj->x / (float)width - 1.0,
+ -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+
+ 2.0 * (obj->x + obj->w) / (float)width - 1.0,
+ -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+
+ 2.0 * obj->x / (float)width - 1.0,
+ -2.0 * obj->y / (float)height + 1.0,
+
+ 2.0 * (obj->x + obj->w) / (float)width - 1.0,
+ -2.0 * obj->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, obj->w, obj->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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);
+
+ free(bgra);
+ return 0;
+}
+
+abc_render_t abc_render_form =
+{
+ .type = ABC_HTML_FORM,
+
+ .draw = _render_draw_form,
+ .fini = _render_fini_form,
+};
#include"abc.h"
-const char* vert_shader =
+static const char* vert_shader =
"#version 330 core\n"
"layout(location = 0) in vec4 position; \n"
"layout(location = 1) in vec2 a_texCoord; \n"
"v_texCoord = a_texCoord; \n"
"} \n";
-const char* frag_shader =
+static const char* frag_shader =
"#version 330 core\n"
"in vec2 v_texCoord; \n"
"out vec4 outputColor; \n"
--- /dev/null
+#include"abc.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;
+
+
+static int _render_fini_input(abc_render_t* render)
+{
+ return 0;
+}
+
+static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, int height)
+{
+ 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, obj->w, obj->h, NULL);
+
+ abc_obj_t* type;
+ abc_obj_t* attr;
+ cairo_text_extents_t extents;
+ cairo_surface_t* surface;
+ cairo_t* cr;
+
+ uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
+ if (!bgra)
+ return -ENOMEM;
+
+ surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4);
+ cr = cairo_create(surface);
+
+ cairo_set_line_width(cr, 1);
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, 0, obj->w, obj->h);
+ cairo_fill(cr);
+ cairo_stroke(cr);
+
+ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_set_line_width (cr, 2);
+ cairo_rectangle(cr, 2, 2, obj->w - 4, obj->h - 4);
+ cairo_stroke (cr);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
+ if (attr)
+ cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
+ if (attr)
+ cairo_set_font_size(cr, atoi(attr->value->data));
+
+ int x_cursor = 6;
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_VALUE);
+ type = abc_obj_find_attr(obj, ABC_HTML_ATTR_TYPE);
+
+ if (attr && attr->value && attr->value->len > 0) {
+
+ if (!strcmp(type->value->data, "password")) {
+
+ char* passwd = strdup(attr->value->data);
+ if (!passwd) {
+ free(bgra);
+ return -ENOMEM;
+ }
+
+ memset(passwd, '*', attr->value->len);
+
+ cairo_text_extents(cr, passwd, &extents);
+ cairo_move_to (cr, extents.x_bearing + 4, -extents.y_bearing + (obj->h - extents.height) / 2);
+ cairo_show_text(cr, passwd);
+
+ free(passwd);
+ passwd = NULL;
+ } else {
+ cairo_text_extents(cr, attr->value->data, &extents);
+ cairo_move_to (cr, extents.x_bearing + 4, -extents.y_bearing + (obj->h - extents.height) / 2);
+ cairo_show_text(cr, attr->value->data);
+ }
+ cairo_stroke(cr);
+
+ x_cursor = 6 + extents.x_bearing + extents.width;
+ }
+
+ if (obj->clicked && obj->jiffies % 72 < 36) {
+ cairo_set_line_width (cr, 1);
+
+ cairo_move_to(cr, x_cursor, 4);
+ cairo_line_to(cr, x_cursor, obj->h - 4);
+ cairo_stroke (cr);
+ }
+
+ cairo_surface_write_to_png(surface, "tmp.png");
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ surface = NULL;
+ cr = NULL;
+
+ float mvp[16];
+ __compute_mvp(mvp, 0, 0, 0);
+
+ scf_logd("x: %d, y: %d, w: %d, h: %d\n", obj->x, obj->y, obj->w, obj->h);
+
+ GLfloat vert_update[] =
+ {
+ 2.0 * obj->x / (float)width - 1.0,
+ -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+
+ 2.0 * (obj->x + obj->w) / (float)width - 1.0,
+ -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+
+ 2.0 * obj->x / (float)width - 1.0,
+ -2.0 * obj->y / (float)height + 1.0,
+
+ 2.0 * (obj->x + obj->w) / (float)width - 1.0,
+ -2.0 * obj->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, obj->w, obj->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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);
+
+ free(bgra);
+ return 0;
+}
+
+abc_render_t abc_render_input =
+{
+ .type = ABC_HTML_INPUT,
+
+ .draw = _render_draw_input,
+ .fini = _render_fini_input,
+};
--- /dev/null
+#include"abc.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;
+
+
+static int _render_fini_label(abc_render_t* render)
+{
+ return 0;
+}
+
+static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, int height)
+{
+ if (!obj->text)
+ return 0;
+
+ 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, obj->w, obj->h, NULL);
+
+ abc_obj_t* attr;
+ cairo_text_extents_t extents;
+ cairo_surface_t* surface;
+ cairo_t* cr;
+
+ uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
+ if (!bgra)
+ return -ENOMEM;
+
+ surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4);
+ cr = cairo_create(surface);
+
+ cairo_set_line_width(cr, 1);
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, 0, obj->w, obj->h);
+ cairo_fill(cr);
+ cairo_stroke(cr);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
+ if (attr)
+ cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
+ if (attr)
+ cairo_set_font_size(cr, atoi(attr->value->data));
+
+ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_text_extents(cr, obj->text->data, &extents);
+
+ cairo_move_to (cr, extents.x_bearing + 2, -extents.y_bearing + 2);
+ cairo_show_text(cr, obj->text->data);
+
+// cairo_surface_write_to_png(surface, "tmp.png");
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ surface = NULL;
+ cr = NULL;
+
+ float mvp[16];
+ __compute_mvp(mvp, 0, 0, 0);
+
+ scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
+
+ GLfloat vert_update[] =
+ {
+ 2.0 * obj->x / (float)width - 1.0,
+ -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+
+ 2.0 * (obj->x + obj->w) / (float)width - 1.0,
+ -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+
+ 2.0 * obj->x / (float)width - 1.0,
+ -2.0 * obj->y / (float)height + 1.0,
+
+ 2.0 * (obj->x + obj->w) / (float)width - 1.0,
+ -2.0 * obj->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, obj->w, obj->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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);
+
+ free(bgra);
+ return 0;
+}
+
+abc_render_t abc_render_label =
+{
+ .type = ABC_HTML_LABEL,
+
+ .draw = _render_draw_label,
+ .fini = _render_fini_label,
+};
gtk_gl_area_make_current(self);
if (gtk_gl_area_get_error(self) != NULL) {
- printf("%s(),%d, error:\n", __func__, __LINE__);
+ scf_loge("\n");
return;
}
- printf("%s(),%d, width: %d, height: %d\n", __func__, __LINE__, width, height);
+ scf_logi("width: %d, height: %d\n", width, height);
context = gtk_gl_area_get_context(self);
if (gdk_gl_context_get_use_es(context))
- printf("%s(),%d, gles\n", __func__, __LINE__);
+ scf_logi("gles\n");
else
- printf("%s(),%d, gl\n", __func__, __LINE__);
+ scf_logi("gl\n");
}
static void unrealize(GtkWidget *widget)
{
- printf("%s(),%d\n", __func__, __LINE__);
+ scf_logi("\n");
}
static gboolean render(GtkGLArea* self, GdkGLContext* context, gpointer user_data)
abc_obj_t* prev = ctx->current->current;
abc_obj_t* obj = abc_obj_find(ctx->current->root, x, y);
+ abc_obj_t* attr;
int ret = 0;
gdk_window_set_cursor(window, cursor);
g_object_unref(cursor);
+ prev->clicked = 0;
ret = 1;
}
scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
obj->key->data, obj->x, obj->y, obj->w, obj->h, x, y);
-
switch (obj->type) {
case ABC_HTML_A:
ret = 1;
break;
+
+ case ABC_HTML_INPUT:
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TYPE);
+ if (attr) {
+ if (!strcmp(attr->value->data, "text") || !strcmp(attr->value->data, "password")) {
+
+ display = gtk_widget_get_display(GTK_WIDGET(ctx->gl_area));
+ window = gtk_widget_get_window (GTK_WIDGET(ctx->gl_area));
+ cursor = gdk_cursor_new_for_display(display, GDK_XTERM);
+
+ gdk_window_set_cursor(window, cursor);
+ g_object_unref(cursor);
+ ret = 1;
+ }
+ }
+ break;
default:
break;
};
return ret;
}
-static int __do_button_release(abc_ctx_t* ctx, int x, int y)
+static int __do_button_release_a(abc_ctx_t* ctx, abc_obj_t* obj, int x, int y)
{
- abc_html_t* html;
- abc_obj_t* attr;
- abc_obj_t* obj = abc_obj_find(ctx->current->root, x, y);
+ abc_html_t* html = NULL;
+ abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HREF);
- if (!obj)
- return -ENOMEM;
+ int ret = abc_html_open(&html, attr->value->data);
+ if (ret < 0)
+ return ret;
- scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
- obj->key->data, obj->x, obj->y, obj->w, obj->h, x, y);
+ ret = abc_html_parse(html);
+ if (ret < 0) {
+ abc_html_close(html);
+ html = NULL;
+ return ret;
+ }
- int ret = 0;
+ scf_list_add_tail(&ctx->html_list, &html->list);
- if (ABC_HTML_A == obj->type) {
+ html->root->gtk_builder = ctx->builder;
- html = NULL;
- attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HREF);
+ ctx->current = html;
- ret = abc_html_open(&html, attr->value->data);
- if (ret < 0)
- return ret;
+ int width = gtk_widget_get_allocated_width (GTK_WIDGET(ctx->gl_area));
+ int height = gtk_widget_get_allocated_height(GTK_WIDGET(ctx->gl_area));
- ret = abc_html_parse(html);
- if (ret < 0) {
- abc_html_close(html);
- html = NULL;
- return ret;
- }
+ abc_layout_root(NULL, ctx->current->root, width, height);
- scf_list_add_tail(&ctx->html_list, &html->list);
+ __do_button_move(ctx, x, y);
- html->root->gtk_builder = ctx->builder;
+ gtk_widget_set_sensitive(GTK_WIDGET(ctx->back), TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(ctx->forward), FALSE);
- ctx->current = html;
+ return 1;
+}
- int width = gtk_widget_get_allocated_width (GTK_WIDGET(ctx->gl_area));
- int height = gtk_widget_get_allocated_height(GTK_WIDGET(ctx->gl_area));
+static int __do_button_release(abc_ctx_t* ctx, int x, int y)
+{
+ abc_obj_t* attr;
+ abc_obj_t* obj = abc_obj_find(ctx->current->root, x, y);
+ if (!obj)
+ return -ENOMEM;
- abc_layout_root(NULL, ctx->current->root, width, height);
+ scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
+ obj->key->data, obj->x, obj->y, obj->w, obj->h, x, y);
- __do_button_move(ctx, x, y);
+ switch (obj->type) {
- gtk_widget_set_sensitive(GTK_WIDGET(ctx->back), TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(ctx->forward), FALSE);
+ case ABC_HTML_A:
+ return __do_button_release_a(ctx, obj, x, y);
+ break;
- ret = 1;
- }
+ case ABC_HTML_INPUT:
+ obj->clicked = 1;
+ obj->jiffies = 0;
- return ret;
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_TYPE);
+
+ if (!strcmp(attr->value->data, "submit")) {
+ abc_obj_print(ctx->current->root);
+ return 0;
+ }
+
+ return __do_button_move(ctx, x, y);
+ break;
+ default:
+ break;
+ };
+
+ return 0;
}
static void back_clicked(GtkButton* self, gpointer user_data)
if (gtk_widget_get_window(GTK_WIDGET(ctx->gl_area)) == event->window) {
+ scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f\n",
+ event->x_root, event->y_root, event->x, event->y);
+
int ret = __do_button_release(ctx, event->x, event->y);
if (ret > 0)
gtk_gl_area_queue_render(ctx->gl_area);
return TRUE;
}
+static void __utf8_delete(abc_ctx_t* ctx)
+{
+ abc_obj_t* obj;
+ abc_obj_t* attr;
+
+ if (!ctx->current || !ctx->current->current)
+ return;
+
+ obj = ctx->current->current;
+ if (ABC_HTML_INPUT != obj->type)
+ return;
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TYPE);
+
+ if (!strcmp(attr->value->data, "text") || !strcmp(attr->value->data, "password")) {
+ uint8_t c;
+ int i;
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_VALUE);
+
+ for (i = attr->value->len - 1; i >= 0; i--) {
+ c = attr->value->data[i];
+
+ attr->value->data[--attr->value->len] = '\0';
+
+ if (c < 0x80)
+ break;
+
+ if ((c >> 6) != 0x2)
+ break;
+ }
+ }
+}
+
+static gboolean key_press_event(GtkWidget* self, GdkEventKey* event, gpointer user_data)
+{
+ abc_ctx_t* ctx = user_data;
+
+ scf_logi("event keyval: %c, %d\n", event->keyval, event->keyval);
+
+ switch (event->keyval) {
+ case GDK_KEY_BackSpace:
+ case GDK_KEY_Delete:
+ __utf8_delete(ctx);
+ break;
+ default:
+ break;
+ };
+
+ return gtk_im_context_filter_keypress(ctx->im, event);
+}
+
static gboolean button_move_event(GtkWidget* self, GdkEventMotion* event, gpointer user_data)
{
abc_ctx_t* ctx = user_data;
return TRUE;
}
+static gboolean timer_handler(gpointer user_data)
+{
+ abc_ctx_t* ctx = user_data;
+ abc_obj_t* obj;
+
+ if (ctx->current) {
+ obj = ctx->current->current;
+
+ if (obj) {
+ obj->jiffies++;
+ gtk_gl_area_queue_render(ctx->gl_area);
+ }
+ }
+
+ return TRUE;
+}
+
+static void im_preedit_start(GtkIMContext* self, gpointer user_data)
+{
+}
+
+static void im_preedit_end(GtkIMContext* self, gpointer user_data)
+{
+}
+
+static void im_preedit_changed(GtkIMContext* self, gpointer user_data)
+{
+}
+
+static gboolean im_retrieve_surrounding(GtkIMContext* self, gpointer user_data)
+{
+ return TRUE;
+}
+
+static gboolean im_delete_surrounding(GtkIMContext* self, gint offset, gint n_chars, gpointer user_data)
+{
+ scf_logi("offset: %d, n_chars: %d\n", offset, n_chars);
+ return TRUE;
+}
+
+static void im_commit(GtkIMContext* self, gchar* str, gpointer user_data)
+{
+ abc_ctx_t* ctx = user_data;
+ abc_obj_t* obj;
+ abc_obj_t* attr;
+
+ scf_logw("str: %s\n", str);
+
+ if (ctx->current) {
+ obj = ctx->current->current;
+
+ if (obj && ABC_HTML_INPUT == obj->type) {
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_VALUE);
+
+ scf_string_cat_cstr(attr->value, str);
+
+ gtk_gl_area_queue_render(ctx->gl_area);
+ }
+ }
+}
+
int main(int argc, char *argv[])
{
abc_ctx_t ctx = ABC_CTX_INIT(ctx);
gtk_widget_add_events(GTK_WIDGET(gl_area), GDK_POINTER_MOTION_MASK);
g_signal_connect(window, "button-release-event", G_CALLBACK(button_release_event), &ctx);
+ g_signal_connect(window, "key-press-event", G_CALLBACK(key_press_event), &ctx);
g_signal_connect(gl_area, "motion-notify-event", G_CALLBACK(button_move_event), &ctx);
+ g_timeout_add(10, timer_handler, &ctx);
+
+ ctx.im = gtk_im_multicontext_new();
+ if (!ctx.im) {
+ scf_loge("\n");
+ return -ENOMEM;
+ }
+
+ gtk_im_context_set_client_window(ctx.im, gtk_widget_get_window(GTK_WIDGET(window)));
+ gtk_im_context_focus_in (ctx.im);
+
+ g_signal_connect(ctx.im, "commit", G_CALLBACK(im_commit), &ctx);
+ g_signal_connect(ctx.im, "retrieve-surrounding", G_CALLBACK(im_preedit_changed), &ctx);
+ g_signal_connect(ctx.im, "delete-surrounding", G_CALLBACK(im_delete_surrounding), &ctx);
+ g_signal_connect(ctx.im, "preedit-changed", G_CALLBACK(im_preedit_changed), &ctx);
+ g_signal_connect(ctx.im, "preedit-start", G_CALLBACK(im_preedit_start), &ctx);
+ g_signal_connect(ctx.im, "preedit-end", G_CALLBACK(im_preedit_end), &ctx);
+
gtk_widget_show_all(GTK_WIDGET(window));
gtk_main();