eterm/src/activeeterm.c

391 lines
8.6 KiB
C

/*--------------------------------*-C-*---------------------------------*
* File: activeeterm.c
*
* Copyright 1997 Nat Friedman, Massachusetts Institute of Technology
* <ndf@mit.edu>
*
* 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 file contains the glue functions to make active tags work in eterm. */
/*
In order to dingify a program, this plugin file must define the following
functions with the specified behavior. Note that functions can be defined
as macros just fine.
The functions are broken up into two groups. The first group of functions
are the wrapper functions which get called by the main program. These
functions call the internal active tags functions. The second group of
functions are the internal functions which are called by the active
tags functions.
WRAPPER FUNCTIONS
int tag_click( ... )
This should call tag_activate after it has properly assembled the
binding mask and determined the row and column properly. tag_click()
is called from inside the main program.
void tag_pointer_new_position( ... )
This should call show_tag after it has computed the row and column
properly and done whatever processing it needs to do.
void tag_scroll( ... )
void tag_init ( ... )
void tag_sig_child ( ... )
void tag_hide ( ... )
INTERNAL FUNCTIONS
void get_tag_mode(char * mode)
This function stores a string containing the current mode in the
mode parameter. This can be very simple (for example
strcpy(mode, "browser") might be sufficient), or somewhat more complex
for those programs which can change modes, such as rxvt.
int row_width(void)
returns the maximum width of each row.
const char ** get_rows(void)
returns the comparison region. current_row() and current_col() should
be indexes into this region.
void set_tag_highlight(int row, int col, tag_highlight_t highlight)
Highlights the specified character with the specified highlighting.
tag_highlight_t get_tag_highlight(int row, int col)
Returns the current highlighting information for the specified
character.
*/
static const char cvs_ident[] = "$Id$";
#include "feature.h"
#ifdef USE_ACTIVE_TAGS
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "activetags.h"
#include "activeeterm.h"
#include "mem.h" /* From libmej */
/*
WRAPPER FUNCTIONS
*/
void
tag_pointer_new_position(int x, int y)
{
int row, col;
if (!active_tags_enabled)
return;
col = Pixel2Col(x);
row = Pixel2Row(y);
#ifdef ACTIVE_TAG_CLICK_CLUES
if (show_tag(row, col))
set_click_clue_timer();
else {
destroy_click_clue();
unset_click_clue_timer();
}
#else
show_tag(row, col);
#endif
}
void
tag_scroll(int nlines, int row1, int row2)
{
if (!active_tags_enabled)
return;
#ifdef ACTIVE_TAG_CLICK_CLUES
if (tag_screen_scroll(nlines, row1, row2)) {
destroy_click_clue();
unset_click_clue_timer();
}
#else
(void) tag_screen_scroll(nlines, row1, row2);
#endif
}
void
tag_init(void)
{
if (!active_tags_enabled)
return;
tag_env = "X";
#ifdef ACTIVE_TAG_CLICK_CLUES
init_click_clues();
#endif
initialize_tags();
}
#if 0
void
#endif
inline void
tag_hide(void)
{
if (!active_tags_enabled)
return;
erase_tag_highlighting();
}
int
tag_click(int x, int y, unsigned int button, unsigned int keystate)
{
int binding_mask;
int row, col;
int retval;
if (!active_tags_enabled)
return 0;
#ifdef ACTIVE_TAG_CLICK_CLUES
destroy_click_clue();
unset_click_clue_timer();
#endif
/* Build the binding mask. Button3 == 3. We need it to be 4
(100 binary) to fit in the binding mask properly. */
if (button == Button3)
button = TAG_BINDING_BUTTON3;
binding_mask = button;
if (keystate & ShiftMask)
binding_mask |= TAG_BINDING_SHIFT;
if (keystate & ControlMask)
binding_mask |= TAG_BINDING_CONTROL;
if (keystate & Mod1Mask)
binding_mask |= TAG_BINDING_META;
row = Pixel2Row(y);
col = Pixel2Col(x);
retval = tag_activate(row, col, binding_mask);
return retval;
}
/*
INTERNAL FUNCTIONS
*/
/* This function finds the current tag mode and stores it in the 'mode'
parameter. The current mode is equivalent to argv[0] of the program
currently controlling the eterm's terminal. */
void
get_tag_mode(char *mode)
{
char proc_name[1024];
FILE *f;
pid_t pid;
if ((pid = tcgetpgrp(cmd_fd)) == -1) {
fprintf(stderr, "Couldn't get tag mode!\n");
strcpy(mode, "");
return;
}
sprintf(proc_name, "/proc/%d/cmdline", pid);
if ((f = fopen(proc_name, "r")) == NULL) {
fprintf(stderr, "Couldn't open proc!\n");
strcpy(mode, "");
return;
}
fscanf(f, "%s", mode);
fclose(f);
}
/* These were changed to macros and moved into activeeterm.h. -vendu */
#if 0
int
row_width(void)
{
return TermWin.ncol;
}
int
tag_min_row(void)
{
return 0;
}
int
tag_max_row(void)
{
return TermWin.nrow - 1;
}
#endif
void
tag_get_row(int row_num, char **row)
{
/* FIXME: I guess this works :) -vendu */
*row = drawn_text[row_num];
}
int
tag_eterm_color(int tag_color)
{
switch (tag_color) {
case TAG_HIGHLIGHT_BLACK:
return 2;
case TAG_HIGHLIGHT_WHITE:
return 1;
case TAG_HIGHLIGHT_RED:
return 3;
case TAG_HIGHLIGHT_GREEN:
return 4;
case TAG_HIGHLIGHT_YELLOW:
return 5;
case TAG_HIGHLIGHT_BLUE:
return 6;
case TAG_HIGHLIGHT_MAGENTA:
return 7;
case TAG_HIGHLIGHT_CYAN:
return 8;
default:
return -1;
}
}
int
eterm_tag_color(int eterm_color)
{
switch (eterm_color) {
case 0:
return TAG_HIGHLIGHT_NORMAL;
case 7:
return TAG_HIGHLIGHT_MAGENTA;
case 1:
return TAG_HIGHLIGHT_WHITE;
case 2:
return TAG_HIGHLIGHT_BLACK;
case 3:
return TAG_HIGHLIGHT_RED;
case 4:
return TAG_HIGHLIGHT_GREEN;
case 5:
return TAG_HIGHLIGHT_YELLOW;
case 6:
return TAG_HIGHLIGHT_BLUE;
case 8:
return TAG_HIGHLIGHT_CYAN;
default:
return TAG_HIGHLIGHT_NORMAL;
}
}
void
set_tag_highlight(int row, int col, tag_highlight_t highlight)
{
unsigned int rend_mask = 0;
unsigned int back;
unsigned int fore;
/* rend_t ** rp = &(screen.rend[row + TermWin.saveLines - TermWin.view_start][col]); */
if (highlight.attributes & TAG_HIGHLIGHT_RVID)
rend_mask |= RS_RVid;
if (highlight.attributes & TAG_HIGHLIGHT_ULINE)
rend_mask |= RS_Uline;
if (highlight.attributes & TAG_HIGHLIGHT_BOLD)
rend_mask |= RS_Bold;
if (highlight.fg_color == TAG_HIGHLIGHT_NORMAL)
fore = SET_FGCOLOR(0, fgColor);
else
fore = SET_FGCOLOR(0, tag_eterm_color(highlight.fg_color));
if (highlight.bg_color == TAG_HIGHLIGHT_NORMAL)
back = SET_BGCOLOR(0, bgColor);
else
back = SET_BGCOLOR(0, tag_eterm_color(highlight.bg_color));
screen.rend[row + TermWin.saveLines - TermWin.view_start][col] =
rend_mask | fore | back;
}
void
get_tag_highlight(int row, int col, tag_highlight_t * highlight)
{
unsigned int rend;
rend = screen.rend[row + TermWin.saveLines - TermWin.view_start][col];
highlight->attributes = 0;
if (rend & RS_RVid)
highlight->attributes |= TAG_HIGHLIGHT_RVID;
if (rend & RS_Uline)
highlight->attributes |= TAG_HIGHLIGHT_ULINE;
if (rend & RS_Bold)
highlight->attributes |= TAG_HIGHLIGHT_BOLD;
if (rend & RS_Blink)
highlight->attributes |= TAG_HIGHLIGHT_BLINK;
highlight->fg_color = eterm_tag_color(GET_FGCOLOR(rend));
highlight->bg_color = eterm_tag_color(GET_BGCOLOR(rend));
}
/* Set the UID appropriately */
int
set_tag_uid(void)
{
return 1;
}
/* Set stdout for loop actions */
int
set_tag_stdout(void)
{
if (close(1) < 0) {
perror("close");
return 0;
}
if (dup(cmd_fd) < 0) {
perror("dup");
return 0;
}
return 1;
}
/* Set the PWD to the pwd of the process eterm is running */
int
set_tag_pwd(void)
{
char dir[1024];
sprintf(dir, "/proc/%d/cwd", cmd_pid);
if (chdir(dir) < 0)
return 0;
return 1;
}
#endif /* USE_ACTIVE_TAGS */