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