15dfecf96Smrg/* 25dfecf96Smrg * Copyright (c) 2001 by The XFree86 Project, Inc. 35dfecf96Smrg * 45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a 55dfecf96Smrg * copy of this software and associated documentation files (the "Software"), 65dfecf96Smrg * to deal in the Software without restriction, including without limitation 75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the 95dfecf96Smrg * Software is furnished to do so, subject to the following conditions: 105dfecf96Smrg * 115dfecf96Smrg * The above copyright notice and this permission notice shall be included in 125dfecf96Smrg * all copies or substantial portions of the Software. 135dfecf96Smrg * 145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 205dfecf96Smrg * SOFTWARE. 215dfecf96Smrg * 225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall 235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other 245dfecf96Smrg * dealings in this Software without prior written authorization from the 255dfecf96Smrg * XFree86 Project. 265dfecf96Smrg * 275dfecf96Smrg * Author: Paulo César Pereira de Andrade 285dfecf96Smrg */ 295dfecf96Smrg 305dfecf96Smrg/* $XFree86: xc/programs/xedit/lisp.c,v 1.20tsi Exp $ */ 315dfecf96Smrg 325dfecf96Smrg#include "xedit.h" 335dfecf96Smrg#include "lisp/lisp.h" 345dfecf96Smrg#include "lisp/xedit.h" 355dfecf96Smrg#include <unistd.h> 365dfecf96Smrg#include <locale.h> 375dfecf96Smrg#include <ctype.h> 385dfecf96Smrg 395dfecf96Smrg#include <X11/Xaw/SmeBSB.h> 405dfecf96Smrg#include <X11/Xaw/SimpleMenu.h> 415dfecf96Smrg 425dfecf96Smrg/* 435dfecf96Smrg * Prototypes 445dfecf96Smrg */ 455dfecf96Smrgstatic void XeditDoLispEval(Widget); 465dfecf96Smrgstatic void EditModeCallback(Widget, XtPointer, XtPointer); 475dfecf96Smrg 485dfecf96Smrg/* 495dfecf96Smrg * Initialization 505dfecf96Smrg */ 515dfecf96Smrgstatic int lisp_initialized; 525dfecf96Smrgextern Widget scratch; 535dfecf96Smrgstatic Widget edit_mode_menu, edit_mode_entry, edit_mode_none; 545dfecf96Smrg 555dfecf96Smrg/* 565dfecf96Smrg * Implementation 575dfecf96Smrg */ 585dfecf96Smrgvoid 595dfecf96SmrgXeditLispInitialize(void) 605dfecf96Smrg{ 615dfecf96Smrg setlocale(LC_NUMERIC, "C"); 625dfecf96Smrg lisp_initialized = 1; 635dfecf96Smrg LispBegin(); 645dfecf96Smrg LispXeditInitialize(); 655dfecf96Smrg} 665dfecf96Smrg 675dfecf96Smrgvoid 685dfecf96SmrgXeditLispCleanUp(void) 695dfecf96Smrg{ 705dfecf96Smrg LispEnd(); 715dfecf96Smrg} 725dfecf96Smrg 735dfecf96Smrgvoid 745dfecf96SmrgXeditLispEval(Widget w, XEvent *event, String *params, Cardinal *num_params) 755dfecf96Smrg{ 765dfecf96Smrg XeditDoLispEval(messwidget); 775dfecf96Smrg} 785dfecf96Smrg 795dfecf96Smrgvoid 805dfecf96SmrgXeditPrintLispEval(Widget w, XEvent *event, String *params, Cardinal *num_params) 815dfecf96Smrg{ 825dfecf96Smrg if (XawTextGetSource(w) == scratch) { 835dfecf96Smrg XtCallActionProc(w, "newline", event, params, *num_params); 845dfecf96Smrg XeditDoLispEval(w); 855dfecf96Smrg } 865dfecf96Smrg else 875dfecf96Smrg XtCallActionProc(w, "newline-and-indent", event, params, *num_params); 885dfecf96Smrg} 895dfecf96Smrg 905dfecf96Smrgvoid 915dfecf96SmrgXeditKeyboardReset(Widget w, XEvent *event, String *params, Cardinal *num_params) 925dfecf96Smrg{ 935dfecf96Smrg XtCallActionProc(w, "keyboard-reset", event, params, *num_params); 945dfecf96Smrg} 955dfecf96Smrg 965dfecf96Smrgvoid 975dfecf96SmrgSetTextProperties(xedit_flist_item *item) 985dfecf96Smrg{ 995dfecf96Smrg if (lisp_initialized) { 1005dfecf96Smrg Widget source = XawTextGetSource(textwindow); 1015dfecf96Smrg XawTextPosition top = XawTextTopPosition(textwindow); 1025dfecf96Smrg 1035dfecf96Smrg if (source != item->source) 1045dfecf96Smrg XawTextSetSource(textwindow, item->source, 0); 1055dfecf96Smrg XeditLispSetEditMode(item, NULL); 1065dfecf96Smrg if (source != item->source) 1075dfecf96Smrg XawTextSetSource(textwindow, source, top); 1085dfecf96Smrg } 1095dfecf96Smrg} 1105dfecf96Smrg 1115dfecf96Smrgvoid 1125dfecf96SmrgUnsetTextProperties(xedit_flist_item *item) 1135dfecf96Smrg{ 1145dfecf96Smrg XeditLispUnsetEditMode(item); 1155dfecf96Smrg} 1165dfecf96Smrg 1175dfecf96Smrgstatic void 1185dfecf96SmrgXeditDoLispEval(Widget output) 1195dfecf96Smrg{ 1205dfecf96Smrg Widget src; 1215dfecf96Smrg XawTextBlock block; 1225dfecf96Smrg XawTextPosition position, end; 1235dfecf96Smrg 1245dfecf96Smrg /* get lisp expression */ 1255dfecf96Smrg src = XawTextGetSource(textwindow); 1265dfecf96Smrg position = XawTextGetInsertionPoint(textwindow); 1275dfecf96Smrg --position; 1285dfecf96Smrg while (position >= 0) { 1295dfecf96Smrg (void)XawTextSourceRead(src, position, &block, 1); 1305dfecf96Smrg if (!isspace(block.ptr[0])) 1315dfecf96Smrg break; 1325dfecf96Smrg --position; 1335dfecf96Smrg } 1345dfecf96Smrg end = position + 1; 1355dfecf96Smrg 1365dfecf96Smrg if (block.ptr[0] != ')') { 1375dfecf96Smrg while (position >= 0) { 1385dfecf96Smrg (void)XawTextSourceRead(src, position, &block, 1); 1395dfecf96Smrg if (isspace(block.ptr[0]) || 1405dfecf96Smrg block.ptr[0] == '(' || 1415dfecf96Smrg block.ptr[0] == ')' || 1425dfecf96Smrg block.ptr[0] == '"' || 1435dfecf96Smrg block.ptr[0] == '|') 1445dfecf96Smrg break; 1455dfecf96Smrg --position; 1465dfecf96Smrg } 1475dfecf96Smrg if (!isspace(block.ptr[0])) 1485dfecf96Smrg ++position; 1495dfecf96Smrg } 1505dfecf96Smrg else { 1515dfecf96Smrg /* XXX note that embedded '(' and ')' will confuse this code */ 1525dfecf96Smrg XawTextPosition last, tmp; 1535dfecf96Smrg int level = 0; 1545dfecf96Smrg char ptr[2]; 1555dfecf96Smrg 1565dfecf96Smrg last = position; 1575dfecf96Smrg ptr[1] = '\0'; 1585dfecf96Smrg block.ptr = ptr; 1595dfecf96Smrg do { 1605dfecf96Smrg block.ptr[0] = '('; 1615dfecf96Smrg position = XawTextSourceSearch(src, last, XawsdLeft, &block); 1625dfecf96Smrg if (position == XawTextSearchError) { 1635dfecf96Smrg Feep(); 1645dfecf96Smrg return; 1655dfecf96Smrg } 1665dfecf96Smrg block.ptr[0] = ')'; 1675dfecf96Smrg tmp = position; 1685dfecf96Smrg do { 1695dfecf96Smrg tmp = XawTextSourceSearch(src, tmp, XawsdRight, &block); 1705dfecf96Smrg if (tmp == XawTextSearchError) { 1715dfecf96Smrg Feep(); 1725dfecf96Smrg return; 1735dfecf96Smrg } 1745dfecf96Smrg if (tmp <= last) 1755dfecf96Smrg ++level; 1765dfecf96Smrg } while (++tmp <= last); 1775dfecf96Smrg --level; 1785dfecf96Smrg last = position; 1795dfecf96Smrg } while (level); 1805dfecf96Smrg /* check for extra characters */ 1815dfecf96Smrg while (position > 0) { 1825dfecf96Smrg (void)XawTextSourceRead(src, position - 1, &block, 1); 1835dfecf96Smrg if (block.length != 1 || 1845dfecf96Smrg isspace(block.ptr[0]) || 1855dfecf96Smrg block.ptr[0] == ')' || 1865dfecf96Smrg block.ptr[0] == '"' || 1875dfecf96Smrg block.ptr[0] == '|') 1885dfecf96Smrg break; 1895dfecf96Smrg --position; 1905dfecf96Smrg } 1915dfecf96Smrg } 1925dfecf96Smrg 1935dfecf96Smrg if (position < 0 || position >= end) 1945dfecf96Smrg Feep(); 1955dfecf96Smrg else 1965dfecf96Smrg XeditLispExecute(output, position, end); 1975dfecf96Smrg} 1985dfecf96Smrg 1995dfecf96Smrgvoid 2005dfecf96SmrgCreateEditModePopup(Widget parent) 2015dfecf96Smrg{ 2025dfecf96Smrg int i; 2035dfecf96Smrg Widget sme; 2045dfecf96Smrg static char *editModes = "editModes"; 2055dfecf96Smrg 2065dfecf96Smrg XtVaCreateManagedWidget("modeMenuItem", smeBSBObjectClass, parent, 2075dfecf96Smrg XtNmenuName, editModes, NULL); 2085dfecf96Smrg edit_mode_menu = XtCreatePopupShell(editModes, simpleMenuWidgetClass, 2095dfecf96Smrg parent, NULL, 0); 2105dfecf96Smrg XtRealizeWidget(edit_mode_menu); 2115dfecf96Smrg 2125dfecf96Smrg edit_mode_none = XtCreateManagedWidget("none", smeBSBObjectClass, 2135dfecf96Smrg edit_mode_menu, NULL, 0); 2145dfecf96Smrg XtAddCallback(edit_mode_none, XtNcallback, EditModeCallback, NULL); 2155dfecf96Smrg 2165dfecf96Smrg for (i = 0; i < num_mode_infos; i++) { 2175dfecf96Smrg sme = XtVaCreateManagedWidget("mode", smeBSBObjectClass, edit_mode_menu, 2185dfecf96Smrg XtNlabel, mode_infos[i].desc, NULL); 2195dfecf96Smrg XtAddCallback(sme, XtNcallback, EditModeCallback, 2205dfecf96Smrg (XtPointer)(mode_infos + i)); 2215dfecf96Smrg mode_infos[i].sme = sme; 2225dfecf96Smrg } 2235dfecf96Smrg} 2245dfecf96Smrg 2255dfecf96Smrgvoid 2265dfecf96SmrgSetEditModeMenu(void) 2275dfecf96Smrg{ 2285dfecf96Smrg int i; 2295dfecf96Smrg Widget old_entry = edit_mode_entry, new_entry = edit_mode_none; 2305dfecf96Smrg xedit_flist_item *item = FindTextSource(XawTextGetSource(textwindow), NULL); 2315dfecf96Smrg 2325dfecf96Smrg for (i = 0; i < num_mode_infos; i++) { 2335dfecf96Smrg if (item->xldata && item->xldata->syntax && 2345dfecf96Smrg mode_infos[i].syntax == item->xldata->syntax) { 2355dfecf96Smrg new_entry = mode_infos[i].sme; 2365dfecf96Smrg break; 2375dfecf96Smrg } 2385dfecf96Smrg } 2395dfecf96Smrg 2405dfecf96Smrg if (old_entry != new_entry) { 2415dfecf96Smrg if (old_entry) 2425dfecf96Smrg XtVaSetValues(old_entry, XtNleftBitmap, None, NULL); 2435dfecf96Smrg XtVaSetValues(new_entry, XtNleftBitmap, flist.pixmap, NULL); 2445dfecf96Smrg edit_mode_entry = new_entry; 2455dfecf96Smrg } 2465dfecf96Smrg} 2475dfecf96Smrg 2485dfecf96Smrgstatic void 2495dfecf96SmrgEditModeCallback(Widget w, XtPointer client_data, XtPointer call_data) 2505dfecf96Smrg{ 2515dfecf96Smrg Widget source = XawTextGetSource(textwindow); 2525dfecf96Smrg EditModeInfo *info = (EditModeInfo*)client_data; 2535dfecf96Smrg xedit_flist_item *item = FindTextSource(source, NULL); 2545dfecf96Smrg 2555dfecf96Smrg /* If no edit mode selected and selecting the plain/none mode */ 2565dfecf96Smrg if ((info == NULL && 2575dfecf96Smrg (item->xldata == NULL || item->xldata->syntax == NULL)) || 2585dfecf96Smrg /* if selecting the current mode */ 2595dfecf96Smrg (info && item && item->xldata && info->syntax && 2605dfecf96Smrg info->syntax == item->xldata->syntax)) 2615dfecf96Smrg return; 2625dfecf96Smrg 2635dfecf96Smrg XawTextSourceClearEntities(source, 2645dfecf96Smrg XawTextSourceScan(source, 0, XawstAll, 2655dfecf96Smrg XawsdLeft, 1, True), 2665dfecf96Smrg XawTextSourceScan(source, 0, XawstAll, 2675dfecf96Smrg XawsdRight, 1, True)); 2685dfecf96Smrg XeditLispUnsetEditMode(item); 2695dfecf96Smrg if (info) 2705dfecf96Smrg XeditLispSetEditMode(item, info->symbol); 2715dfecf96Smrg else 2725dfecf96Smrg item->properties = NULL; 2735dfecf96Smrg UpdateTextProperties(1); 2745dfecf96Smrg} 275