/*--------------------------------*-C-*---------------------------------* * File: activeeterm.c * * Copyright 1997 Nat Friedman, Massachusetts Institute of Technology * * * 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 #include #include #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 */