1 /* change further to gtkviwindow have no knowledge of ipvi */ 2 #include "config.h" 3 4 #include <gdk/gdkkeysyms.h> 5 #include <gtk/gtk.h> 6 #if 0 7 #ifdef HAVE_ZVT 8 #include <zvt/zvtterm.h> 9 #include <zvt/vt.h> 10 #endif 11 #endif 12 13 #include "../common/common.h" 14 #include "../ipc/ip.h" 15 16 #include "gtkvi.h" 17 #include "gtkviscreen.h" 18 #include "gtkviwindow.h" 19 #include "gtk_extern.h" 20 21 enum { 22 RENAME, 23 LAST_SIGNAL 24 }; 25 26 static void gtk_vi_window_class_init (GtkViWindowClass *klass); 27 static void gtk_vi_window_init (GtkViWindow *vi); 28 static void gtk_vi_window_destroy (GtkObject *object); 29 30 static int vi_key_press_event __P((GtkWidget*, GdkEventKey*, GtkViWindow*)); 31 static void vi_map __P((GtkWidget *, GtkWidget*)); 32 static void vi_resized __P((GtkWidget *, int, int, IPVIWIN*)); 33 static void vi_adjustment_value_changed __P((GtkAdjustment *, IPVIWIN *)); 34 35 static void vi_input_func __P((gpointer , gint , GdkInputCondition)); 36 37 static void vi_init_window __P((GtkViWindow *window, int)); 38 39 static int vi_addstr __P((IPVIWIN*, const char *, u_int32_t)); 40 static int vi_waddstr __P((IPVIWIN*, const CHAR_T *, u_int32_t)); 41 static int vi_attribute __P((IPVIWIN*,u_int32_t ,u_int32_t )); 42 static int vi_bell __P((IPVIWIN*)); 43 static int vi_busyon __P((IPVIWIN*, const char *, u_int32_t)); 44 static int vi_busyoff __P((IPVIWIN*)); 45 static int vi_clrtoeol __P((IPVIWIN*)); 46 static int vi_deleteln __P((IPVIWIN*)); 47 static int vi_discard __P((IPVIWIN*)); 48 static int vi_editopt __P((IPVIWIN*, const char *, u_int32_t, 49 const char *, u_int32_t, u_int32_t)); 50 static int vi_insertln __P((IPVIWIN*)); 51 static int vi_move __P((IPVIWIN*, u_int32_t, u_int32_t)); 52 static int vi_quit __P((IPVIWIN*)); 53 static int vi_redraw __P((IPVIWIN*)); 54 static int vi_refresh __P((IPVIWIN*)); 55 static int vi_rename __P((IPVIWIN*, const char *, u_int32_t)); 56 static int vi_rewrite __P((IPVIWIN*, u_int32_t)); 57 static int vi_scrollbar __P((IPVIWIN*, u_int32_t, u_int32_t , u_int32_t )); 58 static int vi_select __P((IPVIWIN*, const char *, u_int32_t)); 59 static int vi_split __P((IPVIWIN*)); 60 static int vi_ex_init __P((IPVIWIN*)); 61 static int vi_vi_init __P((IPVIWIN*)); 62 static int vi_fork __P((IPVIWIN*)); 63 64 static GtkWidgetClass *parent_class = NULL; 65 static guint vi_window_signals[LAST_SIGNAL] = { 0 }; 66 67 GtkType 68 gtk_vi_window_get_type (void) 69 { 70 static GtkType vi_window_type = 0; 71 72 if (!vi_window_type) 73 { 74 static const GtkTypeInfo vi_window_info = 75 { 76 "GtkViWindow", 77 sizeof (GtkViWindow), 78 sizeof (GtkViWindowClass), 79 (GtkClassInitFunc) gtk_vi_window_class_init, 80 (GtkObjectInitFunc) gtk_vi_window_init, 81 /* reserved_1 */ NULL, 82 /* reserved_2 */ NULL, 83 (GtkClassInitFunc) NULL, 84 }; 85 86 vi_window_type = gtk_type_unique (GTK_TYPE_NOTEBOOK, &vi_window_info); 87 } 88 89 return vi_window_type; 90 } 91 92 static void 93 gtk_vi_window_class_init (GtkViWindowClass *class) 94 { 95 GtkObjectClass *object_class; 96 97 object_class = (GtkObjectClass*) class; 98 parent_class = gtk_type_class (GTK_TYPE_WIDGET); 99 100 vi_window_signals[RENAME] = 101 gtk_signal_new ("rename", 102 GTK_RUN_FIRST, 103 GTK_CLASS_TYPE(object_class), 104 GTK_SIGNAL_OFFSET (GtkViScreenClass, rename), 105 gtk_marshal_VOID__STRING, 106 GTK_TYPE_NONE, 1, GTK_TYPE_STRING, 0); 107 108 #ifndef HAVE_PANGO 109 gtk_object_class_add_signals(object_class, vi_window_signals, LAST_SIGNAL); 110 #endif 111 112 object_class->destroy = gtk_vi_window_destroy; 113 } 114 115 static void 116 gtk_vi_window_init (GtkViWindow *vi) 117 { 118 } 119 120 GtkWidget * 121 gtk_vi_window_new (GtkVi *vi) 122 { 123 GtkViWindow* window; 124 GtkWidget *vi_widget; 125 GtkWidget *vscroll; 126 GtkWidget *table; 127 GtkWidget *term; 128 int fd; 129 #ifdef HAVE_ZVT 130 int pty[2]; 131 #endif 132 133 window = gtk_type_new(gtk_vi_window_get_type()); 134 135 window->vi = vi; 136 //vi->vi_window = GTK_WIDGET(window); 137 138 vi_widget = gtk_vi_screen_new(NULL); 139 gtk_widget_show(GTK_WIDGET(vi_widget)); 140 /* 141 vi->vi = vi_widget; 142 */ 143 window->vi_screen = vi_widget; 144 145 vscroll = gtk_vscrollbar_new(GTK_VI_SCREEN(vi_widget)->vadj); 146 gtk_widget_show(vscroll); 147 148 table = gtk_table_new(2, 2, FALSE); 149 gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(vi_widget), 150 0, 1, 0, 1); 151 gtk_table_attach(GTK_TABLE(table), vscroll, 1, 2, 0, 1, 152 (GtkAttachOptions)0, GTK_FILL, 0, 0); 153 gtk_widget_show(table); 154 gtk_signal_connect(GTK_OBJECT(table), "map", GTK_SIGNAL_FUNC(vi_map), 155 vi_widget/*->ipvi*/); 156 window->table = table; 157 158 159 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(window), FALSE); 160 gtk_notebook_set_show_border(GTK_NOTEBOOK(window), FALSE); 161 gtk_notebook_append_page(GTK_NOTEBOOK(window), table, NULL); 162 163 term = 0; 164 fd = -1; 165 166 #if 0 167 #ifdef HAVE_ZVT 168 term = zvt_term_new(); 169 zvt_term_set_blink(ZVT_TERM(term), FALSE); 170 zvt_term_get_ptys(ZVT_TERM(term), 0, pty); 171 fd = pty[1]; /* slave */ 172 gtk_widget_show(term); 173 gtk_notebook_append_page(GTK_NOTEBOOK(window), term, NULL); 174 #endif 175 #endif 176 window->term = term; 177 178 vi_init_window(window, fd); 179 180 gtk_signal_connect(GTK_OBJECT(vi_widget), "resized", 181 GTK_SIGNAL_FUNC(vi_resized), window->ipviwin); 182 gtk_signal_connect(GTK_OBJECT(vi_widget), "key_press_event", 183 (GtkSignalFunc) vi_key_press_event, window); 184 window->value_changed = 185 gtk_signal_connect(GTK_OBJECT(GTK_VI_SCREEN(vi_widget)->vadj), 186 "value_changed", 187 (GtkSignalFunc) vi_adjustment_value_changed, window->ipviwin); 188 189 return GTK_WIDGET(window); 190 } 191 192 static void 193 gtk_vi_window_destroy (GtkObject *object) 194 { 195 GtkViWindow *vi_window; 196 197 g_return_if_fail (object != NULL); 198 g_return_if_fail (GTK_IS_VI_WINDOW (object)); 199 200 vi_window = (GtkViWindow*) object; 201 202 if (vi_window->table) { 203 gtk_signal_disconnect_by_data(GTK_OBJECT(vi_window->table), 204 vi_window->vi_screen); 205 vi_window->table = 0; 206 } 207 208 if (vi_window->vi_screen) { 209 gtk_signal_disconnect_by_data(GTK_OBJECT(vi_window->vi_screen), 210 vi_window->ipviwin); 211 gtk_signal_disconnect(GTK_OBJECT(GTK_VI_SCREEN(vi_window->vi_screen)->vadj), 212 vi_window->value_changed); 213 gtk_widget_destroy(vi_window->vi_screen); 214 vi_window->vi_screen = 0; 215 } 216 217 GTK_OBJECT_CLASS(parent_class)->destroy (object); 218 } 219 220 void 221 gtk_vi_window_scrollbar(GtkViWindow *vi, guint top, guint size, guint max) 222 { 223 GtkViScreen *vi_screen; 224 /* work around gcc bug */ 225 volatile guint mymax = max; 226 volatile guint mysize = size; 227 228 vi_screen = GTK_VI_SCREEN(vi->vi_screen); 229 vi_screen->vadj->value = top; 230 vi_screen->vadj->upper = mymax; 231 vi_screen->vadj->page_size = 232 vi_screen->vadj->page_increment = mysize; 233 gtk_signal_handler_block(GTK_OBJECT(vi_screen->vadj), vi->value_changed); 234 gtk_adjustment_changed(vi_screen->vadj); 235 /* 236 gtk_adjustment_value_changed(vi_screen->vadj); 237 */ 238 gtk_signal_handler_unblock(GTK_OBJECT(vi_screen->vadj), vi->value_changed); 239 } 240 241 /* 242 * PUBLIC: void gtk_vi_quit __P((GtkViWindow*, gint)); 243 */ 244 void 245 gtk_vi_quit(vi, write) 246 GtkViWindow *vi; 247 gint write; 248 { 249 if (write) 250 vi->ipviwin->wq(vi->ipviwin); 251 else 252 vi->ipviwin->quit(vi->ipviwin); 253 } 254 255 /* 256 * PUBLIC: void gtk_vi_show_term __P((GtkViWindow*, gint)); 257 */ 258 void 259 gtk_vi_show_term(window, show) 260 GtkViWindow *window; 261 gint show; 262 { 263 gtk_notebook_set_page(GTK_NOTEBOOK(window), show ? 1 : 0); 264 } 265 266 /* 267 * PUBLIC: void gtk_vi_key_press_event __P((GtkViWindow*, GdkEventKey*)); 268 */ 269 void 270 gtk_vi_key_press_event(window, event) 271 GtkViWindow *window; 272 GdkEventKey *event; 273 { 274 #if 0 275 static struct { 276 guint key; 277 gint offset; 278 } table[] = { 279 {GDK_Home, GTK_STRUCT_OFFSET(IPVI, c_bol) }, 280 //{VI_C_BOTTOM, GTK_STRUCT_OFFSET(IPVI, c_bottom) }, 281 {GDK_End, GTK_STRUCT_OFFSET(IPVI, c_eol) }, 282 {GDK_Insert, GTK_STRUCT_OFFSET(IPVI, c_insert) }, 283 {GDK_Left, GTK_STRUCT_OFFSET(IPVI, c_left) }, 284 {GDK_Right, GTK_STRUCT_OFFSET(IPVI, c_right) }, 285 //{VI_C_TOP, GTK_STRUCT_OFFSET(IPVI, c_top) }, 286 }; 287 #endif 288 static struct { 289 guint keyval; 290 char key; 291 } table[] = { 292 { GDK_Left, 'h' }, 293 { GDK_Right, 'l' }, 294 { GDK_Up, 'k' }, 295 { GDK_Down, 'j' }, 296 { GDK_Page_Up, 'B' - '@' }, 297 { GDK_Page_Down, 'F' - '@' }, 298 }; 299 char key = event->keyval; 300 int i; 301 302 #if 0 303 for (i = 0; i < sizeof(table)/sizeof(*table); ++i) 304 if (table[i].key == event->keyval) { 305 int (*fun) __P((IPVI*)) = 306 *(int (**) __P((IPVI*)) )(((char *)vi->ipvi)+table[i].offset); 307 fun(vi->ipvi); 308 return; 309 } 310 #endif 311 for (i = 0; i < sizeof(table)/sizeof(*table); ++i) 312 if (table[i].keyval == event->keyval) { 313 window->ipviwin->string(window->ipviwin, &table[i].key, 1); 314 return; 315 } 316 317 if (event->state & GDK_CONTROL_MASK) { 318 if ((key >= 'a') && (key <= 'z')) 319 key -= 'a' - 'A'; 320 key -= '@'; 321 } 322 /* 323 fprintf(stderr, "key_press %d %d %d %c %p\n", 324 event->length, event->keyval, event->keyval, key, ipvi); 325 */ 326 if (event->length > 0) 327 window->ipviwin->string(window->ipviwin, &key, 1); 328 } 329 330 331 332 static int 333 vi_key_press_event(vi_screen, event, vi) 334 GtkViWindow *vi; 335 GtkWidget *vi_screen; 336 GdkEventKey *event; 337 { 338 gint handled; 339 340 handled = gtk_accel_groups_activate (GTK_OBJECT (vi), 341 event->keyval, (GdkModifierType) event->state); 342 if (handled) 343 return 1; 344 345 gtk_vi_key_press_event(vi, event); 346 gtk_signal_emit_stop_by_name(GTK_OBJECT(vi_screen), "key_press_event"); 347 /* handled */ 348 return 1; 349 } 350 351 static void 352 vi_map(table, vi_screen) 353 GtkWidget *vi_screen; 354 GtkWidget *table; 355 { 356 gtk_widget_grab_focus(vi_screen); 357 } 358 359 static void 360 vi_resized(vi_screen, rows, cols, ipviwin) 361 int rows,cols; 362 IPVIWIN *ipviwin; 363 GtkWidget *vi_screen; 364 { 365 GtkViWindow *vi_window = GTK_VI_WINDOW((GtkVi*)(ipviwin->private_data)); 366 367 ipviwin->resize(ipviwin, rows, cols); 368 vi_window->resized = 1; 369 } 370 371 static void 372 vi_adjustment_value_changed (adjustment, ipviwin) 373 GtkAdjustment *adjustment; 374 IPVIWIN *ipviwin; 375 { 376 GtkViWindow *vi_window = GTK_VI_WINDOW((GtkVi*)(ipviwin->private_data)); 377 378 if (vi_window->resized) 379 ipviwin->c_settop(ipviwin, adjustment->value); 380 } 381 382 383 static void 384 vi_input_func (gpointer data, gint source, GdkInputCondition condition) 385 { 386 IPVIWIN *ipviwin = (IPVIWIN *) data; 387 388 (void)ipviwin->input(ipviwin, source); 389 } 390 391 static void 392 vi_init_window (GtkViWindow *window, int fd) 393 { 394 static struct ip_si_operations ipsi_ops_gtk = { 395 vi_addstr, 396 vi_attribute, 397 vi_bell, 398 vi_busyoff, 399 vi_busyon, 400 vi_clrtoeol, 401 vi_deleteln, 402 vi_discard, 403 vi_editopt, 404 vi_insertln, 405 vi_move, 406 vi_quit, 407 vi_redraw, 408 vi_refresh, 409 vi_rename, 410 vi_rewrite, 411 vi_scrollbar, 412 vi_select, 413 vi_split, 414 (IPFunc_a)vi_waddstr, 415 }; 416 GtkVi *vi = window->vi; 417 418 vi->ipvi->new_window(vi->ipvi, &window->ipviwin, fd); 419 420 window->ipviwin->private_data = window; 421 window->ipviwin->set_ops(window->ipviwin, &ipsi_ops_gtk); 422 window->input_func = gtk_input_add_full(window->ipviwin->ifd, 423 GDK_INPUT_READ, 424 vi_input_func, 0, (gpointer)window->ipviwin, 0); 425 } 426 427 static int 428 vi_addstr(ipviwin, str, len) 429 IPVIWIN *ipviwin; 430 const char *str; 431 u_int32_t len; 432 { 433 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 434 435 gtk_vi_screen_addstr(GTK_VI_SCREEN(vi->vi_screen), str, len); 436 return (0); 437 } 438 439 static int 440 vi_waddstr(ipviwin, str, len) 441 IPVIWIN *ipviwin; 442 const CHAR_T *str; 443 u_int32_t len; 444 { 445 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 446 447 gtk_vi_screen_waddstr(GTK_VI_SCREEN(vi->vi_screen), str, len/sizeof(CHAR_T)); 448 return (0); 449 } 450 451 static int 452 vi_attribute(ipviwin,attribute,on) 453 IPVIWIN *ipviwin; 454 u_int32_t attribute, on; 455 { 456 GtkViWindow* window = (GtkViWindow*)(ipviwin->private_data); 457 458 if (attribute == SA_ALTERNATE) { 459 gtk_vi_show_term(window, !on); 460 } 461 else 462 gtk_vi_screen_attribute(GTK_VI_SCREEN(window->vi_screen), attribute, on); 463 return (0); 464 } 465 466 static int 467 vi_bell(ipbp) 468 IPVIWIN *ipbp; 469 { 470 /* 471 fprintf(stderr, "vi_bell\n"); 472 */ 473 #if 0 474 /* 475 * XXX 476 * Future... implement visible bell. 477 */ 478 XBell(XtDisplay(__vi_screen->area), 0); 479 #endif 480 return (0); 481 } 482 483 static int 484 vi_busyon (IPVIWIN* ipviwin, const char *a, u_int32_t s) 485 { 486 /* 487 fprintf(stderr, "vi_busyon\n"); 488 */ 489 #if 0 490 __vi_set_cursor(__vi_screen, 1); 491 #endif 492 return (0); 493 } 494 495 static int 496 vi_busyoff(ipbp) 497 IPVIWIN *ipbp; 498 { 499 /* 500 fprintf(stderr, "vi_busyoff\n"); 501 */ 502 #if 0 503 __vi_set_cursor(__vi_screen, 0); 504 #endif 505 return (0); 506 } 507 508 static int 509 vi_clrtoeol(ipviwin) 510 IPVIWIN *ipviwin; 511 { 512 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 513 514 gtk_vi_screen_clrtoel(GTK_VI_SCREEN(vi->vi_screen)); 515 return 0; 516 } 517 518 static int 519 vi_deleteln(ipviwin) 520 IPVIWIN *ipviwin; 521 { 522 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 523 524 gtk_vi_screen_deleteln(GTK_VI_SCREEN(vi->vi_screen)); 525 return (0); 526 } 527 528 static int 529 vi_editopt (IPVIWIN* a, const char *b, u_int32_t c, 530 const char *d, u_int32_t e, u_int32_t f) 531 { 532 /* 533 fprintf(stderr, "%p %p vi_editopt\n", a, a->private_data); 534 */ 535 #if 0 536 /* XXX: Nothing. */ 537 #endif 538 return (0); 539 } 540 541 542 static int 543 vi_discard(ipbp) 544 IPVIWIN *ipbp; 545 { 546 /* 547 fprintf(stderr, "vi_discard\n"); 548 */ 549 #if 0 550 /* XXX: Nothing. */ 551 #endif 552 return (0); 553 } 554 555 static int 556 vi_insertln(ipviwin) 557 IPVIWIN *ipviwin; 558 { 559 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 560 561 gtk_vi_screen_insertln(GTK_VI_SCREEN(vi->vi_screen)); 562 return (0); 563 } 564 565 static int 566 vi_move(ipviwin, row, col) 567 IPVIWIN *ipviwin; 568 u_int32_t row; 569 u_int32_t col; 570 { 571 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 572 573 gtk_vi_screen_move(GTK_VI_SCREEN(vi->vi_screen), row, col); 574 return (0); 575 } 576 577 static int 578 vi_redraw(ipviwin) 579 IPVIWIN *ipviwin; 580 { 581 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 582 583 gtk_widget_draw(GTK_WIDGET(vi->vi_screen), NULL); 584 return (0); 585 } 586 587 static int 588 vi_refresh(ipviwin) 589 IPVIWIN *ipviwin; 590 { 591 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 592 593 gtk_vi_screen_refresh(GTK_VI_SCREEN(vi->vi_screen)); 594 return (0); 595 } 596 597 static int 598 vi_quit(ipviwin) 599 IPVIWIN *ipviwin; 600 { 601 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 602 603 gtk_input_remove(vi->input_func); 604 gtk_widget_destroy(GTK_WIDGET(vi)); 605 return (0); 606 } 607 608 static int 609 vi_rename(ipviwin, str, len) 610 IPVIWIN *ipviwin; 611 const char *str; 612 u_int32_t len; 613 { 614 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 615 616 gchar* name = g_strndup(str, len); 617 gtk_signal_emit_by_name(GTK_OBJECT(vi), "rename", name); 618 g_free(name); 619 return (0); 620 } 621 622 static int 623 vi_rewrite(ipviwin, row) 624 IPVIWIN *ipviwin; 625 u_int32_t row; 626 { 627 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 628 629 gtk_vi_screen_rewrite(GTK_VI_SCREEN(vi->vi_screen), row); 630 return (0); 631 } 632 633 634 static int 635 vi_scrollbar(ipviwin, top, size, max) 636 IPVIWIN *ipviwin; 637 u_int32_t top, size, max; 638 { 639 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 640 641 gtk_vi_window_scrollbar(vi, top, size, max); 642 643 return (0); 644 } 645 646 static int vi_select (IPVIWIN* a, const char * b, u_int32_t c) 647 { 648 /* 649 fprintf(stderr, "vi_select\n"); 650 */ 651 #if 0 652 /* XXX: Nothing. */ 653 #endif 654 return (0); 655 } 656 657 static int 658 vi_split(ipbp) 659 IPVIWIN *ipbp; 660 { 661 fprintf(stderr, "vi_split\n"); 662 #if 0 663 /* XXX: Nothing. */ 664 #endif 665 return (0); 666 } 667 668 static int 669 vi_ex_init(ipviwin) 670 IPVIWIN *ipviwin; 671 { 672 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 673 674 /* 675 gtk_vi_show_term(vi, 1); 676 */ 677 return 0; 678 } 679 680 static int 681 vi_vi_init(ipviwin) 682 IPVIWIN *ipviwin; 683 { 684 GtkViWindow* vi = (GtkViWindow*)(ipviwin->private_data); 685 686 /* 687 gtk_vi_show_term(vi, 0); 688 */ 689 return 0; 690 } 691