1dbd550edSchristos /*-
2dbd550edSchristos * Copyright (c) 1996
3dbd550edSchristos * Rob Zimmermann. All rights reserved.
4dbd550edSchristos * Copyright (c) 1996
5dbd550edSchristos * Keith Bostic. All rights reserved.
6dbd550edSchristos *
7dbd550edSchristos * See the LICENSE file for redistribution information.
8dbd550edSchristos */
9dbd550edSchristos
10dbd550edSchristos #include "config.h"
11dbd550edSchristos
12*2f698edbSchristos #include <sys/cdefs.h>
13*2f698edbSchristos #if 0
14dbd550edSchristos #ifndef lint
15dbd550edSchristos static const char sccsid[] = "Id: m_func.c,v 8.28 2003/11/05 17:09:59 skimo Exp (Berkeley) Date: 2003/11/05 17:09:59 ";
16dbd550edSchristos #endif /* not lint */
17*2f698edbSchristos #else
18*2f698edbSchristos __RCSID("$NetBSD: m_func.c,v 1.2 2014/01/26 21:43:45 christos Exp $");
19*2f698edbSchristos #endif
20dbd550edSchristos
21dbd550edSchristos #include <sys/types.h>
22dbd550edSchristos #include <sys/queue.h>
23dbd550edSchristos
24dbd550edSchristos #include <Xm/PanedW.h>
25dbd550edSchristos #include <Xm/ScrollBar.h>
26dbd550edSchristos
27dbd550edSchristos #include <bitstring.h>
28dbd550edSchristos #include <stdio.h>
29dbd550edSchristos #include <stdlib.h>
30dbd550edSchristos #include <string.h>
31dbd550edSchristos
32dbd550edSchristos #undef LOCK_SUCCESS
33dbd550edSchristos #include "../common/common.h"
34dbd550edSchristos #include "../ipc/ip.h"
35dbd550edSchristos #include "m_motif.h"
36dbd550edSchristos
37dbd550edSchristos
38dbd550edSchristos static int
vi_addstr(int ipvi,char * str1,u_int32_t len1)39dbd550edSchristos vi_addstr(int ipvi, char *str1, u_int32_t len1)
40dbd550edSchristos {
41dbd550edSchristos #ifdef TRACE
42dbd550edSchristos vtrace("addstr() {%.*s}\n", ipbp->len1, ipbp->str1);
43dbd550edSchristos #endif
44dbd550edSchristos /* Add to backing store. */
45dbd550edSchristos memcpy(CharAt(__vi_screen, __vi_screen->cury, __vi_screen->curx),
46dbd550edSchristos str1, len1);
47dbd550edSchristos memset(FlagAt(__vi_screen, __vi_screen->cury, __vi_screen->curx),
48dbd550edSchristos __vi_screen->color, len1);
49dbd550edSchristos
50dbd550edSchristos /* Draw from backing store. */
51dbd550edSchristos __vi_draw_text(__vi_screen,
52dbd550edSchristos __vi_screen->cury, __vi_screen->curx, len1);
53dbd550edSchristos
54dbd550edSchristos /* Advance the caret. */
55dbd550edSchristos __vi_move_caret(__vi_screen,
56dbd550edSchristos __vi_screen->cury, __vi_screen->curx + len1);
57dbd550edSchristos return (0);
58dbd550edSchristos }
59dbd550edSchristos
60dbd550edSchristos static int
vi_attribute(int ipvi,u_int32_t val1,u_int32_t val2)61dbd550edSchristos vi_attribute(int ipvi, u_int32_t val1, u_int32_t val2)
62dbd550edSchristos {
63dbd550edSchristos switch (val1) {
64dbd550edSchristos case SA_ALTERNATE:
65dbd550edSchristos /* XXX: Nothing. */
66dbd550edSchristos break;
67dbd550edSchristos case SA_INVERSE:
68dbd550edSchristos __vi_screen->color = val2;
69dbd550edSchristos break;
70dbd550edSchristos }
71dbd550edSchristos return (0);
72dbd550edSchristos }
73dbd550edSchristos
74dbd550edSchristos static int
vi_bell(int ipvi)75dbd550edSchristos vi_bell(int ipvi)
76dbd550edSchristos {
77dbd550edSchristos /*
78dbd550edSchristos * XXX
79dbd550edSchristos * Future... implement visible bell.
80dbd550edSchristos */
81dbd550edSchristos XBell(XtDisplay(__vi_screen->area), 0);
82dbd550edSchristos return (0);
83dbd550edSchristos }
84dbd550edSchristos
85dbd550edSchristos static int
vi_busyon(int ipvi,char * str1,u_int32_t len1)86dbd550edSchristos vi_busyon(int ipvi, char *str1, u_int32_t len1)
87dbd550edSchristos {
88dbd550edSchristos __vi_set_cursor(__vi_screen, 1);
89dbd550edSchristos return (0);
90dbd550edSchristos }
91dbd550edSchristos
92dbd550edSchristos static int
vi_busyoff(int ipvi)93dbd550edSchristos vi_busyoff(int ipvi)
94dbd550edSchristos {
95dbd550edSchristos __vi_set_cursor(__vi_screen, 0);
96dbd550edSchristos return (0);
97dbd550edSchristos }
98dbd550edSchristos
99dbd550edSchristos static int
vi_clrtoeol(int ipvi)100dbd550edSchristos vi_clrtoeol(int ipvi)
101dbd550edSchristos {
102dbd550edSchristos int len;
103dbd550edSchristos char *ptr;
104dbd550edSchristos
105dbd550edSchristos len = __vi_screen->cols - __vi_screen->curx;
106dbd550edSchristos ptr = CharAt(__vi_screen, __vi_screen->cury, __vi_screen->curx);
107dbd550edSchristos
108dbd550edSchristos /* Clear backing store. */
109dbd550edSchristos memset(ptr, ' ', len);
110dbd550edSchristos memset(FlagAt(__vi_screen, __vi_screen->cury, __vi_screen->curx),
111dbd550edSchristos COLOR_STANDARD, len);
112dbd550edSchristos
113dbd550edSchristos /* Draw from backing store. */
114dbd550edSchristos __vi_draw_text(__vi_screen, __vi_screen->cury, __vi_screen->curx, len);
115dbd550edSchristos
116dbd550edSchristos return (0);
117dbd550edSchristos }
118dbd550edSchristos
119dbd550edSchristos static int
vi_deleteln(int ipvi)120dbd550edSchristos vi_deleteln(int ipvi)
121dbd550edSchristos {
122dbd550edSchristos int y, rows, len, height, width;
123dbd550edSchristos
124dbd550edSchristos y = __vi_screen->cury;
125dbd550edSchristos rows = __vi_screen->rows - (y+1);
126dbd550edSchristos len = __vi_screen->cols * rows;
127dbd550edSchristos
128dbd550edSchristos /* Don't want to copy the caret! */
129dbd550edSchristos __vi_erase_caret(__vi_screen);
130dbd550edSchristos
131dbd550edSchristos /* Adjust backing store and the flags. */
132dbd550edSchristos memmove(CharAt(__vi_screen, y, 0), CharAt(__vi_screen, y+1, 0), len);
133dbd550edSchristos memmove(FlagAt(__vi_screen, y, 0), FlagAt(__vi_screen, y+1, 0), len);
134dbd550edSchristos
135dbd550edSchristos /* Move the bits on the screen. */
136dbd550edSchristos width = __vi_screen->ch_width * __vi_screen->cols;
137dbd550edSchristos height = __vi_screen->ch_height * rows;
138dbd550edSchristos XCopyArea(XtDisplay(__vi_screen->area), /* display */
139dbd550edSchristos XtWindow(__vi_screen->area), /* src */
140dbd550edSchristos XtWindow(__vi_screen->area), /* dest */
141dbd550edSchristos __vi_copy_gc, /* context */
142dbd550edSchristos 0, YTOP(__vi_screen, y+1), /* srcx, srcy */
143dbd550edSchristos width, height,
144dbd550edSchristos 0, YTOP(__vi_screen, y) /* dstx, dsty */
145dbd550edSchristos );
146dbd550edSchristos /* Need to let X take over. */
147dbd550edSchristos XmUpdateDisplay(__vi_screen->area);
148dbd550edSchristos
149dbd550edSchristos return (0);
150dbd550edSchristos }
151dbd550edSchristos
152dbd550edSchristos static int
vi_discard(int ipvi)153dbd550edSchristos vi_discard(int ipvi)
154dbd550edSchristos {
155dbd550edSchristos /* XXX: Nothing. */
156dbd550edSchristos return (0);
157dbd550edSchristos }
158dbd550edSchristos
159dbd550edSchristos static int
vi_insertln(int ipvi)160dbd550edSchristos vi_insertln(int ipvi)
161dbd550edSchristos {
162dbd550edSchristos int y, rows, height, width;
163dbd550edSchristos char *from, *to;
164dbd550edSchristos
165dbd550edSchristos y = __vi_screen->cury;
166dbd550edSchristos rows = __vi_screen->rows - (1+y);
167dbd550edSchristos from = CharAt(__vi_screen, y, 0),
168dbd550edSchristos to = CharAt(__vi_screen, y+1, 0);
169dbd550edSchristos
170dbd550edSchristos /* Don't want to copy the caret! */
171dbd550edSchristos __vi_erase_caret(__vi_screen);
172dbd550edSchristos
173dbd550edSchristos /* Adjust backing store. */
174dbd550edSchristos memmove(to, from, __vi_screen->cols * rows);
175dbd550edSchristos memset(from, ' ', __vi_screen->cols);
176dbd550edSchristos
177dbd550edSchristos /* And the backing store. */
178dbd550edSchristos from = FlagAt(__vi_screen, y, 0),
179dbd550edSchristos to = FlagAt(__vi_screen, y+1, 0);
180dbd550edSchristos memmove(to, from, __vi_screen->cols * rows);
181dbd550edSchristos memset(from, COLOR_STANDARD, __vi_screen->cols);
182dbd550edSchristos
183dbd550edSchristos /* Move the bits on the screen. */
184dbd550edSchristos width = __vi_screen->ch_width * __vi_screen->cols;
185dbd550edSchristos height = __vi_screen->ch_height * rows;
186dbd550edSchristos
187dbd550edSchristos XCopyArea(XtDisplay(__vi_screen->area), /* display */
188dbd550edSchristos XtWindow(__vi_screen->area), /* src */
189dbd550edSchristos XtWindow(__vi_screen->area), /* dest */
190dbd550edSchristos __vi_copy_gc, /* context */
191dbd550edSchristos 0, YTOP(__vi_screen, y), /* srcx, srcy */
192dbd550edSchristos width, height,
193dbd550edSchristos 0, YTOP(__vi_screen, y+1) /* dstx, dsty */
194dbd550edSchristos );
195dbd550edSchristos
196dbd550edSchristos /* clear out the new space */
197dbd550edSchristos XClearArea(XtDisplay(__vi_screen->area), /* display */
198dbd550edSchristos XtWindow(__vi_screen->area), /* window */
199dbd550edSchristos 0, YTOP(__vi_screen, y), /* srcx, srcy */
200dbd550edSchristos 0, __vi_screen->ch_height, /* w=full, height */
201dbd550edSchristos True /* no exposures */
202dbd550edSchristos );
203dbd550edSchristos
204dbd550edSchristos /* Need to let X take over. */
205dbd550edSchristos XmUpdateDisplay(__vi_screen->area);
206dbd550edSchristos
207dbd550edSchristos return (0);
208dbd550edSchristos }
209dbd550edSchristos
210dbd550edSchristos static int
vi_move(int ipvi,u_int32_t val1,u_int32_t val2)211dbd550edSchristos vi_move(int ipvi, u_int32_t val1, u_int32_t val2)
212dbd550edSchristos {
213dbd550edSchristos __vi_move_caret(__vi_screen, val1, val2);
214dbd550edSchristos return (0);
215dbd550edSchristos }
216dbd550edSchristos
217dbd550edSchristos static int
vi_redraw(int ipvi)218dbd550edSchristos vi_redraw(int ipvi)
219dbd550edSchristos {
220dbd550edSchristos __vi_expose_func(0, __vi_screen, 0);
221dbd550edSchristos return (0);
222dbd550edSchristos }
223dbd550edSchristos
224dbd550edSchristos static int
vi_refresh(int ipvi)225dbd550edSchristos vi_refresh(int ipvi)
226dbd550edSchristos {
227dbd550edSchristos /* probably ok to scroll again */
228dbd550edSchristos __vi_clear_scroll_block();
229dbd550edSchristos
230dbd550edSchristos /* if the tag stack widget is active, set the text field there
231dbd550edSchristos * to agree with the current caret position.
232dbd550edSchristos * Note that this really ought to be done by core due to wrapping issues
233dbd550edSchristos */
234dbd550edSchristos __vi_set_word_at_caret( __vi_screen );
235dbd550edSchristos
236dbd550edSchristos /* similarly, the text ruler... */
237dbd550edSchristos __vi_set_text_ruler( __vi_screen->cury, __vi_screen->curx );
238dbd550edSchristos
239dbd550edSchristos return (0);
240dbd550edSchristos }
241dbd550edSchristos
242dbd550edSchristos static int
vi_quit(int ipvi)243dbd550edSchristos vi_quit(int ipvi)
244dbd550edSchristos {
245dbd550edSchristos if (__vi_exitp != NULL)
246dbd550edSchristos __vi_exitp();
247dbd550edSchristos
248dbd550edSchristos return (0);
249dbd550edSchristos }
250dbd550edSchristos
251dbd550edSchristos static int
vi_rename(int ipvi,char * str1,u_int32_t len1)252dbd550edSchristos vi_rename(int ipvi, char *str1, u_int32_t len1)
253dbd550edSchristos {
254dbd550edSchristos Widget shell;
255dbd550edSchristos size_t len;
256dbd550edSchristos const char *tail, *p;
257dbd550edSchristos
258dbd550edSchristos /* For the icon, use the tail. */
259dbd550edSchristos for (p = str1, len = len1; len > 1; ++p, --len)
260dbd550edSchristos if (p[0] == '/')
261dbd550edSchristos tail = p + 1;
262dbd550edSchristos /*
263dbd550edSchristos * XXX
264dbd550edSchristos * Future: Attach a title to each screen. For now, we change
265dbd550edSchristos * the title of the shell.
266dbd550edSchristos */
267dbd550edSchristos shell = __vi_screen->area;
268dbd550edSchristos while ( ! XtIsShell(shell) ) shell = XtParent(shell);
269dbd550edSchristos XtVaSetValues(shell,
270dbd550edSchristos XmNiconName, tail,
271dbd550edSchristos XmNtitle, str1,
272dbd550edSchristos 0
273dbd550edSchristos );
274dbd550edSchristos return (0);
275dbd550edSchristos }
276dbd550edSchristos
277dbd550edSchristos static int
vi_rewrite(int ipvi,u_int32_t val1)278dbd550edSchristos vi_rewrite(int ipvi, u_int32_t val1)
279dbd550edSchristos {
280dbd550edSchristos /* XXX: Nothing. */
281dbd550edSchristos return (0);
282dbd550edSchristos }
283dbd550edSchristos
284dbd550edSchristos
285dbd550edSchristos static int
vi_scrollbar(int ipvi,u_int32_t val1,u_int32_t val2,u_int32_t val3)286dbd550edSchristos vi_scrollbar(int ipvi, u_int32_t val1, u_int32_t val2, u_int32_t val3)
287dbd550edSchristos {
288dbd550edSchristos int top, size, maximum, old_max;
289dbd550edSchristos
290dbd550edSchristos /* in the buffer,
291dbd550edSchristos * val1 contains the top visible line number
292dbd550edSchristos * val2 contains the number of visible lines
293dbd550edSchristos * val3 contains the number of lines in the file
294dbd550edSchristos */
295dbd550edSchristos top = val1;
296dbd550edSchristos size = val2;
297dbd550edSchristos maximum = val3;
298dbd550edSchristos
299dbd550edSchristos #if 0
300dbd550edSchristos fprintf( stderr, "Setting scrollbar\n" );
301dbd550edSchristos fprintf( stderr, "\tvalue\t\t%d\n", top );
302dbd550edSchristos fprintf( stderr, "\tsize\t\t%d\n", size );
303dbd550edSchristos fprintf( stderr, "\tmaximum\t\t%d\n", maximum );
304dbd550edSchristos #endif
305dbd550edSchristos
306dbd550edSchristos /* armor plating. core thinks there are no lines in an
307dbd550edSchristos * empty file, but says we are on line 1
308dbd550edSchristos */
309dbd550edSchristos if ( top >= maximum ) {
310dbd550edSchristos #if 0
311dbd550edSchristos fprintf( stderr, "Correcting for top >= maximum\n" );
312dbd550edSchristos #endif
313dbd550edSchristos maximum = top + 1;
314dbd550edSchristos size = 1;
315dbd550edSchristos }
316dbd550edSchristos
317dbd550edSchristos /* armor plating. core may think there are more
318dbd550edSchristos * lines visible than remain in the file
319dbd550edSchristos */
320dbd550edSchristos if ( top+size >= maximum ) {
321dbd550edSchristos #if 0
322dbd550edSchristos fprintf( stderr, "Correcting for top+size >= maximum\n" );
323dbd550edSchristos #endif
324dbd550edSchristos size = maximum - top;
325dbd550edSchristos }
326dbd550edSchristos
327dbd550edSchristos /* need to increase the maximum before changing the values */
328dbd550edSchristos XtVaGetValues( __vi_screen->scroll, XmNmaximum, &old_max, 0 );
329dbd550edSchristos if ( maximum > old_max )
330dbd550edSchristos XtVaSetValues( __vi_screen->scroll, XmNmaximum, maximum, 0 );
331dbd550edSchristos
332dbd550edSchristos /* change the rest of the values without generating a callback */
333dbd550edSchristos XmScrollBarSetValues( __vi_screen->scroll,
334dbd550edSchristos top,
335dbd550edSchristos size,
336dbd550edSchristos 1, /* increment */
337dbd550edSchristos size, /* page_increment */
338dbd550edSchristos False /* do not notify me */
339dbd550edSchristos );
340dbd550edSchristos
341dbd550edSchristos /* need to decrease the maximum after changing the values */
342dbd550edSchristos if ( maximum < old_max )
343dbd550edSchristos XtVaSetValues( __vi_screen->scroll, XmNmaximum, maximum, 0 );
344dbd550edSchristos
345dbd550edSchristos /* done */
346dbd550edSchristos return (0);
347dbd550edSchristos }
348dbd550edSchristos
349dbd550edSchristos static int
vi_select(int ipvi,char * str1,u_int32_t len1)350dbd550edSchristos vi_select(int ipvi, char *str1, u_int32_t len1)
351dbd550edSchristos {
352dbd550edSchristos /* XXX: Nothing. */
353dbd550edSchristos return (0);
354dbd550edSchristos }
355dbd550edSchristos
356dbd550edSchristos static int
vi_split(int ipvi)357dbd550edSchristos vi_split(int ipvi)
358dbd550edSchristos {
359dbd550edSchristos /* XXX: Nothing. */
360dbd550edSchristos return (0);
361dbd550edSchristos }
362dbd550edSchristos
363dbd550edSchristos IPSIOPS ipsi_ops_motif = {
364dbd550edSchristos vi_addstr,
365dbd550edSchristos vi_attribute,
366dbd550edSchristos vi_bell,
367dbd550edSchristos vi_busyoff,
368dbd550edSchristos vi_busyon,
369dbd550edSchristos vi_clrtoeol,
370dbd550edSchristos vi_deleteln,
371dbd550edSchristos vi_discard,
372dbd550edSchristos __vi_editopt,
373dbd550edSchristos vi_insertln,
374dbd550edSchristos vi_move,
375dbd550edSchristos vi_quit,
376dbd550edSchristos vi_redraw,
377dbd550edSchristos vi_refresh,
378dbd550edSchristos vi_rename,
379dbd550edSchristos vi_rewrite,
380dbd550edSchristos vi_scrollbar,
381dbd550edSchristos vi_select,
382dbd550edSchristos vi_split,
383dbd550edSchristos vi_addstr,
384dbd550edSchristos };
385