diff --git a/Makefile.in b/Makefile.in index ce4d84d..166cf69 100644 --- a/Makefile.in +++ b/Makefile.in @@ -36,6 +36,7 @@ SOURCES= \ $(wildcard src/terminal/@OSNAME@/*.rc) \ $(wildcard src/terminal/@OSNAME@/*.c) \ $(wildcard src/terminal/properties/*.c) \ + $(wildcard src/terminal/drawing/*.c) \ $(wildcard src/terminal/font/*.c) \ $(wildcard src/filetransfer/*.c) \ $(wildcard src/selection/*.c) \ diff --git a/src/include/terminal.h b/src/include/terminal.h index 60360ec..88b18b2 100644 --- a/src/include/terminal.h +++ b/src/include/terminal.h @@ -187,6 +187,8 @@ G_BEGIN_DECLS }; + G_GNUC_INTERNAL void v3270_activate(GtkWidget *widget); + /*--[ Globals ]--------------------------------------------------------------------------------------*/ G_END_DECLS diff --git a/src/terminal/actions.c b/src/terminal/actions.c new file mode 100644 index 0000000..140df04 --- /dev/null +++ b/src/terminal/actions.c @@ -0,0 +1,69 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +LIB3270_EXPORT void v3270_disconnect(GtkWidget *widget) +{ + g_return_if_fail(GTK_IS_V3270(widget)); + v3270_disable_updates(widget); + debug("%s",__FUNCTION__); + lib3270_unselect(GTK_V3270(widget)->host); + debug("%s",__FUNCTION__); + lib3270_disconnect(GTK_V3270(widget)->host); + debug("%s",__FUNCTION__); + v3270_enable_updates(widget); + debug("%s",__FUNCTION__); +} + +LIB3270_EXPORT int v3270_reconnect(GtkWidget *widget) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL); + + return lib3270_reconnect(GTK_V3270(widget)->host,0); +} + +void v3270_activate(GtkWidget *widget) +{ + v3270 * terminal = GTK_V3270(widget); + + terminal->activity.timestamp = time(0); + + if(lib3270_is_connected(terminal->host)) + lib3270_enter(terminal->host); + else if(lib3270_get_url(terminal->host)) + v3270_reconnect(widget); + else + g_warning("Terminal widget %p activated without connection or valid url",terminal); +} + diff --git a/src/terminal/draw.c b/src/terminal/draw.c deleted file mode 100644 index c3160cf..0000000 --- a/src/terminal/draw.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como draw.c e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -#ifdef WIN32 - #include - #include - #include -#endif // WIN32 - - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - -/*--[ Implement ]------------------------------------------------------------------------------------*/ - -gboolean v3270_draw(GtkWidget * widget, cairo_t * cr) -{ - v3270 * terminal = GTK_V3270(widget); - - cairo_set_source_surface(cr,terminal->surface,0,0); - cairo_paint(cr); - - if(lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_CROSSHAIR) && (terminal->cursor.show&2)) - { - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - - gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_CROSS_HAIR); - - cairo_rectangle(cr, 0,terminal->cursor.rect.y+terminal->font.height,allocation.width,1); - cairo_fill(cr); - - cairo_rectangle(cr, terminal->cursor.rect.x,0,1,terminal->oia.rect->y-3); - cairo_fill(cr); - } - - if(terminal->cursor.show == 3) - { - cairo_set_source_surface(cr,terminal->cursor.surface,terminal->cursor.rect.x,terminal->cursor.rect.y); - - if(lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_INSERT)) - { - cairo_rectangle(cr, terminal->cursor.rect.x, - terminal->cursor.rect.y, - terminal->cursor.rect.width, - terminal->cursor.rect.height ); - } - else - { - cairo_rectangle(cr, terminal->cursor.rect.x, - terminal->cursor.rect.y+terminal->font.height, - terminal->cursor.rect.width, - terminal->font.descent ); - } - - cairo_fill(cr); - } - - return FALSE; -} - -#if( !GTK_CHECK_VERSION(3,0,0)) -gboolean v3270_expose(GtkWidget *widget, GdkEventExpose *event) -{ - cairo_t *cr = gdk_cairo_create(widget->window); - v3270_draw(widget,cr); - cairo_destroy(cr); - return FALSE; -} -#endif // GTk3 - - -static void get_element_colors(unsigned short attr, GdkRGBA **fg, GdkRGBA **bg, GdkRGBA *color) -{ - if(attr & LIB3270_ATTR_SELECTED) - { - *fg = color+V3270_COLOR_SELECTED_FG; - *bg = color+V3270_COLOR_SELECTED_BG; - } - else - { - *bg = color+((attr & 0x00F0) >> 4); - - if(attr & LIB3270_ATTR_FIELD) - *fg = color+(attr & 0x0003)+V3270_COLOR_FIELD; - else - *fg = color+(attr & 0x000F); - } -} - -void v3270_draw_element(cairo_t *cr, unsigned char chr, unsigned short attr, H3270 *session, v3270FontInfo *fontInfo, GdkRectangle *rect, GdkRGBA *color) -{ - GdkRGBA *fg; - GdkRGBA *bg; - - get_element_colors(attr,&fg,&bg,color); - v3270_draw_char(cr,chr,attr,session,fontInfo,rect,fg,bg); - - if(attr & LIB3270_ATTR_UNDERLINE) - { - cairo_scaled_font_t * font = cairo_get_scaled_font(cr); - cairo_font_extents_t extents; - double sl; - - cairo_scaled_font_extents(font,&extents); - - sl = extents.descent/3; - if(sl < 1) - sl = 1; - - gdk_cairo_set_source_rgba(cr,fg); - - cairo_rectangle(cr,rect->x,rect->y+sl+extents.ascent+(extents.descent/2),rect->width,sl); - cairo_fill(cr); - - cairo_stroke(cr); - } - -} - -void v3270_draw_text_at(cairo_t *cr, int x, int y, v3270FontInfo *font, const char *str) { - - size_t szText = strlen(str); - - if(szText == 1 && isspace(*str)) { - return; - } - - // Tem string, desenha - cairo_status_t status; - cairo_glyph_t * glyphs = NULL; - int num_glyphs = 0; - cairo_text_cluster_t * clusters = NULL; - int num_clusters = 0; - cairo_text_cluster_flags_t cluster_flags; - cairo_scaled_font_t * scaled_font = cairo_get_scaled_font(cr); - - status = cairo_scaled_font_text_to_glyphs( - scaled_font, - (double) x, (double) (y+font->height), - str, szText, - &glyphs, &num_glyphs, - &clusters, &num_clusters, &cluster_flags ); - - if (status == CAIRO_STATUS_SUCCESS) { - cairo_show_text_glyphs(cr,str,szText,glyphs, num_glyphs,clusters, num_clusters, cluster_flags); - } - - if(glyphs) - cairo_glyph_free(glyphs); - - if(clusters) - cairo_text_cluster_free(clusters); - -} - -void v3270_draw_text(cairo_t *cr, const GdkRectangle *rect, v3270FontInfo *font, const char *str) { - v3270_draw_text_at(cr,rect->x,rect->y,font,str); -} - -void v3270_draw_char(cairo_t *cr, unsigned char chr, unsigned short attr, H3270 *session, v3270FontInfo *font, GdkRectangle *rect, GdkRGBA *fg, GdkRGBA *bg) -{ - // Clear element area - gdk_cairo_set_source_rgba(cr,bg); - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); - - // Set foreground color - gdk_cairo_set_source_rgba(cr,fg); - - // Draw char - if( (attr & LIB3270_ATTR_MARKER) && lib3270_get_toggle(session,LIB3270_TOGGLE_VIEW_FIELD) ) - { - double sz = (double) rect->width; - if(rect->height < rect->width) - sz = (double) rect->height; - - cairo_save(cr); - - sz /= 10; - - cairo_translate(cr, rect->x + (rect->width / 2), rect->y + (rect->height / 2)); - cairo_scale(cr, sz, sz); - cairo_arc(cr, 0., 0., 1., 0., 2 * M_PI); - - cairo_restore(cr); - } - else if(attr & LIB3270_ATTR_CG) - { - switch(chr) - { - case 0xd3: // CG 0xab, plus - cairo_move_to(cr,rect->x+(rect->width/2),rect->y); - cairo_rel_line_to(cr,0,rect->height); - cairo_move_to(cr,rect->x,rect->y+(rect->height/2)); - cairo_rel_line_to(cr,rect->width,0); - break; - - case 0xa2: // CG 0x92, horizontal line - cairo_move_to(cr,rect->x,rect->y+(rect->height/2)); - cairo_rel_line_to(cr,rect->width,0); - break; - - case 0x85: // CG 0x184, vertical line - cairo_move_to(cr,rect->x+(rect->width/2),rect->y); - cairo_rel_line_to(cr,0,rect->height); - break; - - case 0xd4: // CG 0xac, LR corner - cairo_move_to(cr,rect->x, rect->y+(rect->height/2)); - cairo_rel_line_to(cr,rect->width/2,0); - cairo_rel_line_to(cr,0,-(rect->height/2)); - break; - - case 0xd5: // CG 0xad, UR corner - cairo_move_to(cr,rect->x, rect->y+(rect->height/2)); - cairo_rel_line_to(cr,rect->width/2,0); - cairo_rel_line_to(cr,0,rect->height/2); - break; - - case 0xc5: // CG 0xa4, UL corner - cairo_move_to(cr,rect->x+rect->width,rect->y+(rect->height/2)); - cairo_rel_line_to(cr,-(rect->width/2),0); - cairo_rel_line_to(cr,0,(rect->height/2)); - break; - - case 0xc4: // CG 0xa3, LL corner - cairo_move_to(cr,rect->x+rect->width,rect->y+(rect->height/2)); - cairo_rel_line_to(cr,-(rect->width/2),0); - cairo_rel_line_to(cr,0,-(rect->height/2)); - break; - - case 0xc6: // CG 0xa5, left tee - cairo_move_to(cr,rect->x+(rect->width/2),rect->y+(rect->height/2)); - cairo_rel_line_to(cr,rect->width/2,0); - cairo_move_to(cr,rect->x+(rect->width/2),rect->y); - cairo_rel_line_to(cr,0,rect->height); - break; - - case 0xd6: // CG 0xae, right tee - cairo_move_to(cr,rect->x+(rect->width/2),rect->y+(rect->height/2)); - cairo_rel_line_to(cr,-(rect->width/2),0); - cairo_move_to(cr,rect->x+(rect->width/2),rect->y); - cairo_rel_line_to(cr,0,rect->height); - break; - - case 0xc7: // CG 0xa6, bottom tee - cairo_move_to(cr,rect->x+(rect->width/2),rect->y+(rect->height/2)); - cairo_rel_line_to(cr,0,-(rect->height/2)); - cairo_move_to(cr,rect->x,rect->y+(rect->height/2)); - cairo_rel_line_to(cr,rect->width,0); - break; - - case 0xd7: // CG 0xaf, top tee - cairo_move_to(cr,rect->x+(rect->width/2),rect->y+(rect->height/2)); - cairo_rel_line_to(cr,0,rect->height/2); - cairo_move_to(cr,rect->x,rect->y+(rect->height/2)); - cairo_rel_line_to(cr,rect->width,0); - break; - - case 0x8c: // CG 0xf7, less or equal "≤" - v3270_draw_text(cr,rect,font,"≤"); - break; - - case 0xae: // CG 0xd9, greater or equal "≥" - v3270_draw_text(cr,rect,font,"≥"); - break; - - case 0xbe: // CG 0x3e, not equal "≠" - v3270_draw_text(cr,rect,font,"≠"); - break; - - case 0xad: // "[" - v3270_draw_text(cr,rect,font,"["); - break; - - case 0xbd: // "]" - v3270_draw_text(cr,rect,font,"]"); - break; - - default: - cairo_rectangle(cr, rect->x+1, rect->y+1, rect->width-2, rect->height-2); - } - } - else if(chr) - { - gchar *utf = g_convert((char *) &chr, 1, "UTF-8", lib3270_get_display_charset(session), NULL, NULL, NULL); - - if(utf) - { - v3270_draw_text(cr,rect,font,utf); - g_free(utf); - } - } - - cairo_stroke(cr); -} - -#if !GTK_CHECK_VERSION(2, 22, 0) -cairo_surface_t *gdk_window_create_similar_surface(GdkWindow *window, cairo_content_t content, int width, int height) -{ - cairo_t *cairoContext = gdk_cairo_create(window); - cairo_surface_t *cairoSurface = cairo_get_target(cairoContext); - cairo_surface_t *newSurface = cairo_surface_create_similar(cairoSurface, content, width, height); - cairo_destroy(cairoContext); - return newSurface; -} -#endif // GTK_CHECK_VERSION(2, 22, 0) - -/// @brief Draw terminal contents. -/// -/// @param terminal Terminal widget. -/// @param cr a cairo context. -/// @param width the width of the rectangle. -/// @param height the height of the rectangle. -/// -void v3270_redraw(v3270 *terminal, cairo_t * cr, gint width, gint height) -{ - unsigned int rows, cols, r; - GdkRectangle rect; - int addr, cursor; - - gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_BACKGROUND); - cairo_rectangle(cr, 0, 0, width, height); - cairo_fill(cr); - cairo_stroke(cr); - - lib3270_get_screen_size(terminal->host,&rows,&cols); - - memset(&rect,0,sizeof(rect)); - rect.y = terminal->font.margin.top; - rect.width = terminal->font.width; - rect.height = terminal->font.spacing; - addr = 0; - cursor = lib3270_get_cursor_address(terminal->host); - - cairo_set_scaled_font(cr,terminal->font.scaled); - - for(r = 0; r < rows; r++) - { - unsigned int c; - - rect.x = terminal->font.margin.left; - - for(c=0;c < cols;c++) - { - struct v3270_character element = { 0, 0 }; - - lib3270_get_contents(terminal->host,addr,addr,&element.chr,&element.attr); - - if(addr == cursor) - v3270_update_cursor_rect(terminal,&rect,&element); - - v3270_draw_element(cr,element.chr,element.attr,terminal->host,&terminal->font,&rect,terminal->color); - - addr++; - rect.x += rect.width; - } - - rect.y += terminal->font.spacing; - - } - - v3270_draw_oia(terminal, cr, rect.y, cols); - -} - -LIB3270_EXPORT void v3270_reload(GtkWidget *widget) -{ - v3270 * terminal = GTK_V3270(widget); - - if(!(gtk_widget_get_realized(widget) && terminal->drawing)) - return; - - gint width = gtk_widget_get_allocated_width(widget); - gint height = gtk_widget_get_allocated_height(widget); - - cairo_t * cr = cairo_create(terminal->surface); - - v3270_redraw(terminal, cr, width, height); - - cairo_destroy(cr); - - /* - v3270 * terminal = GTK_V3270(widget); - cairo_t * cr; - - - - // Create new terminal image - if(terminal->surface) - cairo_surface_destroy(terminal->surface); - - terminal->surface = (cairo_surface_t *) gdk_window_create_similar_surface(gtk_widget_get_window(widget),CAIRO_CONTENT_COLOR,width,height); - - // Update the created image - cr = cairo_create(terminal->surface); - v3270_compute_font_size(terminal, cr, width, height); - v3270_update_font_metrics(terminal, width, height); - - v3270_redraw(terminal, cr, width, height); - - cairo_destroy(cr); - */ -} - -void v3270_update_char(H3270 *session, int addr, unsigned char chr, unsigned short attr, unsigned char cursor) -{ - v3270 * terminal = GTK_V3270(lib3270_get_user_data(session)); - cairo_t * cr; - GdkRectangle rect; - unsigned int rows,cols; - struct v3270_character element; - - element.chr = chr; - element.attr = attr; - - if(!(gtk_widget_get_realized(GTK_WIDGET(terminal)) && terminal->drawing)) - return; - - if(!terminal->surface) - { - v3270_reload(GTK_WIDGET(terminal)); - gtk_widget_queue_draw(GTK_WIDGET(terminal)); - return; - } - - lib3270_get_screen_size(terminal->host,&rows,&cols); - - memset(&rect,0,sizeof(rect)); - rect.x = terminal->font.margin.left + ((addr % cols) * terminal->font.width); - rect.y = terminal->font.margin.top + ((addr / cols) * terminal->font.spacing); - rect.width = terminal->font.width; - rect.height = terminal->font.spacing; - - cr = cairo_create(terminal->surface); - cairo_set_scaled_font(cr,terminal->font.scaled); - v3270_draw_element(cr, chr, attr, terminal->host, &terminal->font, &rect,terminal->color); - cairo_destroy(cr); - - if(cursor) - v3270_update_cursor_rect(terminal,&rect,&element); - - v3270_queue_draw_area(GTK_WIDGET(terminal),rect.x,rect.y,rect.width,rect.height); - -} - -void v3270_update_cursor_surface(v3270 *widget,unsigned char chr,unsigned short attr) -{ - if(widget->cursor.surface && widget->drawing) - { - GdkRectangle rect = widget->cursor.rect; - cairo_t * cr = cairo_create(widget->cursor.surface); - GdkRGBA * fg; - GdkRGBA * bg; - - get_element_colors(attr,&fg,&bg,widget->color); - - cairo_set_scaled_font(cr,widget->font.scaled); - - rect.x = 0; - rect.y = 0; - v3270_draw_char(cr,chr,attr,widget->host,&widget->font,&rect,bg,fg); - - cairo_destroy(cr); - } - - -} - -void v3270_update_cursor_rect(v3270 *widget, GdkRectangle *rect, const struct v3270_character *element) -{ - widget->cursor.chr = element->chr; - widget->cursor.rect = *rect; - widget->cursor.attr = element->attr; - widget->cursor.rect.height = widget->font.height + widget->font.descent; - v3270_update_cursor_surface(widget,element->chr,element->attr); -} - -void v3270_queue_draw_area(GtkWidget *widget, gint x, gint y, gint width, gint height) -{ - - if(GTK_V3270(widget)->drawing && gtk_widget_get_realized(widget)) - { - gtk_widget_queue_draw_area(widget,x,y,width,height); - } - -} - -void v3270_disable_updates(GtkWidget *widget) -{ - GTK_V3270(widget)->drawing = 0; -} - -void v3270_enable_updates(GtkWidget *widget) -{ - if(gtk_widget_get_realized(widget)) - { - GTK_V3270(widget)->drawing = 1; - v3270_reload(widget); - gtk_widget_queue_draw(widget); - } -} diff --git a/src/terminal/drawing/draw.c b/src/terminal/drawing/draw.c new file mode 100644 index 0000000..35135ad --- /dev/null +++ b/src/terminal/drawing/draw.c @@ -0,0 +1,553 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como draw.c e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + /* +#ifdef WIN32 + #include + #include + #include +#endif // WIN32 +*/ + + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +void v3270_cursor_draw(v3270 *widget) +{ + int pos = lib3270_get_cursor_address(widget->host); + unsigned char c; + unsigned short attr; + + lib3270_get_contents(widget->host,pos,pos,&c,&attr); + v3270_update_cursor_surface(widget,c,attr); + v3270_queue_draw_area( GTK_WIDGET(widget), + widget->cursor.rect.x,widget->cursor.rect.y, + widget->cursor.rect.width,widget->cursor.rect.height); + +} + +gboolean v3270_draw(GtkWidget * widget, cairo_t * cr) +{ + v3270 * terminal = GTK_V3270(widget); + + cairo_set_source_surface(cr,terminal->surface,0,0); + cairo_paint(cr); + + if(lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_CROSSHAIR) && (terminal->cursor.show&2)) + { + GtkAllocation allocation; + gtk_widget_get_allocation(widget, &allocation); + + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_CROSS_HAIR); + + cairo_rectangle(cr, 0,terminal->cursor.rect.y+terminal->font.height,allocation.width,1); + cairo_fill(cr); + + cairo_rectangle(cr, terminal->cursor.rect.x,0,1,terminal->oia.rect->y-3); + cairo_fill(cr); + } + + if(terminal->cursor.show == 3) + { + cairo_set_source_surface(cr,terminal->cursor.surface,terminal->cursor.rect.x,terminal->cursor.rect.y); + + if(lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_INSERT)) + { + cairo_rectangle(cr, terminal->cursor.rect.x, + terminal->cursor.rect.y, + terminal->cursor.rect.width, + terminal->cursor.rect.height ); + } + else + { + cairo_rectangle(cr, terminal->cursor.rect.x, + terminal->cursor.rect.y+terminal->font.height, + terminal->cursor.rect.width, + terminal->font.descent ); + } + + cairo_fill(cr); + } + + return FALSE; +} + +#if( !GTK_CHECK_VERSION(3,0,0)) +gboolean v3270_expose(GtkWidget *widget, GdkEventExpose *event) +{ + cairo_t *cr = gdk_cairo_create(widget->window); + v3270_draw(widget,cr); + cairo_destroy(cr); + return FALSE; +} +#endif // GTk3 + + +static void get_element_colors(unsigned short attr, GdkRGBA **fg, GdkRGBA **bg, GdkRGBA *color) +{ + if(attr & LIB3270_ATTR_SELECTED) + { + *fg = color+V3270_COLOR_SELECTED_FG; + *bg = color+V3270_COLOR_SELECTED_BG; + } + else + { + *bg = color+((attr & 0x00F0) >> 4); + + if(attr & LIB3270_ATTR_FIELD) + *fg = color+(attr & 0x0003)+V3270_COLOR_FIELD; + else + *fg = color+(attr & 0x000F); + } +} + +void v3270_draw_element(cairo_t *cr, unsigned char chr, unsigned short attr, H3270 *session, v3270FontInfo *fontInfo, GdkRectangle *rect, GdkRGBA *color) +{ + GdkRGBA *fg; + GdkRGBA *bg; + + get_element_colors(attr,&fg,&bg,color); + v3270_draw_char(cr,chr,attr,session,fontInfo,rect,fg,bg); + + if(attr & LIB3270_ATTR_UNDERLINE) + { + cairo_scaled_font_t * font = cairo_get_scaled_font(cr); + cairo_font_extents_t extents; + double sl; + + cairo_scaled_font_extents(font,&extents); + + sl = extents.descent/3; + if(sl < 1) + sl = 1; + + gdk_cairo_set_source_rgba(cr,fg); + + cairo_rectangle(cr,rect->x,rect->y+sl+extents.ascent+(extents.descent/2),rect->width,sl); + cairo_fill(cr); + + cairo_stroke(cr); + } + +} + +void v3270_draw_text_at(cairo_t *cr, int x, int y, v3270FontInfo *font, const char *str) { + + size_t szText = strlen(str); + + if(szText == 1 && isspace(*str)) { + return; + } + + // Tem string, desenha + cairo_status_t status; + cairo_glyph_t * glyphs = NULL; + int num_glyphs = 0; + cairo_text_cluster_t * clusters = NULL; + int num_clusters = 0; + cairo_text_cluster_flags_t cluster_flags; + cairo_scaled_font_t * scaled_font = cairo_get_scaled_font(cr); + + status = cairo_scaled_font_text_to_glyphs( + scaled_font, + (double) x, (double) (y+font->height), + str, szText, + &glyphs, &num_glyphs, + &clusters, &num_clusters, &cluster_flags ); + + if (status == CAIRO_STATUS_SUCCESS) { + cairo_show_text_glyphs(cr,str,szText,glyphs, num_glyphs,clusters, num_clusters, cluster_flags); + } + + if(glyphs) + cairo_glyph_free(glyphs); + + if(clusters) + cairo_text_cluster_free(clusters); + +} + +void v3270_draw_text(cairo_t *cr, const GdkRectangle *rect, v3270FontInfo *font, const char *str) { + v3270_draw_text_at(cr,rect->x,rect->y,font,str); +} + +void v3270_draw_char(cairo_t *cr, unsigned char chr, unsigned short attr, H3270 *session, v3270FontInfo *font, GdkRectangle *rect, GdkRGBA *fg, GdkRGBA *bg) +{ + // Clear element area + gdk_cairo_set_source_rgba(cr,bg); + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); + + // Set foreground color + gdk_cairo_set_source_rgba(cr,fg); + + // Draw char + if( (attr & LIB3270_ATTR_MARKER) && lib3270_get_toggle(session,LIB3270_TOGGLE_VIEW_FIELD) ) + { + double sz = (double) rect->width; + if(rect->height < rect->width) + sz = (double) rect->height; + + cairo_save(cr); + + sz /= 10; + + cairo_translate(cr, rect->x + (rect->width / 2), rect->y + (rect->height / 2)); + cairo_scale(cr, sz, sz); + cairo_arc(cr, 0., 0., 1., 0., 2 * M_PI); + + cairo_restore(cr); + } + else if(attr & LIB3270_ATTR_CG) + { + switch(chr) + { + case 0xd3: // CG 0xab, plus + cairo_move_to(cr,rect->x+(rect->width/2),rect->y); + cairo_rel_line_to(cr,0,rect->height); + cairo_move_to(cr,rect->x,rect->y+(rect->height/2)); + cairo_rel_line_to(cr,rect->width,0); + break; + + case 0xa2: // CG 0x92, horizontal line + cairo_move_to(cr,rect->x,rect->y+(rect->height/2)); + cairo_rel_line_to(cr,rect->width,0); + break; + + case 0x85: // CG 0x184, vertical line + cairo_move_to(cr,rect->x+(rect->width/2),rect->y); + cairo_rel_line_to(cr,0,rect->height); + break; + + case 0xd4: // CG 0xac, LR corner + cairo_move_to(cr,rect->x, rect->y+(rect->height/2)); + cairo_rel_line_to(cr,rect->width/2,0); + cairo_rel_line_to(cr,0,-(rect->height/2)); + break; + + case 0xd5: // CG 0xad, UR corner + cairo_move_to(cr,rect->x, rect->y+(rect->height/2)); + cairo_rel_line_to(cr,rect->width/2,0); + cairo_rel_line_to(cr,0,rect->height/2); + break; + + case 0xc5: // CG 0xa4, UL corner + cairo_move_to(cr,rect->x+rect->width,rect->y+(rect->height/2)); + cairo_rel_line_to(cr,-(rect->width/2),0); + cairo_rel_line_to(cr,0,(rect->height/2)); + break; + + case 0xc4: // CG 0xa3, LL corner + cairo_move_to(cr,rect->x+rect->width,rect->y+(rect->height/2)); + cairo_rel_line_to(cr,-(rect->width/2),0); + cairo_rel_line_to(cr,0,-(rect->height/2)); + break; + + case 0xc6: // CG 0xa5, left tee + cairo_move_to(cr,rect->x+(rect->width/2),rect->y+(rect->height/2)); + cairo_rel_line_to(cr,rect->width/2,0); + cairo_move_to(cr,rect->x+(rect->width/2),rect->y); + cairo_rel_line_to(cr,0,rect->height); + break; + + case 0xd6: // CG 0xae, right tee + cairo_move_to(cr,rect->x+(rect->width/2),rect->y+(rect->height/2)); + cairo_rel_line_to(cr,-(rect->width/2),0); + cairo_move_to(cr,rect->x+(rect->width/2),rect->y); + cairo_rel_line_to(cr,0,rect->height); + break; + + case 0xc7: // CG 0xa6, bottom tee + cairo_move_to(cr,rect->x+(rect->width/2),rect->y+(rect->height/2)); + cairo_rel_line_to(cr,0,-(rect->height/2)); + cairo_move_to(cr,rect->x,rect->y+(rect->height/2)); + cairo_rel_line_to(cr,rect->width,0); + break; + + case 0xd7: // CG 0xaf, top tee + cairo_move_to(cr,rect->x+(rect->width/2),rect->y+(rect->height/2)); + cairo_rel_line_to(cr,0,rect->height/2); + cairo_move_to(cr,rect->x,rect->y+(rect->height/2)); + cairo_rel_line_to(cr,rect->width,0); + break; + + case 0x8c: // CG 0xf7, less or equal "≤" + v3270_draw_text(cr,rect,font,"≤"); + break; + + case 0xae: // CG 0xd9, greater or equal "≥" + v3270_draw_text(cr,rect,font,"≥"); + break; + + case 0xbe: // CG 0x3e, not equal "≠" + v3270_draw_text(cr,rect,font,"≠"); + break; + + case 0xad: // "[" + v3270_draw_text(cr,rect,font,"["); + break; + + case 0xbd: // "]" + v3270_draw_text(cr,rect,font,"]"); + break; + + default: + cairo_rectangle(cr, rect->x+1, rect->y+1, rect->width-2, rect->height-2); + } + } + else if(chr) + { + gchar *utf = g_convert((char *) &chr, 1, "UTF-8", lib3270_get_display_charset(session), NULL, NULL, NULL); + + if(utf) + { + v3270_draw_text(cr,rect,font,utf); + g_free(utf); + } + } + + cairo_stroke(cr); +} + +#if !GTK_CHECK_VERSION(2, 22, 0) +cairo_surface_t *gdk_window_create_similar_surface(GdkWindow *window, cairo_content_t content, int width, int height) +{ + cairo_t *cairoContext = gdk_cairo_create(window); + cairo_surface_t *cairoSurface = cairo_get_target(cairoContext); + cairo_surface_t *newSurface = cairo_surface_create_similar(cairoSurface, content, width, height); + cairo_destroy(cairoContext); + return newSurface; +} +#endif // GTK_CHECK_VERSION(2, 22, 0) + +/// @brief Draw terminal contents. +/// +/// @param terminal Terminal widget. +/// @param cr a cairo context. +/// @param width the width of the rectangle. +/// @param height the height of the rectangle. +/// +void v3270_redraw(v3270 *terminal, cairo_t * cr, gint width, gint height) +{ + unsigned int rows, cols, r; + GdkRectangle rect; + int addr, cursor; + + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_BACKGROUND); + cairo_rectangle(cr, 0, 0, width, height); + cairo_fill(cr); + cairo_stroke(cr); + + lib3270_get_screen_size(terminal->host,&rows,&cols); + + memset(&rect,0,sizeof(rect)); + rect.y = terminal->font.margin.top; + rect.width = terminal->font.width; + rect.height = terminal->font.spacing; + addr = 0; + cursor = lib3270_get_cursor_address(terminal->host); + + cairo_set_scaled_font(cr,terminal->font.scaled); + + for(r = 0; r < rows; r++) + { + unsigned int c; + + rect.x = terminal->font.margin.left; + + for(c=0;c < cols;c++) + { + struct v3270_character element = { 0, 0 }; + + lib3270_get_contents(terminal->host,addr,addr,&element.chr,&element.attr); + + if(addr == cursor) + v3270_update_cursor_rect(terminal,&rect,&element); + + v3270_draw_element(cr,element.chr,element.attr,terminal->host,&terminal->font,&rect,terminal->color); + + addr++; + rect.x += rect.width; + } + + rect.y += terminal->font.spacing; + + } + + v3270_draw_oia(terminal, cr, rect.y, cols); + +} + +LIB3270_EXPORT void v3270_reload(GtkWidget *widget) +{ + v3270 * terminal = GTK_V3270(widget); + + if(!(gtk_widget_get_realized(widget) && terminal->drawing)) + return; + + gint width = gtk_widget_get_allocated_width(widget); + gint height = gtk_widget_get_allocated_height(widget); + + cairo_t * cr = cairo_create(terminal->surface); + + v3270_redraw(terminal, cr, width, height); + + cairo_destroy(cr); + + /* + v3270 * terminal = GTK_V3270(widget); + cairo_t * cr; + + + + // Create new terminal image + if(terminal->surface) + cairo_surface_destroy(terminal->surface); + + terminal->surface = (cairo_surface_t *) gdk_window_create_similar_surface(gtk_widget_get_window(widget),CAIRO_CONTENT_COLOR,width,height); + + // Update the created image + cr = cairo_create(terminal->surface); + v3270_compute_font_size(terminal, cr, width, height); + v3270_update_font_metrics(terminal, width, height); + + v3270_redraw(terminal, cr, width, height); + + cairo_destroy(cr); + */ +} + +void v3270_update_char(H3270 *session, int addr, unsigned char chr, unsigned short attr, unsigned char cursor) +{ + v3270 * terminal = GTK_V3270(lib3270_get_user_data(session)); + cairo_t * cr; + GdkRectangle rect; + unsigned int rows,cols; + struct v3270_character element; + + element.chr = chr; + element.attr = attr; + + if(!(gtk_widget_get_realized(GTK_WIDGET(terminal)) && terminal->drawing)) + return; + + if(!terminal->surface) + { + v3270_reload(GTK_WIDGET(terminal)); + gtk_widget_queue_draw(GTK_WIDGET(terminal)); + return; + } + + lib3270_get_screen_size(terminal->host,&rows,&cols); + + memset(&rect,0,sizeof(rect)); + rect.x = terminal->font.margin.left + ((addr % cols) * terminal->font.width); + rect.y = terminal->font.margin.top + ((addr / cols) * terminal->font.spacing); + rect.width = terminal->font.width; + rect.height = terminal->font.spacing; + + cr = cairo_create(terminal->surface); + cairo_set_scaled_font(cr,terminal->font.scaled); + v3270_draw_element(cr, chr, attr, terminal->host, &terminal->font, &rect,terminal->color); + cairo_destroy(cr); + + if(cursor) + v3270_update_cursor_rect(terminal,&rect,&element); + + v3270_queue_draw_area(GTK_WIDGET(terminal),rect.x,rect.y,rect.width,rect.height); + +} + +void v3270_update_cursor_surface(v3270 *widget,unsigned char chr,unsigned short attr) +{ + if(widget->cursor.surface && widget->drawing) + { + GdkRectangle rect = widget->cursor.rect; + cairo_t * cr = cairo_create(widget->cursor.surface); + GdkRGBA * fg; + GdkRGBA * bg; + + get_element_colors(attr,&fg,&bg,widget->color); + + cairo_set_scaled_font(cr,widget->font.scaled); + + rect.x = 0; + rect.y = 0; + v3270_draw_char(cr,chr,attr,widget->host,&widget->font,&rect,bg,fg); + + cairo_destroy(cr); + } + + +} + +void v3270_update_cursor_rect(v3270 *widget, GdkRectangle *rect, const struct v3270_character *element) +{ + widget->cursor.chr = element->chr; + widget->cursor.rect = *rect; + widget->cursor.attr = element->attr; + widget->cursor.rect.height = widget->font.height + widget->font.descent; + v3270_update_cursor_surface(widget,element->chr,element->attr); +} + +void v3270_queue_draw_area(GtkWidget *widget, gint x, gint y, gint width, gint height) +{ + + if(GTK_V3270(widget)->drawing && gtk_widget_get_realized(widget)) + { + gtk_widget_queue_draw_area(widget,x,y,width,height); + } + +} + +void v3270_disable_updates(GtkWidget *widget) +{ + GTK_V3270(widget)->drawing = 0; +} + +void v3270_enable_updates(GtkWidget *widget) +{ + if(gtk_widget_get_realized(widget)) + { + GTK_V3270(widget)->drawing = 1; + v3270_reload(widget); + gtk_widget_queue_draw(widget); + } +} diff --git a/src/terminal/drawing/oia.c b/src/terminal/drawing/oia.c new file mode 100644 index 0000000..6e630cd --- /dev/null +++ b/src/terminal/drawing/oia.c @@ -0,0 +1,1170 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como oia.c e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + + #define ENABLE_NLS + #define GETTEXT_PACKAGE PACKAGE_NAME + + #include + #include + #include + + /* + #ifdef WIN32 + #include + #include + #include + #endif // WIN32 + */ + + #include + #include + #include + #include + #include + #include + #include + #include + + #ifdef HAVE_LIBM + #include + #endif // HAVE_LIBM + + #include + #include + #include + #include + +/*--[ Prototipes ]-----------------------------------------------------------------------------------*/ + +static void draw_cursor_position(cairo_t *cr, GdkRectangle *rect, v3270FontInfo *metrics, int row, int col); + +/*--[ Statics ]--------------------------------------------------------------------------------------*/ + + #include "xbm/locked.xbm" + #include "xbm/unlocked.xbm" + #include "xbm/negotiated.xbm" + #include "xbm/warning.xbm" + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +static void short2string(char *ptr, unsigned short vlr, size_t sz) +{ + int f; + + for(f=sz-1;f>=0;f--) + { + ptr[f] = '0'+(vlr%10); + vlr /= 10; + } +} + + +#ifdef HAVE_LIBM +static gint draw_spinner(cairo_t *cr, GdkRectangle *r, GdkRGBA *color, gint step) +{ + static const guint num_steps = 10; + + gdouble dx = r->width/2; + gdouble dy = r->height/2; + gdouble radius = MIN (r->width / 2, r->height / 2); + gdouble half = num_steps / 2; + gint i; + + cairo_save(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + + cairo_rectangle(cr, r->x, r->y, r->width, r->height); + cairo_clip(cr); + cairo_translate(cr, r->x, r->y); + + step++; + step %= num_steps; + +// debug("%s step=%d",__FUNCTION__,step); + + for (i = 0; i < ((gint) num_steps); i++) + { + gint inset = 0.7 * radius; + + /* transparency is a function of time and intial value */ + gdouble t = (gdouble) ((i + num_steps - step) % num_steps) / num_steps; + + cairo_save(cr); + + cairo_set_source_rgba (cr, + color[V3270_COLOR_OIA_SPINNER].red, + color[V3270_COLOR_OIA_SPINNER].green, + color[V3270_COLOR_OIA_SPINNER].blue, + t); + + cairo_set_line_width (cr, 2.0); + cairo_move_to (cr, + dx + (radius - inset) * cos (i * G_PI / half), + dy + (radius - inset) * sin (i * G_PI / half)); + cairo_line_to (cr, + dx + radius * cos (i * G_PI / half), + dy + radius * sin (i * G_PI / half)); + cairo_stroke (cr); + + cairo_restore (cr); + } + + cairo_restore(cr); + + return step; +} +#endif // HAVE_LIBM + +static void setup_cursor_position(GdkRectangle *rect, v3270FontInfo *metrics, cairo_t *cr, H3270 *host, int cols, G_GNUC_UNUSED GdkRGBA *color) +{ + rect->width = metrics->width * 8; + rect->x -= rect->width; + + if(lib3270_get_toggle(host,LIB3270_TOGGLE_CURSOR_POS)) + { + int addr = lib3270_get_cursor_address(host); + draw_cursor_position(cr,rect,metrics,addr/cols,addr%cols); + } +} + +static void setup_ticking_position(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) +{ + char buffer[7]; + cairo_text_extents_t extents; + + short2string(buffer,0,2); + buffer[2] = ':'; + short2string(buffer+3,0,2); + buffer[5] = 0; + + cairo_text_extents(cr,buffer,&extents); + rect->width = ((int) extents.width + 2); + rect->x -= rect->width; +} + +static void setup_spinner_position(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, G_GNUC_UNUSED cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) +{ + rect->width = rect->height; + rect->x -= rect->width; +// draw_spinner(cr,rect,color,0); +} + +static void setup_luname_position(GdkRectangle *rect, v3270FontInfo *font, cairo_t *cr, H3270 *host, G_GNUC_UNUSED int cols, GdkRGBA *color) +{ + const char *luname = lib3270_get_luname(host); + + rect->width *= 16; + rect->x -= rect->width; + + cairo_save(cr); + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_clip(cr); + +#ifdef DEBUG + cairo_set_source_rgb(cr,0.1,0.1,0.1); +#else + gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_BACKGROUND); +#endif + + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); + + if(luname) + { + gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_LUNAME); + v3270_draw_text(cr,rect,font,luname); + } + + cairo_restore(cr); + +} + +static void setup_single_char_right(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, G_GNUC_UNUSED cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) +{ + rect->x -= rect->width; + + /* +#ifdef DEBUG + cairo_set_source_rgb(cr,0.1,0.1,0.1); + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); +#endif +*/ + +} + +static void setup_insert_position(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) +{ + if(rect->width > rect->height) + { + rect->width = rect->height; + } + else if(rect->height > rect->width) + { + rect->y += (rect->height - rect->width)/2; + rect->height = rect->width; + } + + rect->x -= rect->width; + +#ifdef DEBUG + cairo_set_source_rgb(cr,0.1,0.1,0.1); + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); +#endif + +} + + + +static void setup_double_char_position(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) +{ + rect->width <<= 1; + rect->x -= rect->width; + +#ifdef DEBUG + cairo_set_source_rgb(cr,0.1,0.1,0.1); + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); +#endif + +} + +static int draw_centered_char(cairo_t *cr, v3270FontInfo *metrics, int x, int y, const gchar chr) +{ + char str[2] = { chr, 0 }; +// cairo_text_extents_t extents; + + cairo_set_scaled_font(cr,metrics->scaled); +// cairo_text_extents(cr,str,&extents); + + v3270_draw_text_at(cr, x, y, metrics, str); + + return y+metrics->height+2; + +} + +static void draw_undera(cairo_t *cr, H3270 *host, v3270FontInfo *metrics, GdkRGBA *color, GdkRectangle *rect) +{ + gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_BACKGROUND); + + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); + + if(lib3270_get_undera(host)) + { + int y; + + gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_FOREGROUND); + + y = draw_centered_char(cr, metrics,rect->x,rect->y, lib3270_in_e(host) ? 'B' : 'A'); + + cairo_move_to(cr,rect->x,y); + cairo_rel_line_to(cr,10,0); + cairo_stroke(cr); + + } +// debug("%s",__FUNCTION__); + +} + +void v3270_draw_connection(cairo_t *cr, H3270 *host, v3270FontInfo *metrics, GdkRGBA *color, const GdkRectangle *rect) +{ + gchar str = ' '; + + gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_BACKGROUND); + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); + + gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_FOREGROUND); + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_stroke(cr); + + if(lib3270_get_oia_box_solid(host)) + { + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); + return; + } + + if(lib3270_in_ansi(host)) + str = 'N'; + else if(lib3270_in_sscp(host)) + str = 'S'; + else + str = '?'; + + draw_centered_char(cr,metrics,rect->x,rect->y,str); + +} + +static void draw_xbm(cairo_t *cr, GdkRectangle *rect, int width, int height, unsigned char *bits) +{ + double sz = rect->width < rect->height ? rect->width : rect->height; + cairo_surface_t * icon = cairo_image_surface_create_for_data( + bits, + CAIRO_FORMAT_A1, + width,height, + cairo_format_stride_for_width(CAIRO_FORMAT_A1,width)); + + cairo_save(cr); + + cairo_scale(cr, sz / ((double) width), + sz / ((double) height)); + + cairo_mask_surface(cr,icon,(rect->width-sz)/2,(rect->height-sz)/2); + + cairo_surface_destroy(icon); + + cairo_restore(cr); +} + +void v3270_draw_ssl_status(v3270 *widget, cairo_t *cr, GdkRectangle *rect) +{ + gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_BACKGROUND); + + cairo_translate(cr, rect->x, rect->y); + cairo_rectangle(cr, 0, 0, rect->width, rect->height); + cairo_fill(cr); + + switch(lib3270_get_ssl_state(widget->host)) + { + case LIB3270_SSL_UNDEFINED: // Undefined. + break; + + case LIB3270_SSL_UNSECURE: // No secure connection + gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_FOREGROUND); + draw_xbm(cr,rect,unlocked_width,unlocked_height,unlocked_bits); + break; + + case LIB3270_SSL_NEGOTIATING: // Negotiating SSL + if(widget->blink.show) + { + gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_STATUS_WARNING); + draw_xbm(cr,rect,negotiated_width,negotiated_height,negotiated_bits); + } + break; + + case LIB3270_SSL_NEGOTIATED: // Connection secure, no CA, self-signed or expired CRL + gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_STATUS_OK); + draw_xbm(cr,rect,locked_width,locked_height,locked_bits); + gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_STATUS_WARNING); + draw_xbm(cr,rect,warning_width,warning_height,warning_bits); + break; + + case LIB3270_SSL_SECURE: // Connection secure with CA check + gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_STATUS_OK); + draw_xbm(cr,rect,locked_width,locked_height,locked_bits); + break; + + } + + +} + +static void draw_status_message(cairo_t *cr, LIB3270_MESSAGE id, v3270FontInfo *font, GdkRGBA *color, const GdkRectangle *r) +{ + #ifdef DEBUG + #define OIA_MESSAGE(x,c,y) { #x, c, y } + #else + #define OIA_MESSAGE(x,c,y) { c, y } + #endif + + static const struct _message + { + #ifdef DEBUG + const gchar * dbg; + #endif + enum V3270_COLOR + color; + const gchar * msg; + } message[] = + { + OIA_MESSAGE( LIB3270_MESSAGE_NONE, + V3270_COLOR_OIA_STATUS_OK, + NULL ), + + OIA_MESSAGE( LIB3270_MESSAGE_SYSWAIT, + V3270_COLOR_OIA_STATUS_OK, + N_( "X System" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_TWAIT, + V3270_COLOR_OIA_STATUS_OK, + N_( "X Wait" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_CONNECTED, + V3270_COLOR_OIA_STATUS_OK, + NULL ), + + OIA_MESSAGE( LIB3270_MESSAGE_DISCONNECTED, + V3270_COLOR_OIA_STATUS_INVALID, + N_( "X Not Connected" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_AWAITING_FIRST, + V3270_COLOR_OIA_STATUS_OK, + N_( "X" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_MINUS, + V3270_COLOR_OIA_STATUS_OK, + N_( "X -f" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_PROTECTED, + V3270_COLOR_OIA_STATUS_INVALID, + N_( "X Protected" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_NUMERIC, + V3270_COLOR_OIA_STATUS_INVALID, + N_( "X Numeric" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_OVERFLOW, + V3270_COLOR_OIA_STATUS_INVALID, + N_( "X Overflow" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_INHIBIT, + V3270_COLOR_OIA_STATUS_INVALID, + N_( "X Inhibit" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_KYBDLOCK, + V3270_COLOR_OIA_STATUS_INVALID, + N_( "X") ), + + OIA_MESSAGE( LIB3270_MESSAGE_X, + V3270_COLOR_OIA_STATUS_INVALID, + N_( "X" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_RESOLVING, + V3270_COLOR_OIA_STATUS_WARNING, + N_( "X Resolving" ) ), + + OIA_MESSAGE( LIB3270_MESSAGE_CONNECTING, + V3270_COLOR_OIA_STATUS_WARNING, + N_( "X Connecting" ) ), + + + }; + + GdkRectangle rect; + const gchar * msg = message[0].msg; + + memcpy(&rect,r,sizeof(GdkRectangle)); + + if(id >= 0 && id < G_N_ELEMENTS(message)) + { + msg = message[id].msg; +#ifdef DEBUG + if(!msg) + msg = message[id].dbg; +#endif // DEBUG + } + + // Limpa o bloco + gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_BACKGROUND); + cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height); + cairo_fill(cr); + + if(msg && *msg) + { + msg = gettext(msg); + } + + if(msg && *msg) + { + rect.x++; + +// debug("%s(%s)",__FUNCTION__,msg); + + gdk_cairo_set_source_rgba(cr,color+message[id].color); + + if(*msg == 'X') + { + cairo_save(cr); + + cairo_move_to(cr,rect.x+1,rect.y+(font->height)-(font->ascent)); + cairo_rel_line_to(cr,font->width,font->ascent); + cairo_rel_move_to(cr,-font->width,0); + cairo_rel_line_to(cr,font->width,-font->ascent); + + cairo_stroke(cr); + rect.x += font->width; + msg++; + + cairo_restore(cr); + } + + while(isspace(*msg)) + { + msg++; + rect.x += font->width; + } + + if(*msg) + { + v3270_draw_text(cr,&rect, font, msg); +// cairo_move_to(cr,x,rect->y+metrics->height); +// cairo_show_text(cr,msg); + } + + } + +} + +static void draw_insert(cairo_t *cr, H3270 *host, GdkRGBA *color, GdkRectangle *rect) +{ + if(lib3270_get_toggle(host,LIB3270_TOGGLE_INSERT)) + { + double y = rect->y+(rect->height-2); + + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_clip(cr); + + gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_FOREGROUND); + + cairo_move_to(cr,rect->x,y); + cairo_rel_line_to(cr,rect->width/2,-(rect->height/1.7)); + cairo_line_to(cr,rect->x+rect->width,y); + cairo_stroke(cr); + } + +} + +// v3270_draw_oia(cr, terminal->host, rect.y, cols, &terminal->font, terminal->color,terminal->oia_rect); +// void v3270_draw_oia(cairo_t *cr, H3270 *host, int row, int cols, v3270FontInfo *metrics, GdkRGBA *color, GdkRectangle *rect) + +void v3270_draw_oia(v3270 *terminal, cairo_t *cr, int row, int cols) +{ + static const struct _right_fields + { + V3270_OIA_FIELD id; + void (*draw)(GdkRectangle *rect, v3270FontInfo *metrics, cairo_t *cr, H3270 *host, int cols, GdkRGBA *color); + } right[] = + { + { V3270_OIA_CURSOR_POSITION, setup_cursor_position }, + { V3270_OIA_TIMER, setup_ticking_position }, + { V3270_OIA_SPINNER, setup_spinner_position }, + { V3270_OIA_LUNAME, setup_luname_position }, +#ifdef HAVE_PRINTER + { V3270_OIA_PRINTER, setup_single_char_right }, +#endif // HAVE_PRINTER + { V3270_OIA_SCRIPT, setup_single_char_right }, + { V3270_OIA_INSERT, setup_insert_position }, + { V3270_OIA_TYPEAHEAD, setup_single_char_right }, + { V3270_OIA_SHIFT, setup_double_char_position }, +// { V3270_OIA_CAPS, setup_single_char_right }, + { V3270_OIA_ALT, setup_single_char_right }, + { V3270_OIA_SSL, setup_double_char_position }, + }; + + int f; + int rCol = terminal->font.margin.left+(cols*terminal->font.width); + int lCol = terminal->font.margin.left+1; + + row += OIA_TOP_MARGIN; + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_SEPARATOR); + cairo_rectangle(cr, terminal->font.margin.left, row, cols*terminal->font.width, 1); + cairo_fill(cr); + + row += 2; + + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_BACKGROUND); + cairo_rectangle(cr, terminal->font.margin.left, row, cols*terminal->font.width, terminal->font.spacing); + cairo_fill(cr); + + for(f=0;f< (int) G_N_ELEMENTS(right);f++) + { + GdkRectangle *r = terminal->oia.rect+right[f].id; + + memset(r,0,sizeof(GdkRectangle)); + r->x = rCol; + r->y = row; + r->width = terminal->font.width; + r->height = terminal->font.spacing; + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_FOREGROUND); + right[f].draw(r,&terminal->font,cr,terminal->host,cols,terminal->color); + rCol = r->x - (terminal->font.width/3); + } + + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_FOREGROUND); + + draw_centered_char(cr,&terminal->font,lCol,row,'4'); + + cairo_stroke(cr); + cairo_rectangle(cr, lCol, row, terminal->font.width+2, terminal->font.spacing); + cairo_stroke(cr); + + lCol += (terminal->font.width+5); + + // Undera indicator + terminal->oia.rect[V3270_OIA_UNDERA].x = lCol; + terminal->oia.rect[V3270_OIA_UNDERA].y = row; + terminal->oia.rect[V3270_OIA_UNDERA].width = terminal->font.width+3; + terminal->oia.rect[V3270_OIA_UNDERA].height = terminal->font.spacing; + draw_undera(cr,terminal->host,&terminal->font,terminal->color,terminal->oia.rect+V3270_OIA_UNDERA); + + lCol += (3 + terminal->oia.rect[V3270_OIA_UNDERA].width); + + // Connection indicator + terminal->oia.rect[V3270_OIA_CONNECTION].x = lCol; + terminal->oia.rect[V3270_OIA_CONNECTION].y = row; + terminal->oia.rect[V3270_OIA_CONNECTION].width = terminal->font.width+3; + terminal->oia.rect[V3270_OIA_CONNECTION].height = terminal->font.spacing; + v3270_draw_connection(cr,terminal->host,&terminal->font,terminal->color,terminal->oia.rect+V3270_OIA_CONNECTION); + + lCol += (4 + terminal->oia.rect[V3270_OIA_CONNECTION].width); + + memset(terminal->oia.rect+V3270_OIA_MESSAGE,0,sizeof(GdkRectangle)); + + if(lCol < rCol) + { + GdkRectangle *r = terminal->oia.rect+V3270_OIA_MESSAGE; + r->x = lCol; + r->y = row; + r->width = rCol - lCol; + r->height = terminal->font.spacing; + draw_status_message(cr,lib3270_get_program_message(terminal->host),&terminal->font,terminal->color,r); + } + + cairo_save(cr); +// v3270_draw_ssl_status(cr,terminal->host,&terminal->font,terminal->color,terminal->oia.rect+V3270_OIA_SSL); + v3270_draw_ssl_status(terminal,cr,terminal->oia.rect+V3270_OIA_SSL); + cairo_restore(cr); + + cairo_save(cr); + draw_insert(cr,terminal->host,terminal->color,terminal->oia.rect+V3270_OIA_INSERT); + cairo_restore(cr); +} + +/** + * Begin update of a specific OIA field. + * + * @param terminal 3270 terminal widget. + * @param r Rectangle to receive updated region. + * @param id Field id. + * + * @return cairo object for drawing. + * + */ +cairo_t * v3270_oia_set_update_region(v3270 * terminal, GdkRectangle **r, V3270_OIA_FIELD id) +{ + GdkRectangle * rect = terminal->oia.rect + id; + cairo_t * cr = cairo_create(terminal->surface); + + cairo_set_scaled_font(cr,terminal->font.scaled); + + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_clip(cr); + + *r = rect; + +#ifdef DEBUG + cairo_set_source_rgb(cr,0.1,0.1,0.1); +#else + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_BACKGROUND); +#endif + + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); + + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_FOREGROUND); + + return cr; +} + +void v3270_update_luname(GtkWidget *widget,const gchar *name) +{ + cairo_t * cr; + GdkRectangle * rect; + v3270 * terminal = GTK_V3270(widget); + + if(terminal->surface) + { + cr = v3270_oia_set_update_region(terminal,&rect,V3270_OIA_LUNAME); + + if(name) + { +// cairo_move_to(cr,rect->x,rect->y+terminal->font.height); +// cairo_show_text(cr,name); +// cairo_stroke(cr); + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_LUNAME); + v3270_draw_text_at(cr, rect->x, rect->y, &terminal->font, name); + + } + + cairo_destroy(cr); + + v3270_queue_draw_area(GTK_WIDGET(terminal),rect->x,rect->y,rect->width,rect->height); + } + + g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->properties.luname); + +} + +void v3270_update_message(v3270 *widget, LIB3270_MESSAGE id) +{ + cairo_t * cr; + GdkRectangle * rect; + + if(!widget->surface) + return; + + cr = v3270_oia_set_update_region(widget,&rect,V3270_OIA_MESSAGE); + + draw_status_message(cr,id,&widget->font,widget->color,rect); + + cairo_destroy(cr); + + v3270_queue_draw_area(GTK_WIDGET(widget),rect->x,rect->y,rect->width,rect->height); + + if(widget->accessible) + v3270_acessible_set_state(widget->accessible,id); + +} + +static void draw_cursor_position(cairo_t *cr, GdkRectangle *rect, v3270FontInfo *metrics, int row, int col) +{ + cairo_text_extents_t extents; + char buffer[10]; + + short2string(buffer,row+1,3); + buffer[3] = '/'; + short2string(buffer+4,col+1,3); + buffer[7] = 0; + + cairo_text_extents(cr,buffer,&extents); + v3270_draw_text_at(cr,(rect->x+rect->width)-(extents.width+2),rect->y,metrics,buffer); +} + +void v3270_update_cursor(H3270 *session, unsigned short row, unsigned short col, unsigned char c, unsigned short attr) +{ + v3270 * terminal = GTK_V3270(lib3270_get_user_data(session)); + GdkRectangle saved; + + if(!terminal->surface) + return; + + // Update cursor rectangle + saved = terminal->cursor.rect; + + terminal->cursor.rect.x = terminal->font.margin.left + (col * terminal->cursor.rect.width); + terminal->cursor.rect.y = terminal->font.margin.top + (row * terminal->font.spacing); + terminal->cursor.rect.width = terminal->font.width; + terminal->cursor.rect.height = terminal->font.height+terminal->font.descent; + terminal->cursor.show |= 1; + + v3270_queue_draw_area( GTK_WIDGET(terminal), saved.x, + saved.y, + saved.width, + saved.height); + + + v3270_update_cursor_surface(terminal,c,attr); + + v3270_queue_draw_area( GTK_WIDGET(terminal), + terminal->cursor.rect.x,terminal->cursor.rect.y, + terminal->cursor.rect.width,terminal->cursor.rect.height); + + if(lib3270_get_toggle(session,LIB3270_TOGGLE_CROSSHAIR)) + { + GtkAllocation allocation; + gtk_widget_get_allocation(GTK_WIDGET(terminal), &allocation); + + v3270_queue_draw_area(GTK_WIDGET(terminal),0,saved.y+terminal->font.height,allocation.width,1); + v3270_queue_draw_area(GTK_WIDGET(terminal),saved.x,0,1,terminal->oia.rect->y-3); + + v3270_queue_draw_area(GTK_WIDGET(terminal),0,terminal->cursor.rect.y+terminal->font.height,allocation.width,1); + v3270_queue_draw_area(GTK_WIDGET(terminal),terminal->cursor.rect.x,0,1,terminal->oia.rect->y-3); + } + + if(lib3270_get_toggle(session,LIB3270_TOGGLE_CURSOR_POS)) + { + // Update OIA + GdkRectangle * rect; + cairo_t * cr; + + cr = v3270_oia_set_update_region(terminal,&rect,V3270_OIA_CURSOR_POSITION); + + draw_cursor_position(cr,rect,&terminal->font,row,col); + + cairo_destroy(cr); + + v3270_queue_draw_area(GTK_WIDGET(terminal),rect->x,rect->y,rect->width,rect->height); + } + + if(terminal->accessible) + g_signal_emit_by_name(ATK_TEXT(terminal->accessible),"text-caret-moved",lib3270_get_cursor_address(session)); + +} + +struct timer_info +{ + time_t start; + time_t last; +#ifdef HAVE_LIBM + gint step; +#endif // HAVE_LIBM + v3270 * terminal; +}; + +static void release_timer(struct timer_info *info) +{ + info->terminal->timer = NULL; + + if(info->terminal->surface) + { + // Erase timer info + static const int id[] = { V3270_OIA_TIMER, +#ifdef HAVE_LIBM + V3270_OIA_SPINNER +#endif // HAVE_LIBM + }; + int f; + + cairo_t *cr = cairo_create(info->terminal->surface); + +#ifdef DEBUG + cairo_set_source_rgb(cr,0.1,0.1,0.1); +#else + gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_BACKGROUND); +#endif + + for(f=0;f< (int) G_N_ELEMENTS(id);f++) + { + GdkRectangle *rect = info->terminal->oia.rect + id[f]; + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); + v3270_queue_draw_area(GTK_WIDGET(info->terminal),rect->x,rect->y,rect->width,rect->height); + } + cairo_destroy(cr); + } + + g_free(info); +} + +void v3270_draw_shift_status(v3270 *terminal) +{ + GdkRectangle *r; + cairo_t *cr; + + if(!terminal->surface) + return; + + cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_SHIFT); + cairo_translate(cr, r->x, r->y+1); + + if(r->width > 2 && r->height > 7 && (terminal->keyflags & KEY_FLAG_SHIFT)) + { + int b,x,y,w,h,l; + int height = r->height-6; + + if(height > r->width) + { + w = r->width; + h = w*1.5; + } + else // width > height + { + h = height; + w = h/1.5; + } + + // Set image position + x = (r->width - w)/2; + y = (height - h)/2; + l = (w/3); + b = y+(w/1.5); + + cairo_move_to(cr,x+(w/2),y); + cairo_line_to(cr,x+w,b); + cairo_line_to(cr,(x+w)-l,b); + cairo_line_to(cr,(x+w)-l,y+h); + cairo_line_to(cr,x+l,y+h); + cairo_line_to(cr,x+l,b); + cairo_line_to(cr,x,b); + cairo_close_path(cr); + + cairo_stroke(cr); + + } + + cairo_destroy(cr); + v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); + +} + +void v3270_oia_update_text_field(v3270 *terminal, gboolean flag, V3270_OIA_FIELD id, const gchar chr) +{ + GdkRectangle * r; + cairo_t * cr; + gchar text[] = { chr, 0 }; + + if(!terminal->surface) + return; + + cr = v3270_oia_set_update_region(terminal,&r,id); + cairo_translate(cr, r->x, r->y); + + if(flag) + { + v3270_draw_text_at(cr,0,0,&terminal->font,text); +// cairo_move_to(cr,0,terminal->font.height); +// cairo_show_text(cr, text); +// cairo_stroke(cr); + } + + cairo_destroy(cr); + v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); +} + +#ifdef KEY_FLAG_ALT +void v3270_draw_alt_status(v3270 *terminal) +{ + v3270_oia_update_text_field(terminal,terminal->keyflags & KEY_FLAG_ALT,V3270_OIA_ALT,'A'); +} +#else +void v3270_draw_alt_status(v3270 G_GNUC_UNUSED(*terminal)) +{ +} +#endif // KEY_FLAG_ALT + +void v3270_draw_ins_status(v3270 *terminal) +{ + GdkRectangle *r; + cairo_t *cr; + + if(!terminal->surface) + return; + + cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_INSERT); + + draw_insert(cr,terminal->host,terminal->color,r); + + cairo_destroy(cr); + v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); + +} + +static gboolean update_timer(struct timer_info *info) +{ + cairo_t * cr; + time_t now = time(0); + GdkRectangle * rect; + +// debug("%s %p",__FUNCTION__,info->terminal->surface); + if(!info->terminal->surface) + return TRUE; + + cr = cairo_create(info->terminal->surface); + + if(now != info->last) + { + time_t seconds = now - info->start; + char buffer[7]; + + rect = info->terminal->oia.rect + V3270_OIA_TIMER; + + gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_BACKGROUND); + + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); + + gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_FOREGROUND); + + short2string(buffer,seconds/60,2); + buffer[2] = ':'; + short2string(buffer+3,seconds%60,2); + buffer[5] = 0; + + cairo_set_scaled_font(cr,info->terminal->font.scaled); +// cairo_move_to(cr,rect->x,rect->y+info->terminal->font.height); +// cairo_show_text(cr, buffer); + + v3270_draw_text(cr, rect, &info->terminal->font, buffer); + + cairo_stroke(cr); + + info->last = now; + v3270_queue_draw_area(GTK_WIDGET(info->terminal),rect->x,rect->y,rect->width,rect->height); + } + +#ifdef HAVE_LIBM + + rect = info->terminal->oia.rect + V3270_OIA_SPINNER; + +#ifdef DEBUG + cairo_set_source_rgb(cr,0.1,0.1,0.1); +#else + gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_BACKGROUND); +#endif + + cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); + cairo_fill(cr); + + gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_FOREGROUND); + + info->step = draw_spinner(cr, rect, info->terminal->color, info->step); + + v3270_queue_draw_area(GTK_WIDGET(info->terminal),rect->x,rect->y,rect->width,rect->height); + +#endif // HAVE_LIBM + + cairo_destroy(cr); + + return TRUE; +} + +void v3270_start_timer(GtkWidget *widget) +{ + struct timer_info *info; + v3270 *terminal = GTK_V3270(widget); + + if(terminal->timer) + { + g_source_ref(terminal->timer); + return; + } + + info = g_new0(struct timer_info,1); + info->terminal = terminal; + info->start = time(0); + + update_timer(info); + + terminal->timer = g_timeout_source_new(100); + g_source_set_callback(terminal->timer,(GSourceFunc) update_timer, info, (GDestroyNotify) release_timer); + + g_source_attach(terminal->timer,NULL); + g_source_unref(terminal->timer); + +} + +void v3270_stop_timer(GtkWidget *widget) +{ + v3270 *terminal = GTK_V3270(widget); + + if(terminal->timer) + { + if(terminal->timer->ref_count < 2) + { + g_source_destroy(terminal->timer); + } + else + { + g_source_unref(terminal->timer); + } + } + +} + +void v3270_blink_ssl(v3270 *terminal) +{ + if(terminal->surface) + { + GdkRectangle * r; + cairo_t * cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_SSL); + + v3270_draw_ssl_status(terminal,cr,r); + v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); + cairo_destroy(cr); + + } + +} + +void v3270_update_oia(v3270 *terminal, LIB3270_FLAG id, unsigned char on) +{ + cairo_t *cr; + GdkRectangle *r; + + if(!(terminal->surface && terminal->drawing)) + return; + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wswitch" + switch(id) + { + case LIB3270_FLAG_BOXSOLID: +// debug("%s LIB3270_FLAG_BOXSOLID",__FUNCTION__); + cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_CONNECTION); + v3270_draw_connection(cr,terminal->host,&terminal->font,terminal->color,r); + cairo_destroy(cr); + v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); + break; + + case LIB3270_FLAG_UNDERA: +// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); + cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_UNDERA); +// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); + draw_undera(cr,terminal->host,&terminal->font,terminal->color,r); +// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); + cairo_destroy(cr); +// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); + v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); +// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); + break; + + case LIB3270_FLAG_TYPEAHEAD: +// debug("%s LIB3270_FLAG_TYPEAHEAD",__FUNCTION__); + v3270_oia_update_text_field(terminal,on,V3270_OIA_TYPEAHEAD,'T'); + break; + +#ifdef HAVE_PRINTER + case LIB3270_FLAG_PRINTER: +// debug("%s LIB3270_FLAG_PRINTER",__FUNCTION__); + v3270_oia_update_text_field(terminal,on,V3270_OIA_PRINTER,'P'); + break; +#endif // HAVE_PRINTER + +/* + case LIB3270_FLAG_SCRIPT: + v3270_oia_update_text_field(terminal,on,V3270_OIA_SCRIPT,terminal->script_id); + break; +*/ + + } + #pragma GCC diagnostic pop + +} + +int v3270_set_script(GtkWidget *widget, const gchar id) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL); + + v3270 * terminal = GTK_V3270(widget); + + if(id && terminal->script) + return EBUSY; + + terminal->script = id; + + if(terminal->script) + v3270_start_blinking(widget); + + return 0; +} diff --git a/src/terminal/drawing/surface.c b/src/terminal/drawing/surface.c new file mode 100644 index 0000000..7a6b9f2 --- /dev/null +++ b/src/terminal/drawing/surface.c @@ -0,0 +1,86 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +/** + * @brief Reconfigure widget surface. + * + * Called when the widget is resized or moved to regenerate the cairo surface: + * + * * Recreate the surface. + * * Compute the new font size & metrics. + * * Redraw contents. + * * Emit "GDK_CONFIGURE" event. + * + */ +void v3270_reconfigure(v3270 * terminal) +{ + GtkAllocation allocation; + GtkWidget *widget; + GdkEvent *event = gdk_event_new(GDK_CONFIGURE); + + widget = GTK_WIDGET(terminal); + + gtk_widget_get_allocation(widget, &allocation); + + event->configure.window = g_object_ref(gtk_widget_get_window(widget)); + event->configure.send_event = TRUE; + event->configure.x = allocation.x; + event->configure.y = allocation.y; + event->configure.width = allocation.width; + event->configure.height = allocation.height; + + if(terminal->surface) + cairo_surface_destroy(terminal->surface); + + terminal->surface = (cairo_surface_t *) gdk_window_create_similar_surface(gtk_widget_get_window(widget),CAIRO_CONTENT_COLOR,allocation.width,allocation.height); + + // Update the created image + cairo_t * cr = cairo_create(terminal->surface); + v3270_compute_font_size(terminal, cr, allocation.width, allocation.height); + v3270_update_font_metrics(terminal, allocation.width, allocation.height); + + v3270_redraw(terminal, cr, allocation.width, allocation.height); + + cairo_destroy(cr); + +#if( !GTK_CHECK_VERSION(3,0,0)) + terminal->width = allocation.width; + terminal->height = allocation.height; +#endif + + gtk_widget_event(widget, event); + gdk_event_free(event); +} + + diff --git a/src/terminal/oia.c b/src/terminal/oia.c deleted file mode 100644 index b634a3d..0000000 --- a/src/terminal/oia.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como oia.c e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - - #include - - #define ENABLE_NLS - #define GETTEXT_PACKAGE PACKAGE_NAME - - #include - #include - #include - - #ifdef WIN32 - #include - #include - #include - #endif // WIN32 - - #include - #include - #include - #include - #include - #include - #include - #include - - #ifdef HAVE_LIBM - #include - #endif // HAVE_LIBM - - #include - #include - #include - #include - -/*--[ Prototipes ]-----------------------------------------------------------------------------------*/ - -static void draw_cursor_position(cairo_t *cr, GdkRectangle *rect, v3270FontInfo *metrics, int row, int col); - -/*--[ Statics ]--------------------------------------------------------------------------------------*/ - - #include "xbm/locked.xbm" - #include "xbm/unlocked.xbm" - #include "xbm/negotiated.xbm" - #include "xbm/warning.xbm" - -/*--[ Implement ]------------------------------------------------------------------------------------*/ - -static void short2string(char *ptr, unsigned short vlr, size_t sz) -{ - int f; - - for(f=sz-1;f>=0;f--) - { - ptr[f] = '0'+(vlr%10); - vlr /= 10; - } -} - - -#ifdef HAVE_LIBM -static gint draw_spinner(cairo_t *cr, GdkRectangle *r, GdkRGBA *color, gint step) -{ - static const guint num_steps = 10; - - gdouble dx = r->width/2; - gdouble dy = r->height/2; - gdouble radius = MIN (r->width / 2, r->height / 2); - gdouble half = num_steps / 2; - gint i; - - cairo_save(cr); - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - - cairo_rectangle(cr, r->x, r->y, r->width, r->height); - cairo_clip(cr); - cairo_translate(cr, r->x, r->y); - - step++; - step %= num_steps; - -// debug("%s step=%d",__FUNCTION__,step); - - for (i = 0; i < ((gint) num_steps); i++) - { - gint inset = 0.7 * radius; - - /* transparency is a function of time and intial value */ - gdouble t = (gdouble) ((i + num_steps - step) % num_steps) / num_steps; - - cairo_save(cr); - - cairo_set_source_rgba (cr, - color[V3270_COLOR_OIA_SPINNER].red, - color[V3270_COLOR_OIA_SPINNER].green, - color[V3270_COLOR_OIA_SPINNER].blue, - t); - - cairo_set_line_width (cr, 2.0); - cairo_move_to (cr, - dx + (radius - inset) * cos (i * G_PI / half), - dy + (radius - inset) * sin (i * G_PI / half)); - cairo_line_to (cr, - dx + radius * cos (i * G_PI / half), - dy + radius * sin (i * G_PI / half)); - cairo_stroke (cr); - - cairo_restore (cr); - } - - cairo_restore(cr); - - return step; -} -#endif // HAVE_LIBM - -static void setup_cursor_position(GdkRectangle *rect, v3270FontInfo *metrics, cairo_t *cr, H3270 *host, int cols, G_GNUC_UNUSED GdkRGBA *color) -{ - rect->width = metrics->width * 8; - rect->x -= rect->width; - - if(lib3270_get_toggle(host,LIB3270_TOGGLE_CURSOR_POS)) - { - int addr = lib3270_get_cursor_address(host); - draw_cursor_position(cr,rect,metrics,addr/cols,addr%cols); - } -} - -static void setup_ticking_position(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) -{ - char buffer[7]; - cairo_text_extents_t extents; - - short2string(buffer,0,2); - buffer[2] = ':'; - short2string(buffer+3,0,2); - buffer[5] = 0; - - cairo_text_extents(cr,buffer,&extents); - rect->width = ((int) extents.width + 2); - rect->x -= rect->width; -} - -static void setup_spinner_position(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, G_GNUC_UNUSED cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) -{ - rect->width = rect->height; - rect->x -= rect->width; -// draw_spinner(cr,rect,color,0); -} - -static void setup_luname_position(GdkRectangle *rect, v3270FontInfo *font, cairo_t *cr, H3270 *host, G_GNUC_UNUSED int cols, GdkRGBA *color) -{ - const char *luname = lib3270_get_luname(host); - - rect->width *= 16; - rect->x -= rect->width; - - cairo_save(cr); - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_clip(cr); - -#ifdef DEBUG - cairo_set_source_rgb(cr,0.1,0.1,0.1); -#else - gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_BACKGROUND); -#endif - - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); - - if(luname) - { - gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_LUNAME); - v3270_draw_text(cr,rect,font,luname); - } - - cairo_restore(cr); - -} - -static void setup_single_char_right(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, G_GNUC_UNUSED cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) -{ - rect->x -= rect->width; - - /* -#ifdef DEBUG - cairo_set_source_rgb(cr,0.1,0.1,0.1); - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); -#endif -*/ - -} - -static void setup_insert_position(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) -{ - if(rect->width > rect->height) - { - rect->width = rect->height; - } - else if(rect->height > rect->width) - { - rect->y += (rect->height - rect->width)/2; - rect->height = rect->width; - } - - rect->x -= rect->width; - -#ifdef DEBUG - cairo_set_source_rgb(cr,0.1,0.1,0.1); - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); -#endif - -} - - - -static void setup_double_char_position(GdkRectangle *rect, G_GNUC_UNUSED v3270FontInfo *metrics, cairo_t *cr, G_GNUC_UNUSED H3270 *host, G_GNUC_UNUSED int cols, G_GNUC_UNUSED GdkRGBA *color) -{ - rect->width <<= 1; - rect->x -= rect->width; - -#ifdef DEBUG - cairo_set_source_rgb(cr,0.1,0.1,0.1); - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); -#endif - -} - -static int draw_centered_char(cairo_t *cr, v3270FontInfo *metrics, int x, int y, const gchar chr) -{ - char str[2] = { chr, 0 }; -// cairo_text_extents_t extents; - - cairo_set_scaled_font(cr,metrics->scaled); -// cairo_text_extents(cr,str,&extents); - - v3270_draw_text_at(cr, x, y, metrics, str); - - return y+metrics->height+2; - -} - -static void draw_undera(cairo_t *cr, H3270 *host, v3270FontInfo *metrics, GdkRGBA *color, GdkRectangle *rect) -{ - gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_BACKGROUND); - - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); - - if(lib3270_get_undera(host)) - { - int y; - - gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_FOREGROUND); - - y = draw_centered_char(cr, metrics,rect->x,rect->y, lib3270_in_e(host) ? 'B' : 'A'); - - cairo_move_to(cr,rect->x,y); - cairo_rel_line_to(cr,10,0); - cairo_stroke(cr); - - } -// debug("%s",__FUNCTION__); - -} - -void v3270_draw_connection(cairo_t *cr, H3270 *host, v3270FontInfo *metrics, GdkRGBA *color, const GdkRectangle *rect) -{ - gchar str = ' '; - - gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_BACKGROUND); - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); - - gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_FOREGROUND); - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_stroke(cr); - - if(lib3270_get_oia_box_solid(host)) - { - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); - return; - } - - if(lib3270_in_ansi(host)) - str = 'N'; - else if(lib3270_in_sscp(host)) - str = 'S'; - else - str = '?'; - - draw_centered_char(cr,metrics,rect->x,rect->y,str); - -} - -static void draw_xbm(cairo_t *cr, GdkRectangle *rect, int width, int height, unsigned char *bits) -{ - double sz = rect->width < rect->height ? rect->width : rect->height; - cairo_surface_t * icon = cairo_image_surface_create_for_data( - bits, - CAIRO_FORMAT_A1, - width,height, - cairo_format_stride_for_width(CAIRO_FORMAT_A1,width)); - - cairo_save(cr); - - cairo_scale(cr, sz / ((double) width), - sz / ((double) height)); - - cairo_mask_surface(cr,icon,(rect->width-sz)/2,(rect->height-sz)/2); - - cairo_surface_destroy(icon); - - cairo_restore(cr); -} - -void v3270_draw_ssl_status(v3270 *widget, cairo_t *cr, GdkRectangle *rect) -{ - gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_BACKGROUND); - - cairo_translate(cr, rect->x, rect->y); - cairo_rectangle(cr, 0, 0, rect->width, rect->height); - cairo_fill(cr); - - switch(lib3270_get_ssl_state(widget->host)) - { - case LIB3270_SSL_UNDEFINED: // Undefined. - break; - - case LIB3270_SSL_UNSECURE: // No secure connection - gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_FOREGROUND); - draw_xbm(cr,rect,unlocked_width,unlocked_height,unlocked_bits); - break; - - case LIB3270_SSL_NEGOTIATING: // Negotiating SSL - if(widget->blink.show) - { - gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_STATUS_WARNING); - draw_xbm(cr,rect,negotiated_width,negotiated_height,negotiated_bits); - } - break; - - case LIB3270_SSL_NEGOTIATED: // Connection secure, no CA, self-signed or expired CRL - gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_STATUS_OK); - draw_xbm(cr,rect,locked_width,locked_height,locked_bits); - gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_STATUS_WARNING); - draw_xbm(cr,rect,warning_width,warning_height,warning_bits); - break; - - case LIB3270_SSL_SECURE: // Connection secure with CA check - gdk_cairo_set_source_rgba(cr,widget->color+V3270_COLOR_OIA_STATUS_OK); - draw_xbm(cr,rect,locked_width,locked_height,locked_bits); - break; - - } - - -} - -static void draw_status_message(cairo_t *cr, LIB3270_MESSAGE id, v3270FontInfo *font, GdkRGBA *color, const GdkRectangle *r) -{ - #ifdef DEBUG - #define OIA_MESSAGE(x,c,y) { #x, c, y } - #else - #define OIA_MESSAGE(x,c,y) { c, y } - #endif - - static const struct _message - { - #ifdef DEBUG - const gchar * dbg; - #endif - enum V3270_COLOR - color; - const gchar * msg; - } message[] = - { - OIA_MESSAGE( LIB3270_MESSAGE_NONE, - V3270_COLOR_OIA_STATUS_OK, - NULL ), - - OIA_MESSAGE( LIB3270_MESSAGE_SYSWAIT, - V3270_COLOR_OIA_STATUS_OK, - N_( "X System" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_TWAIT, - V3270_COLOR_OIA_STATUS_OK, - N_( "X Wait" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_CONNECTED, - V3270_COLOR_OIA_STATUS_OK, - NULL ), - - OIA_MESSAGE( LIB3270_MESSAGE_DISCONNECTED, - V3270_COLOR_OIA_STATUS_INVALID, - N_( "X Not Connected" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_AWAITING_FIRST, - V3270_COLOR_OIA_STATUS_OK, - N_( "X" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_MINUS, - V3270_COLOR_OIA_STATUS_OK, - N_( "X -f" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_PROTECTED, - V3270_COLOR_OIA_STATUS_INVALID, - N_( "X Protected" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_NUMERIC, - V3270_COLOR_OIA_STATUS_INVALID, - N_( "X Numeric" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_OVERFLOW, - V3270_COLOR_OIA_STATUS_INVALID, - N_( "X Overflow" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_INHIBIT, - V3270_COLOR_OIA_STATUS_INVALID, - N_( "X Inhibit" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_KYBDLOCK, - V3270_COLOR_OIA_STATUS_INVALID, - N_( "X") ), - - OIA_MESSAGE( LIB3270_MESSAGE_X, - V3270_COLOR_OIA_STATUS_INVALID, - N_( "X" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_RESOLVING, - V3270_COLOR_OIA_STATUS_WARNING, - N_( "X Resolving" ) ), - - OIA_MESSAGE( LIB3270_MESSAGE_CONNECTING, - V3270_COLOR_OIA_STATUS_WARNING, - N_( "X Connecting" ) ), - - - }; - - GdkRectangle rect; - const gchar * msg = message[0].msg; - - memcpy(&rect,r,sizeof(GdkRectangle)); - - if(id >= 0 && id < G_N_ELEMENTS(message)) - { - msg = message[id].msg; -#ifdef DEBUG - if(!msg) - msg = message[id].dbg; -#endif // DEBUG - } - - // Limpa o bloco - gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_BACKGROUND); - cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height); - cairo_fill(cr); - - if(msg && *msg) - { - msg = gettext(msg); - } - - if(msg && *msg) - { - rect.x++; - -// debug("%s(%s)",__FUNCTION__,msg); - - gdk_cairo_set_source_rgba(cr,color+message[id].color); - - if(*msg == 'X') - { - cairo_save(cr); - - cairo_move_to(cr,rect.x+1,rect.y+(font->height)-(font->ascent)); - cairo_rel_line_to(cr,font->width,font->ascent); - cairo_rel_move_to(cr,-font->width,0); - cairo_rel_line_to(cr,font->width,-font->ascent); - - cairo_stroke(cr); - rect.x += font->width; - msg++; - - cairo_restore(cr); - } - - while(isspace(*msg)) - { - msg++; - rect.x += font->width; - } - - if(*msg) - { - v3270_draw_text(cr,&rect, font, msg); -// cairo_move_to(cr,x,rect->y+metrics->height); -// cairo_show_text(cr,msg); - } - - } - -} - -static void draw_insert(cairo_t *cr, H3270 *host, GdkRGBA *color, GdkRectangle *rect) -{ - if(lib3270_get_toggle(host,LIB3270_TOGGLE_INSERT)) - { - double y = rect->y+(rect->height-2); - - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_clip(cr); - - gdk_cairo_set_source_rgba(cr,color+V3270_COLOR_OIA_FOREGROUND); - - cairo_move_to(cr,rect->x,y); - cairo_rel_line_to(cr,rect->width/2,-(rect->height/1.7)); - cairo_line_to(cr,rect->x+rect->width,y); - cairo_stroke(cr); - } - -} - -// v3270_draw_oia(cr, terminal->host, rect.y, cols, &terminal->font, terminal->color,terminal->oia_rect); -// void v3270_draw_oia(cairo_t *cr, H3270 *host, int row, int cols, v3270FontInfo *metrics, GdkRGBA *color, GdkRectangle *rect) - -void v3270_draw_oia(v3270 *terminal, cairo_t *cr, int row, int cols) -{ - static const struct _right_fields - { - V3270_OIA_FIELD id; - void (*draw)(GdkRectangle *rect, v3270FontInfo *metrics, cairo_t *cr, H3270 *host, int cols, GdkRGBA *color); - } right[] = - { - { V3270_OIA_CURSOR_POSITION, setup_cursor_position }, - { V3270_OIA_TIMER, setup_ticking_position }, - { V3270_OIA_SPINNER, setup_spinner_position }, - { V3270_OIA_LUNAME, setup_luname_position }, -#ifdef HAVE_PRINTER - { V3270_OIA_PRINTER, setup_single_char_right }, -#endif // HAVE_PRINTER - { V3270_OIA_SCRIPT, setup_single_char_right }, - { V3270_OIA_INSERT, setup_insert_position }, - { V3270_OIA_TYPEAHEAD, setup_single_char_right }, - { V3270_OIA_SHIFT, setup_double_char_position }, -// { V3270_OIA_CAPS, setup_single_char_right }, - { V3270_OIA_ALT, setup_single_char_right }, - { V3270_OIA_SSL, setup_double_char_position }, - }; - - int f; - int rCol = terminal->font.margin.left+(cols*terminal->font.width); - int lCol = terminal->font.margin.left+1; - - row += OIA_TOP_MARGIN; - gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_SEPARATOR); - cairo_rectangle(cr, terminal->font.margin.left, row, cols*terminal->font.width, 1); - cairo_fill(cr); - - row += 2; - - gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_BACKGROUND); - cairo_rectangle(cr, terminal->font.margin.left, row, cols*terminal->font.width, terminal->font.spacing); - cairo_fill(cr); - - for(f=0;f< (int) G_N_ELEMENTS(right);f++) - { - GdkRectangle *r = terminal->oia.rect+right[f].id; - - memset(r,0,sizeof(GdkRectangle)); - r->x = rCol; - r->y = row; - r->width = terminal->font.width; - r->height = terminal->font.spacing; - gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_FOREGROUND); - right[f].draw(r,&terminal->font,cr,terminal->host,cols,terminal->color); - rCol = r->x - (terminal->font.width/3); - } - - gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_FOREGROUND); - - draw_centered_char(cr,&terminal->font,lCol,row,'4'); - - cairo_stroke(cr); - cairo_rectangle(cr, lCol, row, terminal->font.width+2, terminal->font.spacing); - cairo_stroke(cr); - - lCol += (terminal->font.width+5); - - // Undera indicator - terminal->oia.rect[V3270_OIA_UNDERA].x = lCol; - terminal->oia.rect[V3270_OIA_UNDERA].y = row; - terminal->oia.rect[V3270_OIA_UNDERA].width = terminal->font.width+3; - terminal->oia.rect[V3270_OIA_UNDERA].height = terminal->font.spacing; - draw_undera(cr,terminal->host,&terminal->font,terminal->color,terminal->oia.rect+V3270_OIA_UNDERA); - - lCol += (3 + terminal->oia.rect[V3270_OIA_UNDERA].width); - - // Connection indicator - terminal->oia.rect[V3270_OIA_CONNECTION].x = lCol; - terminal->oia.rect[V3270_OIA_CONNECTION].y = row; - terminal->oia.rect[V3270_OIA_CONNECTION].width = terminal->font.width+3; - terminal->oia.rect[V3270_OIA_CONNECTION].height = terminal->font.spacing; - v3270_draw_connection(cr,terminal->host,&terminal->font,terminal->color,terminal->oia.rect+V3270_OIA_CONNECTION); - - lCol += (4 + terminal->oia.rect[V3270_OIA_CONNECTION].width); - - memset(terminal->oia.rect+V3270_OIA_MESSAGE,0,sizeof(GdkRectangle)); - - if(lCol < rCol) - { - GdkRectangle *r = terminal->oia.rect+V3270_OIA_MESSAGE; - r->x = lCol; - r->y = row; - r->width = rCol - lCol; - r->height = terminal->font.spacing; - draw_status_message(cr,lib3270_get_program_message(terminal->host),&terminal->font,terminal->color,r); - } - - cairo_save(cr); -// v3270_draw_ssl_status(cr,terminal->host,&terminal->font,terminal->color,terminal->oia.rect+V3270_OIA_SSL); - v3270_draw_ssl_status(terminal,cr,terminal->oia.rect+V3270_OIA_SSL); - cairo_restore(cr); - - cairo_save(cr); - draw_insert(cr,terminal->host,terminal->color,terminal->oia.rect+V3270_OIA_INSERT); - cairo_restore(cr); -} - -/** - * Begin update of a specific OIA field. - * - * @param terminal 3270 terminal widget. - * @param r Rectangle to receive updated region. - * @param id Field id. - * - * @return cairo object for drawing. - * - */ -cairo_t * v3270_oia_set_update_region(v3270 * terminal, GdkRectangle **r, V3270_OIA_FIELD id) -{ - GdkRectangle * rect = terminal->oia.rect + id; - cairo_t * cr = cairo_create(terminal->surface); - - cairo_set_scaled_font(cr,terminal->font.scaled); - - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_clip(cr); - - *r = rect; - -#ifdef DEBUG - cairo_set_source_rgb(cr,0.1,0.1,0.1); -#else - gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_BACKGROUND); -#endif - - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); - - gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_FOREGROUND); - - return cr; -} - -void v3270_update_luname(GtkWidget *widget,const gchar *name) -{ - cairo_t * cr; - GdkRectangle * rect; - v3270 * terminal = GTK_V3270(widget); - - if(terminal->surface) - { - cr = v3270_oia_set_update_region(terminal,&rect,V3270_OIA_LUNAME); - - if(name) - { -// cairo_move_to(cr,rect->x,rect->y+terminal->font.height); -// cairo_show_text(cr,name); -// cairo_stroke(cr); - gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_OIA_LUNAME); - v3270_draw_text_at(cr, rect->x, rect->y, &terminal->font, name); - - } - - cairo_destroy(cr); - - v3270_queue_draw_area(GTK_WIDGET(terminal),rect->x,rect->y,rect->width,rect->height); - } - - g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->properties.luname); - -} - -void v3270_update_message(v3270 *widget, LIB3270_MESSAGE id) -{ - cairo_t * cr; - GdkRectangle * rect; - - if(!widget->surface) - return; - - cr = v3270_oia_set_update_region(widget,&rect,V3270_OIA_MESSAGE); - - draw_status_message(cr,id,&widget->font,widget->color,rect); - - cairo_destroy(cr); - - v3270_queue_draw_area(GTK_WIDGET(widget),rect->x,rect->y,rect->width,rect->height); - - if(widget->accessible) - v3270_acessible_set_state(widget->accessible,id); - -} - -static void draw_cursor_position(cairo_t *cr, GdkRectangle *rect, v3270FontInfo *metrics, int row, int col) -{ - cairo_text_extents_t extents; - char buffer[10]; - - short2string(buffer,row+1,3); - buffer[3] = '/'; - short2string(buffer+4,col+1,3); - buffer[7] = 0; - - cairo_text_extents(cr,buffer,&extents); - v3270_draw_text_at(cr,(rect->x+rect->width)-(extents.width+2),rect->y,metrics,buffer); -} - -void v3270_update_cursor(H3270 *session, unsigned short row, unsigned short col, unsigned char c, unsigned short attr) -{ - v3270 * terminal = GTK_V3270(lib3270_get_user_data(session)); - GdkRectangle saved; - - if(!terminal->surface) - return; - - // Update cursor rectangle - saved = terminal->cursor.rect; - - terminal->cursor.rect.x = terminal->font.margin.left + (col * terminal->cursor.rect.width); - terminal->cursor.rect.y = terminal->font.margin.top + (row * terminal->font.spacing); - terminal->cursor.rect.width = terminal->font.width; - terminal->cursor.rect.height = terminal->font.height+terminal->font.descent; - terminal->cursor.show |= 1; - - v3270_queue_draw_area( GTK_WIDGET(terminal), saved.x, - saved.y, - saved.width, - saved.height); - - - v3270_update_cursor_surface(terminal,c,attr); - - v3270_queue_draw_area( GTK_WIDGET(terminal), - terminal->cursor.rect.x,terminal->cursor.rect.y, - terminal->cursor.rect.width,terminal->cursor.rect.height); - - if(lib3270_get_toggle(session,LIB3270_TOGGLE_CROSSHAIR)) - { - GtkAllocation allocation; - gtk_widget_get_allocation(GTK_WIDGET(terminal), &allocation); - - v3270_queue_draw_area(GTK_WIDGET(terminal),0,saved.y+terminal->font.height,allocation.width,1); - v3270_queue_draw_area(GTK_WIDGET(terminal),saved.x,0,1,terminal->oia.rect->y-3); - - v3270_queue_draw_area(GTK_WIDGET(terminal),0,terminal->cursor.rect.y+terminal->font.height,allocation.width,1); - v3270_queue_draw_area(GTK_WIDGET(terminal),terminal->cursor.rect.x,0,1,terminal->oia.rect->y-3); - } - - if(lib3270_get_toggle(session,LIB3270_TOGGLE_CURSOR_POS)) - { - // Update OIA - GdkRectangle * rect; - cairo_t * cr; - - cr = v3270_oia_set_update_region(terminal,&rect,V3270_OIA_CURSOR_POSITION); - - draw_cursor_position(cr,rect,&terminal->font,row,col); - - cairo_destroy(cr); - - v3270_queue_draw_area(GTK_WIDGET(terminal),rect->x,rect->y,rect->width,rect->height); - } - - if(terminal->accessible) - g_signal_emit_by_name(ATK_TEXT(terminal->accessible),"text-caret-moved",lib3270_get_cursor_address(session)); - -} - -struct timer_info -{ - time_t start; - time_t last; -#ifdef HAVE_LIBM - gint step; -#endif // HAVE_LIBM - v3270 * terminal; -}; - -static void release_timer(struct timer_info *info) -{ - info->terminal->timer = NULL; - - if(info->terminal->surface) - { - // Erase timer info - static const int id[] = { V3270_OIA_TIMER, -#ifdef HAVE_LIBM - V3270_OIA_SPINNER -#endif // HAVE_LIBM - }; - int f; - - cairo_t *cr = cairo_create(info->terminal->surface); - -#ifdef DEBUG - cairo_set_source_rgb(cr,0.1,0.1,0.1); -#else - gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_BACKGROUND); -#endif - - for(f=0;f< (int) G_N_ELEMENTS(id);f++) - { - GdkRectangle *rect = info->terminal->oia.rect + id[f]; - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); - v3270_queue_draw_area(GTK_WIDGET(info->terminal),rect->x,rect->y,rect->width,rect->height); - } - cairo_destroy(cr); - } - - g_free(info); -} - -void v3270_draw_shift_status(v3270 *terminal) -{ - GdkRectangle *r; - cairo_t *cr; - - if(!terminal->surface) - return; - - cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_SHIFT); - cairo_translate(cr, r->x, r->y+1); - - if(r->width > 2 && r->height > 7 && (terminal->keyflags & KEY_FLAG_SHIFT)) - { - int b,x,y,w,h,l; - int height = r->height-6; - - if(height > r->width) - { - w = r->width; - h = w*1.5; - } - else // width > height - { - h = height; - w = h/1.5; - } - - // Set image position - x = (r->width - w)/2; - y = (height - h)/2; - l = (w/3); - b = y+(w/1.5); - - cairo_move_to(cr,x+(w/2),y); - cairo_line_to(cr,x+w,b); - cairo_line_to(cr,(x+w)-l,b); - cairo_line_to(cr,(x+w)-l,y+h); - cairo_line_to(cr,x+l,y+h); - cairo_line_to(cr,x+l,b); - cairo_line_to(cr,x,b); - cairo_close_path(cr); - - cairo_stroke(cr); - - } - - cairo_destroy(cr); - v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); - -} - -void v3270_oia_update_text_field(v3270 *terminal, gboolean flag, V3270_OIA_FIELD id, const gchar chr) -{ - GdkRectangle * r; - cairo_t * cr; - gchar text[] = { chr, 0 }; - - if(!terminal->surface) - return; - - cr = v3270_oia_set_update_region(terminal,&r,id); - cairo_translate(cr, r->x, r->y); - - if(flag) - { - v3270_draw_text_at(cr,0,0,&terminal->font,text); -// cairo_move_to(cr,0,terminal->font.height); -// cairo_show_text(cr, text); -// cairo_stroke(cr); - } - - cairo_destroy(cr); - v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); -} - -#ifdef KEY_FLAG_ALT -void v3270_draw_alt_status(v3270 *terminal) -{ - v3270_oia_update_text_field(terminal,terminal->keyflags & KEY_FLAG_ALT,V3270_OIA_ALT,'A'); -} -#else -void v3270_draw_alt_status(v3270 G_GNUC_UNUSED(*terminal)) -{ -} -#endif // KEY_FLAG_ALT - -void v3270_draw_ins_status(v3270 *terminal) -{ - GdkRectangle *r; - cairo_t *cr; - - if(!terminal->surface) - return; - - cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_INSERT); - - draw_insert(cr,terminal->host,terminal->color,r); - - cairo_destroy(cr); - v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); - -} - -static gboolean update_timer(struct timer_info *info) -{ - cairo_t * cr; - time_t now = time(0); - GdkRectangle * rect; - -// debug("%s %p",__FUNCTION__,info->terminal->surface); - if(!info->terminal->surface) - return TRUE; - - cr = cairo_create(info->terminal->surface); - - if(now != info->last) - { - time_t seconds = now - info->start; - char buffer[7]; - - rect = info->terminal->oia.rect + V3270_OIA_TIMER; - - gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_BACKGROUND); - - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); - - gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_FOREGROUND); - - short2string(buffer,seconds/60,2); - buffer[2] = ':'; - short2string(buffer+3,seconds%60,2); - buffer[5] = 0; - - cairo_set_scaled_font(cr,info->terminal->font.scaled); -// cairo_move_to(cr,rect->x,rect->y+info->terminal->font.height); -// cairo_show_text(cr, buffer); - - v3270_draw_text(cr, rect, &info->terminal->font, buffer); - - cairo_stroke(cr); - - info->last = now; - v3270_queue_draw_area(GTK_WIDGET(info->terminal),rect->x,rect->y,rect->width,rect->height); - } - -#ifdef HAVE_LIBM - - rect = info->terminal->oia.rect + V3270_OIA_SPINNER; - -#ifdef DEBUG - cairo_set_source_rgb(cr,0.1,0.1,0.1); -#else - gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_BACKGROUND); -#endif - - cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); - cairo_fill(cr); - - gdk_cairo_set_source_rgba(cr,info->terminal->color+V3270_COLOR_OIA_FOREGROUND); - - info->step = draw_spinner(cr, rect, info->terminal->color, info->step); - - v3270_queue_draw_area(GTK_WIDGET(info->terminal),rect->x,rect->y,rect->width,rect->height); - -#endif // HAVE_LIBM - - cairo_destroy(cr); - - return TRUE; -} - -void v3270_start_timer(GtkWidget *widget) -{ - struct timer_info *info; - v3270 *terminal = GTK_V3270(widget); - - if(terminal->timer) - { - g_source_ref(terminal->timer); - return; - } - - info = g_new0(struct timer_info,1); - info->terminal = terminal; - info->start = time(0); - - update_timer(info); - - terminal->timer = g_timeout_source_new(100); - g_source_set_callback(terminal->timer,(GSourceFunc) update_timer, info, (GDestroyNotify) release_timer); - - g_source_attach(terminal->timer,NULL); - g_source_unref(terminal->timer); - -} - -void v3270_stop_timer(GtkWidget *widget) -{ - v3270 *terminal = GTK_V3270(widget); - - if(terminal->timer) - { - if(terminal->timer->ref_count < 2) - { - g_source_destroy(terminal->timer); - } - else - { - g_source_unref(terminal->timer); - } - } - -} - -void v3270_blink_ssl(v3270 *terminal) -{ - if(terminal->surface) - { - GdkRectangle * r; - cairo_t * cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_SSL); - - v3270_draw_ssl_status(terminal,cr,r); - v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); - cairo_destroy(cr); - - } - -} - -void v3270_update_oia(v3270 *terminal, LIB3270_FLAG id, unsigned char on) -{ - cairo_t *cr; - GdkRectangle *r; - - if(!(terminal->surface && terminal->drawing)) - return; - - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wswitch" - switch(id) - { - case LIB3270_FLAG_BOXSOLID: -// debug("%s LIB3270_FLAG_BOXSOLID",__FUNCTION__); - cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_CONNECTION); - v3270_draw_connection(cr,terminal->host,&terminal->font,terminal->color,r); - cairo_destroy(cr); - v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); - break; - - case LIB3270_FLAG_UNDERA: -// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); - cr = v3270_oia_set_update_region(terminal,&r,V3270_OIA_UNDERA); -// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); - draw_undera(cr,terminal->host,&terminal->font,terminal->color,r); -// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); - cairo_destroy(cr); -// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); - v3270_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height); -// debug("%s LIB3270_FLAG_UNDERA",__FUNCTION__); - break; - - case LIB3270_FLAG_TYPEAHEAD: -// debug("%s LIB3270_FLAG_TYPEAHEAD",__FUNCTION__); - v3270_oia_update_text_field(terminal,on,V3270_OIA_TYPEAHEAD,'T'); - break; - -#ifdef HAVE_PRINTER - case LIB3270_FLAG_PRINTER: -// debug("%s LIB3270_FLAG_PRINTER",__FUNCTION__); - v3270_oia_update_text_field(terminal,on,V3270_OIA_PRINTER,'P'); - break; -#endif // HAVE_PRINTER - -/* - case LIB3270_FLAG_SCRIPT: - v3270_oia_update_text_field(terminal,on,V3270_OIA_SCRIPT,terminal->script_id); - break; -*/ - - } - #pragma GCC diagnostic pop - -} - -int v3270_set_script(GtkWidget *widget, const gchar id) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL); - - v3270 * terminal = GTK_V3270(widget); - - if(id && terminal->script) - return EBUSY; - - terminal->script = id; - - if(terminal->script) - v3270_start_blinking(widget); - - return 0; -} diff --git a/src/terminal/properties/get.c b/src/terminal/properties/get.c index cea40fd..c0ed3d5 100644 --- a/src/terminal/properties/get.c +++ b/src/terminal/properties/get.c @@ -111,3 +111,42 @@ } } + +LIB3270_EXPORT const gchar * v3270_get_url(GtkWidget *widget) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),NULL); + return lib3270_get_url(GTK_V3270(widget)->host); +} + +LIB3270_EXPORT const gchar * v3270_get_luname(GtkWidget *widget) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),""); + return lib3270_get_luname(GTK_V3270(widget)->host); +} + +LIB3270_EXPORT const gchar * v3270_get_session_name(GtkWidget *widget) +{ +#ifdef DEBUG + v3270 * terminal = GTK_V3270(widget); + debug("Session name: [%s] Application name: [%s]",terminal->session_name, g_get_application_name()); +#endif // DEBUG + + if(!(GTK_IS_V3270(widget) && GTK_V3270(widget)->session_name)) + return g_get_application_name(); + + return GTK_V3270(widget)->session_name; +} + +LIB3270_EXPORT H3270 * v3270_get_session(GtkWidget *widget) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),NULL); + + return GTK_V3270(widget)->host; +} + +LIB3270_EXPORT gboolean v3270_is_connected(GtkWidget *widget) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); + return lib3270_is_connected(GTK_V3270(widget)->host) ? TRUE : FALSE; +} + diff --git a/src/terminal/properties/set.c b/src/terminal/properties/set.c index 9f20c9f..61592a6 100644 --- a/src/terminal/properties/set.c +++ b/src/terminal/properties/set.c @@ -132,3 +132,71 @@ } +/** + * v3270_set_url: + * + * @widget: V3270 widget. + * @uri: a valid tn3270 URL. + * + * Set the default URL for the tn3270e host. + * + * Since: 5.0 + **/ +LIB3270_EXPORT void v3270_set_url(GtkWidget *widget, const gchar *uri) +{ + g_return_if_fail(GTK_IS_V3270(widget)); + lib3270_set_url(GTK_V3270(widget)->host,uri); +} + +LIB3270_EXPORT void v3270_set_session_name(GtkWidget *widget, const gchar *name) +{ + g_return_if_fail(GTK_IS_V3270(widget)); + g_return_if_fail(name != NULL); + + if(GTK_V3270(widget)->session_name) { + + debug("Old session name was \"%s\"",GTK_V3270(widget)->session_name); + + if(!strcmp(GTK_V3270(widget)->session_name,name)) { + // Same session name, keep it. + return; + } + + g_free(GTK_V3270(widget)->session_name); + + } + + GTK_V3270(widget)->session_name = g_strdup(name); + + debug("New session name is \"%s\"",GTK_V3270(widget)->session_name); + + g_signal_emit(GTK_WIDGET(widget), v3270_widget_signal[V3270_SIGNAL_SESSION_CHANGED], 0); + +} + +LIB3270_EXPORT int v3270_set_host_type(GtkWidget *widget, LIB3270_HOST_TYPE type) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL); + return lib3270_set_host_type(GTK_V3270(widget)->host, type); +} + +LIB3270_EXPORT int v3270_set_host_type_by_name(GtkWidget *widget, const char *name) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL); + return lib3270_set_host_type_by_name(GTK_V3270(widget)->host,name); +} + +LIB3270_EXPORT int v3270_set_host_charset(GtkWidget *widget, const gchar *name) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); + return lib3270_set_host_charset(GTK_V3270(widget)->host,name); +} + +void v3270_set_cursor(GtkWidget *widget, LIB3270_POINTER id) +{ + gdk_window_set_cursor( + gtk_widget_get_window(widget), + GTK_V3270_GET_CLASS(widget)->cursors[id % LIB3270_POINTER_COUNT] + ); +} + diff --git a/src/terminal/surface.c b/src/terminal/surface.c deleted file mode 100644 index 8d40649..0000000 --- a/src/terminal/surface.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como - e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - - #include - #include - -/*--[ Implement ]------------------------------------------------------------------------------------*/ - -/** - * @brief Reconfigure widget surface. - * - * Called when the widget is resized or moved to regenerate the cairo surface: - * - * * Recreate the surface. - * * Compute the new font size & metrics. - * * Redraw contents. - * * Emite "GDK_CONFIGURE" event. - * - */ -void v3270_reconfigure(v3270 * terminal) -{ - GtkAllocation allocation; - GtkWidget *widget; - GdkEvent *event = gdk_event_new(GDK_CONFIGURE); - - widget = GTK_WIDGET(terminal); - - gtk_widget_get_allocation(widget, &allocation); - - event->configure.window = g_object_ref(gtk_widget_get_window(widget)); - event->configure.send_event = TRUE; - event->configure.x = allocation.x; - event->configure.y = allocation.y; - event->configure.width = allocation.width; - event->configure.height = allocation.height; - - if(terminal->surface) - cairo_surface_destroy(terminal->surface); - - terminal->surface = (cairo_surface_t *) gdk_window_create_similar_surface(gtk_widget_get_window(widget),CAIRO_CONTENT_COLOR,allocation.width,allocation.height); - - // Update the created image - cairo_t * cr = cairo_create(terminal->surface); - v3270_compute_font_size(terminal, cr, allocation.width, allocation.height); - v3270_update_font_metrics(terminal, allocation.width, allocation.height); - - v3270_redraw(terminal, cr, allocation.width, allocation.height); - - cairo_destroy(cr); - -#if( !GTK_CHECK_VERSION(3,0,0)) - terminal->width = allocation.width; - terminal->height = allocation.height; -#endif - - gtk_widget_event(widget, event); - gdk_event_free(event); -} - - diff --git a/src/terminal/widget.c b/src/terminal/widget.c index de5fee8..339cac8 100644 --- a/src/terminal/widget.c +++ b/src/terminal/widget.c @@ -71,30 +71,13 @@ static void v3270_realize ( GtkWidget * widget) ; static void v3270_size_allocate ( GtkWidget * widget, GtkAllocation * allocation ); -// Signals -static void v3270_activate (GtkWidget *widget); +static gboolean v3270_focus_in_event(GtkWidget *widget, GdkEventFocus *event); +static gboolean v3270_focus_out_event(GtkWidget *widget, GdkEventFocus *event); -gboolean v3270_focus_in_event(GtkWidget *widget, GdkEventFocus *event); -gboolean v3270_focus_out_event(GtkWidget *widget, GdkEventFocus *event); - -static void v3270_destroy (GtkWidget * object); +static void v3270_destroy (GtkWidget * object); /*--[ Implement ]------------------------------------------------------------------------------------*/ -void v3270_cursor_draw(v3270 *widget) -{ - int pos = lib3270_get_cursor_address(widget->host); - unsigned char c; - unsigned short attr; - - lib3270_get_contents(widget->host,pos,pos,&c,&attr); - v3270_update_cursor_surface(widget,c,attr); - v3270_queue_draw_area( GTK_WIDGET(widget), - widget->cursor.rect.x,widget->cursor.rect.y, - widget->cursor.rect.width,widget->cursor.rect.height); - -} - static gboolean v3270_popup_menu(GtkWidget * widget) { GdkEventButton event; @@ -767,33 +750,6 @@ G_GNUC_INTERNAL void gtk_widget_get_allocation(GtkWidget *widget, GtkAllocation #endif // !GTK(2,18) -LIB3270_EXPORT void v3270_disconnect(GtkWidget *widget) -{ - g_return_if_fail(GTK_IS_V3270(widget)); - v3270_disable_updates(widget); - debug("%s",__FUNCTION__); - lib3270_unselect(GTK_V3270(widget)->host); - debug("%s",__FUNCTION__); - lib3270_disconnect(GTK_V3270(widget)->host); - debug("%s",__FUNCTION__); - v3270_enable_updates(widget); - debug("%s",__FUNCTION__); -} - -LIB3270_EXPORT H3270 * v3270_get_session(GtkWidget *widget) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),NULL); - - return GTK_V3270(widget)->host; -} - -LIB3270_EXPORT int v3270_reconnect(GtkWidget *widget) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL); - - return lib3270_reconnect(GTK_V3270(widget)->host,0); -} - static gboolean notify_focus(GtkWidget *widget, GdkEventFocus *event) { GtkAccessible *obj = GTK_V3270(widget)->accessible; @@ -803,6 +759,7 @@ static gboolean notify_focus(GtkWidget *widget, GdkEventFocus *event) return FALSE; } + gboolean v3270_focus_in_event(GtkWidget *widget, GdkEventFocus *event) { v3270 * terminal = GTK_V3270(widget); @@ -821,20 +778,6 @@ gboolean v3270_focus_out_event(GtkWidget *widget, GdkEventFocus *event) return notify_focus(widget,event); } -static void v3270_activate(GtkWidget *widget) -{ - v3270 * terminal = GTK_V3270(widget); - - terminal->activity.timestamp = time(0); - - if(lib3270_is_connected(terminal->host)) - lib3270_enter(terminal->host); - else if(lib3270_get_url(terminal->host)) - v3270_reconnect(widget); - else - g_warning("Terminal widget %p activated without connection or valid url",terminal); -} - const GtkWidgetClass * v3270_get_parent_class(void) { return GTK_WIDGET_CLASS(v3270_parent_class); @@ -845,125 +788,3 @@ LIB3270_EXPORT GtkIMContext * v3270_get_im_context(GtkWidget *widget) return GTK_V3270(widget)->input_method; } -/** - * v3270_set_url: - * - * @widget: V3270 widget. - * @uri: a valid tn3270 URL. - * - * Set the default URL for the tn3270e host. - * - * Since: 5.0 - **/ -LIB3270_EXPORT void v3270_set_url(GtkWidget *widget, const gchar *uri) -{ - g_return_if_fail(GTK_IS_V3270(widget)); - lib3270_set_url(GTK_V3270(widget)->host,uri); -} - -LIB3270_EXPORT const gchar * v3270_get_url(GtkWidget *widget) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),NULL); - return lib3270_get_url(GTK_V3270(widget)->host); -} - -LIB3270_EXPORT const gchar * v3270_get_luname(GtkWidget *widget) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),""); - return lib3270_get_luname(GTK_V3270(widget)->host); -} - -LIB3270_EXPORT const gchar * v3270_get_session_name(GtkWidget *widget) -{ -#ifdef DEBUG - v3270 * terminal = GTK_V3270(widget); - debug("Session name: [%s] Application name: [%s]",terminal->session_name, g_get_application_name()); -#endif // DEBUG - - if(!(GTK_IS_V3270(widget) && GTK_V3270(widget)->session_name)) - return g_get_application_name(); - - return GTK_V3270(widget)->session_name; -} - -LIB3270_EXPORT void v3270_set_session_name(GtkWidget *widget, const gchar *name) -{ - g_return_if_fail(GTK_IS_V3270(widget)); - g_return_if_fail(name != NULL); - - if(GTK_V3270(widget)->session_name) { - - debug("Old session name was \"%s\"",GTK_V3270(widget)->session_name); - - if(!strcmp(GTK_V3270(widget)->session_name,name)) { - // Same session name, keep it. - return; - } - - g_free(GTK_V3270(widget)->session_name); - - } - - GTK_V3270(widget)->session_name = g_strdup(name); - - debug("New session name is \"%s\"",GTK_V3270(widget)->session_name); - - g_signal_emit(GTK_WIDGET(widget), v3270_widget_signal[V3270_SIGNAL_SESSION_CHANGED], 0); - -} - -LIB3270_EXPORT int v3270_set_host_type(GtkWidget *widget, LIB3270_HOST_TYPE type) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL); - return lib3270_set_host_type(GTK_V3270(widget)->host, type); -} - -LIB3270_EXPORT int v3270_set_host_type_by_name(GtkWidget *widget, const char *name) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL); - return lib3270_set_host_type_by_name(GTK_V3270(widget)->host,name); -} - -LIB3270_EXPORT gboolean v3270_is_connected(GtkWidget *widget) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); - return lib3270_is_connected(GTK_V3270(widget)->host) ? TRUE : FALSE; -} - -LIB3270_EXPORT int v3270_set_host_charset(GtkWidget *widget, const gchar *name) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); - return lib3270_set_host_charset(GTK_V3270(widget)->host,name); -} - -/* -LIB3270_EXPORT GtkWidget * v3270_get_default_widget(void) -{ - H3270 * hSession = lib3270_get_default_session_handle(); - - if(!hSession) - { - g_warning("%s: No default session available",__FUNCTION__); - return NULL; - } - - GtkWidget *widget = lib3270_get_user_data(hSession); - - if(!(widget && GTK_IS_V3270(widget))) - { - g_warning("%s: Can't determine default widget",__FUNCTION__); - return NULL; - } - - return GTK_WIDGET(widget); -} -*/ - -void v3270_set_cursor(GtkWidget *widget, LIB3270_POINTER id) -{ - gdk_window_set_cursor( - gtk_widget_get_window(widget), - GTK_V3270_GET_CLASS(widget)->cursors[id % LIB3270_POINTER_COUNT] - ); -} - diff --git a/v3270.cbp b/v3270.cbp index f84864c..ec8f62e 100644 --- a/v3270.cbp +++ b/v3270.cbp @@ -202,6 +202,9 @@ + + @@ -214,7 +217,13 @@ - + + + + + @@ -249,9 +258,6 @@ - - @@ -268,9 +274,6 @@ - - -- libgit2 0.21.2