⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textsel.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
static const char CVSID[] = "$Id: textSel.c,v 1.12 2003/05/09 17:43:48 edg Exp $";/********************************************************************************									       ** textSel.c - Selection and clipboard routines for NEdit text widget		       **									       ** Copyright (C) 1999 Mark Edel						       **									       ** This is free software; you can redistribute it and/or modify it under the    ** terms of the GNU General Public License as published by the Free Software    ** Foundation; either version 2 of the License, or (at your option) any later   ** version.							               ** 									       ** This software is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        ** FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License        ** for more details.							       ** 									       ** You should have received a copy of the GNU General Public License along with ** software; if not, write to the Free Software Foundation, Inc., 59 Temple     ** Place, Suite 330, Boston, MA  02111-1307 USA		                       **									       ** Nirvana Text Editor	    						       ** Dec. 15, 1995								       **									       ** Written by Mark Edel							       **									       ********************************************************************************/#ifdef HAVE_CONFIG_H#include "../config.h"#endif#include "textSel.h"#include "textP.h"#include "text.h"#include "textDisp.h"#include "textBuf.h"#include <stdio.h>#include <string.h>#include <limits.h>#include <Xm/Xm.h>#include <Xm/CutPaste.h>#include <Xm/Text.h>#include <X11/Xatom.h>#if XmVersion >= 1002#include <Xm/PrimitiveP.h>#endif#ifdef HAVE_DEBUG_H#include "../debug.h"#endif#define N_SELECT_TARGETS 7#define N_CLIP_TARGETS 4#define N_ATOMS 11enum atomIndex {A_TEXT, A_TARGETS, A_MULTIPLE, A_TIMESTAMP,	A_INSERT_SELECTION, A_DELETE, A_CLIPBOARD, A_INSERT_INFO,	A_ATOM_PAIR, A_MOTIF_DESTINATION, A_COMPOUND_TEXT};/* Results passed back to the convert proc processing an INSERT_SELECTION   request, by getInsertSelection when the selection to insert has been   received and processed */enum insertResultFlags {INSERT_WAITING, UNSUCCESSFUL_INSERT, SUCCESSFUL_INSERT};/* Actions for selection notify event handler upon receiving confermation   of a successful convert selection request */enum selectNotifyActions {UNSELECT_SECONDARY, REMOVE_SECONDARY,	EXCHANGE_SECONDARY};	/* temporary structure for passing data to the event handler for completing   selection requests (the hard way, via xlib calls) */typedef struct {    int action;    XtIntervalId timeoutProcID;    Time timeStamp;    Widget widget;    char *actionText;    int length;} selectNotifyInfo;static void modifiedCB(int pos, int nInserted, int nDeleted,	int nRestyled, char *deletedText, void *cbArg);static void sendSecondary(Widget w, Time time, Atom sel, int action,	char *actionText, int actionTextLen);static void getSelectionCB(Widget w, XtPointer clientData, Atom *selType,	Atom *type, XtPointer value, unsigned long *length, int *format);static void getInsertSelectionCB(Widget w, XtPointer clientData,Atom *selType,	Atom *type, XtPointer value, unsigned long *length, int *format);static void getExchSelCB(Widget w, XtPointer clientData, Atom *selType,	Atom *type, XtPointer value, unsigned long *length, int *format);static Boolean convertSelectionCB(Widget w, Atom *selType, Atom *target,	Atom *type, XtPointer *value, unsigned long *length, int *format);static void loseSelectionCB(Widget w, Atom *selType);static Boolean convertSecondaryCB(Widget w, Atom *selType, Atom *target,	Atom *type, XtPointer *value, unsigned long *length, int *format);static void loseSecondaryCB(Widget w, Atom *selType);static Boolean convertMotifDestCB(Widget w, Atom *selType, Atom *target,	Atom *type, XtPointer *value, unsigned long *length, int *format);static void loseMotifDestCB(Widget w, Atom *selType);static void selectNotifyEH(Widget w, XtPointer data, XEvent *event,	Boolean *continueDispatch);static void selectNotifyTimerProc(XtPointer clientData, XtIntervalId *id);static Atom getAtom(Display *display, int atomNum);/*** Designate text widget "w" to be the selection owner for primary selections** in its attached buffer (a buffer can be attached to multiple text widgets).*/void HandleXSelections(Widget w){    int i;    textBuffer *buf = ((TextWidget)w)->text.textD->buffer;        /* Remove any existing selection handlers for other widgets */    for (i=0; i<buf->nModifyProcs; i++) {    	if (buf->modifyProcs[i] == modifiedCB) {    	    BufRemoveModifyCB(buf, modifiedCB, buf->cbArgs[i]);    	    break;    	}    }        /* Add a handler with this widget as the CB arg (and thus the sel. owner) */    BufAddModifyCB(((TextWidget)w)->text.textD->buffer, modifiedCB, w);}/*** Discontinue ownership of selections for widget "w"'s attached buffer** (if "w" was the designated selection owner)*/void StopHandlingXSelections(Widget w){    int i;    textBuffer *buf = ((TextWidget)w)->text.textD->buffer;        for (i=0; i<buf->nModifyProcs; i++) {    	if (buf->modifyProcs[i] == modifiedCB && buf->cbArgs[i] == w) {    	    BufRemoveModifyCB(buf, modifiedCB, buf->cbArgs[i]);    	    return;    	}    }}/*** Copy the primary selection to the clipboard*/void CopyToClipboard(Widget w, Time time){    char *text;    long itemID = 0;    XmString s;    int stat, length;        /* Get the selected text, if there's no selection, do nothing */    text = BufGetSelectionText(((TextWidget)w)->text.textD->buffer);    if (*text == '\0') {    	XtFree(text);    	return;    }    /* If the string contained ascii-nul characters, something else was       substituted in the buffer.  Put the nulls back */    length = strlen(text);    BufUnsubstituteNullChars(text, ((TextWidget)w)->text.textD->buffer);        /* Use the XmClipboard routines to copy the text to the clipboard.       If errors occur, just give up.  */    stat = XmClipboardStartCopy(XtDisplay(w), XtWindow(w),    	    s=XmStringCreateSimple("NEdit"), time, w, NULL, &itemID);    XmStringFree(s);    if (stat != ClipboardSuccess)    	return;#ifdef notdef    /* Note that we were previously passing length + 1 here, but I suspect       that this was inconsistent with the somewhat ambiguous policy of       including a terminating null but not mentioning it in the length */#endif    if (XmClipboardCopy(XtDisplay(w), XtWindow(w), itemID, "STRING",    	    text, length, 0, NULL) != ClipboardSuccess) {    	XtFree(text);    	return;    }    XtFree(text);    XmClipboardEndCopy(XtDisplay(w), XtWindow(w), itemID);}/*** Insert the X PRIMARY selection (from whatever window currently owns it)** at the cursor position.*/void InsertPrimarySelection(Widget w, Time time, int isColumnar){   static int isColFlag;   /* Theoretically, strange things could happen if the user managed to get      in any events between requesting receiving the selection data, however,      getSelectionCB simply inserts the selection at the cursor.  Don't      bother with further measures until real problems are observed. */   isColFlag = isColumnar;   XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, getSelectionCB, &isColFlag,   	    time);}/*** Insert the secondary selection at the motif destination by initiating** an INSERT_SELECTION request to the current owner of the MOTIF_DESTINATION** selection.  Upon completion, unselect the secondary selection.  If** "removeAfter" is true, also delete the secondary selection from the** widget's buffer upon completion.*/void SendSecondarySelection(Widget w, Time time, int removeAfter){    sendSecondary(w, time, getAtom(XtDisplay(w), A_MOTIF_DESTINATION),    	    removeAfter ? REMOVE_SECONDARY : UNSELECT_SECONDARY, NULL, 0);}/*** Exchange Primary and secondary selections (to be called by the widget** with the secondary selection)*/void ExchangeSelections(Widget w, Time time){   if (!((TextWidget)w)->text.textD->buffer->secondary.selected)       return;      /* Initiate an long series of events: 1) get the primary selection,      2) replace the primary selection with this widget's secondary, 3) replace      this widget's secondary with the text returned from getting the primary      selection.  This could be done with a much more efficient MULTIPLE      request following ICCCM conventions, but the X toolkit MULTIPLE handling      routines can't handle INSERT_SELECTION requests inside of MULTIPLE      requests, because they don't allow access to the requested property atom      in  inside of an XtConvertSelectionProc.  It's simply not worth      duplicating all of Xt's selection handling routines for a little      performance, and this would make the code incompatible with Motif text      widgets */   XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, getExchSelCB, NULL, time);}/*** Insert the contents of the PRIMARY selection at the cursor position in** widget "w" and delete the contents of the selection in its current owner** (if the selection owner supports DELETE targets).*/void MovePrimarySelection(Widget w, Time time, int isColumnar){   static Atom targets[2] = {XA_STRING};   static int isColFlag;   static XtPointer clientData[2] =   	    {(XtPointer)&isColFlag, (XtPointer)&isColFlag};      targets[1] = getAtom(XtDisplay(w), A_DELETE);   isColFlag = isColumnar;   /* some strangeness here: the selection callback appears to be getting      clientData[1] for targets[0] */   XtGetSelectionValues(w, XA_PRIMARY, targets, 2, getSelectionCB,   	    clientData, time);}/*** Insert the X CLIPBOARD selection at the cursor position.  If isColumnar,** do an BufInsertCol for a columnar paste instead of BufInsert.*/void InsertClipboard(Widget w, int isColumnar){    unsigned long length, retLength;    textDisp *textD = ((TextWidget)w)->text.textD;    textBuffer *buf = ((TextWidget)w)->text.textD->buffer;    int cursorLineStart, column, cursorPos;    char *string;    long id = 0;    /* Get the clipboard contents.  Note: this code originally used the       CLIPBOARD selection, rather than the Motif clipboard interface.  It       was changed because Motif widgets in the same application would hang       when users pasted data from nedit text widgets.  This happened because       the XmClipboard routines used by the widgets do blocking event reads,       preventing a response by a selection owner in the same application.       While the Motif clipboard routines as they are used below, limit the       size of the data that be transferred via the clipboard, and are       generally slower and buggier, they do preserve the clipboard across       widget destruction and even program termination. */    if (XmClipboardInquireLength(XtDisplay(w), XtWindow(w), "STRING", &length)    	    != ClipboardSuccess || length == 0)    	return;    string = XtMalloc(length+1);    if (XmClipboardRetrieve(XtDisplay(w), XtWindow(w), "STRING", string,    	    length, &retLength, &id) != ClipboardSuccess || retLength == 0) {    	XtFree(string);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -