From ad1610c2e33a36b266a29f5419d7419cd99cf7bf Mon Sep 17 00:00:00 2001 From: Miguel de Icaza Date: Thu, 12 Mar 1998 03:29:45 +0000 Subject: [PATCH] Viewer works; Entry widgets are synced with selection; panel fills properly (fixes a bunch of file operations); more dialog boxes exported to the gnome edition -mig --- gnome/ChangeLog | 14 +- gnome/Makefile.in | 3 +- gnome/gconf.h | 2 + gnome/gmain.c | 2 + gnome/gmc-chargrid.c | 117 ++++++++++--- gnome/gmc-chargrid.h | 12 +- gnome/gscreen.c | 8 +- gnome/gwidget.c | 14 ++ gnome/layout | 24 +++ src/ChangeLog | 17 ++ src/boxes.c | 11 +- src/cmd.c | 19 ++- src/screen.c | 3 +- src/view.c | 382 +++++++++---------------------------------- src/view.h | 35 +++- src/widget.c | 64 ++++---- tk/tkview.c | 241 +++++++++++++++++++++++++++ 17 files changed, 574 insertions(+), 394 deletions(-) diff --git a/gnome/ChangeLog b/gnome/ChangeLog index ab4696265..5ed8df074 100644 --- a/gnome/ChangeLog +++ b/gnome/ChangeLog @@ -1,3 +1,15 @@ +Wed Mar 11 15:28:45 1998 Miguel de Icaza + + * gwidget.c (entry_release): Now the WEntrys track the current + selection.p + (x_update_input): Repaint the widget after changing the position. + + * gscreen.c (x_fill_panel): Remember the selected item on the + panel before filling it up, as gtk_clist emits a select_item + signal when filling it up, which changes the current selection + (and thus some routines that invoke the reload panel option + fail). + 1998-03-11 Federico Mena Quintero * gmc-chargrid.c (gmc_char_grid_get_size): New public function. @@ -16,8 +28,6 @@ Tue Mar 10 23:46:29 1998 Miguel de Icaza - * glayout.c - * gscreen.c (x_adjust_top_file): We no longer adjust the top displayed filename. diff --git a/gnome/Makefile.in b/gnome/Makefile.in index eba2511bf..0306daef0 100644 --- a/gnome/Makefile.in +++ b/gnome/Makefile.in @@ -27,6 +27,7 @@ GNOMESRCS = \ gdesktop.c \ gutil.c \ gtrans.c \ + gview.c \ gmc-chargrid.c GNOMEHDRS = \ @@ -54,7 +55,7 @@ OOBJS = main.o dlg.o screen.o widget.o wtools.o info.o boxes.o \ OBJS = $(LOBJS) $(OOBJS) \ gkey.o gmain.o gscreen.o gwidget.o gmenu.o ghelp.o ginfo.o \ - glayout.o gtools.o gdesktop.o gtrans.o gutil.o gmc-chargrid.o + glayout.o gtools.o gdesktop.o gtrans.o gutil.o gmc-chargrid.o gview.o # # Distribution variables diff --git a/gnome/gconf.h b/gnome/gconf.h index 346c4989e..1f1efb1bb 100644 --- a/gnome/gconf.h +++ b/gnome/gconf.h @@ -20,6 +20,8 @@ #define PORT_HAS_BACKTAB_CHAR 1 #define PORT_NOT_FOCUS_SELECT_ITEM 1 #define PORT_NOT_UNFOCUS_UNSELECT_ITEM 1 +#define PORT_WANTS_VIEW 1 +#define PORT_HAS_VIEW_FREEZE 1 #define mi_getch() fprintf (stderr, "mi_getch is not implemented in this port\n") #define frontend_run_dlg(x) gtkrundlg_event (x) diff --git a/gnome/gmain.c b/gnome/gmain.c index 1838aadfd..b0c0153a9 100644 --- a/gnome/gmain.c +++ b/gnome/gmain.c @@ -29,6 +29,8 @@ struct gmc_color_pairs_s gmc_color_pairs [MAX_COLOR_PAIRS]; char *default_edition_colors = "normal=black:" +"selected=red:" +"viewunderline=brightred,blue:" "directory=blue:" "marked=white,seagreen:" "execute=slateblue:" diff --git a/gnome/gmc-chargrid.c b/gnome/gmc-chargrid.c index 919ca1ed8..54b7619d3 100644 --- a/gnome/gmc-chargrid.c +++ b/gnome/gmc-chargrid.c @@ -19,8 +19,8 @@ #define ATTRS(cgrid) ((struct attr *) cgrid->attrs) struct attr { - gulong fg; - gulong bg; + GdkColor *fg; + GdkColor *bg; }; @@ -256,6 +256,7 @@ update_strip (GmcCharGrid *cgrid, int x, int y, int width) struct attr *attrs; int first; gulong color; + gulong ocolor; GdkColor gcolor; chars = CHARS (cgrid) + (cgrid->width * y + x); @@ -269,11 +270,12 @@ update_strip (GmcCharGrid *cgrid, int x, int y, int width) while (i < width) { first = i; - color = attrs[i].bg; + ocolor = attrs[i].bg ? attrs[i].bg->pixel : GTK_WIDGET (cgrid)->style->bg[GTK_STATE_NORMAL].pixel; + color = ocolor; do { i++; - } while ((i < width) && (color == attrs[i].bg)); + } while ((i < width) && (color == ocolor)); gcolor.pixel = color; gdk_gc_set_foreground (cgrid->gc, &gcolor); @@ -293,11 +295,12 @@ update_strip (GmcCharGrid *cgrid, int x, int y, int width) while (i < width) { first = i; - color = attrs[i].fg; + ocolor = attrs[i].fg ? attrs[i].fg->pixel : GTK_WIDGET (cgrid)->style->fg[GTK_STATE_NORMAL].pixel; + color = ocolor; do { i++; - } while ((i < width) && (color == attrs[i].fg)); + } while ((i < width) && (color == ocolor)); gcolor.pixel = color; gdk_gc_set_foreground (cgrid->gc, &gcolor); @@ -343,18 +346,19 @@ gmc_char_grid_expose (GtkWidget *widget, GdkEventExpose *event) x2 = (event->area.x + event->area.width) / cgrid->char_width; y2 = (event->area.y + event->area.height) / cgrid->char_height; - update_region (cgrid, x1, y1, (x2 - x1) + 1, (y2 - y1) + 1); + update_region (cgrid, x1, y1, (x2 - x1) + 1, (y2 - y1)); } return FALSE; } void -gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height) +gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height, GdkColor *bg) { int x1, y1, x2, y2; int xx, yy; char *ch; + struct attr *attrs; g_return_if_fail (cgrid != NULL); g_return_if_fail (GMC_IS_CHAR_GRID (cgrid)); @@ -364,13 +368,28 @@ gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height) x2 = MIN (x + width, cgrid->width); y2 = MIN (y + height, cgrid->height); - ch = CHARS (cgrid) + (y1 * cgrid->width + x1); + ch = CHARS (cgrid) + (y1 * cgrid->width); + attrs = ATTRS (cgrid) + (y1 * cgrid->width); for (yy = y1; yy < y2; yy++) { - for (xx = x1; xx < x2; xx++) + for (xx = x1; xx < x2; xx++) { ch[xx] = ' '; + if (bg) { + if (!attrs[xx].bg) + attrs[xx].bg = g_new (GdkColor, 1); + + *attrs[xx].bg = *bg; + } else { + if (attrs[xx].bg) + g_free (attrs[xx].bg); + + attrs[xx].bg = NULL; + } + } + ch += cgrid->width; + attrs += cgrid->width; } if (GTK_WIDGET_DRAWABLE (cgrid) && !cgrid->frozen) @@ -378,11 +397,12 @@ gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height) } void -gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel, char ch) +gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char ch) { char *chars; struct attr *attrs; - + int idx; + g_return_if_fail (cgrid != NULL); g_return_if_fail (GMC_IS_CHAR_GRID (cgrid)); @@ -390,31 +410,55 @@ gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulon || (y < 0) || (y >= cgrid->height)) return; - chars = CHARS (cgrid); - attrs = ATTRS (cgrid); + idx = y * cgrid->width + x; - chars[y * cgrid->width + x] = ch; - attrs[y * cgrid->width + x].fg = fg_pixel; - attrs[y * cgrid->width + x].bg = bg_pixel; + chars = CHARS (cgrid) + idx; + attrs = ATTRS (cgrid) + idx; + + *chars = ch; + + if (fg) { + if (!attrs->fg) + attrs->fg = g_new (GdkColor, 1); + + *attrs->fg = *fg; + } else { + if (attrs->fg) + g_free (attrs->fg); + + attrs->fg = NULL; + } + + if (bg) { + if (!attrs->bg) + attrs->bg = g_new (GdkColor, 1); + + *attrs->bg = *bg; + } else { + if (attrs->bg) + g_free (attrs->bg); + + attrs->bg = NULL; + } if (GTK_WIDGET_DRAWABLE (cgrid) && !cgrid->frozen) update_region (cgrid, x, y, 1, 1); } void -gmc_char_grid_put_string (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel, char *str) +gmc_char_grid_put_string (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char *str) { g_return_if_fail (str != NULL); - gmc_char_grid_put_text (cgrid, x, y, fg_pixel, bg_pixel, str, strlen (str)); + gmc_char_grid_put_text (cgrid, x, y, fg, bg, str, strlen (str)); } void -gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel, char *text, int length) +gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char *text, int length) { char *chars; struct attr *attrs; - int i, pos; + int i, pos, idx; g_return_if_fail (cgrid != NULL); g_return_if_fail (GMC_IS_CHAR_GRID (cgrid)); @@ -429,8 +473,31 @@ gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulon for (i = 0, pos = x; (i < length) && (pos < cgrid->width); i++, pos++) { *chars++ = *text++; - attrs->fg = fg_pixel; - attrs->bg = bg_pixel; + + if (fg) { + if (!attrs->fg) + attrs->fg = g_new (GdkColor, 1); + + *attrs->fg = *fg; + } else { + if (attrs->fg) + g_free (attrs->fg); + + attrs->fg = NULL; + } + + if (bg) { + if (!attrs->bg) + attrs->bg = g_new (GdkColor, 1); + + *attrs->bg = *bg; + } else { + if (attrs->bg) + g_free (attrs->bg); + + attrs->bg = NULL; + } + attrs++; } @@ -540,8 +607,8 @@ gmc_char_grid_real_size_changed (GmcCharGrid *cgrid, guint width, guint height) for (i = 0; i < (width * height); i++) { chars[i] = ' '; - attrs[i].fg = 0; - attrs[i].bg = 0; + attrs[i].fg = NULL; + attrs[i].bg = NULL; } gtk_widget_queue_resize (GTK_WIDGET (cgrid)); diff --git a/gnome/gmc-chargrid.h b/gnome/gmc-chargrid.h index b91cb7dfc..7d0f4fafa 100644 --- a/gnome/gmc-chargrid.h +++ b/gnome/gmc-chargrid.h @@ -9,6 +9,7 @@ #define GMC_CHARGRID_H +#include #include #include @@ -53,13 +54,10 @@ struct _GmcCharGridClass { guint gmc_char_grid_get_type (void); GtkWidget *gmc_char_grid_new (void); -void gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height); -void gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel, - char ch); -void gmc_char_grid_put_string (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel, - char *str); -void gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel, - char *text, int length); +void gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height, GdkColor *bg); +void gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char ch); +void gmc_char_grid_put_string (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char *str); +void gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char *text, int length); void gmc_char_grid_set_font (GmcCharGrid *cgrid, const char *font_name); void gmc_char_grid_set_size (GmcCharGrid *cgrid, guint width, guint height); diff --git a/gnome/gscreen.c b/gnome/gscreen.c index de2d24fb1..d46cc1a8b 100644 --- a/gnome/gscreen.c +++ b/gnome/gscreen.c @@ -95,6 +95,7 @@ x_fill_panel (WPanel *panel) { const int top = panel->count; const int items = panel->format->items; + const int selected = panel->selected; GtkCList *cl = GTK_CLIST (panel->list); int i, col, type_col, color; char **texts; @@ -132,6 +133,9 @@ x_fill_panel (WPanel *panel) if (type_col != -1) panel_file_list_set_type_bitmap (cl, i, type_col, color, fe); } + /* This is needed as the gtk_clist_append changes selected under us :-( */ + panel->selected = selected; + select_item (panel); gtk_clist_thaw (GTK_CLIST (cl)); free (texts); } @@ -332,6 +336,8 @@ static struct { { "Rename/move..", (context_menu_callback) ren_cmd }, { "Delete...", (context_menu_callback) delete_cmd }, { "Link...", (context_menu_callback) link_cmd }, + { "Symlink...", (context_menu_callback) symlink_cmd }, + { "Edit symlink...", (context_menu_callback) edit_symlink_cmd }, { NULL, NULL }, }; @@ -738,10 +744,8 @@ panel_realized (GtkWidget *file_list, WPanel *panel) if (drag_directory && drag_directory_ok){ gtk_widget_show (drag_directory_ok); gtk_widget_show (drag_directory); -#if 0 gdk_dnd_set_drag_shape (drag_directory->window, &hotspot, drag_directory_ok->window, &hotspot); -#endif } /* DND: Drag setup */ diff --git a/gnome/gwidget.c b/gnome/gwidget.c index d9f26db94..54940df91 100644 --- a/gnome/gwidget.c +++ b/gnome/gwidget.c @@ -161,6 +161,14 @@ entry_click (GtkWidget *widget, GdkEvent *event, WInput *in) dlg_select_widget (in->widget.parent, in); } +static void +entry_release (GtkEditable *entry, GdkEvent *event, WInput *in) +{ + in->point = entry->current_pos; + in->mark = (entry->current_pos == entry->selection_start_pos) ? + entry->selection_end_pos : entry->selection_start_pos; +} + int x_create_input (Dlg_head *h, widget_data parent, WInput *in) { @@ -171,8 +179,12 @@ x_create_input (Dlg_head *h, widget_data parent, WInput *in) in->widget.wdata = (widget_data) entry; gtk_entry_set_text (GTK_ENTRY (entry), in->buffer); gtk_entry_set_position (GTK_ENTRY (entry), in->point); + gtk_signal_connect (GTK_OBJECT (entry), "button_press_event", GTK_SIGNAL_FUNC (entry_click), in); + + gtk_signal_connect (GTK_OBJECT (entry), "button_release_event", + GTK_SIGNAL_FUNC (entry_release), in); return 1; } @@ -186,7 +198,9 @@ x_update_input (WInput *in) return; gtk_entry_set_text (entry, in->buffer); + printf ("POniendo el putno en %d\n", in->point); gtk_entry_set_position (entry, in->point); + gtk_widget_draw (GTK_WIDGET (entry), NULL); } /* Listboxes */ diff --git a/gnome/layout b/gnome/layout index 6b214ccb6..6a558d188 100644 --- a/gnome/layout +++ b/gnome/layout @@ -591,3 +591,27 @@ flags= [sort-Widget-radio-1] geometry=1,1,1,6 flags=n + +[quick_symlink-Widget-input-2] +geometry=0,2,7,1 +flags=ew + +[quick_symlink-Widget-input-1] +geometry=0,4,7,1 +flags=ew + +[quick_symlink-Widget-label-1] +geometry=0,1,7,1 +flags=w + +[quick_symlink-Widget-label-2] +geometry=0,3,7,1 +flags= + +[quick_symlink-Widget-ok] +geometry=2,6,1,1 +flags=ew + +[quick_symlink-Widget-cancel] +geometry=4,6,1,1 +flags= diff --git a/src/ChangeLog b/src/ChangeLog index acbb00989..4f25e77ba 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,20 @@ +Wed Mar 11 19:02:48 1998 Miguel de Icaza + + * view.c: Lots of changes: Split the X11 code from the main view + program. This is needed to cleanly support the addition of the + Gnome version of the file viewer; + + New names for old functions (just a view_ prefix): + view_add_character, view_add_string, view_gotoyx, view_set_color, + view_display_clean. Now all of them take a WView argument (which + is ignored in the macro for the text edition). This is to support + multiple open views at once. + + * boxes.c (symlink_dialog): Enable ok/cancel buttons for the Gnome edition. + + * cmd.c (link_cmd, symlink_cmd): Provide the filename to operate + on. + Tue Mar 10 20:41:45 1998 Miguel de Icaza * cmd.c (unselect_cmd_panel, select_cmd_panel): To avoid races on diff --git a/src/boxes.c b/src/boxes.c index 7beee62b5..9ae2f2440 100644 --- a/src/boxes.c +++ b/src/boxes.c @@ -685,7 +685,8 @@ void symlink_dialog (char *existing, char *new, char **ret_existing, { QuickDialog Quick_input; QuickWidget quick_widgets [] = { -#ifdef HAVE_TK +#undef INPUT_INDEX +#if defined(HAVE_TK) || defined(HAVE_GNOME) #define INPUT_INDEX 2 { quick_button, 0, 1, 0, 1, "&Cancel", 0, B_CANCEL, 0, 0, XV_WLAY_DONTCARE, "cancel" }, @@ -694,10 +695,10 @@ void symlink_dialog (char *existing, char *new, char **ret_existing, #else #define INPUT_INDEX 0 #endif - { quick_input, 4, 80, 5, 8, "", 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, "input-1" }, - { quick_label, 4, 80, 4, 8, "", 0, 0, 0, 0, XV_WLAY_BELOWOF, "label-1" }, - { quick_input, 4, 80, 3, 8, "", 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, "input-2" }, - { quick_label, 4, 80, 2, 8, "", 0, 0, 0, 0, XV_WLAY_DONTCARE, "label-2" }, + { quick_input, 6, 80, 5, 8, "", 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, "input-1" }, + { quick_label, 6, 80, 4, 8, "", 0, 0, 0, 0, XV_WLAY_BELOWOF, "label-1" }, + { quick_input, 6, 80, 3, 8, "", 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, "input-2" }, + { quick_label, 6, 80, 2, 8, "", 0, 0, 0, 0, XV_WLAY_DONTCARE, "label-2" }, { 0 } }; Quick_input.xlen = 64; diff --git a/src/cmd.c b/src/cmd.c index 3816903ec..0b96f39dd 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -969,17 +969,18 @@ view_other_cmd (void) } #ifndef OS2_NT -static void do_link (int symbolic_link) +static void +do_link (int symbolic_link, char *fname) { struct stat s; char *dest, *src; int stat_r; if (!symbolic_link){ - stat_r = mc_stat (selection (cpanel)->fname, &s); + stat_r = mc_stat (fname, &s); if (stat_r != 0){ message (1, " Error ", " Couldn't stat %s \n %s ", - selection (cpanel)->fname, unix_error_string (errno)); + fname, unix_error_string (errno)); return; } if (!S_ISREG (s.st_mode)) @@ -987,7 +988,7 @@ static void do_link (int symbolic_link) } if (!symbolic_link){ - src = copy_strings (" Link ", name_trunc (selection (cpanel)->fname, 46), + src = copy_strings (" Link ", name_trunc (fname, 46), " to:", NULL); dest = input_expand_dialog (" Link ", src, ""); free (src); @@ -998,11 +999,11 @@ static void do_link (int symbolic_link) return; } save_cwds_stat (); - if (-1 == mc_link (selection (cpanel)->fname, dest)) + if (-1 == mc_link (fname, dest)) message (1, " Error ", " link: %s ", unix_error_string (errno)); } else { #ifdef OLD_SYMLINK_VERSION - symlink_dialog (selection (cpanel)->fname, "", &dest, &src); + symlink_dialog (fname, "", &dest, &src); #else /* suggest the full path for symlink */ char s[MC_MAXPATHLEN]; @@ -1011,7 +1012,7 @@ static void do_link (int symbolic_link) strcpy(s, cpanel->cwd); if ( ! ((s[0] == '/') && (s[1] == 0))) strcat(s, "/"); - strcat(s, selection (cpanel)->fname); + strcat(s, fname); if (get_other_type () == view_listing) strcpy(d, opanel->cwd); else @@ -1045,12 +1046,12 @@ static void do_link (int symbolic_link) void link_cmd (void) { - do_link (0); + do_link (0, selection (cpanel)->fname); } void symlink_cmd (void) { - do_link (1); + do_link (1, selection (cpanel)->fname); } void edit_symlink_cmd (void) diff --git a/src/screen.c b/src/screen.c index 55d9f87e0..a7bd7bcd0 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2060,7 +2060,6 @@ static key_map panel_keymap [] = { { '\\', unselect_cmd }, { '-', unselect_cmd }, { XCTRL('r'), reread_cmd }, - { ALT('o'), view_other_cmd }, #endif #ifndef HAVE_X @@ -2137,7 +2136,7 @@ panel_callback (Dlg_head *h, WPanel *panel, int msg, int par) return 1; case WIDGET_DRAW: -#ifndef HAVE_XVIEW +#ifndef HAVE_XVIEW paint_panel (panel); #else show_dir (panel); diff --git a/src/view.c b/src/view.c index 6a86f298b..7fa90c792 100644 --- a/src/view.c +++ b/src/view.c @@ -25,6 +25,7 @@ /* }}} */ /* {{{ Declarations */ #include +#include "x.h" #include #ifdef __os2__ # include @@ -49,7 +50,6 @@ #include #include #include - #include "mem.h" #include "mad.h" #include "util.h" @@ -212,10 +212,7 @@ view_destroy (WView *view) view_done (view); if (view->have_frame) delete_hook (&select_file_hook, view_hook); -#ifdef HAVE_TK - free (view->cache); - free (view->color_cache); -#endif + x_destroy_view (view); } static int @@ -500,13 +497,6 @@ static char *load_view_file (WView *view, char *filename) return set_view_init_error (view, " Can't view: not a regular file "); } -#ifdef JUST_FOR_CULTURAL_INFORMATION - /* #ifed out because now we have growing buffers :-) */ - if (view->s.st_size < 1) { - close_view_file (view); - return set_view_init_error (view, " Can't view empty file "); - } -#endif if (view->s.st_size == 0){ /* Must be one of those nice files that grow (/proc) */ close_view_file (view); @@ -675,77 +665,9 @@ view_init (WView *view, char *_command, char *_file, int start_line) /* }}} */ -/* {{{ X Window code */ -#ifdef HAVE_TK -#include "tkmain.h" - -/* Accepts the dim command with the width and the height in characters */ -static int -tk_viewer_callback (ClientData cd, Tcl_Interp *interp, int ac, char *av[]) -{ - WView *view = (WView *) cd; - - if (av [1][0] != 'd') - return TCL_OK; - view->widget.cols = atoi (av [2]); - view->widget.lines = atoi (av [3]); - return TCL_OK; -} - -void -x_create_viewer (WView *view) -{ - char *cmd; - widget_data parent; - - /* First, check if our parent is ".", if this is the case, then - * create a stand alone viewer, otherwise, we create a paneled - * version of the viewer - */ - - if (view->have_frame){ - parent = view->widget.wcontainer; - } else { - parent = view->widget.parent->wdata; - } - cmd = tk_new_command (parent, view, tk_viewer_callback, 'v'); - - tk_evalf ("newview %d %s %s %s", view->have_frame, - view->have_frame ? (char *) view->widget.wcontainer : "{}", - cmd+1, cmd); -} -#else -# define x_create_viewer(x) -#endif -/* }}} */ - /* {{{ Screen update functions */ -#ifdef HAVE_TK -static void -view_status (WView *view) -{ - char *window = wtk_win (view->widget); - - if (!view->status_shown){ - view->status_shown = 0; - - tk_evalf ("view_update_info %s {%s} {%d} {%s} {%s}", - window, name_trunc (view->filename ? view->filename: - view->command ? view->command:"", 20), - -view->start_col, size_trunc (view->s.st_size), - view->growing_buffer ? "[grow]":"[]"); - } -} - -static void -view_percent (WView *view, int p, int w) -{ - fprintf (stderr, "Missing tk view_percent\n"); -} - -#else /* HAVE_TK */ - +#ifndef HAVE_X static void view_percent (WView *view, int p, int w) { @@ -784,7 +706,7 @@ view_status (WView *view) if (view->hex_mode) printw ("Offset 0x%08x", view->edit_cursor); else - printw ("Col %d", -view->start_col); + printw ("Col %d", -view->start_col); } if (w > 60){ widget_move (view, view->have_frame, 42); @@ -799,182 +721,15 @@ view_status (WView *view) if (view->hex_mode) view_percent (view, view->edit_cursor - view->first, w); else - view_percent (view, view->start_display - view->first, w); + view_percent (view, view->start_display - view->first, w); } attrset (SELECTED_COLOR); } -#endif HAVE_TK -#ifdef HAVE_TK - -#define DEF_COLOR 0 -#define BOLD_COLOR 1 -#define UNDERLINE_COLOR 2 -#define MARK_COLOR 3 - -/* The major part of the Tk code deals with caching a line (the - * current one) of text to avoid expensive calls to the Tk text widget - * callback. - * - * We cache all this information on view->cache and the colors on - * view->color_cache. - * - * FIXME: the cache does not know about the contents of the physical - * text widget (depends on your concept of physical), so if we happen - * to hit the case where row is decremented in the void display () routine, - * we will end up with a clean line. - */ - -static int current_color; - -static void -set_color (int font) -{ - current_color = font; -} +#define view_set_color(view,font) attrset (font) static inline void -display_clean(WView *view, int h, int w) -{ - char *win = wtk_win (view->widget); - - tk_evalf ("cleanview %s.v.view", win); -} - -static void -add_character (WView *view, int c) -{ - view->cache [view->dest] = c; - view->color_cache [view->dest] = current_color; -} - -static inline void -add_string (WView *view, char *s) -{ - while (*s) - add_character (view, *s++); -} - -static char * -get_tk_tag_name (int color) -{ - /* Those names are the names of the tags in the Tk source */ - static char *color_tag_names [] = { - "normal", "bold", "underline", "mark" - }; - - return color_tag_names [color]; -} - -/* - * Tk: Flushes the contents of view->cache to the Tk text widget - * - * We get the command information and call the command directly - * to avoid escaping the view->cache contents. - */ -static void -flush_line (WView *view) -{ - char *win = wtk_win (view->widget); - int row = view->current_line; - char *text_name; - Tcl_CmdInfo info; - int i, prev_color; - char str_row [30]; - char *av [5]; - int len = strlen (view->cache); - - /* Fetch the address and clientData for the view */ - text_name = copy_strings (win, ".v.view", 0); - Tcl_GetCommandInfo (interp, text_name, &info); - - /* Setup arguments to the command: - * $win.v.view insert @$row,0 $view->cache - */ - sprintf (str_row, "%d.0", row); - i = 0; - av [i++] = text_name; - av [i++] = "insert"; - av [i++] = str_row; - av [i++] = view->cache; - - /* Call the callback :-) */ - (*info.proc) (info.clientData, interp, i, av); - bzero (view->cache, view->cache_len); - - /* Colorize the line */ - for (prev_color = 0, i = 0; i < len; i++){ - int new_color_start; - char *color_name; - - if (view->color_cache [i] == prev_color) - continue; - - new_color_start = i; - - prev_color = view->color_cache [i]; - - for (;i < len && view->color_cache [i] == prev_color; i++) - ; - - color_name = get_tk_tag_name (prev_color); - tk_evalf ("%s tag add %s %d.%d %d.%d", - text_name, color_name, - row, new_color_start-1, - row, i); - } - - bzero (view->color_cache, view->cache_len); - view->last_col = 0; - free (text_name); -} - -/* Tk: Mantains the line cache */ -void -view_gotoyx (WView *view, int row, int col) -{ - if (row != view->current_line){ - flush_line (view); - } - view->current_line = row; - - /* In case the user has resized the viewer */ - if (col > view->cache_len){ - char *new; - - new = xmalloc (col + 1, "cache"); - strcpy (new, view->cache); - free (view->cache); - view->cache = new; - - new = xmalloc (col + 1, "cache"); - strcpy (new, view->color_cache); - free (view->color_cache); - view->color_cache = new; - - view->cache_len = col; - } - - view->dest = col; - for (; view->last_col+1 < col; view->last_col++){ - view->cache [view->last_col] = ' '; - view->color_cache [view->last_col] = current_color; - } - view->last_col = col; -} - -#else - -#define BOLD_COLOR MARKED_COLOR -#define UNDERLINE_COLOR VIEW_UNDERLINED_COLOR -#define MARK_COLOR SELECTED_COLOR -#define DEF_COLOR NORMAL_COLOR - -#define set_color(font) attrset (font) - - -static inline void -display_clean (WView *view, int height, int width) +view_display_clean (WView *view, int height, int width) { /* FIXME: Should I use widget_erase only and repaint the box? */ if (view->have_frame){ @@ -990,10 +745,22 @@ display_clean (WView *view, int height, int width) widget_erase ((Widget *) view); } -#define add_character(view,c) addch (c) -#define add_string(view,s) addstr (s) -#define view_gotoyx(v,r,c) widget_move (v,r,c) +#define view_add_character(view,c) addch (c) +#define view_add_string(view,s) addstr (s) +#define view_gotoyx(v,r,c) widget_move (v,r,c) +#endif +#ifndef HAVE_TK +/* Both the text mode and gnome editions use this */ +#define BOLD_COLOR MARKED_COLOR +#define UNDERLINE_COLOR VIEW_UNDERLINED_COLOR +#define MARK_COLOR SELECTED_COLOR +#define DEF_COLOR NORMAL_COLOR +#endif + +#ifndef PORT_HAS_VIEW_FREEZE +# define view_freeze(view) +# define view_thaw(view) #endif /* Shows the file pointed to by *start_display on view_win */ @@ -1001,12 +768,14 @@ static long display (WView *view) { #ifdef HAVE_X -# define frame_shift 0 +# define frame_shift 0 +# define STATUS_LINES 0 #else const int frame_shift = view->have_frame; +# define STATUS_LINES 1 #endif int col = 0 + frame_shift; - int row = 1 + frame_shift; + int row = STATUS_LINES + frame_shift; int height, width; long from; int c; @@ -1016,16 +785,17 @@ display (WView *view) height = view->widget.lines - frame_shift; width = view->widget.cols - frame_shift; from = view->start_display; - set_color (DEF_COLOR); + view_set_color (view, DEF_COLOR); - display_clean (view, height, width); + view_freeze (view); + view_display_clean (view, height, width); /* Optionally, display a ruler */ if ((!view->hex_mode) && (ruler)){ char r_buff[4]; int cl; - set_color (BOLD_COLOR); + view_set_color (view, BOLD_COLOR); for (c = frame_shift; c < width; c++) { cl = c-view->start_col; if (ruler == 1) @@ -1038,17 +808,17 @@ display (WView *view) else if ((cl % 5) == 0) r_buff[0] = '*'; - add_character (view, r_buff[0]); + view_add_character (view, r_buff[0]); if ((cl != 0) && (cl % 10) == 0){ sprintf(r_buff, "%03d", cl); if (ruler == 1) widget_move (view, row + 1, c - 1); else widget_move (view, row + height - 3, c - 1); - add_string (view, r_buff); + view_add_string (view, r_buff); } } - set_color (DEF_COLOR); + view_set_color (view, DEF_COLOR); if (ruler == 1) row += 2; else @@ -1073,7 +843,7 @@ display (WView *view) /* Print the hex offset */ sprintf (hex_buff, "%05X", (int) (from - view->first)); widget_move (view, row, frame_shift); - add_string (view, hex_buff); + view_add_string (view, hex_buff); /* Hex dump starts from column seven */ col = 7; @@ -1087,14 +857,14 @@ display (WView *view) c = curr->value; curr = curr->next; boldflag = 3; - set_color (7); + view_set_color (view, 7); } else c = (unsigned char) get_byte (view, from); if (view->found_len && from >= view->search_start && from < view->search_start + view->found_len){ boldflag = 1; - set_color (BOLD_COLOR); + view_set_color (view, BOLD_COLOR); } /* Display the navigation cursor */ if (from == view->edit_cursor) { @@ -1103,39 +873,39 @@ display (WView *view) view->cursor_col = col; } boldflag = 2; - set_color (view->view_side == view_side_left ? 15 : 31); + view_set_color (view, view->view_side == view_side_left ? 15 : 31); } /* Print a hex number (sprintf is too slow) */ hex_buff [0] = hex_char [(c >> 4)]; hex_buff [1] = hex_char [c & 15]; view_gotoyx (view, row, col); - add_string (view, hex_buff); + view_add_string (view, hex_buff); col += 3; /* Turn off the cursor or changed byte highlighting here */ if (boldflag > 1) - set_color (DEF_COLOR); + view_set_color (view, DEF_COLOR); if ((bytes & 3) == 3 && bytes + 1 < view->bytes_per_line){ /* Turn off the search highlighting */ if (boldflag == 1 && from == view->search_start + view->found_len - 1) - set_color (DEF_COLOR); + view_set_color (view, DEF_COLOR); /* Hex numbers are printed in the groups of four */ /* Groups are separated by a vline */ - add_character (view, ' '); + view_add_character (view, ' '); one_vline (); view_gotoyx (view, row, col + 1); col += 2; if (boldflag && from==view->search_start+view->found_len-1) - set_color (BOLD_COLOR); + view_set_color (view, BOLD_COLOR); } if (boldflag && from < view->search_start + view->found_len - 1 && bytes != view->bytes_per_line - 1) - add_character (view, ' '); + view_add_character (view, ' '); /* Print the corresponding ascii character */ view_gotoyx (view, row, text_start + bytes); @@ -1146,13 +916,13 @@ display (WView *view) default: break; case 1: - set_color (BOLD_COLOR); + view_set_color (view, BOLD_COLOR); goto setcursor; case 2: - set_color (view->view_side == view_side_left ? 31 : 15); + view_set_color (view, view->view_side == view_side_left ? 31 : 15); goto setcursor; case 3: - set_color (7); + view_set_color (view, 7); setcursor: if (view->view_side == view_side_right){ @@ -1160,11 +930,11 @@ display (WView *view) view->cursor_row = row; } } - add_character (view, c); + view_add_character (view, c); if (boldflag){ boldflag = 0; - set_color (DEF_COLOR); + view_set_color (view, DEF_COLOR); } } } @@ -1204,16 +974,16 @@ display (WView *view) col--; boldflag = 1; if (get_byte (view, from - 1) == '_' && get_byte (view, from + 1) != '_') - set_color (UNDERLINE_COLOR); + view_set_color (view, UNDERLINE_COLOR); else - set_color (BOLD_COLOR); + view_set_color (view, BOLD_COLOR); continue; } } if (view->found_len && from >= view->search_start && from < view->search_start + view->found_len){ boldflag = 1; - set_color (MARK_COLOR); + view_set_color (view, MARK_COLOR); } if (col >= frame_shift-view->start_col && col < width-view->start_col) @@ -1222,12 +992,12 @@ display (WView *view) if (!is_printable (c)) c = '.'; - add_character (view, c); + view_add_character (view, c); } col++; if (boldflag){ boldflag = 0; - set_color (DEF_COLOR); + view_set_color (view, DEF_COLOR); } /* Very last thing */ @@ -1235,11 +1005,11 @@ display (WView *view) get_byte (view, from+1); } #ifdef HAVE_TK - /* Tk: This flushes the last line */ view_gotoyx (view, view->current_line+1, 0); #endif } view->last = from; + view_thaw (view); return from; } @@ -1709,11 +1479,11 @@ search (WView *view, char *text, int (*search)(WView *, char *, char *, int)) update_activate = 0; for (; ; isatbeg = 1, free (s)){ -#ifdef HAVE_TK +#ifdef HAVE_X static int count; if ((count++ % 32) == 0) - tk_dispatch_all (); + x_flush_events (); if (!d->running) break; #endif @@ -2532,9 +2302,9 @@ view (char *_command, char *_file, int *move_dir_p, int start_line) *move_dir_p = 0; return !error; } -#else -Dlg_head *view_dlg; +#endif +#ifndef PORT_WANTS_VIEW void view_adjust_size (Dlg_head *h) { @@ -2548,6 +2318,9 @@ view_adjust_size (Dlg_head *h) widget_set_size (&bar->widget, LINES-1, 0, 1, COLS); } +/* Only the text mode edition uses this */ +Dlg_head *view_dlg; + /* Real view only */ int view (char *_command, char *_file, int *move_dir_p, int start_line) @@ -2556,20 +2329,23 @@ view (char *_command, char *_file, int *move_dir_p, int start_line) int error; WView *wview; WButtonBar *bar; - + Dlg_head *our_dlg; /* Create dialog and widgets, put them on the dialog */ - view_dlg = create_dlg (0, 0, LINES, COLS, midnight_colors, + our_dlg = create_dlg (0, 0, LINES, COLS, midnight_colors, view_mode_callback, "[Internal File Viewer]", "view", DLG_NONE); +#ifndef HAVE_X + view_dlg = our_dlg; +#endif wview = view_new (0, 0, COLS, LINES-1, 0); bar = buttonbar_new (1); - add_widget (view_dlg, wview); - add_widget (view_dlg, bar); + add_widget (our_dlg, wview); + add_widget (our_dlg, bar); error = view_init (wview, _command, _file, start_line); if (move_dir_p) @@ -2580,11 +2356,11 @@ view (char *_command, char *_file, int *move_dir_p, int start_line) * be aware of it */ if (!error){ - run_dlg (view_dlg); + run_dlg (our_dlg); if (move_dir_p) *move_dir_p = wview->move_dir; } - destroy_dlg (view_dlg); + destroy_dlg (our_dlg); return !error; } @@ -2673,9 +2449,7 @@ view_callback (Dlg_head *h, WView *v, int msg, int par) return 1; case WIDGET_FOCUS: -#ifdef HAVE_TK - tk_evalf ("focus %s.v.view", wtk_win (view->widget)); -#endif + x_focus_view (view); view_labels (view); return 1; @@ -2707,17 +2481,9 @@ view_new (int y, int x, int cols, int lines, int is_panel) view->have_frame = is_panel; view->last_byte = -1; view->monitor = 0; -#ifdef HAVE_TK - view->status_shown = 0; - view->current_line = 1; - view->cache_len = 80; - view->last_col = 0; - view->cache = xmalloc (81, "view->cache"); - view->color_cache = xmalloc (81, "view->cache"); - view->direction = 1; - bzero (view->cache, 81); - view->dest = 0; -#endif + + x_init_view (view); + widget_want_cursor (view->widget, 0); return view; diff --git a/src/view.h b/src/view.h index 9dfef7277..54c596da5 100644 --- a/src/view.h +++ b/src/view.h @@ -87,7 +87,12 @@ typedef struct { int last_col; /* last column used */ int status_shown; /* Have we show the file information? */ #endif - + +#ifdef HAVE_GNOME + int current_x, current_y; /* Current x,y position */ + int color; /* Current color */ +#endif + int move_dir; /* return value from widget: * 0 do nothing * -1 view previous file @@ -141,4 +146,32 @@ struct hexedit_change_node { unsigned char value; }; +#ifdef HAVE_TK +#define DEF_COLOR 0 +#define BOLD_COLOR 1 +#define UNDERLINE_COLOR 2 +#define MARK_COLOR 3 +#endif + +#ifdef HAVE_X +#ifdef WANT_WIDGETS +void view_add_character (WView *view, int c); +void view_add_string (WView *view, char *s); +void view_gotoyx (WView *view, int r, int c); +void view_set_color (WView *view, int font); +void view_display_clean (WView *view, int h, int w); + +#ifdef PORT_HAS_VIEW_FREEZE +void view_freeze (WView *view); +void view_thaw (WView *view); +#endif + +#endif +#else +# define x_init_view(x) +# define x_destroy_view(x) +# define x_create_viewer(x) +# define x_focus_view(x) +#endif + #endif /* __VIEW_H */ diff --git a/src/widget.c b/src/widget.c index 9ab4a6a33..8d27f25cc 100644 --- a/src/widget.c +++ b/src/widget.c @@ -1425,41 +1425,41 @@ static struct { void (*fn)(WInput *in); } input_map [] = { /* Motion */ - { XCTRL('a'), beginning_of_line }, - { KEY_HOME, beginning_of_line }, - { KEY_A1, beginning_of_line }, - { XCTRL('e'), end_of_line }, - { KEY_END, end_of_line }, - { KEY_C1, end_of_line }, - { KEY_LEFT, key_left }, - { XCTRL('b'), backward_char }, - { ALT('b'), backward_word }, - { KEY_RIGHT, key_right }, - { XCTRL('f'), forward_char }, - { ALT('f'), forward_word }, - - /* Editing */ - { 0177, backward_delete }, - { KEY_BACKSPACE,backward_delete }, - { XCTRL('h'), backward_delete }, - { KEY_DC, delete_char }, - { XCTRL('d'), delete_char }, - { ALT('d'), kill_word }, + { XCTRL('a'), beginning_of_line }, + { KEY_HOME, beginning_of_line }, + { KEY_A1, beginning_of_line }, + { XCTRL('e'), end_of_line }, + { KEY_END, end_of_line }, + { KEY_C1, end_of_line }, + { KEY_LEFT, key_left }, + { XCTRL('b'), backward_char }, + { ALT('b'), backward_word }, + { KEY_RIGHT, key_right }, + { XCTRL('f'), forward_char }, + { ALT('f'), forward_word }, + + /* Editing */ + { 0177, backward_delete }, + { KEY_BACKSPACE, backward_delete }, + { XCTRL('h'), backward_delete }, + { KEY_DC, delete_char }, + { XCTRL('d'), delete_char }, + { ALT('d'), kill_word }, { ALT(KEY_BACKSPACE), back_kill_word }, - { ALT(XCTRL('h')), back_kill_word }, - { ALT(127), back_kill_word }, + { ALT(XCTRL('h')), back_kill_word }, + { ALT(127), back_kill_word }, /* Region manipulation */ - { 0, set_mark }, - { XCTRL('w'), kill_region }, - { ALT('w'), kill_save }, - { XCTRL('y'), yank }, - { XCTRL('k'), kill_line }, - - /* History */ - { ALT('p'), hist_prev }, - { ALT('n'), hist_next }, - { ALT('h'), show_hist }, + { 0, set_mark }, + { XCTRL('w'), kill_region }, + { ALT('w'), kill_save }, + { XCTRL('y'), yank }, + { XCTRL('k'), kill_line }, + + /* History */ + { ALT('p'), hist_prev }, + { ALT('n'), hist_next }, + { ALT('h'), show_hist }, /* Completion */ { ALT('\t'), complete }, diff --git a/tk/tkview.c b/tk/tkview.c index 791dbbc6b..81bf634a3 100644 --- a/tk/tkview.c +++ b/tk/tkview.c @@ -22,3 +22,244 @@ smaller than a complete tkview.c program, and it's just interface code so that the code knows about the window resize. */ + +#include "dlg.h" +#include "view.h" +#include "tkmain.h" + +x_init_view (WView *view) +{ + view->status_shown = 0; + view->current_line = 1; + view->cache_len = 80; + view->last_col = 0; + view->cache = xmalloc (81, "view->cache"); + view->color_cache = xmalloc (81, "view->cache"); + view->direction = 1; + bzero (view->cache, 81); + view->dest = 0; +} + +void +x_destroy_view (WView *view) +{ + free (view->cache); + free (view->color_cache); +} + + +/* Accepts the dim command with the width and the height in characters */ +static int +tk_viewer_callback (ClientData cd, Tcl_Interp *interp, int ac, char *av[]) +{ + WView *view = (WView *) cd; + + if (av [1][0] != 'd') + return TCL_OK; + view->widget.cols = atoi (av [2]); + view->widget.lines = atoi (av [3]); + return TCL_OK; +} + +void +x_create_viewer (WView *view) +{ + char *cmd; + widget_data parent; + + /* First, check if our parent is ".", if this is the case, then + * create a stand alone viewer, otherwise, we create a paneled + * version of the viewer + */ + + if (view->have_frame){ + parent = view->widget.wcontainer; + } else { + parent = view->widget.parent->wdata; + } + cmd = tk_new_command (parent, view, tk_viewer_callback, 'v'); + + tk_evalf ("newview %d %s %s %s", view->have_frame, + view->have_frame ? (char *) view->widget.wcontainer : "{}", + cmd+1, cmd); +} + +void +x_focus_view (WView *view) +{ + tk_evalf ("focus %s.v.view", wtk_win (view->widget)); +} + +void +view_status (WView *view) +{ + char *window = wtk_win (view->widget); + + if (!view->status_shown){ + view->status_shown = 0; + + tk_evalf ("view_update_info %s {%s} {%d} {%s} {%s}", + window, name_trunc (view->filename ? view->filename: + view->command ? view->command:"", 20), + -view->start_col, size_trunc (view->s.st_size), + view->growing_buffer ? "[grow]":"[]"); + } +} + +void +view_percent (WView *view, int p, int w) +{ + fprintf (stderr, "Missing tk view_percent\n"); +} + +/* The major part of the Tk code deals with caching a line (the + * current one) of text to avoid expensive calls to the Tk text widget + * callback. + * + * We cache all this information on view->cache and the colors on + * view->color_cache. + * + * FIXME: the cache does not know about the contents of the physical + * text widget (depends on your concept of physical), so if we happen + * to hit the case where row is decremented in the void display () routine, + * we will end up with a clean line. + */ + +static int current_color; + +void +view_set_color (int font) +{ + current_color = font; +} + +void +view_display_clean(WView *view, int h, int w) +{ + char *win = wtk_win (view->widget); + + tk_evalf ("cleanview %s.v.view", win); +} + +void +view_add_character (WView *view, int c) +{ + view->cache [view->dest] = c; + view->color_cache [view->dest] = current_color; +} + +void +view_add_string (WView *view, char *s) +{ + while (*s) + add_character (view, *s++); +} + +static char * +get_tk_tag_name (int color) +{ + /* Those names are the names of the tags in the Tk source */ + static char *color_tag_names [] = { + "normal", "bold", "underline", "mark" + }; + + return color_tag_names [color]; +} + +/* + * Tk: Flushes the contents of view->cache to the Tk text widget + * + * We get the command information and call the command directly + * to avoid escaping the view->cache contents. + */ +static void +flush_line (WView *view) +{ + char *win = wtk_win (view->widget); + int row = view->current_line; + char *text_name; + Tcl_CmdInfo info; + int i, prev_color; + char str_row [30]; + char *av [5]; + int len = strlen (view->cache); + + /* Fetch the address and clientData for the view */ + text_name = copy_strings (win, ".v.view", 0); + Tcl_GetCommandInfo (interp, text_name, &info); + + /* Setup arguments to the command: + * $win.v.view insert @$row,0 $view->cache + */ + sprintf (str_row, "%d.0", row); + i = 0; + av [i++] = text_name; + av [i++] = "insert"; + av [i++] = str_row; + av [i++] = view->cache; + + /* Call the callback :-) */ + (*info.proc) (info.clientData, interp, i, av); + bzero (view->cache, view->cache_len); + + /* Colorize the line */ + for (prev_color = 0, i = 0; i < len; i++){ + int new_color_start; + char *color_name; + + if (view->color_cache [i] == prev_color) + continue; + + new_color_start = i; + + prev_color = view->color_cache [i]; + + for (;i < len && view->color_cache [i] == prev_color; i++) + ; + + color_name = get_tk_tag_name (prev_color); + tk_evalf ("%s tag add %s %d.%d %d.%d", + text_name, color_name, + row, new_color_start-1, + row, i); + } + + bzero (view->color_cache, view->cache_len); + view->last_col = 0; + free (text_name); +} + +/* Tk: Mantains the line cache */ +void +view_gotoyx (WView *view, int row, int col) +{ + if (row != view->current_line){ + flush_line (view); + } + view->current_line = row; + + /* In case the user has resized the viewer */ + if (col > view->cache_len){ + char *new; + + new = xmalloc (col + 1, "cache"); + strcpy (new, view->cache); + free (view->cache); + view->cache = new; + + new = xmalloc (col + 1, "cache"); + strcpy (new, view->color_cache); + free (view->color_cache); + view->color_cache = new; + + view->cache_len = col; + } + + view->dest = col; + for (; view->last_col+1 < col; view->last_col++){ + view->cache [view->last_col] = ' '; + view->color_cache [view->last_col] = current_color; + } + view->last_col = col; +} +#endif