fix scrolling to lines not in current vertical window (leftright option)
[nvi.git] / motif_l / m_func.c
blob089da2e37a6a834fe558df964fdbcca788496e79
1 /*-
2 * Copyright (c) 1996
3 * Rob Zimmermann. All rights reserved.
4 * Copyright (c) 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 static const char sccsid[] = "$Id: m_func.c,v 8.27 2001/06/28 19:48:32 skimo Exp $ (Berkeley) $Date: 2001/06/28 19:48:32 $";
14 #endif /* not lint */
16 #include <sys/types.h>
17 #include <sys/queue.h>
19 #include <Xm/PanedW.h>
20 #include <Xm/ScrollBar.h>
22 #include <bitstring.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
27 #include "../common/common.h"
28 #include "../ipc/ip.h"
29 #include "m_motif.h"
32 static int
33 vi_addstr(int ipvi, char *str1, u_int32_t len1)
35 #ifdef TRACE
36 vtrace("addstr() {%.*s}\n", ipbp->len1, ipbp->str1);
37 #endif
38 /* Add to backing store. */
39 memcpy(CharAt(__vi_screen, __vi_screen->cury, __vi_screen->curx),
40 str1, len1);
41 memset(FlagAt(__vi_screen, __vi_screen->cury, __vi_screen->curx),
42 __vi_screen->color, len1);
44 /* Draw from backing store. */
45 __vi_draw_text(__vi_screen,
46 __vi_screen->cury, __vi_screen->curx, len1);
48 /* Advance the caret. */
49 __vi_move_caret(__vi_screen,
50 __vi_screen->cury, __vi_screen->curx + len1);
51 return (0);
54 static int
55 vi_attribute(int ipvi, u_int32_t val1, u_int32_t val2)
57 switch (val1) {
58 case SA_ALTERNATE:
59 /* XXX: Nothing. */
60 break;
61 case SA_INVERSE:
62 __vi_screen->color = val2;
63 break;
65 return (0);
68 static int
69 vi_bell(int ipvi)
72 * XXX
73 * Future... implement visible bell.
75 XBell(XtDisplay(__vi_screen->area), 0);
76 return (0);
79 static int
80 vi_busyon(int ipvi, char *str1, u_int32_t len1)
82 __vi_set_cursor(__vi_screen, 1);
83 return (0);
86 static int
87 vi_busyoff(int ipvi)
89 __vi_set_cursor(__vi_screen, 0);
90 return (0);
93 static int
94 vi_clrtoeol(int ipvi)
96 int len;
97 char *ptr;
99 len = __vi_screen->cols - __vi_screen->curx;
100 ptr = CharAt(__vi_screen, __vi_screen->cury, __vi_screen->curx);
102 /* Clear backing store. */
103 memset(ptr, ' ', len);
104 memset(FlagAt(__vi_screen, __vi_screen->cury, __vi_screen->curx),
105 COLOR_STANDARD, len);
107 /* Draw from backing store. */
108 __vi_draw_text(__vi_screen, __vi_screen->cury, __vi_screen->curx, len);
110 return (0);
113 static int
114 vi_deleteln(int ipvi)
116 int y, rows, len, height, width;
118 y = __vi_screen->cury;
119 rows = __vi_screen->rows - (y+1);
120 len = __vi_screen->cols * rows;
122 /* Don't want to copy the caret! */
123 __vi_erase_caret(__vi_screen);
125 /* Adjust backing store and the flags. */
126 memmove(CharAt(__vi_screen, y, 0), CharAt(__vi_screen, y+1, 0), len);
127 memmove(FlagAt(__vi_screen, y, 0), FlagAt(__vi_screen, y+1, 0), len);
129 /* Move the bits on the screen. */
130 width = __vi_screen->ch_width * __vi_screen->cols;
131 height = __vi_screen->ch_height * rows;
132 XCopyArea(XtDisplay(__vi_screen->area), /* display */
133 XtWindow(__vi_screen->area), /* src */
134 XtWindow(__vi_screen->area), /* dest */
135 __vi_copy_gc, /* context */
136 0, YTOP(__vi_screen, y+1), /* srcx, srcy */
137 width, height,
138 0, YTOP(__vi_screen, y) /* dstx, dsty */
140 /* Need to let X take over. */
141 XmUpdateDisplay(__vi_screen->area);
143 return (0);
146 static int
147 vi_discard(int ipvi)
149 /* XXX: Nothing. */
150 return (0);
153 static int
154 vi_insertln(int ipvi)
156 int y, rows, height, width;
157 char *from, *to;
159 y = __vi_screen->cury;
160 rows = __vi_screen->rows - (1+y);
161 from = CharAt(__vi_screen, y, 0),
162 to = CharAt(__vi_screen, y+1, 0);
164 /* Don't want to copy the caret! */
165 __vi_erase_caret(__vi_screen);
167 /* Adjust backing store. */
168 memmove(to, from, __vi_screen->cols * rows);
169 memset(from, ' ', __vi_screen->cols);
171 /* And the backing store. */
172 from = FlagAt(__vi_screen, y, 0),
173 to = FlagAt(__vi_screen, y+1, 0);
174 memmove(to, from, __vi_screen->cols * rows);
175 memset(from, COLOR_STANDARD, __vi_screen->cols);
177 /* Move the bits on the screen. */
178 width = __vi_screen->ch_width * __vi_screen->cols;
179 height = __vi_screen->ch_height * rows;
181 XCopyArea(XtDisplay(__vi_screen->area), /* display */
182 XtWindow(__vi_screen->area), /* src */
183 XtWindow(__vi_screen->area), /* dest */
184 __vi_copy_gc, /* context */
185 0, YTOP(__vi_screen, y), /* srcx, srcy */
186 width, height,
187 0, YTOP(__vi_screen, y+1) /* dstx, dsty */
190 /* clear out the new space */
191 XClearArea(XtDisplay(__vi_screen->area), /* display */
192 XtWindow(__vi_screen->area), /* window */
193 0, YTOP(__vi_screen, y), /* srcx, srcy */
194 0, __vi_screen->ch_height, /* w=full, height */
195 True /* no exposures */
198 /* Need to let X take over. */
199 XmUpdateDisplay(__vi_screen->area);
201 return (0);
204 static int
205 vi_move(int ipvi, u_int32_t val1, u_int32_t val2)
207 __vi_move_caret(__vi_screen, val1, val2);
208 return (0);
211 static int
212 vi_redraw(int ipvi)
214 __vi_expose_func(0, __vi_screen, 0);
215 return (0);
218 static int
219 vi_refresh(int ipvi)
221 /* probably ok to scroll again */
222 __vi_clear_scroll_block();
224 /* if the tag stack widget is active, set the text field there
225 * to agree with the current caret position.
226 * Note that this really ought to be done by core due to wrapping issues
228 __vi_set_word_at_caret( __vi_screen );
230 /* similarly, the text ruler... */
231 __vi_set_text_ruler( __vi_screen->cury, __vi_screen->curx );
233 return (0);
236 static int
237 vi_quit(int ipvi)
239 if (__vi_exitp != NULL)
240 __vi_exitp();
242 return (0);
245 static int
246 vi_rename(int ipvi, char *str1, u_int32_t len1)
248 Widget shell;
249 size_t len;
250 const char *tail, *p;
252 /* For the icon, use the tail. */
253 for (p = str1, len = len1; len > 1; ++p, --len)
254 if (p[0] == '/')
255 tail = p + 1;
257 * XXX
258 * Future: Attach a title to each screen. For now, we change
259 * the title of the shell.
261 shell = __vi_screen->area;
262 while ( ! XtIsShell(shell) ) shell = XtParent(shell);
263 XtVaSetValues(shell,
264 XmNiconName, tail,
265 XmNtitle, str1,
268 return (0);
271 static int
272 vi_rewrite(int ipvi, u_int32_t val1)
274 /* XXX: Nothing. */
275 return (0);
279 static int
280 vi_scrollbar(int ipvi, u_int32_t val1, u_int32_t val2, u_int32_t val3)
282 int top, size, maximum, old_max;
284 /* in the buffer,
285 * val1 contains the top visible line number
286 * val2 contains the number of visible lines
287 * val3 contains the number of lines in the file
289 top = val1;
290 size = val2;
291 maximum = val3;
293 #if 0
294 fprintf( stderr, "Setting scrollbar\n" );
295 fprintf( stderr, "\tvalue\t\t%d\n", top );
296 fprintf( stderr, "\tsize\t\t%d\n", size );
297 fprintf( stderr, "\tmaximum\t\t%d\n", maximum );
298 #endif
300 /* armor plating. core thinks there are no lines in an
301 * empty file, but says we are on line 1
303 if ( top >= maximum ) {
304 #if 0
305 fprintf( stderr, "Correcting for top >= maximum\n" );
306 #endif
307 maximum = top + 1;
308 size = 1;
311 /* armor plating. core may think there are more
312 * lines visible than remain in the file
314 if ( top+size >= maximum ) {
315 #if 0
316 fprintf( stderr, "Correcting for top+size >= maximum\n" );
317 #endif
318 size = maximum - top;
321 /* need to increase the maximum before changing the values */
322 XtVaGetValues( __vi_screen->scroll, XmNmaximum, &old_max, 0 );
323 if ( maximum > old_max )
324 XtVaSetValues( __vi_screen->scroll, XmNmaximum, maximum, 0 );
326 /* change the rest of the values without generating a callback */
327 XmScrollBarSetValues( __vi_screen->scroll,
328 top,
329 size,
330 1, /* increment */
331 size, /* page_increment */
332 False /* do not notify me */
335 /* need to decrease the maximum after changing the values */
336 if ( maximum < old_max )
337 XtVaSetValues( __vi_screen->scroll, XmNmaximum, maximum, 0 );
339 /* done */
340 return (0);
343 static int
344 vi_select(int ipvi, char *str1, u_int32_t len1)
346 /* XXX: Nothing. */
347 return (0);
350 static int
351 vi_split(int ipvi)
353 /* XXX: Nothing. */
354 return (0);
357 IPSIOPS ipsi_ops_motif = {
358 vi_addstr,
359 vi_attribute,
360 vi_bell,
361 vi_busyoff,
362 vi_busyon,
363 vi_clrtoeol,
364 vi_deleteln,
365 vi_discard,
366 __vi_editopt,
367 vi_insertln,
368 vi_move,
369 vi_quit,
370 vi_redraw,
371 vi_refresh,
372 vi_rename,
373 vi_rewrite,
374 vi_scrollbar,
375 vi_select,
376 vi_split,
377 vi_addstr,