static void glw_image_dtor(glw_t *w) { glw_image_t *gi = (glw_image_t *)w; rstr_release(gi->gi_pending_url); if(gi->gi_current != NULL) glw_tex_deref(w->glw_root, gi->gi_current); if(gi->gi_pending != NULL) glw_tex_deref(w->glw_root, gi->gi_pending); glw_renderer_free(&gi->gi_gr); }
static void glw_image_dtor(glw_t *w) { glw_image_t *gi = (void *)w; free(gi->gi_pending_filename); if(gi->gi_current != NULL) glw_tex_deref(w->glw_root, gi->gi_current); if(gi->gi_pending != NULL) glw_tex_deref(w->glw_root, gi->gi_pending); glw_renderer_free(&gi->gi_gr); }
static void set_source(struct glw *w, const char *str) { glw_fx_texrot_t *fx = (glw_fx_texrot_t *)w; if(fx->fx_tex != NULL) glw_tex_deref(w->glw_root, fx->fx_tex); fx->fx_tex = glw_tex_create(w->glw_root, str, 0, -1, -1); }
static void set_source(struct glw *w, rstr_t *url) { glw_fx_texrot_t *fx = (glw_fx_texrot_t *)w; if(fx->fx_tex != NULL) glw_tex_deref(w->glw_root, fx->fx_tex); fx->fx_tex = glw_tex_create(w->glw_root, url, 0, -1, -1, 0, 0, 0); }
static void glw_fx_texrot_dtor(glw_t *w) { glw_fx_texrot_t *fx = (void *)w; glw_gf_unregister(&fx->fx_flushctrl); if(fx->fx_tex != NULL) glw_tex_deref(w->glw_root, fx->fx_tex); if(fx->fx_rtt_initialized) glw_rtt_destroy(w->glw_root, &fx->fx_rtt); }
static void glw_image_set(glw_t *w, va_list ap) { glw_image_t *gi = (glw_image_t *)w; glw_attribute_t attrib; do { attrib = va_arg(ap, int); switch(attrib) { case GLW_ATTRIB_ANGLE: gi->gi_angle = va_arg(ap, double); break; case GLW_ATTRIB_SATURATION: gi->gi_saturation = va_arg(ap, double); compute_colors(gi); break; case GLW_ATTRIB_PIXMAP: if(gi->gi_pending != NULL) glw_tex_deref(w->glw_root, gi->gi_pending); free(gi->gi_pending_filename); gi->gi_pending_filename = NULL; gi->gi_pending = glw_tex_create_from_pixmap(w->glw_root, va_arg(ap, pixmap_t *)); break; case GLW_ATTRIB_ALPHA_EDGES: gi->gi_alpha_edge = va_arg(ap, int); gi->gi_mode = GI_MODE_ALPHA_EDGES; break; default: GLW_ATTRIB_CHEW(attrib, ap); break; } } while(attrib); if(w->glw_class == &glw_icon) { } }
static void glw_image_layout(glw_t *w, glw_rctx_t *rc) { glw_image_t *gi = (void *)w; glw_root_t *gr = w->glw_root; glw_loadable_texture_t *glt; glw_rctx_t rc0; glw_t *c; int hq = (w->glw_class == &glw_icon || w->glw_class == &glw_image); if(gi->gi_pending_url != NULL) { // Request to load int xs = -1, ys = -1; int flags = 0; gi->gi_loading_new_url = 1; if(gi->gi_pending != NULL) { glw_tex_deref(w->glw_root, gi->gi_pending); gi->gi_pending = NULL; } if(rstr_get(gi->gi_pending_url)[0] == 0) { // Empty string, unload all if(gi->gi_current != NULL) { glw_tex_deref(w->glw_root, gi->gi_current); gi->gi_current = NULL; } gi->gi_update = 1; } else { if(w->glw_class == &glw_repeatedimage) flags |= GLW_TEX_REPEAT; if(hq) { if(rc->rc_width < rc->rc_height) { xs = rc->rc_width; } else { ys = rc->rc_height; } } if(xs && ys) { if(w->glw_flags & GLW_DEBUG) TRACE(TRACE_DEBUG, "IMG", "Loading texture: %s", rstr_get(gi->gi_pending_url)); gi->gi_pending = glw_tex_create(w->glw_root, gi->gi_pending_url, flags, xs, ys); rstr_release(gi->gi_pending_url); gi->gi_pending_url = NULL; } } } if((glt = gi->gi_pending) != NULL) { glw_tex_layout(gr, glt); if(glw_is_tex_inited(&glt->glt_texture) || glt->glt_state == GLT_STATE_ERROR) { // Pending texture completed, ok or error: transfer to current if(gi->gi_current != NULL) glw_tex_deref(w->glw_root, gi->gi_current); gi->gi_current = gi->gi_pending; gi->gi_pending = NULL; gi->gi_update = 1; gi->gi_loading_new_url = 0; } } if((glt = gi->gi_current) == NULL) return; if(gi->gi_loading_new_url) { gi->gi_autofade = GLW_LP(8, gi->gi_autofade, 0); } else { gi->gi_autofade = GLW_LP(8, gi->gi_autofade, 1); } glw_tex_layout(gr, glt); if(glt->glt_state == GLT_STATE_ERROR) { if(!gi->gi_is_ready) { gi->gi_is_ready = 1; glw_signal0(w, GLW_SIGNAL_READINESS, NULL); } } else if(glw_is_tex_inited(&glt->glt_texture)) { int r = !gi->gi_loading_new_url; if(gi->gi_is_ready != r) { gi->gi_is_ready = r; glw_signal0(w, GLW_SIGNAL_READINESS, NULL); } if(gi->gi_update) { gi->gi_update = 0; glw_renderer_free(&gi->gi_gr); switch(gi->gi_mode) { case GI_MODE_NORMAL: glw_renderer_init_quad(&gi->gi_gr); glw_image_layout_normal(gr, rc, gi, glt); break; case GI_MODE_BORDER_SCALING: glw_renderer_init(&gi->gi_gr, 16, 18, borderobject); glw_image_layout_tesselated(gr, rc, gi, glt); break; case GI_MODE_REPEATED_TEXTURE: glw_renderer_init_quad(&gi->gi_gr); glw_image_layout_repeated(gr, rc, gi, glt); break; case GI_MODE_ALPHA_EDGES: glw_renderer_init(&gi->gi_gr, 16, 18, borderobject); glw_image_layout_alpha_edges(gr, rc, gi, glt); break; case GI_MODE_BORDER_ONLY_SCALING: glw_renderer_init(&gi->gi_gr, 16, 16, borderonlyobject); glw_image_layout_tesselated(gr, rc, gi, glt); break; default: abort(); } } else if(gi->gi_last_width != rc->rc_width || gi->gi_last_height != rc->rc_height) { gi->gi_last_width = rc->rc_width; gi->gi_last_height = rc->rc_height; switch(gi->gi_mode) { case GI_MODE_NORMAL: break; case GI_MODE_BORDER_SCALING: case GI_MODE_BORDER_ONLY_SCALING: glw_image_layout_tesselated(gr, rc, gi, glt); break; case GI_MODE_REPEATED_TEXTURE: glw_image_layout_repeated(gr, rc, gi, glt); break; case GI_MODE_ALPHA_EDGES: glw_image_layout_alpha_edges(gr, rc, gi, glt); break; } gi->gi_need_reload = hq; } if(gi->gi_need_reload && gi->gi_pending == NULL && gi->gi_pending_url == NULL && rc->rc_width && rc->rc_height) { gi->gi_need_reload = 0; int xs = -1, ys = -1, rescale; if(rc->rc_width < rc->rc_height) { rescale = rc->rc_width != glt->glt_xs; xs = rc->rc_width; } else { rescale = rc->rc_height != glt->glt_ys; ys = rc->rc_height; } if(rescale) { int flags = 0; if(w->glw_class == &glw_repeatedimage) flags |= GLW_TEX_REPEAT; gi->gi_pending = glw_tex_create(w->glw_root, glt->glt_url, flags, xs, ys); } } } else { if(gi->gi_is_ready) { gi->gi_is_ready = 0; glw_signal0(w, GLW_SIGNAL_READINESS, NULL); } } glw_image_update_constraints(gi); if((c = TAILQ_FIRST(&w->glw_childs)) != NULL) { rc0 = *rc; rc0.rc_width -= gi->gi_box_left + gi->gi_box_right; rc0.rc_height -= gi->gi_box_top + gi->gi_box_bottom; if(rc0.rc_height >= 0 && rc0.rc_width >= 0) glw_layout0(c, &rc0); } }
static void glw_image_layout(glw_t *w, glw_rctx_t *rc) { glw_image_t *gi = (void *)w; glw_root_t *gr = w->glw_root; glw_loadable_texture_t *glt; glw_rctx_t rc0; glw_t *c; if(gi->gi_pending_filename != NULL) { // Request to load int xs = -1, ys = -1; int flags = 0; if(gi->gi_pending != NULL) glw_tex_deref(w->glw_root, gi->gi_pending); if(gi->gi_pending_filename[0] == 0) { gi->gi_pending = NULL; if(gi->gi_current != NULL) { glw_tex_deref(w->glw_root, gi->gi_current); gi->gi_current = NULL; } gi->gi_update = 1; } else { if(w->glw_class == &glw_repeatedimage) flags |= GLW_TEX_REPEAT; if(gi->gi_bitmap_flags & GLW_IMAGE_HQ_SCALING) { if(rc->rc_width < rc->rc_height) { xs = rc->rc_width; } else { ys = rc->rc_height; } } if(xs && ys) { gi->gi_pending = glw_tex_create(w->glw_root, gi->gi_pending_filename, flags, xs, ys); free(gi->gi_pending_filename); gi->gi_pending_filename = NULL; } else { gi->gi_pending = NULL; } } } if((glt = gi->gi_pending) != NULL) { glw_tex_layout(gr, glt); if(glt->glt_state == GLT_STATE_VALID || glt->glt_state == GLT_STATE_ERROR) { // Pending texture completed, ok or error: transfer to current if(gi->gi_current != NULL) glw_tex_deref(w->glw_root, gi->gi_current); gi->gi_current = gi->gi_pending; gi->gi_pending = NULL; gi->gi_update = 1; } } if((glt = gi->gi_current) == NULL) return; glw_tex_layout(gr, glt); if(glt->glt_state == GLT_STATE_ERROR) { if(!gi->gi_was_valid) { glw_signal0(w, GLW_SIGNAL_READY, NULL); gi->gi_was_valid = 1; } } else if(glt->glt_state == GLT_STATE_VALID) { if(!gi->gi_was_valid) { glw_signal0(w, GLW_SIGNAL_READY, NULL); gi->gi_was_valid = 1; } if(gi->gi_update) { gi->gi_update = 0; glw_renderer_free(&gi->gi_gr); switch(gi->gi_mode) { case GI_MODE_NORMAL: glw_renderer_init_quad(&gi->gi_gr); glw_image_layout_normal(gr, rc, gi, glt); break; case GI_MODE_BORDER_SCALING: glw_renderer_init(&gi->gi_gr, 16, 18, borderobject); glw_image_layout_tesselated(gr, rc, gi, glt); break; case GI_MODE_REPEATED_TEXTURE: glw_renderer_init_quad(&gi->gi_gr); glw_image_layout_repeated(gr, rc, gi, glt); break; case GI_MODE_ALPHA_EDGES: glw_renderer_init(&gi->gi_gr, 16, 18, borderobject); glw_image_layout_alpha_edges(gr, rc, gi, glt); break; case GI_MODE_BORDER_ONLY_SCALING: glw_renderer_init(&gi->gi_gr, 16, 16, borderonlyobject); glw_image_layout_tesselated(gr, rc, gi, glt); break; default: abort(); } } else if(gi->gi_last_width != rc->rc_width || gi->gi_last_height != rc->rc_height) { gi->gi_last_width = rc->rc_width; gi->gi_last_height = rc->rc_height; switch(gi->gi_mode) { case GI_MODE_NORMAL: break; case GI_MODE_BORDER_SCALING: case GI_MODE_BORDER_ONLY_SCALING: glw_image_layout_tesselated(gr, rc, gi, glt); break; case GI_MODE_REPEATED_TEXTURE: glw_image_layout_repeated(gr, rc, gi, glt); break; case GI_MODE_ALPHA_EDGES: glw_image_layout_alpha_edges(gr, rc, gi, glt); break; } if(gi->gi_bitmap_flags & GLW_IMAGE_HQ_SCALING && gi->gi_pending == NULL && gi->gi_pending_filename == NULL && rc->rc_width && rc->rc_height) { int xs = -1, ys = -1, rescale; if(rc->rc_width < rc->rc_height) { rescale = abs(rc->rc_width - glt->glt_xs) > glt->glt_xs / 10; xs = rc->rc_width; } else { rescale = abs(rc->rc_height - glt->glt_ys) > glt->glt_ys / 10; ys = rc->rc_height; } if(rescale) { int flags = 0; if(w->glw_class == &glw_repeatedimage) flags |= GLW_TEX_REPEAT; gi->gi_pending = glw_tex_create(w->glw_root, glt->glt_filename, flags, xs, ys); } } } } glw_image_update_constraints(gi); if((c = TAILQ_FIRST(&w->glw_childs)) != NULL) { rc0 = *rc; rc0.rc_width -= gi->gi_box_left + gi->gi_box_right; rc0.rc_height -= gi->gi_box_top + gi->gi_box_bottom; if(rc0.rc_height >= 0 && rc0.rc_width >= 0) glw_layout0(c, &rc0); } }