mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-23 21:06:52 +03:00
ad8e2a60ec
-Marc <marc@redhat.com>
270 lines
6.4 KiB
C
270 lines
6.4 KiB
C
/* 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;
|
|
}
|
|
|