⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editwidget.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* editor initialisation and callback handler.   Copyright (C) 1996-2000 the Free Software Foundation   Authors: 1996, 1997 Paul Sheer   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., 59 Temple Place, Suite 330, Boston, MA   02111-1307, USA. */#include <config.h>#include "edit.h"#ifndef MIDNIGHT#include <X11/Xmd.h>		/* CARD32 */#include <X11/Xatom.h>#include "app_glob.c"#include "coollocal.h"#include "editcmddef.h"#include "mousemark.h"#endif#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK)#include "mad.h"#endif#ifndef MIDNIGHTextern int EditExposeRedraw;CWidget *wedit = 0;void shell_output_kill_jobs (WEdit * edit);void shell_output_kill_job (WEdit * edit, pid_t pid);void edit_destroy_callback (CWidget * w){    if (w) {	shell_output_kill_jobs (w->editor);	edit_clean (w->editor);	if (w->editor)	    free (w->editor);	w->editor = NULL;    } else/* NLS ? */	CError ("Trying to destroy non-existing editor widget.\n");}#define CLOSE_ON_NO_DATA#define SHELL_INPUT_BUF_SIZE 1024static void shell_output_write_callback (int fd, fd_set * reading, fd_set * writing, fd_set * error, void *data){    unsigned char s[SHELL_INPUT_BUF_SIZE];    int i;    WEdit *edit;    long start_mark, end_mark;    edit = (WEdit *) data;/* if the process is available for reading, and there is not selected text, then remove the watch on the process's stdin, and close the stdin */    if (eval_marks (edit, &start_mark, &end_mark)) {	struct shell_job *j;	CRemoveWatch (fd, shell_output_write_callback, WATCH_WRITING);	for (j = edit->jobs; j; j = j->next)	    if (j->in == fd) {		if (j->close_on_error)		    close (fd);		break;	    }	return;    }    for (i = 0; i < SHELL_INPUT_BUF_SIZE && start_mark + i < end_mark; i++)	s[i] = edit_get_byte (edit, start_mark + i);    while ((i = write (fd, s, i)) < 0 && errno == EINTR);    if (i <= 0) {	struct shell_job *j;	for (j = edit->jobs; j; j = j->next)	    if (j->in == fd || j->out == fd) {		if (CChildExitted (j->pid, 0))		    shell_output_kill_job (edit, j->pid);		break;	    }	return;    }    edit_cursor_move (edit, start_mark - edit->curs1);    while (i--)	edit_delete (edit);    edit->force |= REDRAW_PAGE;    edit_update_screen (edit);}#define SHELL_OUTPUT_BUF_SIZE 16384static void shell_output_read_callback (int fd, fd_set * reading, fd_set * writing, fd_set * error, void *data){    WEdit *edit;    unsigned char s[SHELL_OUTPUT_BUF_SIZE];    int i, n, move_mark;    long start_mark, end_mark;    edit = (WEdit *) data;    if (!eval_marks (edit, &start_mark, &end_mark))	move_mark = (start_mark == edit->curs1);    while ((i = read (fd, s, SHELL_OUTPUT_BUF_SIZE)) < 0 && errno == EINTR);    if (i <= 0) {	struct shell_job *j;	for (j = edit->jobs; j; j = j->next)	    if (j->in == fd || j->out == fd) {		if (CChildExitted (j->pid, 0))		    shell_output_kill_job (edit, j->pid);		break;	    }	return;    }    for (n = 0; n < i; n++)	edit_insert (edit, s[n]);/* must insert BEFORE and not INTO the selection */    if (move_mark)	edit_set_markers (edit, start_mark + i, end_mark + i, -1, -1);    edit->force |= REDRAW_PAGE;    edit_update_screen (edit);}void shell_output_add_job (WEdit * edit, int in, int out, pid_t pid, char *name, int close_on_error){    struct shell_job *j;    long start_mark, end_mark;    CAddWatch (out, shell_output_read_callback, WATCH_READING, edit);    if (!eval_marks (edit, &start_mark, &end_mark))	CAddWatch (in, shell_output_write_callback, WATCH_WRITING, edit);    else if (close_on_error) {	close (in);	in = -1;    }    j = malloc (sizeof (*j));    memset (j, 0, sizeof (*j));    j->next = edit->jobs;    j->in = in;    j->out = out;    j->close_on_error = close_on_error;    j->name = (char *) strdup (name);    j->pid = pid;    edit->jobs = j;}static void shell_output_destroy_job (struct shell_job *j){    if (j->out >= 0) {	CRemoveWatch (j->out, shell_output_read_callback, WATCH_READING);	close (j->out);    }    if (j->in >= 0) {	CRemoveWatch (j->in, shell_output_write_callback, WATCH_WRITING);	close (j->in);    }    if (j->pid > 0)	kill (j->pid, SIGTERM);    free (j->name);    memset (j, 0, sizeof (*j));    free (j);}void shell_output_kill_jobs (WEdit * edit){    struct shell_job *j, *n;    if (!edit)	return;    for (j = edit->jobs; j; j = n) {	n = j->next;	shell_output_destroy_job (j);    }    edit->jobs = 0;}void shell_output_kill_job (WEdit * edit, pid_t pid){    struct shell_job *j, *p;    int done;    do {	done = 1;	p = edit->jobs;	for (j = edit->jobs; j; j = j->next) {	    if (j->pid == pid) {		if ((unsigned long) j == (unsigned long) edit->jobs) {		    edit->jobs = edit->jobs->next;		    shell_output_destroy_job (j);		    done = 0;		    break;		} else {		    p->next = j->next;		    shell_output_destroy_job (j);		    done = 0;		    break;		}	    }	    p = j;	}    } while (!done);}void link_hscrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * xevent, CEvent * cwevent, int whichscrbutton);/* returns the position in the edit buffer of a window click */long edit_get_click_pos (WEdit * edit, int x, int y){    long click;/* (1) goto to left margin */    click = edit_bol (edit, edit->curs1);/* (1) move up or down */    if (y > (edit->curs_row + 1))	click = edit_move_forward (edit, click, y - (edit->curs_row + 1), 0);    if (y < (edit->curs_row + 1))	click = edit_move_backward (edit, click, (edit->curs_row + 1) - y);/* (3) move right to x pos */    click = edit_move_forward3 (edit, click, x - edit->start_col - 1, 0);    return click;}void edit_translate_xy (int xs, int ys, int *x, int *y){    *x = xs - EDIT_TEXT_HORIZONTAL_OFFSET;    *y = (ys - EDIT_TEXT_VERTICAL_OFFSET - option_text_line_spacing / 2 - 1) / FONT_PIX_PER_LINE + 1;}extern int just_dropped_something;void mouse_redraw (WEdit * edit, long click){    edit->force |= REDRAW_PAGE | REDRAW_LINE;    edit_update_curs_row (edit);    edit_update_curs_col (edit);    edit->prev_col = edit_get_col (edit);    edit_update_screen (edit);    edit->search_start = click;}static void xy (int x, int y, int *x_return, int *y_return){    edit_translate_xy (x, y, x_return, y_return);}static long cp (WEdit * edit, int x, int y){    return edit_get_click_pos (edit, x, y);}/* return 1 if not marked */static int marks (WEdit * edit, long *start, long *end){    return eval_marks (edit, start, end);}int column_highlighting = 0;static int erange (WEdit * edit, long start, long end, int click){    if (column_highlighting) {	int x;	x = edit_move_forward3 (edit, edit_bol (edit, click), 0, click);	if ((x >= edit->column1 && x < edit->column2)	    || (x > edit->column2 && x <= edit->column1))	    return (start <= click && click < end);	else	    return 0;    }    return (start <= click && click < end);}static void fin_mark (WEdit * edit){    if (edit->mark2 < 0)	edit_mark_cmd (edit, 0);}static void move_mark (WEdit * edit){    edit_mark_cmd (edit, 1);    edit_mark_cmd (edit, 0);}static void release_mark (WEdit * edit, XEvent * event){    if (edit->mark2 < 0)	edit_mark_cmd (edit, 0);    else	edit_mark_cmd (edit, 1);    if (edit->mark1 != edit->mark2 && event) {	edit_get_selection (edit);	XSetSelectionOwner (CDisplay, XA_PRIMARY, CWindowOf (edit->widget), event->xbutton.time);    }#ifdef GTK    else {	edit->widget->editable.has_selection = TRUE;    }#endif}static char *get_block (WEdit * edit, long start_mark, long end_mark, int *type, int *l){    char *t;    t = (char *) edit_get_block (edit, start_mark, end_mark, l);    if (strlen (t) < *l)	*type = DndRawData;	/* if there are nulls in the data, send as raw */    else	*type = DndText;	/* else send as text */    return t;}static void move (WEdit * edit, long click, int y){    edit_cursor_move (edit, click - edit->curs1);}static void dclick (WEdit * edit, XEvent * event){    edit_mark_cmd (edit, 1);    edit_right_word_move (edit, 1);    edit_mark_cmd (edit, 0);    edit_left_word_move (edit, 1);    release_mark (edit, event);}static void redraw (WEdit * edit, long click){    mouse_redraw (edit, click);}void edit_insert_column_of_text (WEdit * edit, unsigned char *data, int size, int width);/* strips out the first i chars and returns a null terminated string, result must be free'd */char *filename_from_url (char *data, int size, int i){    char *p, *f;    int l;    for (p = data + i; (unsigned long) p - (unsigned long) data < size && *p && *p != '\n'; p++);    l = (unsigned long) p - (unsigned long) data - i;    f = malloc (l + 1);    memcpy (f, data + i, l);    f[l] = '\0';    return f;}static int insert_drop (WEdit * e, Window from, unsigned char *data, int size, int xs, int ys, Atom type, Atom action){    long start_mark = 0, end_mark = 0;    int x, y;    edit_translate_xy (xs, ys, &x, &y);/* musn't be able to drop into a block, otherwise a single click will copy a block: */    if (eval_marks (e, &start_mark, &end_mark))	goto fine;    if (start_mark > e->curs1 || e->curs1 >= end_mark)	goto fine;    if (column_highlighting) {	if (!((x >= e->column1 && x < e->column2)	      || (x > e->column2 && x <= e->column1)))	    goto fine;    }    return 1;  fine:    if (from == e->widget->winid && action == CDndClass->XdndActionMove) {	edit_block_move_cmd (e);	edit_mark_cmd (e, 1);	return 0;    } else if (from == e->widget->winid) {	edit_block_copy_cmd (e);	return 0;    } else {			/*  data from another widget, or from another application */	edit_push_action (e, KEY_PRESS + e->start_display);	if (type == XInternAtom (CDisplay, "url/url", False)) {	    if (!strncmp ((char *) data, "file:/", 6)) {		char *f;		edit_insert_file (e, f = filename_from_url ((char *) data, size, strlen ("file:")));		free (f);	    } else {		while (size--)		    edit_insert_ahead (e, data[size]);	    }	} else {	    if (column_highlighting) {		edit_insert_column_of_text (e, data, size, abs (e->column2 - e->column1));	    } else {		while (size--)		    edit_insert_ahead (e, data[size]);	    }	}    }    CExpose (e->widget->ident);    return 0;}static char *mime_majors[2] ={"text", 0};struct mouse_funcs edit_mouse_funcs ={    0,    (void (*)(int, int, int *, int *)) xy,    (long (*)(void *, int, int)) cp,    (int (*)(void *, long *, long *)) marks,    (int (*)(void *, long, long, long)) erange,    (void (*)(void *)) fin_mark,    (void (*)(void *)) move_mark,    (void (*)(void *, XEvent *)) release_mark,    (char *(*)(void *, long, long, int *, int *)) get_block,    (void (*)(void *, long, int)) move,    0,    (void (*)(void *, XEvent *)) dclick,    (void (*)(void *, long)) redraw,    (int (*)(void *, Window, unsigned char *, int, int, int, Atom, Atom)) insert_drop,    (void (*)(void *)) edit_block_delete,    DndText,    mime_majors};static void render_book_marks (CWidget * w);extern int option_editor_bg_normal;void edit_tri_cursor (Window win);/* starting_directory is for the filebrowser */CWidget *CDrawEditor (const char *identifier, Window parent, int x, int y,		      int width, int height, const char *text, const char *filename,		      const char *starting_directory, unsigned int options, unsigned long text_size){    static int made_directory = 0;    int extra_space_for_hscroll = 0;    int max_x = 0;    CWidget *w;    WEdit *e;    CPushFont ("editor", 0);    if (options & EDITOR_HORIZ_SCROLL)	extra_space_for_hscroll = 8;    wedit = w = CSetupWidget (identifier, parent, x, y,			      width + EDIT_FRAME_W, height + EDIT_FRAME_H,			      C_EDITOR_WIDGET, INPUT_KEY, color_palette (option_editor_bg_normal), 1);    xdnd_set_dnd_aware (CDndClass, w->winid, 0);    xdnd_set_type_list (CDndClass, w->winid, xdnd_typelist_send[DndText]);    edit_tri_cursor (w->winid);    w->options = options | WIDGET_TAKES_SELECTION;    w->destroy = edit_destroy_callback;    if (filename)	w->label = (char *) strdup (filename);    else	w->label = (char *) strdup ("");    if (!made_directory) {	mkdir (catstrs (home_dir, EDIT_DIR, 0), 0700);	made_directory = 1;    }    e = w->editor = CMalloc (sizeof (WEdit));    w->funcs = mouse_funcs_new (w->editor, &edit_mouse_funcs);    if (!w->editor) {/* Not essential to translate */	CError (_("Error initialising editor.\n"));	CPopFont ();	return 0;    }    w->editor->widget = w;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -