2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 #ifdef VERBOSE_REV_INFO
25 static char rcs_id[] = "$TOG: TermPrimSelect.c /main/6 1999/10/14 16:22:53 mgreess $";
26 #endif /* VERBOSE_REV_INFO */
30 * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
31 * (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
32 * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
33 * (c) Copyright 1993, 1994, 1996 Novell, Inc. *
34 * (c) Copyright 1995, 1996 Digital Equipment Corporation. *
35 * (c) Copyright 1996 FUJITSU LIMITED. *
36 * (c) Copyright 1996 Hitachi. *
39 #include "TermHeader.h"
40 #include <X11/Xatom.h>
42 #include <Xm/AtomMgr.h>
43 #include <Xm/CutPaste.h>
44 #include <Xm/XmPrivate.h>
45 #include <Xm/ScrollBarP.h>
46 #include "TermPrimAction.h"
47 #include "TermPrimDebug.h"
48 #include "TermPrimP.h"
49 #include "TermPrimData.h"
50 #include "TermPrimRender.h"
51 #include "TermPrimSelectP.h"
52 #include "TermPrimBufferP.h"
53 #include <Xm/DropSMgr.h>
54 #include <Xm/DropTrans.h>
56 #if defined(USL) || defined(OPENBSD_ARCHITECTURE)
61 /* This is for Sun's two button mouse */
63 static char _DtTermEventBindingsCDE[] = "\
64 ~c ~s ~m ~a <Btn1Down>:process-press(grab-focus,process-bdrag)\n\
65 ~c s ~m ~a <Btn1Down>:process-press(extend-start,process-bdrag)\n\
66 ~c ~m ~a <Btn1Motion>:select-adjust()\n\
67 ~c ~m ~a <Btn1Up>:extend-end()";
68 static char _DtTermEventBindingsCDEBtn2[] = "\
69 <Btn2Down>:extend-start()\n\
70 <Btn2Motion>:select-adjust()\n\
71 <Btn2Up>:extend-end()";
74 XmTextScanType defaultScanArray[] =
82 static void RegisterDropSite( Widget w );
83 static void doExtendedSelection (Widget w,Time eventTime);
86 ** Get the current server time (I ripped this off from Xm/TextIn.c).
102 shellMask = XtBuildEventMask(w);
104 if (!(shellMask & PropertyChangeMask))
106 XSelectInput(XtDisplay(w), XtWindow(w), shellMask | PropertyChangeMask);
109 XChangeProperty(XtDisplay(w), XtWindow(w), XA_WM_HINTS, XA_WM_HINTS,
110 32, PropModeAppend, (unsigned char *)NULL, 0);
112 XWindowEvent(XtDisplay(w), XtWindow(w), PropertyChangeMask, &event);
114 if (!(shellMask & PropertyChangeMask))
116 XSelectInput(XtDisplay(w), XtWindow(w), shellMask);
119 return(event.xproperty.time);
130 TermSelectInfo selectInfo =
131 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
135 multiClickTime = XtGetMultiClickTime(XtDisplay(w));
137 if (event->xbutton.time > selectInfo->lastTime &&
138 event->xbutton.time - selectInfo->lastTime <
139 (multiClickTime == 200 ? 500 : multiClickTime))
142 while (i < selectInfo->scanArraySize &&
143 selectInfo->scanArray[i] != selectInfo->scanType)
148 if (++i >= selectInfo->scanArraySize)
152 selectInfo->scanType = selectInfo->scanArray[i];
156 /* single-click event */
157 selectInfo->scanType = selectInfo->scanArray[0];
160 selectInfo->lastTime = event->xbutton.time;
164 ** convert a row,col pair into the equivalent XmTextPosition
167 ** this routine assumes that the calling routine as already checked
168 ** row and col to insure that they are within the bounds of the terminal
169 ** buffer (see _DtTermPrimSelectGrabFocus)
174 DtTermPrimitiveWidget tw,
179 DtTermPrimData tpd = tw->term.tpd;
181 return(((tpd->selectInfo->columns + 1) *
182 (row + tpd->lastUsedHistoryRow)) + col);
189 _DtTermPrimSelectGetSelection
192 XmTextPosition *begin,
196 TermSelectInfo selectInfo =
197 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
199 if (selectInfo->ownPrimary &&
200 (selectInfo->begin <= selectInfo->end) &&
201 selectInfo->begin >= 0)
203 *begin = selectInfo->begin;
204 *end = selectInfo->end;
211 selectInfo->ownPrimary = False;
218 ** convert an x,y pair into the appropriate text position
220 ** Since positions count the number of inter-character spaces, there is
221 ** one more x position on a line than columns on a line; xPos can be in
222 ** the range (0, selectInfo->columns + 1). The same is true for yPos,
223 ** it can be in the range (0, tpd->lastUsedRow - tpd->topRow - 1)
225 ** In the case that we have a history buffer to deal with, text positions
226 ** in the history buffer are forced to come before positions in the term
230 ** this routine assumes that the calling routine as already checked
231 ** x and y to insure that they are within the bounds of the terminal
232 ** window (see _DtTermPrimSelectGrabFocus)
234 ** I believe I'm now doing all checking in this routine for confining
235 ** the x,y to the window. Disregard the previous note. TMH
241 DtTermPrimitiveWidget tw,
246 DtTermPrimData tpd = tw->term.tpd;
247 TermSelectInfo selectInfo = tpd->selectInfo;
252 static short oldYPos = -1;
253 static short oldXPos = -1;
257 if ( x > (int) tw->core.width) x = tw->core.width;
259 ** convert pixel units to character positions
261 yPos = (MAX(0, y) - tpd->offsetY) / tpd->cellHeight;
264 ** yPos cannot exceed the buffer or screen
266 yPos = MIN(yPos, MIN(tw->term.rows, tpd->lastUsedRow - tpd->topRow) - 1) +
270 ** consider the possibility that we have a history buffer
272 if (tpd->useHistoryBuffer)
277 ** yPos is not in the history buffer (order is important,
278 ** step 2 must come before step 3):
279 ** 1) point to history buffer
281 ** 3) decide which row of the buffer we are concerned
284 tb = tpd->historyBuffer;
285 yPos += tpd->lastUsedHistoryRow;
291 ** yPos is not in the history buffer (order is important,
292 ** step 2 must come before step 3):
293 ** 1) point to term buffer
294 ** 2) decide which row of the buffer we are concerned
298 tb = tpd->termBuffer;
300 yPos += tpd->lastUsedHistoryRow;
305 tb = tpd->termBuffer;
309 xPos = (((x - tpd->offsetX) + (tpd->cellWidth / 2)) / tpd->cellWidth) ;
311 if ( MB_CUR_MAX > 1 ) /* check if xPos splits a 2 col char */
313 TermCharInfoRec charInfoRec ;
314 if (_DtTermPrimGetCharacterInfo(tb,row,xPos,&charInfoRec) )
316 if (charInfoRec.width == 2 && charInfoRec.startCol != xPos)
318 if (xPos*tpd->cellWidth < x - tpd->offsetX )
319 xPos++ ; /* set to right of char */
321 xPos-- ; /* set to left of char */
327 if ((yPos != oldYPos) || (xPos != oldXPos))
332 return (((selectInfo->columns + 1) * yPos) + xPos);
336 * Takes a linear position and return buffer, row, and col.
337 * Since positions are between characters, this returns the col to
338 * right of the position.
343 DtTermPrimitiveWidget tw,
350 DtTermPrimData tpd = tw->term.tpd;
351 TermSelectInfo selectInfo = tpd->selectInfo;
354 lrow = pos / (selectInfo->columns + 1);
355 lcol = pos - (lrow * (selectInfo->columns + 1));
357 if ( tpd->useHistoryBuffer ) lrow -= tpd->lastUsedHistoryRow ;
359 if ( lrow < 0 ) { /* in history buffer */
360 *pb=tw->term.tpd->historyBuffer ;
361 lrow += tpd->lastUsedHistoryRow ;
365 *pb = tpd->termBuffer ;
372 * Takes a buffer, row and column and returns the linear position.
374 static XmTextPosition
377 DtTermPrimitiveWidget tw,
383 DtTermPrimData tpd = tw->term.tpd;
384 TermSelectInfo selectInfo = tpd->selectInfo;
388 /* assume row, col in the history buffer or there is no history */
389 pos = (tpd->selectInfo->columns + 1) * row + col;
391 if ( tpd->useHistoryBuffer && pb == tpd->termBuffer)
392 pos += (tpd->selectInfo->columns + 1) * (tpd->lastUsedHistoryRow) ;
397 static XmTextPosition
400 DtTermPrimitiveWidget tw,
401 XmTextPosition scanStart,
402 XmTextScanType scanType,
403 TermScanDirection scanDir,
409 DtTermPrimData tpd = tw->term.tpd;
410 TermSelectInfo selectInfo = tpd->selectInfo;
411 XmTextPosition position = scanStart;
419 case XmSELECT_POSITION:
420 posToBufferRowCol(tw, position, &pb, &row, &col) ;
421 if ( col > _DtTermPrimBufferGetLineWidth(pb, row) )
423 col = selectInfo->columns + 1;
424 position = bufferRowColToPos(tw,pb,row,col) ;
430 posToBufferRowCol(tw, position, &pb, &row, &col) ;
431 width = _DtTermPrimBufferGetLineWidth(pb,row);
432 if ( col > width ) break;
434 if ( MB_CUR_MAX > 1 )
436 TermCharInfoRec charInfoRec ;
438 _DtTermPrimGetCharacterInfo(pb,row,col,&charInfoRec);
439 col = charInfoRec.startCol ; /* align first */
444 _DtTermPrimGetCharacterInfo(pb,row,col?--col:0,&charInfoRec);
445 while( !iswspace(*(wchar_t *)charInfoRec.u.pwc) &&
446 ((col=charInfoRec.startCol-1)>=0) )
448 _DtTermPrimGetCharacterInfo(pb,row,col,&charInfoRec) ;
453 _DtTermPrimGetCharacterInfo(pb,row,col,&charInfoRec);
454 while(++col<=width && !iswspace(*(wchar_t *)charInfoRec.u.pwc))
455 _DtTermPrimGetCharacterInfo(pb,row,col,&charInfoRec);
466 _DtTermPrimBufferGetText(pb, row, col?--col:0, 1, pbuf, False);
467 while( !isspace(*pbuf) && --col >= 0)
468 _DtTermPrimBufferGetText(pb, row, col, 1, pbuf, False );
472 _DtTermPrimBufferGetText(pb, row, col, 1, pbuf, False);
473 while( ++col <= width && !isspace(*pbuf))
474 _DtTermPrimBufferGetText(pb, row, col, 1, pbuf, False );
479 position = bufferRowColToPos(tw,pb,row,col) ;
485 posToBufferRowCol(tw, position, &pb, &row, &col) ;
492 col = selectInfo->columns + 1;
495 position = bufferRowColToPos(tw,pb,row,col) ;
505 pb = tpd->termBuffer ;
506 row = tpd->lastUsedRow-1;
507 col = _DtTermPrimBufferGetLineWidth(pb,row) ;
508 position = bufferRowColToPos(tw,pb,row,col) ;
517 ** refresh all text from start up to stop
520 ** We assume that start is always <= than stop
523 _DtTermPrimRenderRefreshTextLinear
526 XmTextPosition start,
530 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
531 DtTermPrimData tpd = tw->term.tpd;
532 TermSelectInfo selectInfo = tpd->selectInfo;
533 short startRow, startCol;
534 short stopRow , stopCol;
538 ** Turn XmTextPosition into a row and column
540 startRow = start / (selectInfo->columns + 1);
541 startCol = start - (startRow * (selectInfo->columns + 1));
542 stopRow = stop / (selectInfo->columns + 1);
543 stopCol = stop - (stopRow * (selectInfo->columns + 1));
546 ** Accomodate the history buffer as necessary
548 if (tpd->useHistoryBuffer)
550 startRow -= tpd->lastUsedHistoryRow;
551 stopRow -= tpd->lastUsedHistoryRow;
555 ** Now adjust for the top of the window
557 startRow -= tpd->topRow;
558 stopRow -= tpd->topRow;
562 ** refresh the first (and possibly only) line
564 if (startRow == stopRow)
566 _DtTermPrimRefreshText((Widget)tw, startCol, startRow,
570 _DtTermPrimRefreshText((Widget)tw, startCol, startRow,
571 selectInfo->columns - 1, startRow);
574 ** refresh the middle block (if there is one)
576 if (startRow++ < stopRow)
578 _DtTermPrimRefreshText((Widget)tw, 0, startRow,
579 selectInfo->columns - 1, stopRow - 1);
583 ** refresh the last line
585 _DtTermPrimRefreshText((Widget)tw, 0, stopRow, stopCol, stopRow);
593 DtTermPrimitiveWidget tw,
594 XmTextPosition begin,
597 Boolean fromLoseSelection
600 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
601 XmTextPosition oldBegin, oldEnd;
602 Boolean disJoint; /* true if new and current are disjoint */
603 short selectLineBegin;
604 short selectColBegin;
608 Debug('c', fprintf(stderr, ">>setSelection() starting\n"));
610 if (selectInfo->ownPrimary == False &&
613 Debug('c', fprintf(stderr, ">>setSelection() finishing a\n"));
623 if (selectInfo->ownPrimary)
626 ** we own the selection see how much (if any) of the selected
627 ** area needs to be unhighlighted...
629 if (selectInfo->begin < selectInfo->end)
632 ** We own the selection, and its highlighted...
634 if ((end <= selectInfo->begin) ||
635 (begin >= selectInfo->end))
638 ** The two areas don't intersect, simply clear the old
641 Debug('c', fprintf(stderr, " new & old are disjoint\n"));
642 selectInfo->ownPrimary = False;
643 _DtTermPrimRenderRefreshTextLinear((Widget)tw,
645 selectInfo->end - 1);
646 selectInfo->ownPrimary = True;
652 ** There is some intersection, save the current begin
653 ** and end so we can clean things up later.
655 Debug('c', fprintf(stderr, " new & old intersect\n"));
656 oldBegin = selectInfo->begin;
657 oldEnd = selectInfo->end;
664 ** We own the selection, but nothing is highlighted...
672 ** we don't own the selection (yet), come up with some reasonable
681 selectInfo->begin = begin;
682 selectInfo->end = end;
686 if (selectInfo->ownPrimary == False)
688 if (!XtOwnSelection((Widget)tw, XA_PRIMARY, selectTime,
689 _DtTermPrimSelectConvert,
690 _DtTermPrimSelectLoseSelection,
691 (XtSelectionDoneProc) NULL))
694 ** XtOwnSelection failed, make a dummy call to setSelection
695 ** (with begin > end) to clear things up...
697 setSelection(tw, 1, -99, selectTime, False);
701 selectInfo->ownPrimary = True;
702 selectInfo->primaryTime = selectTime;
707 ** now highlight the currently selected text...
709 if (selectInfo->ownPrimary)
711 if (disJoint == True)
714 ** the selections are disjoint, simply draw the new one
716 _DtTermPrimRenderRefreshTextLinear((Widget)tw, begin, end - 1);
720 if (begin != oldBegin)
722 if (begin < oldBegin)
725 ** refresh from the new beginning to the old
728 _DtTermPrimRenderRefreshTextLinear((Widget)tw, begin,
731 else if (oldBegin < begin)
734 ** refresh from the old beginning to the new
737 ** NOTE: in this case we want to unhighlight
738 ** previously selected text, so we
739 ** temporarily set ownPrimary to false
741 selectInfo->ownPrimary = False;
742 _DtTermPrimRenderRefreshTextLinear((Widget)tw, oldBegin,
744 selectInfo->ownPrimary = True;
752 ** refresh from the new end to the original end
754 ** NOTE: in this case we want to unhighlight
755 ** previously selected text, so we
756 ** temporarily set ownPrimary to false
758 selectInfo->ownPrimary = False;
759 _DtTermPrimRenderRefreshTextLinear((Widget)tw, end,
761 selectInfo->ownPrimary = True;
763 else if (oldEnd < end)
766 ** refresh from the old end to the new end.
768 _DtTermPrimRenderRefreshTextLinear((Widget)tw, oldEnd,
777 if (!fromLoseSelection)
779 XtDisownSelection((Widget)tw, XA_PRIMARY, selectTime);
781 selectInfo->ownPrimary = False;
784 selectLineBegin = selectInfo->begin / (selectInfo->columns + 1);
785 selectColBegin = selectInfo->begin % (selectInfo->columns + 1);
786 selectLineEnd = (selectInfo->end - 1) / (selectInfo->columns + 1);
787 selectColEnd = (selectInfo->end - 1) % (selectInfo->columns + 1);
790 fprintf(stderr, "set selection units: %d-%d lines: %d-%d\n",
791 selectInfo->begin, selectInfo->end,
794 if (tw->term.tpd->useHistoryBuffer && tw->term.tpd->lastUsedHistoryRow>0) {
795 if (selectLineEnd > tw->term.tpd->lastUsedHistoryRow) {
796 (void) _DtTermPrimBufferSetSelectLines(tw->term.tpd->historyBuffer,
797 selectLineBegin, selectColBegin,
798 tw->term.tpd->lastUsedHistoryRow - 1, selectInfo->columns);
800 (void) _DtTermPrimBufferSetSelectLines(tw->term.tpd->historyBuffer,
801 selectLineBegin, selectColBegin,
802 selectLineEnd, selectColEnd);
804 selectLineBegin -= tw->term.tpd->lastUsedHistoryRow;
805 if (selectLineBegin < 0) {
809 selectLineEnd -= tw->term.tpd->lastUsedHistoryRow;
812 if (selectLineEnd > tw->term.tpd->lastUsedRow) {
813 (void) _DtTermPrimBufferSetSelectLines(tw->term.tpd->termBuffer,
814 selectLineBegin, selectColBegin,
815 tw->term.tpd->lastUsedRow, selectInfo->columns);
817 (void) _DtTermPrimBufferSetSelectLines(tw->term.tpd->termBuffer,
818 selectLineBegin, selectColBegin,
819 selectLineEnd, selectColEnd);
821 Debug('c', fprintf(stderr, ">>setSelection() finishing b\n"));
828 DtTermPrimitiveWidget tw,
834 XmTextPosition position;
835 XmTextPosition newBegin;
836 XmTextPosition newEnd;
837 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
839 Debug('c', fprintf(stderr, ">>handleSelection() starting\n"));
841 position = xyToPos(tw, x, y);
842 newBegin = scan(tw, position, selectInfo->scanType, scanLeft,
844 newEnd = scan(tw, position, selectInfo->scanType, scanRight,
845 1, selectInfo->scanType == XmSELECT_LINE);
847 setSelection(tw, newBegin, newEnd, selectTime, False);
849 if ((position - newBegin) <
852 selectInfo->extendDir = scanLeft;
856 selectInfo->extendDir = scanRight;
858 selectInfo->origBegin = newBegin;
859 selectInfo->origEnd = newEnd;
863 /************************************************************************
865 * browseScroll - timer proc that scrolls the list if the user has left *
866 * the window with the button down. If the button has been *
867 * released, call the standard click stuff. *
869 ************************************************************************/
878 Widget w = (Widget) closure;
879 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
880 DtTermPrimData tpd = tw->term.tpd;
881 TermSelectInfo selectInfo = tpd->selectInfo ;
882 XmScrollBarWidget vsb = (XmScrollBarWidget) tw->term.verticalScrollBar;
883 unsigned long interval;
885 if (selectInfo->cancel) {
886 selectInfo->selectID = 0;
890 if (!selectInfo->selectID) return;
892 _DtTermPrimScrollComplete(w, True);
893 if ( selectInfo->isScrollUp ) {
894 if ( tpd->lastUsedRow-1 >= tpd->topRow + tw->term.rows)
895 _DtTermPrimScrollText(w, 1);
898 _DtTermPrimScrollText(w, -1);
899 _DtTermPrimScrollComplete(w, True);
900 if (selectInfo->extending)
901 doExtendedSelection(w, XtLastTimestampProcessed(XtDisplay(w)));
904 interval = (unsigned long) vsb->scrollBar.repeat_delay;
908 XSync (XtDisplay(w), False);
910 selectInfo->selectID = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
911 interval, browseScroll, (XtPointer) w);
922 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
923 DtTermPrimData tpd = tw->term.tpd;
924 TermSelectInfo selectInfo = tpd->selectInfo;
925 XmScrollBarWidget vsb = (XmScrollBarWidget) tw->term.verticalScrollBar;
926 unsigned long interval;
928 selectInfo->extend.x = event->xmotion.x;
929 selectInfo->extend.y = event->xmotion.y;
931 if ( (event->xmotion.y > (int) tpd->offsetY) &&
932 (event->xmotion.y < (int) (tpd->offsetY + tw->term.rows *
935 if (selectInfo->selectID) {
936 XtRemoveTimeOut(selectInfo->selectID);
937 selectInfo->selectID = 0;
941 if (event->xmotion.y <= (int) tpd->offsetY) {
942 selectInfo->extend.x = 0;
943 selectInfo->extend.y = (int) (tpd->offsetY);
944 selectInfo->isScrollUp = False ;
947 } else if (event->xmotion.y >= (int) (tpd->offsetY + tw->term.rows *
949 selectInfo->extend.x = tw->core.width;
950 selectInfo->extend.y = (int) (tpd->offsetY + tw->term.rows *
952 selectInfo->isScrollUp = True ;
956 interval = (unsigned long) vsb->scrollBar.initial_delay;
960 if (!selectInfo->selectID)
961 selectInfo->selectID = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
962 interval, browseScroll, (XtPointer) w);
969 ** Create and initialize the selection specific information
972 _DtTermPrimSelectCreate
977 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
978 DtTermPrimData tpd = tw->term.tpd;
979 TermSelectInfo selectInfo;
982 selectInfo = (TermSelectInfo)XtMalloc(sizeof(TermSelectInfoRec));
984 selectInfo->begin = 0;
986 selectInfo->columns = tw->term.columns;
987 selectInfo->rows = tpd->bufferRows + tpd->historyBufferRows;
988 selectInfo->direction = (TermScanDirection) XmTEXT_FORWARD;
989 selectInfo->extend.x = 0;
990 selectInfo->extend.y = 0;
991 selectInfo->extending = False;
992 selectInfo->hint.x = 0;
993 selectInfo->hint.y = 0;
994 selectInfo->lastTime = 0;
995 selectInfo->origBegin = 0;
996 selectInfo->origEnd = 0;
997 selectInfo->ownPrimary = False;
998 selectInfo->threshold = 5;
999 selectInfo->selectID = 0;
1000 selectInfo->selectType = TermSelect_NORMAL;
1001 selectInfo->scanType = defaultScanArray[0];
1002 selectInfo->scanArraySize = XtNumber(defaultScanArray);
1003 selectInfo->scanArray = (XmTextScanType *)
1004 XtMalloc(selectInfo->scanArraySize *
1005 sizeof(XmTextScanType));
1006 selectInfo->cancel = True; /* used by scroll selection */
1007 selectInfo->anchor = -1; /* in case extend happens before set*/
1008 selectInfo->sel_start = False;
1009 for (i = 0; i < selectInfo->scanArraySize; i++)
1011 selectInfo->scanArray[i] = defaultScanArray[i];
1014 RegisterDropSite(w);
1019 _DtTermPrimSelectInitBtnEvents(Widget w)
1021 Boolean btn1_transfer = False;
1022 XtVaGetValues((Widget)XmGetXmDisplay(XtDisplay(w)), "enableBtn1Transfer",
1023 &btn1_transfer, NULL);
1025 XtOverrideTranslations(w,
1026 XtParseTranslationTable(_DtTermEventBindingsCDE));
1027 if (btn1_transfer == True) /* for btn2 extend case */
1028 XtOverrideTranslations(w,
1029 XtParseTranslationTable(_DtTermEventBindingsCDEBtn2));
1033 _DtTermPrimSelectDisown
1038 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1039 DtTermPrimData tpd = tw->term.tpd;
1040 TermSelectInfo selectInfo = tpd->selectInfo;
1042 if (selectInfo->ownPrimary == True)
1044 XtDisownSelection(w, XA_PRIMARY, getServerTime(w));
1045 selectInfo->ownPrimary = False ;
1050 _DtTermPrimSelectDestroy
1053 TermSelectInfo selectInfo
1056 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1057 DtTermPrimData tpd = tw->term.tpd;
1059 if (selectInfo->ownPrimary == True)
1061 XtDisownSelection(w, XA_PRIMARY, getServerTime(w));
1063 selectInfo->ownPrimary = False ;
1064 XtFree((char *) selectInfo->scanArray);
1065 XtFree((char *) selectInfo);
1066 tpd->selectInfo = NULL ;
1071 ** determine how much (if any) of the text is selected
1074 ** beginCol + width will never exceed the width of the terminal
1078 _DtTermPrimSelectIsInSelection
1087 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1088 DtTermPrimData tpd = tw->term.tpd;
1089 TermSelectInfo selectInfo = tpd->selectInfo;
1090 Boolean inSelection = True;
1091 XmTextPosition endPosition;
1092 XmTextPosition position;
1093 XmTextPosition begin;
1095 short beginRow, beginCol;
1096 short endRow , endCol;
1098 position = rowColToPos(tw, row, startCol);
1099 endPosition = position + width;
1101 begin = selectInfo->begin;
1102 end = selectInfo->end;
1104 if ((begin >= endPosition) || (end <= position))
1107 ** outside of selection range...
1109 inSelection = False;
1114 ** we're in the selection range, clip endPosition as necessary...
1116 if (position < begin)
1119 ** we start to the left of the selection...
1121 inSelection = False;
1122 endPosition = MIN(endPosition, begin);
1128 ** we must be in the selection, clip endPosition as
1131 endPosition = MIN(endPosition, end);
1136 *selWidth = endPosition - position;
1137 return(inSelection);
1142 _DtTermPrimSelectDoSelection
1147 Cardinal *paramCount
1150 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
1152 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectDoSelection() starting\n"));
1154 handleSelection(tw, event->xbutton.x, event->xbutton.y,
1155 event->xbutton.time);
1160 _DtTermPrimSelectSetHint
1165 Cardinal *paramCount
1168 TermSelectInfo selectInfo =
1169 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
1171 selectInfo->hint.x = event->xbutton.x;
1172 selectInfo->hint.y = event->xbutton.y;
1177 _DtTermPrimSelectStart
1182 Cardinal *paramCount
1185 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1186 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1187 XButtonEvent *btnEvent = (XButtonEvent *) event;
1188 XmTextPosition begin;
1191 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectStart() starting\n"));
1194 ** set the selection hints, and scan type
1196 _DtTermPrimSelectSetHint(w, event, params, paramCount);
1197 setScanType(w, event);
1200 ** Set the current anchor point
1202 selectInfo->anchor = xyToPos(tw, btnEvent->x, btnEvent->y);
1204 if (selectInfo->scanType != XmSELECT_POSITION ||
1205 (_DtTermPrimSelectGetSelection(w, &begin, &end) && begin != end)
1208 _DtTermPrimSelectDoSelection(w, event, params, paramCount);
1214 _DtTermPrimSelectGrabFocus
1219 Cardinal *paramCount
1222 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1223 DtTermPrimData tpd = tw->term.tpd;
1224 TermSelectInfo selectInfo = tpd->selectInfo;
1225 XButtonEvent *btnEvent = (XButtonEvent *) event;
1227 /* setDebugFlags("c") ; */
1228 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectGrabFocus() starting\n"));
1230 /* turn off the cursor */
1231 _DtTermPrimCursorOff(w);
1233 selectInfo->cancel = False;
1234 tw->term.allowOsfKeysyms = True; /* normal dtterm doesn't honor these*/
1236 ** constrain the button event to the terminal's text area
1238 if (btnEvent->x <= (int) tpd->offsetX)
1241 btnEvent->x = (int)(tpd->offsetX + 1);
1242 } else if (btnEvent->x >= (int)(tw->core.width - tpd->offsetX))
1245 btnEvent->x = (int)(tw->core.width - tpd->offsetX - 1);
1248 if (btnEvent->y <= (int)tpd->offsetY)
1251 btnEvent->y = (int)(tpd->offsetY + 1);
1253 else if (btnEvent->y - ((int)(tpd->offsetY +
1254 ((tpd->lastUsedRow - tpd->topRow) *
1255 tpd->cellHeight))) >= selectInfo->threshold)
1258 btnEvent->y = (int)(tpd->offsetY + ((tpd->lastUsedRow - tpd->topRow) *
1259 tpd->cellHeight) - 1);
1262 if (_XmGetFocusPolicy(w) == XmEXPLICIT)
1263 (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
1265 _DtTermPrimSelectStart(w, event, params, paramCount);
1273 TermSelectionHint hint,
1278 return ((abs(hint.x - event->xbutton.x) > threshold) ||
1279 (abs(hint.y - event->xbutton.y) > threshold));
1290 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
1291 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1292 XmTextPosition position;
1293 XmTextPosition begin;
1295 XmTextPosition cursorPos;
1298 if (selectInfo->cancel) {
1299 if (selectInfo->selectID) XtRemoveTimeOut(selectInfo->selectID);
1300 selectInfo->selectID = 0;
1304 position = xyToPos(tw, selectInfo->extend.x, selectInfo->extend.y);
1306 if (!(_DtTermPrimSelectGetSelection(w, &begin, &end)) ||
1311 if ( selectInfo->anchor <0) selectInfo->anchor = position;
1312 selectInfo->origBegin = selectInfo->anchor;
1313 selectInfo->origEnd = selectInfo->anchor;
1314 midPoint = (float)selectInfo->anchor;
1319 (((float)(selectInfo->origEnd -
1320 selectInfo->origBegin) / 2.0) +
1321 (float)selectInfo->origBegin);
1325 ** shift anchor and direction to opposite end of the selection
1327 if ((float)(position) <= midPoint)
1329 selectInfo->anchor = selectInfo->origEnd;
1330 if (!selectInfo->extending)
1332 selectInfo->extendDir = scanLeft;
1335 else if ((float)(position) > midPoint)
1337 selectInfo->anchor = selectInfo->origBegin;
1338 if (!selectInfo->extending)
1340 selectInfo->extendDir = scanRight;
1344 selectInfo->extending = TRUE;
1347 ** check for change in extend direction
1349 if ((selectInfo->extendDir == scanRight &&
1350 position < selectInfo->anchor) ||
1351 (selectInfo->extendDir == scanLeft &&
1352 position > selectInfo->anchor))
1354 selectInfo->extendDir = (selectInfo->extendDir == scanRight) ?
1355 scanLeft : scanRight;
1357 begin = selectInfo->begin;
1358 end = selectInfo->end;
1362 if (selectInfo->extendDir == scanRight)
1364 cursorPos = scan(tw, position, selectInfo->scanType, scanRight, 1,
1365 selectInfo->scanType == XmSELECT_LINE);
1367 begin = selectInfo->anchor;
1371 cursorPos = scan(tw, position, selectInfo->scanType, scanLeft, 1,
1374 end = selectInfo->anchor;
1375 if (selectInfo->scanType == XmSELECT_WORD &&
1376 (int)tw->term.tpd->cellWidth > 1)
1378 if (position == scan (tw, begin, selectInfo->scanType, scanRight, 1,
1381 begin = cursorPos = position;
1386 setSelection(tw, begin, end, eventTime, False);
1390 _DtTermPrimSelectExtendStart(
1394 Cardinal *num_params )
1396 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1397 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1399 selectInfo->cancel = False;
1400 tw->term.allowOsfKeysyms = True ;
1402 _DtTermPrimSelectExtend(w, event, params, num_params);
1407 _DtTermPrimSelectExtend
1412 Cardinal *paramCount
1415 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1416 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1418 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectExtend() starting\n"));
1420 /* turn off the cursor */
1421 _DtTermPrimCursorOff(w);
1423 if (_XmGetFocusPolicy(w) == XmEXPLICIT)
1424 (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
1426 if (selectInfo->cancel) return ;
1428 if ((selectInfo->hint.x > 0) || (selectInfo->hint.y > 0))
1430 if (dragged(selectInfo->hint, event, selectInfo->threshold))
1433 ** extend the selection
1435 handleSelection(tw,selectInfo->hint.x,selectInfo->hint.y,
1436 event->xbutton.time);
1437 selectInfo->hint.x = 0;
1438 selectInfo->hint.y = 0;
1439 selectInfo->extending = True;
1450 ** check for timer scrolling here
1451 ** NOTE: CheckTimerScrolling(w,event) will set extend.[x|y]
1452 * selectInfo->extend.x = event->xbutton.x;
1453 * selectInfo->extend.y = event->xbutton.y;
1455 if (!CheckTimerScrolling(w,event) )
1456 doExtendedSelection(w, event->xbutton.time);
1461 _DtTermPrimSelectExtendEnd
1466 Cardinal *paramCount
1469 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1470 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1472 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectExtendEnd() starting\n"));
1474 selectInfo->cancel = True; /* used by scroll selection */
1475 tw->term.allowOsfKeysyms = False;
1477 if (selectInfo->extending)
1479 _DtTermPrimSelectGetSelection(w, &selectInfo->origBegin,
1480 &selectInfo->origEnd);
1481 setSelection(tw, selectInfo->origBegin, selectInfo->origEnd,
1482 event->xbutton.time, False);
1483 /* _DtTermPrimSelectExtend(w, event, params, paramCount);*/
1486 if (selectInfo->selectID > 0)
1488 XtRemoveTimeOut(selectInfo->selectID);
1489 selectInfo->selectID = 0;
1492 selectInfo->extend.x = 0;
1493 selectInfo->extend.y = 0;
1494 selectInfo->extending = False;
1495 selectInfo->hint.x = 0;
1496 selectInfo->hint.y = 0;
1498 /* turn off the cursor */
1499 _DtTermPrimCursorOn(w);
1511 unsigned long *length,
1515 _TermSelectPrimaryRec *primSelect = (_TermSelectPrimaryRec *) closure;
1516 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1517 DtTermPrimData tpd = tw->term.tpd;
1518 TermSelectInfo selectInfo = tpd->selectInfo;
1519 XTextProperty tmpProp;
1520 XmTextBlockRec block;
1525 int malloc_size=0 , numVals ;
1526 char *total_tmp_value ;
1529 Debug('c', fprintf(stderr, ">>doHandleTargets() starting\n"));
1531 if (_XmGetFocusPolicy(w) == XmEXPLICIT)
1533 (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
1536 if (*type == XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False) ||
1540 tmpProp.value = (unsigned char *) value;
1541 tmpProp.encoding = *type;
1542 tmpProp.format = *format;
1543 tmpProp.nitems = *length;
1545 status = XmbTextPropertyToTextList(XtDisplay(w), &tmpProp,
1546 &tmp_value, &numVals );
1549 ** if no conversions, numVals doesn't change
1551 if (numVals && (status == Success || status > 0))
1553 for (i = 0; i < numVals ; i++)
1555 malloc_size += strlen(tmp_value[i]);
1557 total_tmp_value = XtMalloc ((unsigned) malloc_size + 1);
1558 total_tmp_value[0] = '\0';
1559 for (i = 0; i < numVals ; i++)
1561 strcat(total_tmp_value, tmp_value[i]);
1563 block.ptr = total_tmp_value;
1564 block.length = strlen(total_tmp_value);
1565 block.format = XmFMT_8_BIT;
1566 XFreeStringList(tmp_value);
1570 malloc_size = 1; /* to force space to be freed */
1571 total_tmp_value = XtMalloc ((unsigned)1);
1572 *total_tmp_value = '\0';
1573 block.ptr = total_tmp_value;
1575 block.format = XmFMT_8_BIT;
1579 block.ptr = (char*)value;
1580 block.length = (int) *length; /* NOTE: this causes a truncation on
1581 some architectures */
1582 block.format = XmFMT_8_BIT;
1585 pCharEnd = block.ptr + block.length;
1586 pCharFollow = (char *)block.ptr;
1588 for (pChar = (char *)block.ptr; pChar < pCharEnd; pChar++)
1593 DtTermSubprocSend(w, (unsigned char *) pCharFollow,
1594 pChar - pCharFollow + 1);
1595 pCharFollow = pChar + 1;
1598 if (pCharFollow < pCharEnd)
1600 DtTermSubprocSend(w, (unsigned char *) pCharFollow,
1601 pCharEnd - pCharFollow);
1604 if (malloc_size != 0) XtFree(total_tmp_value);
1605 XtFree((char *)value);
1606 if (primSelect && (--primSelect->ref_count == 0))
1608 XtFree((char *)primSelect);
1614 ** Look at the target list and determine what target to place in the
1615 ** pair. it will then do any necessary conversions before "thrusting"
1616 ** the selection value onto the receiver. this will guarantee the
1617 ** best chance at a successful exchange.
1628 unsigned long *length,
1634 Boolean supportsLocaleData;
1635 Boolean supportsCompoundText;
1637 _TermSelectRec *tmpAction;
1638 _TermSelectPrimaryRec *primSelect;
1640 XTextProperty tmpProp;
1642 XtPointer closures[2];
1647 ** make sure we have something to do...
1649 tmpAction = (_TermSelectRec *) closure;
1650 if (!length || *length == 0) {
1651 XtFree((char *)value);
1653 XtFree((char *)tmpAction->event);
1654 XtFree((char *)tmpAction);
1658 COMPOUND_TEXT = XmInternAtom(XtDisplay(w),"COMPOUND_TEXT", False);
1659 supportsLocaleData = False;
1660 supportsCompoundText = False;
1661 abcString = "ABC"; /* characters in XPCS, so... safe */
1662 atomPtr = (Atom *)value;
1664 tmpProp.value = NULL;
1665 status = XmbTextListToTextProperty(XtDisplay(w), &abcString, 1,
1666 (XICCEncodingStyle)XTextStyle, &tmpProp);
1667 if (status == Success)
1669 CS_OF_LOCALE = tmpProp.encoding;
1674 ** Kludge for failure of XmbText... to
1675 ** handle XPCS characters. Should never
1676 ** happen, but this prevents a core dump
1677 ** if X11 is broken.
1679 CS_OF_LOCALE = (Atom)9999;
1681 if (tmpProp.value != NULL)
1683 XFree((char *)tmpProp.value);
1686 for (i = 0; i < *length; i++, atomPtr++)
1688 if (*atomPtr == CS_OF_LOCALE)
1690 supportsLocaleData = True;
1693 if (*atomPtr == COMPOUND_TEXT)
1695 supportsCompoundText = True;
1698 primSelect = (_TermSelectPrimaryRec *)
1699 XtMalloc((unsigned) sizeof(_TermSelectPrimaryRec));
1702 ** If owner and I are using the same codeset, ask for it. If not,
1703 ** and if the owner supports compound text, ask for compound text.
1704 ** If not, fall back position is to ask for STRING and try to
1705 ** convert it locally.
1707 if (supportsLocaleData)
1709 primSelect->target = targets[0] = CS_OF_LOCALE;
1711 else if (supportsCompoundText)
1713 primSelect->target = targets[0] = COMPOUND_TEXT;
1717 primSelect->target = targets[0] = XA_STRING;
1719 closures[0] = (char *)primSelect;
1721 primSelect->ref_count = 1;
1723 ** Make request to call doHandleTargets() with the primary selection.
1725 XtGetSelectionValue(w, XA_PRIMARY, targets[0], doHandleTargets,
1726 (XtPointer)primSelect,
1727 tmpAction->event->xbutton.time);
1729 XtFree((char *)value);
1731 XtFree((char *)tmpAction->event);
1732 XtFree((char *)tmpAction);
1739 XmTextPosition begin,
1741 Boolean needWideChar
1744 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
1745 DtTermPrimData tpd = tw->term.tpd;
1746 TermSelectInfo selectInfo = tpd->selectInfo;
1758 beginRow = begin / (selectInfo->columns + 1);
1759 beginCol = begin - (beginRow * (selectInfo->columns + 1));
1760 endRow = end / (selectInfo->columns + 1);
1761 endCol = end - (endRow * (selectInfo->columns + 1));
1762 numRows = endRow - beginRow + 1;
1765 ** we need to store end - begin characters, a terminating byte, plus
1766 ** a new line for each line...
1768 ** NOTE: end - begin could result in a truncated long.
1770 buffer = XtMalloc(((int)(end - begin) + 1 + numRows) * sizeof(char)
1771 * BYTES_PER_CHAR(tpd->termBuffer));
1774 ** return a null string if there is nothing to do
1783 ** Accomodate the history buffer as necessary
1785 if (tpd->useHistoryBuffer)
1787 beginRow -= tpd->lastUsedHistoryRow;
1788 endRow -= tpd->lastUsedHistoryRow;
1792 ** get the first (and possibly only) line of text
1795 if (beginRow == endRow)
1799 tb = tpd->historyBuffer;
1800 thisRow = beginRow + tpd->lastUsedHistoryRow;
1804 tb = tpd->termBuffer;
1807 len = _DtTermPrimBufferGetText(tb, thisRow, beginCol,
1808 endCol - beginCol, pBuf, needWideChar);
1815 tb = tpd->historyBuffer;
1816 thisRow = beginRow + tpd->lastUsedHistoryRow;
1820 tb = tpd->termBuffer;
1823 len = _DtTermPrimBufferGetText(tb, thisRow, beginCol,
1824 selectInfo->columns - beginCol, pBuf,
1828 if ( !_DtTermPrimBufferTestLineWrapFlag(tb,thisRow) ) {
1829 *pBuf = '\n'; /* newline */
1834 ** get the middle block (if there is one)
1837 while(beginRow < endRow)
1841 tb = tpd->historyBuffer;
1842 thisRow = beginRow + tpd->lastUsedHistoryRow;
1846 tb = tpd->termBuffer;
1849 len = _DtTermPrimBufferGetText(tb, thisRow, 0,
1850 selectInfo->columns , pBuf,
1854 /* if (len != 0 && len < selectInfo->columns ) { */
1855 if ( !_DtTermPrimBufferTestLineWrapFlag(tb,thisRow) ) {
1856 *pBuf = '\n'; /* newline */
1863 ** get the last line
1867 tb = tpd->historyBuffer;
1868 thisRow = endRow + tpd->lastUsedHistoryRow;
1872 tb = tpd->termBuffer;
1875 len = _DtTermPrimBufferGetText(tb, thisRow, 0, endCol, pBuf,
1885 ** Request targets from selection owner.
1893 Cardinal *paramCount
1896 _TermSelectRec *tmp;
1898 tmp = (_TermSelectRec*)XtMalloc(sizeof(_TermSelectRec));
1901 ** Request targets from the selection owner so you can decide what to
1902 ** request. The decision process and request for the selection is
1903 ** taken care of in handleTargets().
1906 tmp->event = (XEvent *) XtMalloc(sizeof(XEvent));
1907 memcpy((void *)tmp->event, (void *)event, sizeof(XEvent));
1909 tmp->params = params;
1910 tmp->num_params = paramCount;
1912 XtGetSelectionValue(w, XA_PRIMARY,
1913 XmInternAtom(XtDisplay(w), "TARGETS", False),
1914 handleTargets, (XtPointer)tmp, event->xbutton.time);
1918 _DtTermPrimSelectConvert
1925 unsigned long *length,
1929 Atom TARGETS = XmInternAtom(XtDisplay(w), "TARGETS", False);
1931 Atom COMPOUND_TEXT = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
1932 Atom TEXT = XmInternAtom(XtDisplay(w), "TEXT", False);
1933 Atom MOTIF_DROP = XmInternAtom(XtDisplay(w), "_MOTIF_DROP", False);
1934 int maxTargets = 10;
1939 XmTextPosition begin;
1942 char *tmpString = "ABC"; /* characters in XPCS, so... safe */
1943 XTextProperty tmpProp;
1946 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectConvert() starting\n"));
1948 if (*selection == MOTIF_DROP) {
1949 XtSetArg(args[0], XmNclientData, &c_ptr);
1950 XtGetValues(w, args, 1);
1951 widget = (Widget)c_ptr;
1955 if (widget == NULL) return False;
1957 tmpProp.value = NULL;
1958 status = XmbTextListToTextProperty(XtDisplay(widget), &tmpString, 1,
1959 (XICCEncodingStyle)XTextStyle, &tmpProp);
1960 if (status == Success)
1962 CS_OF_LOCALE = tmpProp.encoding;
1967 ** XmbTextList... SHOULD never fail for
1968 ** XPCS character. But if it does, this
1969 ** prevents a core dump.
1971 CS_OF_LOCALE = (Atom) 9999;
1974 if (tmpProp.value != NULL)
1975 XFree((char *) tmpProp.value);
1978 if (*selection == XA_PRIMARY || *selection == MOTIF_DROP)
1980 ownPrimary = _DtTermPrimSelectGetSelection(widget, &begin, &end);
1987 if (*target == TARGETS)
1989 Atom *targets = (Atom *)XtMalloc((unsigned)(maxTargets * sizeof(Atom)));
1992 ** Xt should take care of TIME_STAMP for us.
1995 *value = (XtPointer)targets;
1996 *targets++ = TARGETS; targetCount++;
1997 if (!isDebugFSet('s', 1)) {
1998 *targets++ = COMPOUND_TEXT; targetCount++;
2000 if (!isDebugFSet('s', 2)) {
2001 *targets++ = CS_OF_LOCALE; targetCount++;
2003 if (!isDebugFSet('s', 3)) {
2004 *targets++ = TEXT; targetCount++;
2006 if (!isDebugFSet('s', 4)) {
2007 *targets++ = XA_STRING; targetCount++;
2010 *length = (targetCount * sizeof(Atom)) >> 2; /* convert to work count */
2013 else if (!ownPrimary)
2017 else if ((*target == XA_STRING && !isDebugFSet('s', 4)) ||
2018 (*target == COMPOUND_TEXT && !isDebugFSet('s', 1)))
2020 tmpValue = getString(widget, begin, end, False);
2021 tmpProp.value = NULL;
2022 if ((*target == XA_STRING) && !isDebugFSet('s', 4)) {
2023 *type = (Atom) XA_STRING;
2025 status = XmbTextListToTextProperty(XtDisplay(widget), &tmpValue, 1,
2026 (XICCEncodingStyle)XStringStyle,
2029 else if ((*target == COMPOUND_TEXT) && !isDebugFSet('s',1)) {
2030 *type = COMPOUND_TEXT;
2032 status = XmbTextListToTextProperty(XtDisplay(widget), &tmpValue, 1,
2033 (XICCEncodingStyle)XCompoundTextStyle,
2037 if (status == Success || status > 0)
2040 ** NOTE: casting tmpProp.nitems could result in a truncated long.
2042 if (tmpProp.nitems > 0)
2043 *value = (XtPointer) XtMalloc((unsigned)tmpProp.nitems);
2045 *value = (XtPointer) XtMalloc(1);
2047 *length = tmpProp.nitems;
2048 memcpy((void*)*value, (void*)tmpProp.value,
2049 (unsigned)tmpProp.nitems);
2050 if (tmpProp.value != NULL)
2051 XFree((char*)tmpProp.value);
2057 if (tmpProp.value != NULL)
2058 XFree((char*)tmpProp.value);
2062 else if (((*target == CS_OF_LOCALE) && !isDebugFSet('s', 2)) ||
2063 (*target == TEXT && !isDebugFSet('s', 3)))
2065 *type = CS_OF_LOCALE;
2067 *value = (XtPointer)getString(widget, begin, end, False);
2068 *length = strlen((char*) *value);
2076 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectConvert() exiting\n"));
2081 _DtTermPrimSelectLoseSelection
2087 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2088 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2089 Boolean restoreCursor = False;
2091 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectLoseSelection() starting\n"));
2093 if (*selection == XA_PRIMARY && selectInfo->ownPrimary)
2097 ** We've lost the primary selection, make a dummy call to
2098 ** setSelection (with begin > end) to clear things up...
2100 /* turn off the cursor */
2101 if (tw->term.tpd->cursorState != CURSORoff) {
2102 _DtTermPrimCursorOff(w);
2103 restoreCursor = True;
2106 setSelection(tw, 1, -99, XtLastTimestampProcessed(XtDisplay(w)), True);
2108 /* turn on the cursor */
2109 if (restoreCursor) {
2110 _DtTermPrimCursorOn(w);
2113 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectLoseSelection() exiting\n"));
2117 _DtTermPrimSelectBDragRelease
2122 Cardinal *paramCount
2125 TermSelectInfo selectInfo =
2126 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
2127 XButtonEvent *btnEvent = (XButtonEvent *) event;
2129 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectBDragRelease() starting\n"));
2131 /* Work around for intrinsic bug. Remove once bug is fixed.
2132 ** this is for drag/drop
2134 XtUngrabPointer(w, btnEvent->time);
2136 if ( selectInfo->sel_start ) getTargets(w, event, params, paramCount);
2141 _DtTermPrimSelectInsert
2146 Cardinal *paramCount
2149 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2150 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2152 if (!selectInfo->cancel)
2153 _DtTermPrimSelectBDragRelease(w, event, params, paramCount);
2155 selectInfo->cancel = True ;
2157 /* turn on the cursor */
2158 _DtTermPrimCursorOn(w);
2162 _DtTermPrimSelectIsAboveSelection
2169 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2170 DtTermPrimData tpd = tw->term.tpd;
2171 TermSelectInfo selectInfo = tpd->selectInfo;
2172 XmTextPosition curPos, endPos;
2174 endPos = selectInfo->end ;
2175 curPos = rowColToPos(tw,row,col) ;
2177 if ( curPos < endPos )
2184 _DtTermPrimSelectResize
2189 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2190 DtTermPrimData tpd = tw->term.tpd;
2191 TermSelectInfo selectInfo = tpd->selectInfo;
2193 _DtTermPrimSelectDisown(w) ;
2194 selectInfo->columns = tw->term.columns ;
2198 _DtTermPrimSelectMoveLines
2206 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2207 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2208 short selectLineBegin;
2209 short selectLineEnd;
2213 posToBufferRowCol (tw, selectInfo->begin, &pb, &row, &col);
2215 /* if there are no lines, etc. return... */
2216 if ((len <= 0) || (src == dest) || !selectInfo->ownPrimary ||
2217 pb == tw->term.tpd->historyBuffer ) {
2220 if (row >= src && row < (src + len)) {
2221 selectInfo->begin -= (src - dest) * (selectInfo->columns + 1);
2222 selectInfo->end -= (src - dest) * (selectInfo->columns + 1);
2227 _DtTermPrimSelectDeleteLines
2234 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2235 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2236 short selectLineBegin;
2237 short selectLineEnd;
2241 posToBufferRowCol (tw, selectInfo->begin, &pb, &row, &col);
2243 /* if there are no lines, etc. return... */
2244 if ((len <= 0) || !selectInfo->ownPrimary ||
2245 ((tw->term.tpd->scrollLockTopRow > 0 ||
2246 (tw->term.tpd->scrollLockBottomRow < tw->term.rows-1)) &&
2247 row < tw->term.tpd->scrollLockTopRow)) {
2252 /* figure out what the begin and end lines are... */
2253 selectLineBegin = selectInfo->begin / (selectInfo->columns + 1);
2254 selectLineEnd = (selectInfo->end - 1) / (selectInfo->columns + 1);
2256 /* if the beginning of the selection is after the source, we need to
2257 * move the selection up...
2259 if (selectLineBegin > src) {
2260 selectInfo->begin -= len * (selectInfo->columns + 1);
2261 selectInfo->end -= len * (selectInfo->columns + 1);
2262 if (selectInfo->begin < 0) {
2263 (void) _DtTermPrimSelectDisown(w);
2269 _DtTermPrimSelectInsertLines
2276 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2277 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2278 short selectLineBegin;
2279 short selectLineEnd;
2281 /* if there are no lines, return... */
2282 if ((len <= 0) || !selectInfo->ownPrimary) {
2286 /* figure out what the begin and end lines are... */
2287 selectLineBegin = selectInfo->begin / (selectInfo->columns + 1);
2288 selectLineEnd = (selectInfo->end - 1) / (selectInfo->columns + 1);
2290 /* if the beginning of the selection is at or after the source, we need to
2291 * move the selection up...
2293 if (selectLineBegin >= src) {
2294 selectInfo->begin += len * (selectInfo->columns + 1);
2295 selectInfo->end += len * (selectInfo->columns + 1);
2300 _DtTermPrimSelectAll
2305 Cardinal *paramCount
2308 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2309 DtTermPrimData tpd = tw->term.tpd;
2310 TermSelectInfo selectInfo = tpd->selectInfo;
2311 XButtonEvent *btnEvent = (XButtonEvent *) event;
2312 XmTextPosition begin;
2315 /* position not used in XmSELECT_ALL case */
2316 begin = scan(tw, (XmTextPosition) 0, XmSELECT_ALL, scanLeft,
2318 end = scan(tw, (XmTextPosition) 0, XmSELECT_ALL, scanRight,
2319 1, selectInfo->scanType == XmSELECT_LINE);
2321 /* turn off the cursor */
2322 _DtTermPrimCursorOff(w);
2324 setSelection(tw, begin, end, event->xbutton.time, False);
2326 /* turn on the cursor */
2327 _DtTermPrimCursorOn(w);
2331 _DtTermPrimSelectPage
2336 Cardinal *paramCount
2339 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2340 DtTermPrimData tpd = tw->term.tpd;
2341 TermSelectInfo selectInfo = tpd->selectInfo;
2342 XButtonEvent *btnEvent = (XButtonEvent *) event;
2343 XmTextPosition begin, end;
2344 short lastRow, width;
2347 begin = xyToPos(tw, 1, 1);
2348 end = xyToPos(tw, tw->core.width-1, tw->core.height-1);
2350 /* turn off the cursor */
2351 _DtTermPrimCursorOff(w);
2353 setSelection(tw, begin, end, event->xbutton.time, False);
2355 /* turn on the cursor */
2356 _DtTermPrimCursorOn(w);
2363 static XContext _DtTermDNDContext = 0;
2366 DropTransferCallback(
2372 unsigned long *length,
2375 _DtTermDropTransferRec *transfer_rec = (_DtTermDropTransferRec *) closure;
2376 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)transfer_rec->widget;
2377 DtTermPrimData tpd = tw->term.tpd;
2378 TermSelectInfo selectInfo = tpd->selectInfo;
2380 /* When type = NULL, we are assuming a DELETE request has been requested */
2383 XtFree((char *)value);
2388 doHandleTargets((Widget)tw,NULL,seltype,type,value,length,format) ;
2389 if (transfer_rec->move) {
2390 XmDropTransferEntryRec transferEntries[1];
2391 XmDropTransferEntryRec *transferList = NULL;
2393 transferEntries[0].client_data = (XtPointer) transfer_rec;
2394 transferEntries[0].target = XmInternAtom(XtDisplay(w),"DELETE",
2396 transferList = transferEntries;
2397 XmDropTransferAdd(w, transferEntries, 1);
2405 Display *display = XtDisplay(w);
2406 Screen *screen = XtScreen(w);
2408 XDeleteContext(display, (Window)screen, _DtTermDNDContext);
2415 Display *display = XtDisplay(w);
2416 Screen *screen = XtScreen(w);
2418 _DtTermProcessLock();
2419 if (_DtTermDNDContext == 0)
2420 _DtTermDNDContext = XUniqueContext();
2421 _DtTermProcessUnlock();
2423 XSaveContext(display, (Window)screen,
2424 _DtTermDNDContext, (XPointer)w);
2427 typedef struct _dropDestroyCBClientData {
2428 _DtTermDropTransferRec *transfer_rec;
2429 XtCallbackRec *dropDestroyCB; }
2430 dropDestroyCBClientData;
2436 XtPointer clientData,
2437 XtPointer callData )
2439 dropDestroyCBClientData *ptr = (dropDestroyCBClientData *) clientData;
2441 DeleteDropContext(w);
2444 if (ptr->transfer_rec) XtFree((char *) ptr->transfer_rec);
2445 if (ptr->dropDestroyCB) XtFree((char *) ptr->dropDestroyCB);
2446 XtFree((char *) ptr);
2451 HandleDrop( Widget w, XmDropProcCallbackStruct *cb )
2453 Widget drag_cont, initiator;
2454 /* XmTextWidget tw = (XmTextWidget) w; */
2455 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2456 DtTermPrimData tpd = tw->term.tpd;
2457 TermSelectInfo selectInfo = tpd->selectInfo;
2458 Cardinal numExportTargets, n;
2459 Atom *exportTargets;
2461 XmTextPosition insert_pos, left, right;
2462 XtCallbackRec *dropDestroyCB, *dd_cb;
2463 dropDestroyCBClientData *clientData;
2465 clientData = (dropDestroyCBClientData *) XtMalloc(sizeof(dropDestroyCBClientData));
2466 dropDestroyCB = dd_cb = (XtCallbackRec *) XtMalloc(2 * sizeof (XtCallbackRec));
2468 clientData->dropDestroyCB = dropDestroyCB;
2469 dd_cb->callback = DropDestroyCB;
2470 dd_cb->closure = NULL;
2472 dd_cb->callback = (XtCallbackProc) NULL;
2473 dd_cb->closure = NULL;
2475 drag_cont = cb->dragContext;
2478 XtSetArg(args[n], XmNsourceWidget, &initiator); n++;
2479 XtSetArg(args[n], XmNexportTargets, &exportTargets); n++;
2480 XtSetArg(args[n], XmNnumExportTargets, &numExportTargets); n++;
2481 XtGetValues((Widget) drag_cont, args, n);
2484 XmDropTransferEntryRec transferEntries[2];
2485 XmDropTransferEntryRec *transferList = NULL;
2486 Atom TEXT = XmInternAtom(XtDisplay(w), "TEXT", False);
2487 Atom COMPOUND_TEXT = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
2489 char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
2490 XTextProperty tmp_prop;
2491 _DtTermDropTransferRec *transfer_rec;
2492 Cardinal numTransfers = 0;
2493 Boolean locale_found = False;
2494 Boolean c_text_found = False;
2495 Boolean string_found = False;
2496 Boolean text_found = False;
2499 tmp_prop.value = NULL;
2501 status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
2502 (XICCEncodingStyle)XTextStyle, &tmp_prop);
2503 if (status == Success)
2504 CS_OF_LOCALE = tmp_prop.encoding;
2506 CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
2507 * characters. But just in case someones
2508 * Xlib is broken, this prevents a core dump.
2511 if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
2513 /* intialize data to send to drop transfer callback */
2514 transfer_rec = (_DtTermDropTransferRec *)
2515 XtMalloc(sizeof(_DtTermDropTransferRec));
2516 clientData->transfer_rec = transfer_rec;
2517 transfer_rec->widget = w;
2518 /* don't actually need all of this for dtterm - it was from Text widget
2519 *transfer_rec->insert_pos = insert_pos;
2520 *transfer_rec->num_chars = 0;
2521 *transfer_rec->timestamp = cb->timeStamp;
2525 if (cb->operation & XmDROP_MOVE) {
2526 transfer_rec->move = True;
2528 transfer_rec->move = False;
2531 transferEntries[0].client_data = (XtPointer) transfer_rec;
2532 transferList = transferEntries;
2535 for (n = 0; n < numExportTargets; n++) {
2536 if (exportTargets[n] == CS_OF_LOCALE) {
2537 transferEntries[0].target = CS_OF_LOCALE;
2538 locale_found = True;
2541 if (exportTargets[n] == COMPOUND_TEXT) c_text_found = True;
2542 if (exportTargets[n] == XA_STRING) string_found = True;
2543 if (exportTargets[n] == TEXT) text_found = True;
2547 if (locale_found || c_text_found || string_found || text_found) {
2548 if (!locale_found) {
2550 transferEntries[0].target = COMPOUND_TEXT;
2551 else if (string_found)
2552 transferEntries[0].target = XA_STRING;
2554 transferEntries[0].target = TEXT;
2557 if ( cb->operation & (XmDROP_COPY|XmDROP_MOVE) ) {
2558 XtSetArg(args[n], XmNdropTransfers, transferList); n++;
2559 XtSetArg(args[n], XmNnumDropTransfers, numTransfers); n++;
2561 XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
2562 XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
2565 XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
2566 XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
2568 dropDestroyCB->closure = (XtPointer) clientData;
2569 XtSetArg(args[n], XmNdestroyCallback, dropDestroyCB); n++;
2570 XtSetArg(args[n], XmNtransferProc, DropTransferCallback); n++;
2573 XmDropTransferStart(drag_cont, args, n);
2583 XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *) call;
2585 if (cb->dropAction != XmDROP_HELP) {
2590 XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
2591 XtSetArg(args[1], XmNnumDropTransfers, 0);
2592 XmDropTransferStart(cb->dragContext, args, 2);
2603 char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
2604 XTextProperty tmp_prop;
2607 tmp_prop.value = NULL;
2608 status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
2609 (XICCEncodingStyle)XTextStyle, &tmp_prop);
2610 if (status == Success)
2611 targets[0] = tmp_prop.encoding;
2613 targets[0] = 99999; /* XmbTextList... should never fail for XPCS
2614 * characters. But just in case someones
2615 * Xlib is broken, this prevents a core dump.
2618 if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
2620 targets[1] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
2621 targets[2] = XA_STRING;
2622 targets[3] = XmInternAtom(XtDisplay(w), "TEXT", False);
2625 XtSetArg(args[n], XmNimportTargets, targets); n++;
2626 XtSetArg(args[n], XmNnumImportTargets, 4); n++;
2627 /* XtSetArg(args[n], XmNdragProc, DragProcCallback); n++; */
2628 XtSetArg(args[n], XmNdropProc, DropProcCallback); n++;
2629 XmDropSiteRegister(w, args, n);
2643 Cardinal *num_params )
2645 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2647 char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
2648 XTextProperty tmp_prop;
2650 Cardinal num_targets = 0;
2655 tmp_prop.value = NULL;
2656 status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
2657 (XICCEncodingStyle)XTextStyle, &tmp_prop);
2658 if (status == Success)
2659 targets[num_targets++] = tmp_prop.encoding;
2661 targets[num_targets++] = 99999; /* XmbTextList... should never fail
2662 * for XPCS characters. But just in
2663 * case someones Xlib is broken,
2664 * this prevents a core dump.
2667 if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
2669 targets[num_targets++] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
2670 targets[num_targets++] = XA_STRING;
2671 targets[num_targets++] = XmInternAtom(XtDisplay(w), "TEXT", False);
2673 drag_icon = (Widget) XmeGetTextualDragIcon(w);
2676 XtSetArg(args[n], XmNcursorBackground, tw->core.background_pixel); n++;
2677 XtSetArg(args[n], XmNcursorForeground, tw->primitive.foreground); n++;
2678 XtSetArg(args[n], XmNsourceCursorIcon, drag_icon); n++;
2679 XtSetArg(args[n], XmNexportTargets, targets); n++;
2680 XtSetArg(args[n], XmNnumExportTargets, num_targets); n++;
2681 XtSetArg(args[n], XmNconvertProc, _DtTermPrimSelectConvert); n++;
2682 XtSetArg(args[n], XmNclientData, w); n++;
2683 XtSetArg(args[n], XmNdragOperations, ( XmDROP_COPY)); n++;
2684 (void) XmDragStart(w, event, args, n);
2688 GetXFromPos(Widget w, XmTextPosition pos)
2690 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2691 DtTermPrimData tpd = tw->term.tpd;
2694 TermCharInfoRec charInfoRec ;
2696 posToBufferRowCol(tw,pos,&pb,&row,&col) ;
2697 return(tpd->offsetX+col*tpd->cellWidth);
2702 _DtTermPrimSelectProcessBDrag(
2706 Cardinal *num_params )
2708 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2709 TermSelectInfo selectInfo =
2710 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
2711 XmTextPosition position, left, right;
2712 Position left_x, left_y, right_x, right_y;
2713 /* InputData data = tw->text.input->data; */
2715 selectInfo->cancel = False;
2716 position = xyToPos(tw, event->xbutton.x, event->xbutton.y);
2718 if (_DtTermPrimSelectGetSelection(w, &left, &right) &&
2720 if ((position > left && position < right)
2721 || (position == left &&
2722 event->xbutton.x > GetXFromPos(w, left))
2723 || (position == right &&
2724 event->xbutton.x < GetXFromPos(w, right))) {
2725 selectInfo->sel_start = False;
2726 StartDrag(w, event, params, num_params);
2730 selectInfo->sel_start = True ;
2733 else selectInfo->sel_start = True ;
2737 /* This is the menu interface for copy clipboard */
2739 _DtTermPrimSelectCopyClipboard
2745 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2746 XmTextPosition begin;
2749 char *selected_string = NULL; /* text selection */
2750 long item_id = 0L; /* clipboard item id */
2751 long data_id = 0L; /* clipboard data id */
2752 int status; /* clipboard status */
2753 XmString clip_label;
2754 XTextProperty tmp_prop;
2755 Display *display = XtDisplay(w);
2756 Window window = XtWindow(w);
2759 if ( _DtTermPrimSelectGetSelection(w, &begin, &end) && begin != end ) {
2760 selected_string = getString(w, begin, end, False);
2763 * Using the Xm clipboard facilities,
2764 * copy the selected text to the clipboard
2766 tmp_prop.value = NULL;
2767 if (selected_string != NULL) {
2768 clip_label = XmStringCreateLocalized ("XM_TERM");
2769 /* start copy to clipboard */
2770 status = XmClipboardStartCopy(display, window, clip_label, copy_time,
2773 if (status != ClipboardSuccess) {
2774 XtFree(selected_string);
2775 XmStringFree(clip_label);
2779 status = XmbTextListToTextProperty(display, &selected_string, 1,
2780 (XICCEncodingStyle)XStdICCTextStyle,
2783 if (status != Success && status <= 0) {
2784 XmClipboardCancelCopy(display, window, item_id);
2785 XtFree(selected_string);
2786 XmStringFree(clip_label);
2790 atom_name = XGetAtomName(display, tmp_prop.encoding);
2792 /* move the data to the clipboard */
2793 status = XmClipboardCopy(display, window, item_id, atom_name,
2794 (XtPointer)tmp_prop.value, tmp_prop.nitems,
2799 if (status != ClipboardSuccess) {
2800 XmClipboardCancelCopy(display, window, item_id);
2801 XFree((char*)tmp_prop.value);
2802 XmStringFree(clip_label);
2806 /* end the copy to the clipboard */
2807 status = XmClipboardEndCopy (display, window, item_id);
2809 XtFree((char*)tmp_prop.value);
2810 XmStringFree(clip_label);
2812 if (status != ClipboardSuccess) return False;
2816 if (selected_string!=NULL)
2817 XtFree(selected_string);
2821 /* This is the event interface for copy clipboard */
2823 _DtTermPrimSelectCopyClipboardEventIF
2828 Cardinal *num_params
2831 _DtTermPrimSelectCopyClipboard(w,event->xkey.time) ;
2835 * Retrieves the current data from the clipboard
2836 * and paste it at the current cursor position
2839 _DtTermPrimSelectPasteClipboard
2844 XmTextPosition sel_left = 0;
2845 XmTextPosition sel_right = 0;
2846 XmTextPosition paste_pos_left, paste_pos_right, cursorPos;
2847 int status; /* clipboard status */
2848 char * buffer; /* temporary text buffer */
2849 unsigned long length; /* length of buffer */
2850 unsigned long outlength = 0L; /* length of bytes copied */
2851 long private_id = 0L; /* id of item on clipboard */
2852 Boolean dest_disjoint = True;
2853 XmTextBlockRec block, newblock;
2854 Display *display = XtDisplay(w);
2855 Window window = XtWindow(w);
2856 Boolean get_ct = False;
2858 XTextProperty tmp_prop;
2859 int malloc_size = 0;
2862 char * total_tmp_value = NULL;
2865 status = XmClipboardInquireLength(display, window, "STRING", &length);
2867 if (status == ClipboardNoData || length == 0) {
2868 status = XmClipboardInquireLength(display, window, "COMPOUND_TEXT",
2870 if (status == ClipboardNoData || length == 0) return False;
2874 /* malloc length of clipboard data */
2875 buffer = XtMalloc((unsigned) length);
2878 status = XmClipboardRetrieve(display, window, "STRING", buffer,
2879 length, &outlength, &private_id);
2881 status = XmClipboardRetrieve(display, window, "COMPOUND_TEXT",
2882 buffer, length, &outlength, &private_id);
2886 if (status != ClipboardSuccess) {
2887 XmClipboardEndRetrieve(display, window);
2892 tmp_prop.value = (unsigned char *) buffer;
2894 tmp_prop.encoding = XA_STRING;
2896 tmp_prop.encoding = XmInternAtom(display, "COMPOUND_TEXT", False);
2898 tmp_prop.format = 8;
2899 tmp_prop.nitems = outlength;
2902 status = XmbTextPropertyToTextList(display, &tmp_prop, &tmp_value,
2905 /* if no conversions, num_vals doesn't change */
2906 if (num_vals && (status == Success || status > 0)) {
2907 for (i = 0; i < num_vals ; i++)
2908 malloc_size += strlen(tmp_value[i]);
2910 total_tmp_value = XtMalloc ((unsigned) malloc_size + 1);
2911 total_tmp_value[0] = '\0';
2912 for (i = 0; i < num_vals ; i++)
2913 strcat(total_tmp_value, tmp_value[i]);
2914 block.ptr = total_tmp_value;
2915 block.length = strlen(total_tmp_value);
2916 block.format = XmFMT_8_BIT;
2917 XFreeStringList(tmp_value);
2919 malloc_size = 1; /* to force space to be freed */
2920 total_tmp_value = XtMalloc ((unsigned)1);
2921 *total_tmp_value = '\0';
2922 block.ptr = total_tmp_value;
2924 block.format = XmFMT_8_BIT;
2930 char *pChar, *pCharEnd, *pCharFollow;
2932 pCharEnd = block.ptr + block.length;
2933 pCharFollow = (char *)block.ptr;
2935 for (pChar = (char *)block.ptr; pChar < pCharEnd; pChar++)
2940 DtTermSubprocSend(w, (unsigned char *) pCharFollow,
2941 pChar - pCharFollow + 1);
2942 pCharFollow = pChar + 1;
2945 if (pCharFollow < pCharEnd)
2947 DtTermSubprocSend(w, (unsigned char *) pCharFollow,
2948 pCharEnd - pCharFollow);
2952 if (malloc_size != 0) XtFree(total_tmp_value);
2954 (void) _DtTermPrimCursorOn(w);
2957 /* This is the event interface for paste clipboard */
2959 _DtTermPrimSelectPasteClipboardEventIF
2964 Cardinal *num_params
2967 _DtTermPrimSelectPasteClipboard(w) ;
2971 * This is for the SUN two button mouse
2981 #define ABS_DELTA(x1, x2) (x1 < x2 ? x2 - x1 : x1 - x2)
2983 if( event->type == MotionNotify) {
2984 XEvent * press = (XEvent *) arg;
2986 if (ABS_DELTA(press->xbutton.x_root, event->xmotion.x_root) > DAMPING ||
2987 ABS_DELTA(press->xbutton.y_root, event->xmotion.y_root) > DAMPING)
2990 else if (event->type == ButtonRelease)
3001 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
3002 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
3003 XmTextPosition position, left, right;
3004 Position left_x, right_x, dummy;
3006 position = xyToPos(tw, event->xbutton.x, event->xbutton.y);
3008 if ((!(_DtTermPrimSelectGetSelection(w, &left, &right) &&
3009 (left != right && (position > left && position < right)))
3010 || (position == left &&
3011 event->xbutton.x > GetXFromPos(w, left))
3012 || (position == right &&
3013 event->xbutton.x < GetXFromPos(w, right)))
3015 /* or if it is part of a multiclick sequence */
3016 (event->xbutton.time > selectInfo->lastTime &&
3017 event->xbutton.time - selectInfo->lastTime <
3018 XtGetMultiClickTime(XtDisplay((Widget)w))) )
3021 /* The determination of whether this is a transfer drag cannot be made
3022 until a Motion event comes in. It is not a drag as soon as a
3023 ButtonUp event happens or the MultiClickTimeout expires. */
3026 XPeekIfEvent(XtDisplay(w), &new, LookForButton, (XPointer)event);
3039 #define SELECTION_ACTION 0
3040 #define TRANSFER_ACTION 1
3044 _DtTermPrimSelect2ButtonMouse(
3048 Cardinal *num_params )
3050 /* This action happens when Button1 is pressed and the Selection
3051 and Transfer are integrated on Button1. It is passed two
3052 parameters: the action to call when the event is a selection,
3053 and the action to call when the event is a transfer. */
3055 if (*num_params != 2 /* || !XmIsTextField(w) */)
3057 if (XmTestInSelection(w, event))
3058 XtCallActionProc(w, params[TRANSFER_ACTION], event, params, *num_params);
3060 XtCallActionProc(w, params[SELECTION_ACTION], event, params, *num_params);
3065 _DtTermPrimSelectProcessCancel(
3069 Cardinal *num_params )
3071 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
3072 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
3073 XmTextPosition left_x, right_x;
3075 XmParentInputActionRec p_event ;
3077 if (!tw->term.allowOsfKeysyms) {
3078 _DtTermPrimActionKeyInput(w,event,params,num_params);
3082 selectInfo->cancel = True ;
3084 /* turn off the cursor */
3085 _DtTermPrimCursorOff(w);
3087 /* reset to origLeft and origRight */
3088 setSelection (tw, selectInfo->origBegin, selectInfo->origEnd,
3089 event->xkey.time, False) ;
3091 /* turn on the cursor */
3092 _DtTermPrimCursorOn(w);
3094 if (selectInfo->selectID) {
3095 XtRemoveTimeOut(selectInfo->selectID);
3096 selectInfo->selectID = 0;