1 /* editor initialisation and callback handler.
3 Copyright (C) 1996, 1997 the Free Software Foundation
5 Authors: 1996, 1997 Paul Sheer
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include <X11/Xmd.h> /* CARD32 */
27 #include <X11/Xatom.h>
29 #include "coollocal.h"
30 #include "editcmddef.h"
31 #include "mousemark.h"
37 extern int EditExposeRedraw
;
40 void edit_destroy_callback (CWidget
* w
)
43 edit_clean (w
->editor
);
49 CError ("Trying to destroy non-existing editor widget.\n");
52 void link_hscrollbar_to_editor (CWidget
* scrollbar
, CWidget
* editor
, XEvent
* xevent
, CEvent
* cwevent
, int whichscrbutton
);
54 extern int option_editor_bg_normal
;
55 void edit_tri_cursor (Window win
);
56 /* starting_directory is for the filebrowser */
57 CWidget
*CDrawEditor (const char *identifier
, Window parent
, int x
, int y
,
58 int width
, int height
, const char *text
, const char *filename
,
59 const char *starting_directory
, unsigned int options
, unsigned long text_size
)
61 static made_directory
= 0;
62 int extra_space_for_hscroll
= 0;
66 if (options
& EDITOR_HORIZ_SCROLL
)
67 extra_space_for_hscroll
= 8;
69 wedit
= w
= CSetupWidget (identifier
, parent
, x
, y
,
70 width
+ 7, height
+ 6, C_EDITOR_WIDGET
,
71 ExposureMask
| ButtonPressMask
| ButtonReleaseMask
| \
72 KeyPressMask
| KeyReleaseMask
| ButtonMotionMask
| \
73 PropertyChangeMask
| StructureNotifyMask
| \
74 EnterWindowMask
| LeaveWindowMask
, color_palette (option_editor_bg_normal
), 1);
75 edit_tri_cursor (w
->winid
);
76 w
->options
= options
| WIDGET_TAKES_SELECTION
;
78 w
->destroy
= edit_destroy_callback
;
80 w
->label
= strdup (filename
);
82 w
->label
= strdup ("");
84 if (!made_directory
) {
85 mkdir (catstrs (home_dir
, EDIT_DIR
, 0), 0700);
88 e
= w
->editor
= CMalloc (sizeof (WEdit
));
90 /* Not essential to translate */
91 CError (_ ("Error initialising editor.\n"));
94 w
->editor
->widget
= w
;
95 e
= w
->editor
= edit_init (e
, height
/ FONT_PIX_PER_LINE
, width
/ FONT_MEAN_WIDTH
, filename
, text
, starting_directory
, text_size
);
97 CDestroyWidget (w
->ident
);
103 set_hint_pos (x
+ width
+ 7 + WIDGET_SPACING
, y
+ height
+ 6 + WIDGET_SPACING
+ extra_space_for_hscroll
);
104 if (extra_space_for_hscroll
) {
105 w
->hori_scrollbar
= CDrawHorizontalScrollbar (catstrs (identifier
, ".hsc", 0), parent
,
106 x
, y
+ height
+ 6, width
+ 6, 12, 0, 0);
107 CSetScrollbarCallback (w
->hori_scrollbar
->ident
, w
->ident
, link_hscrollbar_to_editor
);
109 if (!(options
& EDITOR_NO_TEXT
))
110 CDrawText (catstrs (identifier
, ".text", 0), parent
, x
, y
+ height
+ 6 + WIDGET_SPACING
+ extra_space_for_hscroll
, "%s", e
->filename
);
111 if (!(options
& EDITOR_NO_SCROLL
)) {
112 w
->vert_scrollbar
= CDrawVerticalScrollbar (catstrs (identifier
, ".vsc", 0), parent
,
113 x
+ width
+ 7 + WIDGET_SPACING
, y
, height
+ 6, 20, 0, 0);
114 CSetScrollbarCallback (w
->vert_scrollbar
->ident
, w
->ident
, link_scrollbar_to_editor
);
119 void update_scroll_bars (WEdit
* e
)
123 scroll
= e
->widget
->vert_scrollbar
;
125 i
= e
->total_lines
- e
->start_line
+ 1;
126 if (i
> e
->num_widget_lines
)
127 i
= e
->num_widget_lines
;
128 if (e
->total_lines
) {
129 x1
= (double) 65535.0 *e
->start_line
/ (e
->total_lines
+ 1);
130 x2
= (double) 65535.0 *i
/ (e
->total_lines
+ 1);
135 if (x1
!= scroll
->firstline
|| x2
!= scroll
->numlines
) {
136 scroll
->firstline
= x1
;
137 scroll
->numlines
= x2
;
138 EditExposeRedraw
= 1;
139 render_scrollbar (scroll
);
140 EditExposeRedraw
= 0;
143 scroll
= e
->widget
->hori_scrollbar
;
145 i
= e
->max_column
- (-e
->start_col
) + 1;
146 if (i
> e
->num_widget_columns
* FONT_MEAN_WIDTH
)
147 i
= e
->num_widget_columns
* FONT_MEAN_WIDTH
;
148 x1
= (double) 65535.0 *(-e
->start_col
) / (e
->max_column
+ 1);
149 x2
= (double) 65535.0 *i
/ (e
->max_column
+ 1);
150 if (x1
!= scroll
->firstline
|| x2
!= scroll
->numlines
) {
151 scroll
->firstline
= x1
;
152 scroll
->numlines
= x2
;
153 EditExposeRedraw
= 1;
154 render_scrollbar (scroll
);
155 EditExposeRedraw
= 0;
160 /* returns the position in the edit buffer of a window click */
161 long edit_get_click_pos (WEdit
* edit
, int x
, int y
)
164 /* (1) goto to left margin */
165 click
= edit_bol (edit
, edit
->curs1
);
167 /* (1) move up or down */
168 if (y
> (edit
->curs_row
+ 1))
169 click
= edit_move_forward (edit
, click
, y
- (edit
->curs_row
+ 1), 0);
170 if (y
< (edit
->curs_row
+ 1))
171 click
= edit_move_backward (edit
, click
, (edit
->curs_row
+ 1) - y
);
173 /* (3) move right to x pos */
174 click
= edit_move_forward3 (edit
, click
, x
- edit
->start_col
- 1, 0);
178 void edit_translate_xy (int xs
, int ys
, int *x
, int *y
)
180 *x
= xs
- EDIT_TEXT_HORIZONTAL_OFFSET
;
181 *y
= (ys
- EDIT_TEXT_VERTICAL_OFFSET
- option_text_line_spacing
/ 2 - 1) / FONT_PIX_PER_LINE
+ 1;
184 extern int just_dropped_something
;
186 static void mouse_redraw (WEdit
* edit
, long click
)
188 edit
->force
|= REDRAW_PAGE
| REDRAW_LINE
;
189 edit_update_curs_row (edit
);
190 edit_update_curs_col (edit
);
191 edit
->prev_col
= edit_get_col (edit
);
192 edit_update_screen (edit
);
193 edit
->search_start
= click
;
196 static void xy (int x
, int y
, int *x_return
, int *y_return
)
198 edit_translate_xy (x
, y
, x_return
, y_return
);
201 static long cp (WEdit
*edit
, int x
, int y
)
203 return edit_get_click_pos (edit
, x
, y
);
206 /* return 1 if not marked */
207 static int marks (WEdit
* edit
, long *start
, long *end
)
209 return eval_marks (edit
, start
, end
);
212 int column_highlighting
= 0;
214 static int erange (WEdit
* edit
, long start
, long end
, int click
)
216 if (column_highlighting
) {
218 x
= edit_move_forward3 (edit
, edit_bol (edit
, click
), 0, click
);
219 if ((x
>= edit
->column1
&& x
< edit
->column2
)
220 || (x
> edit
->column2
&& x
<= edit
->column1
))
221 return (start
<= click
&& click
< end
);
225 return (start
<= click
&& click
< end
);
228 static void fin_mark (WEdit
*edit
)
231 edit_mark_cmd (edit
, 0);
234 static void move_mark (WEdit
*edit
)
236 edit_mark_cmd (edit
, 1);
237 edit_mark_cmd (edit
, 0);
240 static void release_mark (WEdit
*edit
, XEvent
*event
)
243 edit_mark_cmd (edit
, 0);
245 edit_mark_cmd (edit
, 1);
246 if (edit
->mark1
!= edit
->mark2
) {
247 edit_get_selection (edit
);
248 XSetSelectionOwner (CDisplay
, XA_PRIMARY
, edit
->widget
->winid
, event
->xbutton
.time
);
252 static char *get_block (WEdit
* edit
, long start_mark
, long end_mark
, int *type
, int *l
)
255 t
= (char *) edit_get_block (edit
, start_mark
, end_mark
, l
);
257 *type
= DndRawData
; /* if there are nulls in the data, send as raw */
259 *type
= DndText
; /* else send as text */
263 static void move (WEdit
*edit
, long click
, int y
)
265 edit_cursor_move (edit
, click
- edit
->curs1
);
268 static void dclick (WEdit
*edit
, XEvent
*event
)
270 edit_mark_cmd (edit
, 1);
271 edit_right_word_move (edit
);
272 edit_mark_cmd (edit
, 0);
273 edit_left_word_move (edit
);
274 release_mark (edit
, event
);
277 static void redraw (WEdit
*edit
, long click
)
279 mouse_redraw (edit
, click
);
282 static void edit_mouse_mark (WEdit
* edit
, XEvent
* event
, CEvent
* ce
)
284 edit_update_curs_row (edit
);
285 edit_update_curs_col (edit
);
286 if (event
->type
!= MotionNotify
) {
287 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
288 if (edit
->mark2
== -1)
289 edit_push_action (edit
, MARK_1
+ edit
->mark1
); /* mark1 must be following the cursor */
291 if (event
->type
== ButtonPress
) {
299 (void (*) (int, int, int *, int *)) xy
,
300 (long (*) (void *, int, int)) cp
,
301 (int (*) (void *, long *, long *)) marks
,
302 (int (*) (void *, long, long, long)) erange
,
303 (void (*) (void *)) fin_mark
,
304 (void (*) (void *)) move_mark
,
305 (void (*) (void *, XEvent
*)) release_mark
,
306 (char * (*) (void *, long, long, int *, int *)) get_block
,
307 (void (*) (void *, long, int)) move
,
309 (void (*) (void *, XEvent
*)) dclick
,
310 (void (*) (void *, long)) redraw
314 void link_scrollbar_to_editor (CWidget
* scrollbar
, CWidget
* editor
, XEvent
* xevent
, CEvent
* cwevent
, int whichscrbutton
)
321 if (!e
->widget
->vert_scrollbar
)
323 start_line
= e
->start_line
;
324 if ((xevent
->type
== ButtonRelease
|| xevent
->type
== MotionNotify
) && whichscrbutton
== 3) {
325 edit_move_display (e
, (double) scrollbar
->firstline
* e
->total_lines
/ 65535.0 + 1);
326 } else if (xevent
->type
== ButtonPress
&& (cwevent
->button
== Button1
|| cwevent
->button
== Button2
)) {
327 switch (whichscrbutton
) {
329 edit_move_display (e
, e
->start_line
- e
->num_widget_lines
+ 1);
332 edit_move_display (e
, e
->start_line
- 1);
335 edit_move_display (e
, e
->start_line
+ 1);
338 edit_move_display (e
, e
->start_line
+ e
->num_widget_lines
- 1);
343 scrollbar
->firstline
= (double) 65535.0 *e
->start_line
/ (e
->total_lines
+ 1);
345 scrollbar
->firstline
= 0;
346 i
= e
->total_lines
- e
->start_line
+ 1;
347 if (i
> e
->num_widget_lines
)
348 i
= e
->num_widget_lines
;
350 scrollbar
->numlines
= (double) 65535.0 *i
/ (e
->total_lines
+ 1);
352 scrollbar
->numlines
= 65535;
353 if (start_line
!= e
->start_line
) {
354 e
->force
|= REDRAW_PAGE
| REDRAW_LINE
;
355 set_cursor_position (0, 0, 0, 0, 0, 0, 0, 0, 0);
356 if (CCheckWindowEvent (xevent
->xany
.window
, ButtonReleaseMask
| ButtonMotionMask
, 0))
360 edit_render_keypress (e
);
365 void link_hscrollbar_to_editor (CWidget
* scrollbar
, CWidget
* editor
, XEvent
* xevent
, CEvent
* cwevent
, int whichscrbutton
)
372 if (!e
->widget
->hori_scrollbar
)
374 start_col
= (-e
->start_col
);
375 if ((xevent
->type
== ButtonRelease
|| xevent
->type
== MotionNotify
) && whichscrbutton
== 3) {
376 e
->start_col
= (double) scrollbar
->firstline
* e
->max_column
/ 65535.0 + 1;
377 e
->start_col
-= e
->start_col
% FONT_MEAN_WIDTH
;
378 if (e
->start_col
< 0)
380 e
->start_col
= (-e
->start_col
);
381 } else if (xevent
->type
== ButtonPress
&& (cwevent
->button
== Button1
|| cwevent
->button
== Button2
)) {
382 switch (whichscrbutton
) {
384 edit_scroll_left (e
, (e
->num_widget_columns
- 1) * FONT_MEAN_WIDTH
);
387 edit_scroll_left (e
, FONT_MEAN_WIDTH
);
390 edit_scroll_right (e
, FONT_MEAN_WIDTH
);
393 edit_scroll_right (e
, (e
->num_widget_columns
- 1) * FONT_MEAN_WIDTH
);
397 scrollbar
->firstline
= (double) 65535.0 *(-e
->start_col
) / (e
->max_column
+ 1);
398 i
= e
->max_column
- (-e
->start_col
) + 1;
399 if (i
> e
->num_widget_columns
* FONT_MEAN_WIDTH
)
400 i
= e
->num_widget_columns
* FONT_MEAN_WIDTH
;
401 scrollbar
->numlines
= (double) 65535.0 *i
/ (e
->max_column
+ 1);
402 if (start_col
!= (-e
->start_col
)) {
403 e
->force
|= REDRAW_PAGE
| REDRAW_LINE
;
404 set_cursor_position (0, 0, 0, 0, 0, 0, 0, 0, 0);
405 if (CCheckWindowEvent (xevent
->xany
.window
, ButtonReleaseMask
| ButtonMotionMask
, 0))
409 edit_render_keypress (e
);
415 This section comes from rxvt-2.21b1/src/screen.c by
416 Robert Nation <nation@rocket.sanders.lockheed.com> &
417 mods by mj olesen <olesen@me.QueensU.CA>
419 Changes made for cooledit
421 void selection_send (XSelectionRequestEvent
* rq
)
424 static Atom xa_targets
= None
;
425 if (xa_targets
== None
)
426 xa_targets
= XInternAtom (CDisplay
, "TARGETS", False
);
428 ev
.xselection
.type
= SelectionNotify
;
429 ev
.xselection
.property
= None
;
430 ev
.xselection
.display
= rq
->display
;
431 ev
.xselection
.requestor
= rq
->requestor
;
432 ev
.xselection
.selection
= rq
->selection
;
433 ev
.xselection
.target
= rq
->target
;
434 ev
.xselection
.time
= rq
->time
;
436 if (rq
->target
== xa_targets
) {
438 * On some systems, the Atom typedef is 64 bits wide.
439 * We need to have a typedef that is exactly 32 bits wide,
440 * because a format of 64 is not allowed by the X11 protocol.
442 typedef CARD32 Atom32
;
444 Atom32 target_list
[2];
446 target_list
[0] = (Atom32
) xa_targets
;
447 target_list
[1] = (Atom32
) XA_STRING
;
449 XChangeProperty (CDisplay
, rq
->requestor
, rq
->property
,
450 xa_targets
, 8 * sizeof (target_list
[0]), PropModeReplace
,
451 (unsigned char *) target_list
,
452 sizeof (target_list
) / sizeof (target_list
[0]));
453 ev
.xselection
.property
= rq
->property
;
454 } else if (rq
->target
== XA_STRING
) {
455 XChangeProperty (CDisplay
, rq
->requestor
, rq
->property
,
456 XA_STRING
, 8, PropModeReplace
,
457 selection
.text
, selection
.len
);
458 ev
.xselection
.property
= rq
->property
;
460 XSendEvent (CDisplay
, rq
->requestor
, False
, 0, &ev
);
463 /*{{{ paste selection */
466 * Respond to a notification that a primary selection has been sent
468 void paste_prop (void *data
, void (*insert
) (void *, int), Window win
, unsigned prop
, int delete)
471 unsigned long bytes_after
;
481 unsigned long nitems
;
483 if (XGetWindowProperty (CDisplay
, win
, prop
,
484 nread
/ 4, 65536, delete,
485 AnyPropertyType
, &actual_type
, &actual_fmt
,
486 &nitems
, &bytes_after
,
492 for (i
= 0; i
< nitems
; i
++)
493 (*insert
) (data
, s
[i
]);
495 } while (bytes_after
);
498 void selection_paste (WEdit
* edit
, Window win
, unsigned prop
, int delete)
502 paste_prop ((void *) edit
,
503 (void (*)(void *, int)) edit_insert
,
505 edit_cursor_move (edit
, c
- edit
->curs1
);
506 edit
->force
|= REDRAW_COMPLETELY
| REDRAW_LINE
;
511 void selection_clear (void)
517 void edit_update_screen (WEdit
* e
)
524 edit_scroll_screen_over_cursor (e
);
525 edit_update_curs_row (e
);
526 edit_update_curs_col (e
);
527 update_scroll_bars (e
);
530 if (e
->force
& REDRAW_COMPLETELY
)
531 e
->force
|= REDRAW_PAGE
;
533 /* pop all events for this window for internal handling */
534 if (e
->force
& (REDRAW_CHAR_ONLY
| REDRAW_COMPLETELY
)) {
535 edit_render_keypress (e
);
536 } else if (CCheckWindowEvent (e
->widget
->winid
, ButtonPressMask
| ButtonReleaseMask
| ButtonMotionMask
, 0)
538 e
->force
|= REDRAW_PAGE
;
541 edit_render_keypress (e
);
545 extern int space_width
;
547 static void edit_insert_column_of_text (WEdit
* edit
, unsigned char *data
, int size
, int width
)
551 cursor
= edit
->curs1
;
552 col
= edit_get_col (edit
);
553 for (i
= 0; i
< size
; i
++) {
554 if (data
[i
] == '\n') { /* fill in and move to next line */
557 if (edit_get_byte (edit
, edit
->curs1
) != '\n') {
558 l
= width
- (edit_get_col (edit
) - col
);
560 edit_insert (edit
, ' ');
564 for (p
= edit
->curs1
;; p
++) {
565 if (p
== edit
->last_byte
)
566 edit_insert_ahead (edit
, '\n');
567 if (edit_get_byte (edit
, p
) == '\n') {
572 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
573 l
= col
- edit_get_col (edit
);
574 while (l
>= space_width
) {
575 edit_insert (edit
, ' ');
580 edit_insert (edit
, data
[i
]);
582 edit_cursor_move (edit
, cursor
- edit
->curs1
);
585 #define free_data if (data) {free(data);data=0;}
587 /* handles drag and drop */
588 void handle_client_message (CWidget
* w
, XEvent
* xevent
, CEvent
* cwevent
)
595 int x
, y
, r
, deleted
= 0;
598 long start_mark
= 0, end_mark
= 0;
599 WEdit
*e
= w
->editor
;
601 /* see just below for a comment on what this is for: */
602 if (CIsDropAcknowledge (xevent
, &state
) != DndNotDnd
) {
603 if (!(state
& Button1Mask
) && just_dropped_something
) {
604 edit_push_action (e
, KEY_PRESS
+ e
->start_display
);
605 edit_block_delete_cmd (e
);
609 data_type
= CGetDrop (xevent
, &data
, &size
, &xs
, &ys
);
611 if (data_type
== DndNotDnd
|| xs
< 0 || ys
< 0 || xs
>= w
->width
|| ys
>= w
->height
) {
615 edit_translate_xy (xs
, ys
, &x
, &y
);
616 click
= edit_get_click_pos (e
, x
, y
);
618 r
= eval_marks (e
, &start_mark
, &end_mark
);
619 /* musn't be able to drop into a block, otherwise a single click will copy a block: */
622 if (start_mark
> click
|| click
>= end_mark
)
624 if (column_highlighting
) {
625 if (!((x
>= e
->column1
&& x
< e
->column2
)
626 || (x
> e
->column2
&& x
<= e
->column1
)))
632 edit_push_action (e
, KEY_PRESS
+ e
->start_display
);
634 /* drops to the same window moving to the left: */
635 start_line
= e
->start_line
;
636 if (xevent
->xclient
.data
.l
[2] == xevent
->xclient
.window
&& !(xevent
->xclient
.data
.l
[1] & Button1Mask
))
637 if ((column_highlighting
&& x
< max (e
->column1
, e
->column2
)) || !column_highlighting
) {
638 edit_block_delete_cmd (e
);
641 edit_update_curs_row (e
);
642 edit_move_display (e
, start_line
);
643 click
= edit_get_click_pos (e
, x
, y
); /* click pos changes with edit_block_delete_cmd() */
644 edit_cursor_move (e
, click
- e
->curs1
);
645 if (data_type
== DndFile
) {
646 edit_insert_file (e
, (char *) data
);
647 } else if (data_type
!= DndFiles
) {
648 if (dnd_null_term_type (data_type
)) {
650 len
= strlen ((char *) data
);
651 size
= min (len
, size
);
653 if (column_highlighting
) {
654 edit_insert_column_of_text (e
, data
, size
, abs (e
->column2
- e
->column1
));
657 edit_insert_ahead (e
, data
[size
]);
661 edit_insert_ahead (e
, data
[size
] ? data
[size
] : '\n');
664 /* drops to the same window moving to the right: */
665 if (xevent
->xclient
.data
.l
[2] == xevent
->xclient
.window
&& !(xevent
->xclient
.data
.l
[1] & Button1Mask
))
666 if (column_highlighting
&& !deleted
)
667 edit_block_delete_cmd (e
);
669 /* The drop has now been successfully recieved. We can now send an acknowledge
670 event back to the window that send the data. When this window recieves
671 the acknowledge event, the app can decide whether or not to delete the data.
672 This allows text to be safely moved betweem text windows without the
673 risk of data being lost. In our case, drag with button1 is a copy
674 drag, while drag with any other button is a move drag (i.e. the sending
675 application must delete its selection after recieving an acknowledge
676 event). We must not, however, send an acknowledge signal if a filelist
677 (for example) was passed to us, since the sender might take this to
678 mean that all those files can be deleted! The two types we can acknowledge
680 if (xevent
->xclient
.data
.l
[2] != xevent
->xclient
.window
) /* drops to the same window */
681 if (data_type
== DndText
|| data_type
== DndRawData
)
682 CDropAcknowledge (xevent
);
683 e
->force
|= REDRAW_COMPLETELY
| REDRAW_LINE
;
687 int eh_editor (CWidget
* w
, XEvent
* xevent
, CEvent
* cwevent
)
689 WEdit
*e
= w
->editor
;
691 static int old_tab_spacing
= -1;
696 if (old_tab_spacing
!= option_tab_spacing
)
697 e
->force
|= REDRAW_COMPLETELY
+ REDRAW_LINE
;
698 old_tab_spacing
= option_tab_spacing
;
700 if (xevent
->type
== KeyPress
) {
701 if (xevent
->xkey
.keycode
== 0x31 && xevent
->xkey
.state
== 0xD) {
702 CSetColor (color_palette (18));
703 CRectangle (w
->winid
, 0, 0, w
->width
, w
->height
);
706 switch (xevent
->type
) {
707 case SelectionNotify
:
708 selection_paste (e
, xevent
->xselection
.requestor
, xevent
->xselection
.property
, True
);
711 case SelectionRequest
:
712 selection_send (&(xevent
->xselectionrequest
));
714 /* case SelectionClear: ---> This is handled by coolnext.c: CNextEvent() */
716 handle_client_message (w
, xevent
, cwevent
);
721 edit_render_tidbits (w
);
723 if (xevent
->xbutton
.state
& ControlMask
)
724 column_highlighting
= 1;
726 column_highlighting
= 0;
728 if (!xevent
->xmotion
.state
&& xevent
->type
== MotionNotify
)
730 resolve_button (xevent
, cwevent
);
731 edit_mouse_mark (e
, xevent
, cwevent
);
734 edit_render_expose (e
, &(xevent
->xexpose
));
737 CSetCursorColor (e
->overwrite
? color_palette (24) : color_palette (19));
739 edit_render_tidbits (w
);
740 e
->force
|= REDRAW_CHAR_ONLY
| REDRAW_LINE
;
741 edit_render_keypress (e
);
745 if (column_highlighting
) {
746 column_highlighting
= 0;
747 e
->force
= REDRAW_COMPLETELY
| REDRAW_LINE
;
748 edit_mark_cmd (e
, 1);
752 cwevent
->ident
= w
->ident
;
753 if (!cwevent
->command
&& cwevent
->insert
< 0) { /* no translation */
754 if ((cwevent
->key
== XK_r
|| cwevent
->key
== XK_R
) && (cwevent
->state
& ControlMask
)) {
755 cwevent
->command
= e
->macro_i
< 0 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
757 cwevent
->command
= CKeySymMod (xevent
);
758 if (cwevent
->command
> 0)
759 cwevent
->command
= CK_Macro (cwevent
->command
);
764 r
= edit_execute_key_command (e
, cwevent
->command
, cwevent
->insert
);
766 edit_update_screen (e
);
770 cwevent
->ident
= w
->ident
;
771 cwevent
->command
= xevent
->xkey
.keycode
;
772 r
= cwevent
->handled
= edit_execute_key_command (e
, xevent
->xkey
.keycode
, -1);
777 edit_update_screen (e
);
784 WButtonBar
*edit_bar
;
788 int column_highlighting
= 0;
790 static int edit_callback (Dlg_head
* h
, WEdit
* edit
, int msg
, int par
);
792 static int edit_mode_callback (struct Dlg_head
*h
, int id
, int msg
)
797 int edit_event (WEdit
* edit
, Gpm_Event
* event
, int *result
)
799 *result
= MOU_NORMAL
;
800 edit_update_curs_row (edit
);
801 edit_update_curs_col (edit
);
802 if (event
->type
& (GPM_DOWN
| GPM_DRAG
| GPM_UP
)) {
803 if (event
->y
> 1 && event
->x
> 0
804 && event
->x
<= edit
->num_widget_columns
805 && event
->y
<= edit
->num_widget_lines
+ 1) {
806 if (edit
->mark2
!= -1 && event
->type
& (GPM_UP
| GPM_DRAG
))
807 return 1; /* a lone up mustn't do anything */
808 if (event
->type
& (GPM_DOWN
| GPM_UP
))
809 edit_push_key_press (edit
);
810 edit_cursor_move (edit
, edit_bol (edit
, edit
->curs1
) - edit
->curs1
);
811 if (--event
->y
> (edit
->curs_row
+ 1))
812 edit_cursor_move (edit
,
813 edit_move_forward (edit
, edit
->curs1
, event
->y
- (edit
->curs_row
+ 1), 0)
815 if (event
->y
< (edit
->curs_row
+ 1))
816 edit_cursor_move (edit
,
817 +edit_move_backward (edit
, edit
->curs1
, (edit
->curs_row
+ 1) - event
->y
)
819 edit_cursor_move (edit
, (int) edit_move_forward3 (edit
, edit
->curs1
,
820 event
->x
- edit
->start_col
- 1, 0) - edit
->curs1
);
821 edit
->prev_col
= edit_get_col (edit
);
822 if (event
->type
& GPM_DOWN
) {
823 edit_mark_cmd (edit
, 1); /* reset */
826 if (!(event
->type
& GPM_DRAG
))
827 edit_mark_cmd (edit
, 0);
828 edit
->force
|= REDRAW_COMPLETELY
;
829 edit_update_curs_row (edit
);
830 edit_update_curs_col (edit
);
831 edit_update_screen (edit
);
840 int menubar_event (Gpm_Event
* event
, WMenu
* menubar
); /* menu.c */
842 int edit_mouse_event (Gpm_Event
* event
, void *x
)
845 if (edit_event ((WEdit
*) x
, event
, &result
))
848 return menubar_event (event
, edit_menubar
);
851 extern Menu EditMenuBar
[5];
853 int edit (const char *_file
, int line
)
855 static int made_directory
= 0;
857 int midnight_colors
[4];
860 if (option_backup_ext_int
!= -1) {
861 option_backup_ext
= malloc (sizeof(int) + 1);
862 option_backup_ext
[sizeof(int)] = '\0';
863 memcpy (option_backup_ext
, (char *) &option_backup_ext_int
, sizeof (int));
866 if (!made_directory
) {
867 mkdir (catstrs (home_dir
, EDIT_DIR
, 0), 0700);
878 if (!(wedit
= edit_init (NULL
, LINES
- 2, COLS
, _file
, text
, "", 0))) {
879 message (1, _(" Error "), get_error_msg (""));
884 /* Create a new dialog and add it widgets to it */
885 edit_dlg
= create_dlg (0, 0, LINES
, COLS
, midnight_colors
,
886 edit_mode_callback
, "[Internal File Editor]",
890 edit_dlg
->raw
= 1; /*so that tab = '\t' key works */
892 init_widget (&(wedit
->widget
), 0, 0, LINES
- 1, COLS
,
893 (callback_fn
) edit_callback
,
894 (destroy_fn
) edit_clean
,
895 (mouse_h
) edit_mouse_event
, 0);
897 widget_want_cursor (wedit
->widget
, 1);
899 edit_bar
= buttonbar_new (1);
902 switch (edit_key_emulation
) {
903 case EDIT_KEY_EMULATION_NORMAL
:
904 edit_init_menu_normal (); /* editmenu.c */
906 case EDIT_KEY_EMULATION_EMACS
:
907 edit_init_menu_emacs (); /* editmenu.c */
910 edit_menubar
= menubar_new (0, 0, COLS
, EditMenuBar
, N_menus
);
912 add_widget (edit_dlg
, wedit
);
915 add_widget (edit_dlg
, edit_menubar
);
917 add_widget (edit_dlg
, edit_bar
);
918 edit_move_display (wedit
, line
- 1);
919 edit_move_to_line (wedit
, line
- 1);
924 edit_done_menu (); /* editmenu.c */
926 destroy_dlg (edit_dlg
);
931 static void edit_my_define (Dlg_head
* h
, int idx
, char *text
,
932 void (*fn
) (WEdit
*), WEdit
* edit
)
934 define_label_data (h
, (Widget
*) edit
, idx
, text
, (buttonbarfn
) fn
, edit
);
938 void cmd_F1 (WEdit
* edit
)
940 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (1));
943 void cmd_F2 (WEdit
* edit
)
945 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (2));
948 void cmd_F3 (WEdit
* edit
)
950 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (3));
953 void cmd_F4 (WEdit
* edit
)
955 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (4));
958 void cmd_F5 (WEdit
* edit
)
960 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (5));
963 void cmd_F6 (WEdit
* edit
)
965 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (6));
968 void cmd_F7 (WEdit
* edit
)
970 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (7));
973 void cmd_F8 (WEdit
* edit
)
975 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (8));
978 void cmd_F9 (WEdit
* edit
)
980 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (9));
983 void cmd_F10 (WEdit
* edit
)
985 send_message (edit
->widget
.parent
, (Widget
*) edit
, WIDGET_KEY
, KEY_F (10));
988 void edit_labels (WEdit
* edit
)
990 Dlg_head
*h
= edit
->widget
.parent
;
992 edit_my_define (h
, 1, _("Help"), cmd_F1
, edit
);
993 edit_my_define (h
, 2, _("Save"), cmd_F2
, edit
);
994 edit_my_define (h
, 3, _("Mark"), cmd_F3
, edit
);
995 edit_my_define (h
, 4, _("Replac"), cmd_F4
, edit
);
996 edit_my_define (h
, 5, _("Copy"), cmd_F5
, edit
);
997 edit_my_define (h
, 6, _("Move"), cmd_F6
, edit
);
998 edit_my_define (h
, 7, _("Search"), cmd_F7
, edit
);
999 edit_my_define (h
, 8, _("Delete"), cmd_F8
, edit
);
1000 if (!edit
->have_frame
)
1001 edit_my_define (h
, 9, _("PullDn"), edit_menu_cmd
, edit
);
1002 edit_my_define (h
, 10, _("Quit"), cmd_F10
, edit
);
1004 redraw_labels (h
, (Widget
*) edit
);
1008 long get_key_state ()
1010 return (long) get_modifier ();
1013 void edit_adjust_size (Dlg_head
* h
)
1016 WButtonBar
*edit_bar
;
1018 edit
= (WEdit
*) find_widget_type (h
, (callback_fn
) edit_callback
);
1019 edit_bar
= (WButtonBar
*) edit
->widget
.parent
->current
->next
->widget
;
1020 widget_set_size (&edit
->widget
, 0, 0, LINES
- 1, COLS
);
1021 widget_set_size (&edit_bar
->widget
, LINES
- 1, 0, 1, COLS
);
1022 widget_set_size (&edit_menubar
->widget
, 0, 0, 1, COLS
);
1024 #ifdef RESIZABLE_MENUBAR
1025 menubar_arrange(edit_menubar
);
1029 void edit_update_screen (WEdit
* e
)
1031 edit_scroll_screen_over_cursor (e
);
1033 edit_update_curs_col (e
);
1036 /* pop all events for this window for internal handling */
1039 e
->force
|= REDRAW_PAGE
;
1042 if (e
->force
& REDRAW_COMPLETELY
)
1043 e
->force
|= REDRAW_PAGE
;
1044 edit_render_keypress (e
);
1047 static int edit_callback (Dlg_head
* h
, WEdit
* e
, int msg
, int par
)
1051 e
->force
|= REDRAW_COMPLETELY
;
1055 e
->force
|= REDRAW_COMPLETELY
;
1056 e
->num_widget_lines
= LINES
- 2;
1057 e
->num_widget_columns
= COLS
;
1059 edit_update_screen (e
);
1063 if (edit_drop_hotkey_menu (e
, par
)) /* first check alt-f, alt-e, alt-s, etc for drop menus */
1065 if (!edit_translate_key (e
, 0, par
, get_key_state (), &cmd
, &ch
))
1067 edit_execute_key_command (e
, cmd
, ch
);
1068 edit_update_screen (e
);
1071 case WIDGET_COMMAND
:
1072 edit_execute_key_command (e
, par
, -1);
1073 edit_update_screen (e
);
1076 widget_move (&e
->widget
, e
->curs_row
+ EDIT_TEXT_VERTICAL_OFFSET
, e
->curs_col
+ e
->start_col
);
1079 return default_proc (h
, msg
, par
);