util.c revision 96d43ffd
1/* $XConsortium: util.c,v 1.16 92/08/12 16:46:22 converse Exp $ */ 2 3/* 4 * COPYRIGHT 1987 5 * DIGITAL EQUIPMENT CORPORATION 6 * MAYNARD, MASSACHUSETTS 7 * ALL RIGHTS RESERVED. 8 * 9 * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND 10 * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. 11 * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR 12 * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 13 * 14 * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, 15 * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT 16 * SET FORTH ABOVE. 17 * 18 * 19 * Permission to use, copy, modify, and distribute this software and its 20 * documentation for any purpose and without fee is hereby granted, provided 21 * that the above copyright notice appear in all copies and that both that 22 * copyright notice and this permission notice appear in supporting 23 * documentation, and that the name of Digital Equipment Corporation not be 24 * used in advertising or publicity pertaining to distribution of the software 25 * without specific, written prior permission. 26 */ 27/* $XFree86: xc/programs/xedit/util.c,v 1.26 2003/05/07 20:54:43 herrb Exp $ */ 28 29#include <stdio.h> 30#include <stdarg.h> 31 32#include <libgen.h> /* POSIX basename() */ 33#include <stdlib.h> /* for realpath() */ 34#include <errno.h> /* for ENOENT */ 35#include "xedit.h" 36 37#include <X11/Xfuncs.h> 38#include <X11/Xos.h> /* for types.h */ 39 40#include <sys/stat.h> 41#include <X11/Xmu/CharSet.h> 42#include <X11/Xaw/SmeBSB.h> 43#include <X11/Xaw/SimpleMenu.h> 44 45/* 46 * Prototypes 47 */ 48static void SwitchSourceCallback(Widget, XtPointer, XtPointer); 49static int WindowIndex(Widget); 50static void ChangeTextWindow(Widget); 51 52/* 53 * External 54 */ 55extern void _XawTextShowPosition(TextWidget); 56 57/* 58 * Initialization 59 */ 60extern Widget scratch; 61extern Widget vpanes[2], labels[3], texts[3], forms[3]; 62extern XawTextWrapMode wrapmodes[3]; 63 64#ifndef va_copy 65# ifdef __va_copy 66# define va_copy __va_copy 67# else 68# error "no working va_copy was found" 69# endif 70#endif 71 72/* 73 * Implementation 74 */ 75void 76XeditPrintf(const char *format, ...) 77{ 78 static struct { 79 XawTextPosition last; 80 int size; 81 int length; 82 int repeat; 83 char *buffer; 84 } info; 85 86 size_t size; 87 va_list va; 88 XawTextBlock text; 89 XawTextPosition left, right; 90 char buffer[BUFSIZ]; 91 char *string, rbuffer[32]; 92 93 va_start(va, format); 94 size = vsnprintf(buffer, sizeof(buffer), format, va); 95 va_end(va); 96 97 /* Should never happen... */ 98 if (size >= sizeof(buffer)) { 99 strcpy(buffer + sizeof(buffer) - 5, "...\n"); 100 size = sizeof(buffer) - 1; 101 } 102 else if (size) { 103 left = right = XawTextSourceScan(XawTextGetSource(messwidget), 104 0, XawstAll, XawsdRight, 1, True); 105 106 if (left == info.last && 107 info.buffer && 108 strcmp(buffer, info.buffer) == 0) { 109 string = rbuffer; 110 if (info.repeat == 1) 111 left -= info.buffer[strlen(info.buffer) - 1] == '\n'; 112 else 113 left -= info.length; 114 size = info.length = XmuSnprintf(rbuffer, sizeof(rbuffer), 115 " [%d times]\n", ++info.repeat); 116 } 117 else { 118 string = buffer; 119 if (size >= info.size) 120 info.buffer = XtMalloc(size + 1); 121 strcpy(info.buffer, buffer); 122 info.repeat = 1; 123 } 124 125 text.length = size; 126 text.ptr = string; 127 text.firstPos = 0; 128 text.format = FMT8BIT; 129 130 XawTextReplace(messwidget, left, right, &text); 131 132 info.last = left + text.length; 133 XawTextSetInsertionPoint(messwidget, info.last); 134 } 135} 136 137Widget 138MakeCommandButton(Widget box, char *name, XtCallbackProc function) 139{ 140 Widget w = XtCreateManagedWidget(name, commandWidgetClass, box, NULL, ZERO); 141 if (function != NULL) 142 XtAddCallback(w, XtNcallback, function, (caddr_t) NULL); 143 else 144 XtVaSetValues(w, XtNsensitive, False, NULL); 145 return w; 146} 147 148Widget 149MakeStringBox(Widget parent, String name, String string) 150{ 151 Arg args[5]; 152 Cardinal numargs = 0; 153 Widget StringW; 154 155 XtSetArg(args[numargs], XtNeditType, XawtextEdit); numargs++; 156 XtSetArg(args[numargs], XtNstring, string); numargs++; 157 158 StringW = XtCreateManagedWidget(name, asciiTextWidgetClass, 159 parent, args, numargs); 160 return(StringW); 161} 162 163/* Function Name: GetString 164 * Description: retrieves the string from a asciiText widget. 165 * Arguments: w - the ascii text widget. 166 * Returns: the filename. 167 */ 168 169String 170GetString(Widget w) 171{ 172 String str; 173 Arg arglist[1]; 174 175 XtSetArg(arglist[0], XtNstring, &str); 176 XtGetValues( w, arglist, ONE); 177 return(str); 178} 179 180/* Function Name: MaybeCreateFile 181 * Description: Checks to see if file exists, and if not, creates it. 182 * Arguments: file - name of file to check. 183 * Returns: permissions status 184 */ 185 186FileAccess 187MaybeCreateFile(const char *file) 188{ 189 Boolean exists; 190 int fd; 191 192 if (access(file, F_OK) != 0) { 193 fd = creat(file, 0666); 194 if (fd != -1) 195 close(fd); 196 } 197 198 return(CheckFilePermissions(file, &exists)); 199} 200 201 202FileAccess 203CheckFilePermissions(const char *file, Boolean *exists) 204{ 205 char temp[BUFSIZ], *ptr; 206 207 if (access(file, F_OK) == 0) { 208 *exists = TRUE; 209 210 if (access(file, R_OK) != 0) 211 return(NO_READ); 212 213 if (access(file, R_OK | W_OK) == 0) 214 return(WRITE_OK); 215 return(READ_OK); 216 } 217 218 *exists = FALSE; 219 220 strncpy(temp, file, sizeof(temp) - 1); 221 temp[sizeof(temp) - 1] = '\0'; 222 if ( (ptr = rindex(temp, '/')) == NULL) 223 strcpy(temp, "."); 224 else 225 *ptr = '\0'; 226 227 if (access(temp, R_OK | W_OK | X_OK) == 0) 228 return(WRITE_OK); 229 return(NO_READ); 230} 231 232xedit_flist_item * 233AddTextSource(Widget source, const char *name, const char *filename, int flags, 234 FileAccess file_access) 235{ 236 xedit_flist_item *item; 237 char *wid_name; 238 239 item = (xedit_flist_item*)XtMalloc(sizeof(xedit_flist_item)); 240 item->source = source; 241 item->name = XtNewString(name); 242 item->filename = XtNewString(filename); 243 item->flags = flags; 244 item->file_access = file_access; 245 item->display_position = item->insert_position = 0; 246 item->mode = 0; 247 item->mtime = 0; 248 item->properties = NULL; 249 item->xldata = NULL; 250 /* Try to load associated tags file */ 251 SearchTagsFile(item); 252 253 flist.itens = (xedit_flist_item**) 254 XtRealloc((char*)flist.itens, sizeof(xedit_flist_item*) 255 * (flist.num_itens + 1)); 256 257 flist.itens[flist.num_itens++] = item; 258 259 if (!flist.popup) { 260 flist.popup = XtCreatePopupShell("fileMenu", simpleMenuWidgetClass, 261 topwindow, NULL, 0); 262 /* XXX hack: this don't allow setting the geometry of the popup widget 263 * as it will override any settings when a menu entry is inserted 264 * or deleted, but saves us the trouble generated by a resource 265 * setting like: '*geometry: <width>x<height>' 266 */ 267 XtRealizeWidget(flist.popup); 268 } 269 if ((wid_name = strrchr(item->name, '/')) == NULL) 270 wid_name = item->name; 271 else 272 ++wid_name; 273 item->sme = XtVaCreateManagedWidget(wid_name, smeBSBObjectClass, 274 flist.popup, XtNlabel, item->filename, 275 NULL, NULL); 276 XtAddCallback(item->sme, XtNcallback, 277 SwitchSourceCallback, (XtPointer)item); 278 279 SetTextProperties(item); 280 281 return (item); 282} 283 284Bool 285KillTextSource(xedit_flist_item *item) 286{ 287 xedit_flist_item *nitem = NULL; 288 unsigned idx, i; 289 Arg targs[3]; 290 Cardinal tnum_args; 291 Arg largs[2]; 292 Cardinal lnum_args; 293 char label_buf[BUFSIZ]; 294 295 for (idx = 0; idx < flist.num_itens; idx++) 296 if (flist.itens[idx] == item) { 297 if (idx + 1 < flist.num_itens) 298 nitem = flist.itens[idx + 1]; 299 else if (idx >= 1) 300 nitem = flist.itens[idx - 1]; 301 break; 302 } 303 304 if (idx >= flist.num_itens) 305 return (False); 306 307 flist.current = nitem; 308 if (item == flist.other) 309 flist.other = NULL; 310 311 if (nitem->file_access == READ_OK) 312 XmuSnprintf(label_buf, sizeof(label_buf), "%s READ ONLY", 313 nitem->name); 314 else if (nitem->file_access == WRITE_OK) 315 XmuSnprintf(label_buf, sizeof(label_buf), "%s Read - Write", 316 nitem->name); 317 lnum_args = 0; 318 XtSetArg(largs[lnum_args], XtNlabel, label_buf); ++lnum_args; 319 if (nitem->flags & CHANGED_BIT) 320 XtSetArg(largs[lnum_args], XtNleftBitmap, flist.pixmap); 321 else 322 XtSetArg(largs[lnum_args], XtNleftBitmap, None); 323 ++lnum_args; 324 325 tnum_args = 0; 326 XtSetArg(targs[tnum_args], XtNtextSource, 327 nitem->source); ++tnum_args; 328 XtSetArg(targs[tnum_args], XtNdisplayPosition, 329 nitem->display_position); ++tnum_args; 330 XtSetArg(targs[tnum_args], XtNinsertPosition, 331 nitem->insert_position); ++tnum_args; 332 for (i = 0; i < 3; i++) 333 if (XawTextGetSource(texts[i]) == item->source) { 334 XtSetValues(labels[i], largs, lnum_args); 335 XawTextDisableRedisplay(texts[i]); 336 XtSetValues(texts[i], targs, tnum_args); 337 338 UpdateTextProperties(0); 339 340 _XawTextShowPosition((TextWidget)texts[i]); 341 XawTextEnableRedisplay(texts[i]); 342 if (texts[i] == textwindow) { 343 Arg args[1]; 344 345 if (nitem->source != scratch) 346 XtSetArg(args[0], XtNstring, nitem->name); 347 else 348 XtSetArg(args[0], XtNstring, NULL); 349 XtSetValues(filenamewindow, args, 1); 350 } 351 } 352 353 UnsetTextProperties(item); 354 XtFree(item->name); 355 XtFree(item->filename); 356 XtDestroyWidget(item->sme); 357 XtDestroyWidget(item->source); 358 XtFree((char*)item); 359 360 if (idx < flist.num_itens - 1) 361 memmove(&flist.itens[idx], &flist.itens[idx + 1], 362 (flist.num_itens - idx) * sizeof(xedit_flist_item*)); 363 364 --flist.num_itens; 365 366 return (True); 367} 368 369xedit_flist_item * 370FindTextSource(Widget source, const char *filename) 371{ 372 unsigned i; 373 374 if (source) { 375 for (i = 0; i < flist.num_itens; i++) 376 if (flist.itens[i]->source == source) 377 return (flist.itens[i]); 378 } 379 else if (filename) { 380 for (i = 0; i < flist.num_itens; i++) 381 if (strcmp(flist.itens[i]->filename, filename) == 0) 382 return (flist.itens[i]); 383 } 384 385 return (NULL); 386} 387 388void 389SwitchTextSource(xedit_flist_item *item) 390{ 391 Arg args[4]; 392 Cardinal num_args; 393 char label_buf[BUFSIZ]; 394 xedit_flist_item *old_item = 395 FindTextSource(XawTextGetSource(textwindow), NULL); 396 int i; 397 398 if (old_item != item) 399 flist.other = old_item; 400 flist.current = item; 401 402 XawTextDisableRedisplay(textwindow); 403 if (item->file_access == READ_OK) 404 XmuSnprintf(label_buf, sizeof(label_buf), "%s READ ONLY", 405 item->name); 406 else if (item->file_access == WRITE_OK) 407 XmuSnprintf(label_buf, sizeof(label_buf), "%s Read - Write", 408 item->name); 409 num_args = 0; 410 XtSetArg(args[num_args], XtNlabel, label_buf); ++num_args; 411 if (item->flags & CHANGED_BIT) 412 XtSetArg(args[num_args], XtNleftBitmap, flist.pixmap); 413 else 414 XtSetArg(args[num_args], XtNleftBitmap, None); 415 ++num_args; 416 XtSetValues(labelwindow, args, num_args); 417 418 for (i = 0; i < 3; i++) 419 if (XawTextGetSource(texts[i]) == item->source 420 && XtIsManaged(texts[i])) 421 break; 422 423 if (i < 3) { 424 num_args = 0; 425 XtSetArg(args[num_args], XtNdisplayPosition, 426 &(item->display_position)); ++num_args; 427 XtSetArg(args[num_args], XtNinsertPosition, 428 &(item->insert_position)); ++num_args; 429 XtGetValues(texts[i], args, num_args); 430 } 431 if (old_item != item) { 432 int count, idx = 0; 433 434 num_args = 0; 435 XtSetArg(args[num_args], XtNdisplayPosition, 436 &(old_item->display_position)); ++num_args; 437 XtSetArg(args[num_args], XtNinsertPosition, 438 &(old_item->insert_position)); ++num_args; 439 XtGetValues(textwindow, args, num_args); 440 441 for (count = 0, i = 0; i < 3; i++) 442 if (XawTextGetSource(texts[i]) == old_item->source 443 && XtIsManaged(texts[i])) { 444 if (++count > 1) 445 break; 446 idx = i; 447 } 448 449 if (count == 1) { 450 num_args = 0; 451 XtSetArg(args[num_args], XtNdisplayPosition, 452 &(old_item->display_position)); ++num_args; 453 XtSetArg(args[num_args], XtNinsertPosition, 454 &(old_item->insert_position)); ++num_args; 455 XtGetValues(texts[idx], args, num_args); 456 } 457 } 458 459 num_args = 0; 460 XtSetArg(args[num_args], XtNtextSource, item->source); ++num_args; 461 XtSetArg(args[num_args], XtNdisplayPosition, item->display_position); 462 ++num_args; 463 XtSetArg(args[num_args], XtNinsertPosition, item->insert_position); 464 ++num_args; 465 if (item->flags & WRAP_BIT) 466 XtSetArg(args[num_args], XtNwrap, item->wrap); 467 else 468 XtSetArg(args[num_args], XtNwrap, wrapmodes[WindowIndex(textwindow)]); 469 ++num_args; 470 XtSetValues(textwindow, args, num_args); 471 472 UpdateTextProperties(0); 473 474 _XawTextShowPosition((TextWidget)textwindow); 475 XawTextEnableRedisplay(textwindow); 476 477 num_args = 0; 478 if (item->source != scratch) { 479 XtSetArg(args[num_args], XtNstring, item->name); ++num_args; 480 } 481 else { 482 XtSetArg(args[num_args], XtNstring, NULL); ++num_args; 483 } 484 XtSetValues(filenamewindow, args, num_args); 485 /* XXX This probably should be done by the TextWidget, i.e. notice 486 * if the cursor became inivisible due to an horizontal scroll */ 487 _XawTextShowPosition((TextWidget)filenamewindow); 488} 489 490char * 491ResolveName(char *filename) 492{ 493#ifndef __UNIXOS2__ 494 static char *name; 495 char *result, *tmp = name; 496#endif 497 498 if (filename == NULL) 499 filename = GetString(filenamewindow); 500 501#ifndef __UNIXOS2__ 502 /* Ensure not passing the same pointer again to realpath */ 503 name = XtMalloc(BUFSIZ); 504 XtFree(tmp); 505 result = realpath(filename, name); 506 507 if (result == NULL && errno == ENOENT) { 508 int length; 509 char *dir, *file, *fname; 510 511 length = strlen(filename); 512 tmp = dir = XtMalloc(length + 1); 513 strcpy(dir, filename); 514 fname = strdup(filename); 515 516 file = basename(fname); 517 dir = dirname(tmp); 518 519 /* Creating a new file? */ 520 if (dir && file && strcmp(dir, file) && 521 access(dir, F_OK) == 0 && 522 (result = realpath(dir, name)) == name) { 523 int length = strlen(result); 524 525 XmuSnprintf(result + length, BUFSIZ - length, "%s%s", 526 result[length - 1] == '/' ? "" : "/", file); 527 } 528 529 XtFree(tmp); 530 free(fname); 531 } 532 533 return (result); 534#else 535 return filename; 536#endif 537} 538 539static void 540ChangeTextWindow(Widget w) 541{ 542 Arg args[1]; 543 544 if (textwindow != w) { 545 xedit_flist_item *other, *current; 546 547 other = FindTextSource(XawTextGetSource(textwindow), NULL); 548 current = FindTextSource(XawTextGetSource(w), NULL); 549 if (other != current) 550 flist.other = other; 551 if (current) 552 flist.current = current; 553 XtSetArg(args[0], XtNdisplayCaret, False); 554 XtSetValues(textwindow, args, 1); 555 XtSetArg(args[0], XtNdisplayCaret, True); 556 XtSetValues(w, args, 1); 557 XawTextUnsetSelection(textwindow); 558 textwindow = w; 559 } 560} 561 562/*ARGSUSED*/ 563void 564XeditFocus(Widget w, XEvent *event, String *params, Cardinal *num_params) 565{ 566 Arg args[1]; 567 xedit_flist_item *item; 568 int idx = WindowIndex(w); 569 570 XtSetKeyboardFocus(topwindow, w); 571 572 ChangeTextWindow(w); 573 574 labelwindow = labels[idx]; 575 item = FindTextSource(XawTextGetSource(textwindow), NULL); 576 577 if (item->source != scratch) 578 XtSetArg(args[0], XtNstring, item->name); 579 else 580 XtSetArg(args[0], XtNstring, NULL); 581 582 XtSetValues(filenamewindow, args, 1); 583 584 line_edit = False; 585} 586 587void 588PopupMenu(Widget w, XEvent *event, String *params, Cardinal *num_params) 589{ 590 Cardinal n_params = num_params ? *num_params : 0; 591 592 if (*num_params && XmuCompareISOLatin1(*params, "editMenu") == 0) 593 SetEditMenu(); 594 595 XtCallActionProc(w, "XawPositionSimpleMenu", event, params, n_params); 596 XtCallActionProc(w, "XtMenuPopup", event, params, n_params); 597} 598 599/*ARGSUSED*/ 600static void 601SwitchSourceCallback(Widget entry, XtPointer client_data, XtPointer call_data) 602{ 603 SwitchTextSource((xedit_flist_item*)client_data); 604} 605 606static int 607WindowIndex(Widget w) 608{ 609 int i; 610 611 for (i = 0; i < 3; i++) 612 if (texts[i] == w) 613 return (i); 614 615 return (-1); 616} 617 618void 619DeleteWindow(Widget w, XEvent *event, String *params, Cardinal *num_params) 620{ 621 Widget unmanage[2]; 622 int idx = WindowIndex(w), uidx; 623 Bool current = False; 624 625 if (*num_params == 1 && (*params[0] == 'd' || *params[0] == 'D')) { 626 if (XtIsManaged(XtParent(dirwindow))) 627 SwitchDirWindow(False); 628 return; 629 } 630 631 if (idx < 0 || (!XtIsManaged(texts[1]) && !XtIsManaged(texts[2]))) { 632 Feep(); 633 return; 634 } 635 636 if (num_params && *num_params == 1 && 637 (*params[0] == 'o' || *params[0] == 'O')) 638 current = True; 639 640 uidx = XtIsManaged(texts[1]) ? 1 : 2; 641 642 unmanage[0] = forms[uidx]; 643 unmanage[1] = texts[uidx]; 644 XtUnmanageChildren(unmanage, 2); 645 646 if (!XtIsManaged(texts[2])) 647 XtUnmanageChild(vpanes[1]); 648 649 if ((!current && idx == 0) || (current && idx != 0)) { 650 Arg args[4]; 651 Cardinal num_args; 652 String label_str; 653 Pixmap label_pix; 654 XawTextPosition d_pos, i_pos; 655 Widget source; 656 xedit_flist_item *item; 657 658 num_args = 0; 659 XtSetArg(args[num_args], XtNlabel, &label_str); ++num_args; 660 XtSetArg(args[num_args], XtNleftBitmap, &label_pix); ++num_args; 661 XtGetValues(labels[current ? idx : uidx], args, num_args); 662 663 num_args = 0; 664 XtSetArg(args[num_args], XtNlabel, label_str); ++num_args; 665 XtSetArg(args[num_args], XtNleftBitmap, label_pix); ++num_args; 666 XtSetValues(labels[0], args, num_args); 667 668 num_args = 0; 669 XtSetArg(args[num_args], XtNdisplayPosition, &d_pos); ++num_args; 670 XtSetArg(args[num_args], XtNinsertPosition, &i_pos); ++num_args; 671 XtSetArg(args[num_args], XtNtextSource, &source); ++num_args; 672 XtGetValues(texts[current ? idx : uidx], args, num_args); 673 674 num_args = 0; 675 XtSetArg(args[num_args], XtNdisplayPosition, d_pos); ++num_args; 676 XtSetArg(args[num_args], XtNinsertPosition, i_pos); ++num_args; 677 XtSetArg(args[num_args], XtNtextSource, source); ++num_args; 678 679 item = FindTextSource(source, NULL); 680 if (item && (item->flags & WRAP_BIT)) 681 XtSetArg(args[num_args], XtNwrap, item->wrap); 682 else 683 XtSetArg(args[num_args], XtNwrap, 684 wrapmodes[WindowIndex(texts[current ? idx : uidx])]); 685 XtSetValues(texts[0], args, num_args); 686 687 UpdateTextProperties(0); 688 } 689 690 labelwindow = labels[0]; 691 XeditFocus(texts[0], NULL, NULL, NULL); 692} 693 694void 695SwitchSource(Widget w, XEvent *event, String *params, Cardinal *num_params) 696{ 697 int idx = WindowIndex(w); 698 Widget source; 699 int i; 700 701 if (idx < 0 || textwindow != texts[idx]) { 702 Feep(); 703 return; 704 } 705 706 source = XawTextGetSource(textwindow); 707 708 for (i = 0; i < flist.num_itens; i++) 709 if (flist.itens[i]->source == source) { 710 if (i > 0 && i == flist.num_itens - 1) 711 i = 0; 712 else if (i < flist.num_itens - 1) 713 ++i; 714 else { 715 Feep(); 716 return; 717 } 718 break; 719 } 720 721 if (i >= flist.num_itens) { 722 Feep(); 723 return; 724 } 725 726 SwitchTextSource(flist.itens[i]); 727} 728 729void 730OtherWindow(Widget w, XEvent *event, String *params, Cardinal *num_params) 731{ 732 int oidx, idx = WindowIndex(w); 733 734 if (idx < 0 || (!XtIsManaged(texts[1]) && !XtIsManaged(texts[2]))) { 735 Feep(); 736 return; 737 } 738 739 if (idx == 0) 740 oidx = XtIsManaged(texts[1]) ? 1 : 2; 741 else 742 oidx = 0; 743 744 XeditFocus(texts[oidx], event, params, num_params); 745} 746 747void 748SplitWindow(Widget w, XEvent *event, String *params, Cardinal *num_params) 749{ 750 Arg args[6]; 751 Cardinal num_args; 752 Widget nlabel, ntext, source, sink, manage[2]; 753 Dimension width, height, bw; 754 XawTextPosition i_pos, d_pos; 755 String label_str; 756 Pixmap label_pix; 757 int idx = WindowIndex(w), dimension; 758 Bool vert = True; 759 xedit_flist_item *item; 760 761 if (num_params && *num_params == 1 762 && (*params[0] == 'h' || *params[0] == 'H')) 763 vert = False; 764 765 if (idx < 0 766 || (vert && XtIsManaged(texts[1])) 767 || (!vert && XtIsManaged(vpanes[1]))) { 768 Feep(); 769 return; 770 } 771 772 if (vert) { 773 nlabel = labels[1]; 774 ntext = texts[1]; 775 } 776 else { 777 nlabel = labels[2]; 778 ntext = texts[2]; 779 } 780 ChangeTextWindow(texts[idx]); 781 labelwindow = labels[idx]; 782 783 num_args = 0; 784 XtSetArg(args[num_args], XtNinsertPosition, &i_pos); ++num_args; 785 XtSetArg(args[num_args], XtNdisplayPosition, &d_pos); ++num_args; 786 XtSetArg(args[num_args], XtNtextSource, &source); ++num_args; 787 XtSetArg(args[num_args], XtNtextSink, &sink); ++num_args; 788 XtSetArg(args[num_args], XtNwidth, &width); ++num_args; 789 XtSetArg(args[num_args], XtNheight, &height); ++num_args; 790 XtGetValues(w, args, num_args); 791 792 num_args = 0; 793 XtSetArg(args[num_args], XtNinternalBorderWidth, &bw); ++num_args; 794 XtGetValues(XtParent(w), args, num_args); 795 796 if (vert) { 797 dimension = (int)height - (((int)bw) << 1); 798 num_args = 0; 799 XtSetArg(args[num_args], XtNheight, &height); ++num_args; 800 XtGetValues(labelwindow, args, num_args); 801 dimension -= (int)height; 802 } 803 else 804 dimension = (int)width - (int)bw; 805 806 dimension >>= 1; 807 808 if (dimension <= 0 || dimension < XawTextSinkMaxHeight(sink, 3)) { 809 Feep(); 810 return; 811 } 812 813 num_args = 0; 814 XtSetArg(args[num_args], XtNlabel, &label_str); ++num_args; 815 XtSetArg(args[num_args], XtNleftBitmap, &label_pix); ++num_args; 816 XtGetValues(labelwindow, args, num_args); 817 818 if (vert) { 819 if (XtIsManaged(texts[2])) { 820 manage[0] = forms[2]; 821 manage[1] = texts[2]; 822 XtUnmanageChildren(manage, 2); 823 XtUnmanageChild(vpanes[1]); 824 } 825 } 826 else { 827 if (XtIsManaged(texts[1])) { 828 manage[0] = forms[1]; 829 manage[1] = texts[1]; 830 XtUnmanageChildren(manage, 2); 831 } 832 } 833 834 XawTextDisableRedisplay(texts[0]); 835 XawTextDisableRedisplay(ntext); 836 if (textwindow == texts[1] || textwindow == texts[2]) { 837 num_args = 0; 838 XtSetArg(args[num_args], XtNdisplayPosition, d_pos); ++num_args; 839 XtSetArg(args[num_args], XtNinsertPosition, i_pos); ++num_args; 840 XtSetArg(args[num_args], XtNtextSource, source); ++num_args; 841 ChangeTextWindow(texts[0]); 842 XtSetValues(textwindow, args, num_args); 843 XtSetKeyboardFocus(topwindow, textwindow); 844 845 num_args = 0; 846 XtSetArg(args[num_args], XtNlabel, label_str); ++num_args; 847 XtSetArg(args[num_args], XtNleftBitmap, label_pix); ++num_args; 848 XtSetValues(labelwindow = labels[0], args, num_args); 849 } 850 851 num_args = 0; 852 XtSetArg(args[num_args], XtNlabel, label_str); ++num_args; 853 XtSetArg(args[num_args], XtNleftBitmap, label_pix); ++num_args; 854 XtSetValues(nlabel, args, num_args); 855 856 num_args = 0; 857 XtSetArg(args[num_args], XtNmin, dimension); ++num_args; 858 XtSetArg(args[num_args], XtNmax, dimension); ++num_args; 859 if (!vert) 860 XtSetValues(vpanes[1], args, num_args); 861 else 862 XtSetValues(ntext, args, num_args); 863 864 manage[0] = XtParent(nlabel); 865 manage[1] = ntext; 866 XtManageChildren(manage, 2); 867 if (!vert) 868 XtManageChild(vpanes[1]); 869 870 num_args = 0; 871 XtSetArg(args[num_args], XtNmin, 1); ++num_args; 872 XtSetArg(args[num_args], XtNmax, 65535); ++num_args; 873 if (!vert) { 874 XtSetValues(vpanes[1], args, num_args); 875 num_args = 0; 876 } 877 XtSetArg(args[num_args], XtNtextSource, source); ++num_args; 878 XtSetArg(args[num_args], XtNdisplayPosition, d_pos); ++num_args; 879 XtSetArg(args[num_args], XtNinsertPosition, i_pos); ++num_args; 880 item = FindTextSource(source, NULL); 881 if (item && (item->flags & WRAP_BIT)) 882 XtSetArg(args[num_args], XtNwrap, item->wrap); 883 else 884 XtSetArg(args[num_args], XtNwrap, wrapmodes[WindowIndex(ntext)]); 885 ++num_args; 886 XtSetValues(ntext, args, num_args); 887 888 UpdateTextProperties(0); 889 890 _XawTextShowPosition((TextWidget)textwindow); 891 _XawTextShowPosition((TextWidget)ntext); 892 893 XawTextEnableRedisplay(textwindow); 894 XawTextEnableRedisplay(ntext); 895} 896 897void 898SwitchDirWindow(Bool show) 899{ 900 static int map; /* There must be one instance of this 901 * variable per top level window */ 902 Widget manage[2]; 903 904 if (!show && XtIsManaged(XtParent(dirwindow))) { 905 manage[0] = dirlabel; 906 manage[1] = XtParent(dirwindow); 907 XtUnmanageChildren(manage, 2); 908 XtUnmanageChild(vpanes[1]); 909 910 XtManageChild(vpanes[0]); 911 if (map == 2) { 912 Arg args[2]; 913 Dimension width, bw; 914 915 XtSetArg(args[0], XtNwidth, &width); 916 XtGetValues(texts[0], args, 1); 917 XtSetArg(args[0], XtNinternalBorderWidth, &bw); 918 XtGetValues(XtParent(texts[0]), args, 1); 919 width = (width - bw) >> 1; 920 XtSetArg(args[0], XtNmin, width); 921 XtSetArg(args[0], XtNmax, width); 922 XtSetValues(vpanes[0], args, 1); 923 manage[0] = forms[2]; 924 manage[1] = texts[2]; 925 XtManageChildren(manage, 2); 926 XtManageChild(vpanes[1]); 927 XtSetArg(args[0], XtNmin, 1); 928 XtSetArg(args[0], XtNmax, 65535); 929 XtSetValues(vpanes[0], args, 1); 930 } 931 } 932 else if (show && !XtIsManaged(XtParent(dirwindow))) { 933 XtUnmanageChild(vpanes[0]); 934 if (XtIsManaged(texts[2])) { 935 manage[0] = forms[2]; 936 manage[1] = texts[2]; 937 XtUnmanageChildren(manage, 2); 938 map = 2; 939 } 940 else { 941 map = XtIsManaged(texts[1]); 942 XtManageChild(vpanes[1]); 943 } 944 945 manage[0] = dirlabel; 946 manage[1] = XtParent(dirwindow); 947 XtManageChildren(manage, 2); 948 } 949} 950 951/*ARGSUSED*/ 952void 953DirWindow(Widget w, XEvent *event, String *params, Cardinal *num_params) 954{ 955 Arg args[1]; 956 char path[BUFSIZ + 1], *dir; 957 958 if (XtIsManaged(XtParent(dirwindow))) 959 return; 960 961 if (*num_params == 1) { 962 strncpy(path, params[0], sizeof(path) - 2); 963 path[sizeof(path) - 2] = '\0'; 964 } 965 else { 966 char *slash; 967 xedit_flist_item *item = FindTextSource(XawTextGetSource(textwindow), NULL); 968 969 if (item == NULL || item->source == scratch 970 || (slash = rindex(item->filename, '/')) == NULL) 971 strcpy(path, "./"); 972 else { 973 int len = slash - item->filename + 1; 974 975 if (len > sizeof(path) - 2) 976 len = sizeof(path) - 2; 977 strncpy(path, item->filename, len); 978 path[len] = '\0'; 979 } 980 } 981 982 dir = ResolveName(path); 983 if (dir != NULL) { 984 strncpy(path, dir, sizeof(path) - 2); 985 path[sizeof(path) - 2] = '\0'; 986 if (*path && path[strlen(path) - 1] != '/') 987 strcat(path, "/"); 988 989 XtSetArg(args[0], XtNlabel, ""); 990 XtSetValues(dirlabel, args, 1); 991 992 SwitchDirWindow(True); 993 DirWindowCB(dirwindow, path, NULL); 994 } 995 else 996 Feep(); 997} 998