123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- /* Tk Viewer stuff.
- Copyright (C) 1995 Miguel de Icaza
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- -----
- This module is here so that I can learn to shut up my mouth.
- I know, Jakub is enjoying this moment, anyways, this code is still
- smaller than a complete tkview.c program, and it's just interface
- code so that the code knows about the window resize.
- */
- #include <stdio.h>
- #define WANT_WIDGETS
- #include "dlg.h"
- #include "view.h"
- #include "tkmain.h"
- void
- 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 (WView *view, 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)
- view_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;
- }
|