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/ScrollBarP.h>
45 #include "TermPrimDebug.h"
46 #include "TermPrimP.h"
47 #include "TermPrimData.h"
48 #include "TermPrimRender.h"
49 #include "TermPrimSelectP.h"
50 #include "TermPrimBufferP.h"
51 #include <Xm/DropSMgr.h>
52 #include <Xm/DropTrans.h>
59 /* This is for Sun's two button mouse */
61 static char _DtTermEventBindingsCDE[] = "\
62 ~c ~s ~m ~a <Btn1Down>:process-press(grab-focus,process-bdrag)\n\
63 ~c s ~m ~a <Btn1Down>:process-press(extend-start,process-bdrag)\n\
64 ~c ~m ~a <Btn1Motion>:select-adjust()\n\
65 ~c ~m ~a <Btn1Up>:extend-end()";
66 static char _DtTermEventBindingsCDEBtn2[] = "\
67 <Btn2Down>:extend-start()\n\
68 <Btn2Motion>:select-adjust()\n\
69 <Btn2Up>:extend-end()";
72 XmTextScanType defaultScanArray[] =
80 static void RegisterDropSite( Widget w );
81 static void doExtendedSelection (Widget w,Time eventTime);
84 ** Get the current server time (I ripped this off from Xm/TextIn.c).
100 shellMask = XtBuildEventMask(w);
102 if (!(shellMask & PropertyChangeMask))
104 XSelectInput(XtDisplay(w), XtWindow(w), shellMask | PropertyChangeMask);
107 XChangeProperty(XtDisplay(w), XtWindow(w), XA_WM_HINTS, XA_WM_HINTS,
108 32, PropModeAppend, (unsigned char *)NULL, 0);
110 XWindowEvent(XtDisplay(w), XtWindow(w), PropertyChangeMask, &event);
112 if (!(shellMask & PropertyChangeMask))
114 XSelectInput(XtDisplay(w), XtWindow(w), shellMask);
117 return(event.xproperty.time);
128 TermSelectInfo selectInfo =
129 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
133 multiClickTime = XtGetMultiClickTime(XtDisplay(w));
135 if (event->xbutton.time > selectInfo->lastTime &&
136 event->xbutton.time - selectInfo->lastTime <
137 (multiClickTime == 200 ? 500 : multiClickTime))
140 while (i < selectInfo->scanArraySize &&
141 selectInfo->scanArray[i] != selectInfo->scanType)
146 if (++i >= selectInfo->scanArraySize)
150 selectInfo->scanType = selectInfo->scanArray[i];
154 /* single-click event */
155 selectInfo->scanType = selectInfo->scanArray[0];
158 selectInfo->lastTime = event->xbutton.time;
162 ** convert a row,col pair into the equivalent XmTextPosition
165 ** this routine assumes that the calling routine as already checked
166 ** row and col to insure that they are within the bounds of the terminal
167 ** buffer (see _DtTermPrimSelectGrabFocus)
172 DtTermPrimitiveWidget tw,
177 DtTermPrimData tpd = tw->term.tpd;
179 return(((tpd->selectInfo->columns + 1) *
180 (row + tpd->lastUsedHistoryRow)) + col);
187 _DtTermPrimSelectGetSelection
190 XmTextPosition *begin,
194 TermSelectInfo selectInfo =
195 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
197 if (selectInfo->ownPrimary &&
198 (selectInfo->begin <= selectInfo->end) &&
199 selectInfo->begin >= 0)
201 *begin = selectInfo->begin;
202 *end = selectInfo->end;
209 selectInfo->ownPrimary = False;
216 ** convert an x,y pair into the appropriate text position
218 ** Since positions count the number of inter-character spaces, there is
219 ** one more x position on a line than columns on a line; xPos can be in
220 ** the range (0, selectInfo->columns + 1). The same is true for yPos,
221 ** it can be in the range (0, tpd->lastUsedRow - tpd->topRow - 1)
223 ** In the case that we have a history buffer to deal with, text positions
224 ** in the history buffer are forced to come before positions in the term
228 ** this routine assumes that the calling routine as already checked
229 ** x and y to insure that they are within the bounds of the terminal
230 ** window (see _DtTermPrimSelectGrabFocus)
232 ** I believe I'm now doing all checking in this routine for confining
233 ** the x,y to the window. Disregard the previous note. TMH
239 DtTermPrimitiveWidget tw,
244 DtTermPrimData tpd = tw->term.tpd;
245 TermSelectInfo selectInfo = tpd->selectInfo;
250 static short oldYPos = -1;
251 static short oldXPos = -1;
255 if ( x > (int) tw->core.width) x = tw->core.width;
257 ** convert pixel units to character positions
259 yPos = (MAX(0, y) - tpd->offsetY) / tpd->cellHeight;
262 ** yPos cannot exceed the buffer or screen
264 yPos = MIN(yPos, MIN(tw->term.rows, tpd->lastUsedRow - tpd->topRow) - 1) +
268 ** consider the possibility that we have a history buffer
270 if (tpd->useHistoryBuffer)
275 ** yPos is not in the history buffer (order is important,
276 ** step 2 must come before step 3):
277 ** 1) point to history buffer
279 ** 3) decide which row of the buffer we are concerned
282 tb = tpd->historyBuffer;
283 yPos += tpd->lastUsedHistoryRow;
289 ** yPos is not in the history buffer (order is important,
290 ** step 2 must come before step 3):
291 ** 1) point to term buffer
292 ** 2) decide which row of the buffer we are concerned
296 tb = tpd->termBuffer;
298 yPos += tpd->lastUsedHistoryRow;
303 tb = tpd->termBuffer;
307 xPos = (((x - tpd->offsetX) + (tpd->cellWidth / 2)) / tpd->cellWidth) ;
309 if ( MB_CUR_MAX > 1 ) /* check if xPos splits a 2 col char */
311 TermCharInfoRec charInfoRec ;
312 if (_DtTermPrimGetCharacterInfo(tb,row,xPos,&charInfoRec) )
314 if (charInfoRec.width == 2 && charInfoRec.startCol != xPos)
316 if (xPos*tpd->cellWidth < x - tpd->offsetX )
317 xPos++ ; /* set to right of char */
319 xPos-- ; /* set to left of char */
325 if ((yPos != oldYPos) || (xPos != oldXPos))
330 return (((selectInfo->columns + 1) * yPos) + xPos);
334 * Takes a linear position and return buffer, row, and col.
335 * Since positions are between characters, this returns the col to
336 * right of the position.
341 DtTermPrimitiveWidget tw,
348 DtTermPrimData tpd = tw->term.tpd;
349 TermSelectInfo selectInfo = tpd->selectInfo;
352 lrow = pos / (selectInfo->columns + 1);
353 lcol = pos - (lrow * (selectInfo->columns + 1));
355 if ( tpd->useHistoryBuffer ) lrow -= tpd->lastUsedHistoryRow ;
357 if ( lrow < 0 ) { /* in history buffer */
358 *pb=tw->term.tpd->historyBuffer ;
359 lrow += tpd->lastUsedHistoryRow ;
363 *pb = tpd->termBuffer ;
370 * Takes a buffer, row and column and returns the linear position.
372 static XmTextPosition
375 DtTermPrimitiveWidget tw,
381 DtTermPrimData tpd = tw->term.tpd;
382 TermSelectInfo selectInfo = tpd->selectInfo;
386 /* assume row, col in the history buffer or there is no history */
387 pos = (tpd->selectInfo->columns + 1) * row + col;
389 if ( tpd->useHistoryBuffer && pb == tpd->termBuffer)
390 pos += (tpd->selectInfo->columns + 1) * (tpd->lastUsedHistoryRow) ;
395 static XmTextPosition
398 DtTermPrimitiveWidget tw,
399 XmTextPosition scanStart,
400 XmTextScanType scanType,
401 TermScanDirection scanDir,
407 DtTermPrimData tpd = tw->term.tpd;
408 TermSelectInfo selectInfo = tpd->selectInfo;
409 XmTextPosition position = scanStart;
417 case XmSELECT_POSITION:
418 posToBufferRowCol(tw, position, &pb, &row, &col) ;
419 if ( col > _DtTermPrimBufferGetLineWidth(pb, row) )
421 col = selectInfo->columns + 1;
422 position = bufferRowColToPos(tw,pb,row,col) ;
428 posToBufferRowCol(tw, position, &pb, &row, &col) ;
429 width = _DtTermPrimBufferGetLineWidth(pb,row);
430 if ( col > width ) break;
432 if ( MB_CUR_MAX > 1 )
434 TermCharInfoRec charInfoRec ;
436 _DtTermPrimGetCharacterInfo(pb,row,col,&charInfoRec);
437 col = charInfoRec.startCol ; /* align first */
442 _DtTermPrimGetCharacterInfo(pb,row,col?--col:0,&charInfoRec);
443 while( !iswspace(*(wchar_t *)charInfoRec.u.pwc) &&
444 ((col=charInfoRec.startCol-1)>=0) )
446 _DtTermPrimGetCharacterInfo(pb,row,col,&charInfoRec) ;
451 _DtTermPrimGetCharacterInfo(pb,row,col,&charInfoRec);
452 while(++col<=width && !iswspace(*(wchar_t *)charInfoRec.u.pwc))
453 _DtTermPrimGetCharacterInfo(pb,row,col,&charInfoRec);
464 _DtTermPrimBufferGetText(pb, row, col?--col:0, 1, pbuf, False);
465 while( !isspace(*pbuf) && --col >= 0)
466 _DtTermPrimBufferGetText(pb, row, col, 1, pbuf, False );
470 _DtTermPrimBufferGetText(pb, row, col, 1, pbuf, False);
471 while( ++col <= width && !isspace(*pbuf))
472 _DtTermPrimBufferGetText(pb, row, col, 1, pbuf, False );
477 position = bufferRowColToPos(tw,pb,row,col) ;
483 posToBufferRowCol(tw, position, &pb, &row, &col) ;
490 col = selectInfo->columns + 1;
493 position = bufferRowColToPos(tw,pb,row,col) ;
503 pb = tpd->termBuffer ;
504 row = tpd->lastUsedRow-1;
505 col = _DtTermPrimBufferGetLineWidth(pb,row) ;
506 position = bufferRowColToPos(tw,pb,row,col) ;
515 ** refresh all text from start up to stop
518 ** We assume that start is always <= than stop
521 _DtTermPrimRenderRefreshTextLinear
524 XmTextPosition start,
528 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
529 DtTermPrimData tpd = tw->term.tpd;
530 TermSelectInfo selectInfo = tpd->selectInfo;
531 short startRow, startCol;
532 short stopRow , stopCol;
536 ** Turn XmTextPosition into a row and column
538 startRow = start / (selectInfo->columns + 1);
539 startCol = start - (startRow * (selectInfo->columns + 1));
540 stopRow = stop / (selectInfo->columns + 1);
541 stopCol = stop - (stopRow * (selectInfo->columns + 1));
544 ** Accomodate the history buffer as necessary
546 if (tpd->useHistoryBuffer)
548 startRow -= tpd->lastUsedHistoryRow;
549 stopRow -= tpd->lastUsedHistoryRow;
553 ** Now adjust for the top of the window
555 startRow -= tpd->topRow;
556 stopRow -= tpd->topRow;
560 ** refresh the first (and possibly only) line
562 if (startRow == stopRow)
564 _DtTermPrimRefreshText((Widget)tw, startCol, startRow,
568 _DtTermPrimRefreshText((Widget)tw, startCol, startRow,
569 selectInfo->columns - 1, startRow);
572 ** refresh the middle block (if there is one)
574 if (startRow++ < stopRow)
576 _DtTermPrimRefreshText((Widget)tw, 0, startRow,
577 selectInfo->columns - 1, stopRow - 1);
581 ** refresh the last line
583 _DtTermPrimRefreshText((Widget)tw, 0, stopRow, stopCol, stopRow);
591 DtTermPrimitiveWidget tw,
592 XmTextPosition begin,
595 Boolean fromLoseSelection
598 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
599 XmTextPosition oldBegin, oldEnd;
600 Boolean disJoint; /* true if new and current are disjoint */
601 short selectLineBegin;
602 short selectColBegin;
606 Debug('c', fprintf(stderr, ">>setSelection() starting\n"));
608 if (selectInfo->ownPrimary == False &&
611 Debug('c', fprintf(stderr, ">>setSelection() finishing a\n"));
621 if (selectInfo->ownPrimary)
624 ** we own the selection see how much (if any) of the selected
625 ** area needs to be unhighlighted...
627 if (selectInfo->begin < selectInfo->end)
630 ** We own the selection, and its highlighted...
632 if ((end <= selectInfo->begin) ||
633 (begin >= selectInfo->end))
636 ** The two areas don't intersect, simply clear the old
639 Debug('c', fprintf(stderr, " new & old are disjoint\n"));
640 selectInfo->ownPrimary = False;
641 _DtTermPrimRenderRefreshTextLinear((Widget)tw,
643 selectInfo->end - 1);
644 selectInfo->ownPrimary = True;
650 ** There is some intersection, save the current begin
651 ** and end so we can clean things up later.
653 Debug('c', fprintf(stderr, " new & old intersect\n"));
654 oldBegin = selectInfo->begin;
655 oldEnd = selectInfo->end;
662 ** We own the selection, but nothing is highlighted...
670 ** we don't own the selection (yet), come up with some reasonable
679 selectInfo->begin = begin;
680 selectInfo->end = end;
684 if (selectInfo->ownPrimary == False)
686 if (!XtOwnSelection((Widget)tw, XA_PRIMARY, selectTime,
687 _DtTermPrimSelectConvert,
688 _DtTermPrimSelectLoseSelection,
689 (XtSelectionDoneProc) NULL))
692 ** XtOwnSelection failed, make a dummy call to setSelection
693 ** (with begin > end) to clear things up...
695 setSelection(tw, 1, -99, selectTime, False);
699 selectInfo->ownPrimary = True;
700 selectInfo->primaryTime = selectTime;
705 ** now highlight the currently selected text...
707 if (selectInfo->ownPrimary)
709 if (disJoint == True)
712 ** the selections are disjoint, simply draw the new one
714 _DtTermPrimRenderRefreshTextLinear((Widget)tw, begin, end - 1);
718 if (begin != oldBegin)
720 if (begin < oldBegin)
723 ** refresh from the new beginning to the old
726 _DtTermPrimRenderRefreshTextLinear((Widget)tw, begin,
729 else if (oldBegin < begin)
732 ** refresh from the old beginning to the new
735 ** NOTE: in this case we want to unhighlight
736 ** previously selected text, so we
737 ** temporarily set ownPrimary to false
739 selectInfo->ownPrimary = False;
740 _DtTermPrimRenderRefreshTextLinear((Widget)tw, oldBegin,
742 selectInfo->ownPrimary = True;
750 ** refresh from the new end to the original end
752 ** NOTE: in this case we want to unhighlight
753 ** previously selected text, so we
754 ** temporarily set ownPrimary to false
756 selectInfo->ownPrimary = False;
757 _DtTermPrimRenderRefreshTextLinear((Widget)tw, end,
759 selectInfo->ownPrimary = True;
761 else if (oldEnd < end)
764 ** refresh from the old end to the new end.
766 _DtTermPrimRenderRefreshTextLinear((Widget)tw, oldEnd,
775 if (!fromLoseSelection)
777 XtDisownSelection((Widget)tw, XA_PRIMARY, selectTime);
779 selectInfo->ownPrimary = False;
782 selectLineBegin = selectInfo->begin / (selectInfo->columns + 1);
783 selectColBegin = selectInfo->begin % (selectInfo->columns + 1);
784 selectLineEnd = (selectInfo->end - 1) / (selectInfo->columns + 1);
785 selectColEnd = (selectInfo->end - 1) % (selectInfo->columns + 1);
788 fprintf(stderr, "set selection units: %d-%d lines: %d-%d\n",
789 selectInfo->begin, selectInfo->end,
792 if (tw->term.tpd->useHistoryBuffer && tw->term.tpd->lastUsedHistoryRow>0) {
793 if (selectLineEnd > tw->term.tpd->lastUsedHistoryRow) {
794 (void) _DtTermPrimBufferSetSelectLines(tw->term.tpd->historyBuffer,
795 selectLineBegin, selectColBegin,
796 tw->term.tpd->lastUsedHistoryRow - 1, selectInfo->columns);
798 (void) _DtTermPrimBufferSetSelectLines(tw->term.tpd->historyBuffer,
799 selectLineBegin, selectColBegin,
800 selectLineEnd, selectColEnd);
802 selectLineBegin -= tw->term.tpd->lastUsedHistoryRow;
803 if (selectLineBegin < 0) {
807 selectLineEnd -= tw->term.tpd->lastUsedHistoryRow;
810 if (selectLineEnd > tw->term.tpd->lastUsedRow) {
811 (void) _DtTermPrimBufferSetSelectLines(tw->term.tpd->termBuffer,
812 selectLineBegin, selectColBegin,
813 tw->term.tpd->lastUsedRow, selectInfo->columns);
815 (void) _DtTermPrimBufferSetSelectLines(tw->term.tpd->termBuffer,
816 selectLineBegin, selectColBegin,
817 selectLineEnd, selectColEnd);
819 Debug('c', fprintf(stderr, ">>setSelection() finishing b\n"));
826 DtTermPrimitiveWidget tw,
832 XmTextPosition position;
833 XmTextPosition newBegin;
834 XmTextPosition newEnd;
835 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
837 Debug('c', fprintf(stderr, ">>handleSelection() starting\n"));
839 position = xyToPos(tw, x, y);
840 newBegin = scan(tw, position, selectInfo->scanType, scanLeft,
842 newEnd = scan(tw, position, selectInfo->scanType, scanRight,
843 1, selectInfo->scanType == XmSELECT_LINE);
845 setSelection(tw, newBegin, newEnd, selectTime, False);
847 if ((position - newBegin) <
850 selectInfo->extendDir = scanLeft;
854 selectInfo->extendDir = scanRight;
856 selectInfo->origBegin = newBegin;
857 selectInfo->origEnd = newEnd;
861 /************************************************************************
863 * browseScroll - timer proc that scrolls the list if the user has left *
864 * the window with the button down. If the button has been *
865 * released, call the standard click stuff. *
867 ************************************************************************/
876 Widget w = (Widget) closure;
877 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
878 DtTermPrimData tpd = tw->term.tpd;
879 TermSelectInfo selectInfo = tpd->selectInfo ;
880 XmScrollBarWidget vsb = (XmScrollBarWidget) tw->term.verticalScrollBar;
881 unsigned long interval;
883 if (selectInfo->cancel) {
884 selectInfo->selectID = 0;
888 if (!selectInfo->selectID) return;
890 _DtTermPrimScrollComplete(w, True);
891 if ( selectInfo->isScrollUp ) {
892 if ( tpd->lastUsedRow-1 >= tpd->topRow + tw->term.rows)
893 _DtTermPrimScrollText(w, 1);
896 _DtTermPrimScrollText(w, -1);
897 _DtTermPrimScrollComplete(w, True);
898 if (selectInfo->extending)
899 doExtendedSelection(w, XtLastTimestampProcessed(XtDisplay(w)));
902 interval = (unsigned long) vsb->scrollBar.repeat_delay;
906 XSync (XtDisplay(w), False);
908 selectInfo->selectID = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
909 interval, browseScroll, (XtPointer) w);
920 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
921 DtTermPrimData tpd = tw->term.tpd;
922 TermSelectInfo selectInfo = tpd->selectInfo;
923 XmScrollBarWidget vsb = (XmScrollBarWidget) tw->term.verticalScrollBar;
924 unsigned long interval;
926 selectInfo->extend.x = event->xmotion.x;
927 selectInfo->extend.y = event->xmotion.y;
929 if ( (event->xmotion.y > (int) tpd->offsetY) &&
930 (event->xmotion.y < (int) (tpd->offsetY + tw->term.rows *
933 if (selectInfo->selectID) {
934 XtRemoveTimeOut(selectInfo->selectID);
935 selectInfo->selectID = 0;
939 if (event->xmotion.y <= (int) tpd->offsetY) {
940 selectInfo->extend.x = 0;
941 selectInfo->extend.y = (int) (tpd->offsetY);
942 selectInfo->isScrollUp = False ;
945 } else if (event->xmotion.y >= (int) (tpd->offsetY + tw->term.rows *
947 selectInfo->extend.x = tw->core.width;
948 selectInfo->extend.y = (int) (tpd->offsetY + tw->term.rows *
950 selectInfo->isScrollUp = True ;
954 interval = (unsigned long) vsb->scrollBar.initial_delay;
958 if (!selectInfo->selectID)
959 selectInfo->selectID = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
960 interval, browseScroll, (XtPointer) w);
967 ** Create and initialize the selection specific information
970 _DtTermPrimSelectCreate
975 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
976 DtTermPrimData tpd = tw->term.tpd;
977 TermSelectInfo selectInfo;
980 selectInfo = (TermSelectInfo)XtMalloc(sizeof(TermSelectInfoRec));
982 selectInfo->begin = 0;
984 selectInfo->columns = tw->term.columns;
985 selectInfo->rows = tpd->bufferRows + tpd->historyBufferRows;
986 selectInfo->direction = (TermScanDirection) XmTEXT_FORWARD;
987 selectInfo->extend.x = 0;
988 selectInfo->extend.y = 0;
989 selectInfo->extending = False;
990 selectInfo->hint.x = 0;
991 selectInfo->hint.y = 0;
992 selectInfo->lastTime = 0;
993 selectInfo->origBegin = 0;
994 selectInfo->origEnd = 0;
995 selectInfo->ownPrimary = False;
996 selectInfo->threshold = 5;
997 selectInfo->selectID = 0;
998 selectInfo->selectType = TermSelect_NORMAL;
999 selectInfo->scanType = defaultScanArray[0];
1000 selectInfo->scanArraySize = XtNumber(defaultScanArray);
1001 selectInfo->scanArray = (XmTextScanType *)
1002 XtMalloc(selectInfo->scanArraySize *
1003 sizeof(XmTextScanType));
1004 selectInfo->cancel = True; /* used by scroll selection */
1005 selectInfo->anchor = -1; /* in case extend happens before set*/
1006 selectInfo->sel_start = False;
1007 for (i = 0; i < selectInfo->scanArraySize; i++)
1009 selectInfo->scanArray[i] = defaultScanArray[i];
1012 RegisterDropSite(w);
1017 _DtTermPrimSelectInitBtnEvents(Widget w)
1019 Boolean btn1_transfer = False;
1020 XtVaGetValues((Widget)XmGetXmDisplay(XtDisplay(w)), "enableBtn1Transfer",
1021 &btn1_transfer, NULL);
1023 XtOverrideTranslations(w,
1024 XtParseTranslationTable(_DtTermEventBindingsCDE));
1025 if (btn1_transfer == True) /* for btn2 extend case */
1026 XtOverrideTranslations(w,
1027 XtParseTranslationTable(_DtTermEventBindingsCDEBtn2));
1031 _DtTermPrimSelectDisown
1036 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1037 DtTermPrimData tpd = tw->term.tpd;
1038 TermSelectInfo selectInfo = tpd->selectInfo;
1040 if (selectInfo->ownPrimary == True)
1042 XtDisownSelection(w, XA_PRIMARY, getServerTime(w));
1043 selectInfo->ownPrimary = False ;
1048 _DtTermPrimSelectDestroy
1051 TermSelectInfo selectInfo
1054 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1055 DtTermPrimData tpd = tw->term.tpd;
1057 if (selectInfo->ownPrimary == True)
1059 XtDisownSelection(w, XA_PRIMARY, getServerTime(w));
1061 selectInfo->ownPrimary = False ;
1062 XtFree((char *) selectInfo->scanArray);
1063 XtFree((char *) selectInfo);
1064 tpd->selectInfo = NULL ;
1069 ** determine how much (if any) of the text is selected
1072 ** beginCol + width will never exceed the width of the terminal
1076 _DtTermPrimSelectIsInSelection
1085 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1086 DtTermPrimData tpd = tw->term.tpd;
1087 TermSelectInfo selectInfo = tpd->selectInfo;
1088 Boolean inSelection = True;
1089 XmTextPosition endPosition;
1090 XmTextPosition position;
1091 XmTextPosition begin;
1093 short beginRow, beginCol;
1094 short endRow , endCol;
1096 position = rowColToPos(tw, row, startCol);
1097 endPosition = position + width;
1099 begin = selectInfo->begin;
1100 end = selectInfo->end;
1102 if ((begin >= endPosition) || (end <= position))
1105 ** outside of selection range...
1107 inSelection = False;
1112 ** we're in the selection range, clip endPosition as necessary...
1114 if (position < begin)
1117 ** we start to the left of the selection...
1119 inSelection = False;
1120 endPosition = MIN(endPosition, begin);
1126 ** we must be in the selection, clip endPosition as
1129 endPosition = MIN(endPosition, end);
1134 *selWidth = endPosition - position;
1135 return(inSelection);
1140 _DtTermPrimSelectDoSelection
1145 Cardinal *paramCount
1148 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
1150 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectDoSelection() starting\n"));
1152 handleSelection(tw, event->xbutton.x, event->xbutton.y,
1153 event->xbutton.time);
1158 _DtTermPrimSelectSetHint
1163 Cardinal *paramCount
1166 TermSelectInfo selectInfo =
1167 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
1169 selectInfo->hint.x = event->xbutton.x;
1170 selectInfo->hint.y = event->xbutton.y;
1175 _DtTermPrimSelectStart
1180 Cardinal *paramCount
1183 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1184 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1185 XButtonEvent *btnEvent = (XButtonEvent *) event;
1186 XmTextPosition begin;
1189 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectStart() starting\n"));
1192 ** set the selection hints, and scan type
1194 _DtTermPrimSelectSetHint(w, event, params, paramCount);
1195 setScanType(w, event);
1198 ** Set the current anchor point
1200 selectInfo->anchor = xyToPos(tw, btnEvent->x, btnEvent->y);
1202 if (selectInfo->scanType != XmSELECT_POSITION ||
1203 _DtTermPrimSelectGetSelection(w, &begin, &end) && begin != end
1206 _DtTermPrimSelectDoSelection(w, event, params, paramCount);
1212 _DtTermPrimSelectGrabFocus
1217 Cardinal *paramCount
1220 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1221 DtTermPrimData tpd = tw->term.tpd;
1222 TermSelectInfo selectInfo = tpd->selectInfo;
1223 XButtonEvent *btnEvent = (XButtonEvent *) event;
1225 /* setDebugFlags("c") ; */
1226 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectGrabFocus() starting\n"));
1228 /* turn off the cursor */
1229 _DtTermPrimCursorOff(w);
1231 selectInfo->cancel = False;
1232 tw->term.allowOsfKeysyms = True; /* normal dtterm doesn't honor these*/
1234 ** constrain the button event to the terminal's text area
1236 if (btnEvent->x <= (int) tpd->offsetX)
1239 btnEvent->x = (int)(tpd->offsetX + 1);
1240 } else if (btnEvent->x >= (int)(tw->core.width - tpd->offsetX))
1243 btnEvent->x = (int)(tw->core.width - tpd->offsetX - 1);
1246 if (btnEvent->y <= (int)tpd->offsetY)
1249 btnEvent->y = (int)(tpd->offsetY + 1);
1251 else if (btnEvent->y - ((int)(tpd->offsetY +
1252 ((tpd->lastUsedRow - tpd->topRow) *
1253 tpd->cellHeight))) >= selectInfo->threshold)
1256 btnEvent->y = (int)(tpd->offsetY + ((tpd->lastUsedRow - tpd->topRow) *
1257 tpd->cellHeight) - 1);
1260 if (_XmGetFocusPolicy(w) == XmEXPLICIT)
1261 (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
1263 _DtTermPrimSelectStart(w, event, params, paramCount);
1271 TermSelectionHint hint,
1276 return ((abs(hint.x - event->xbutton.x) > threshold) ||
1277 (abs(hint.y - event->xbutton.y) > threshold));
1288 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
1289 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1290 XmTextPosition position;
1291 XmTextPosition begin;
1293 XmTextPosition cursorPos;
1296 if (selectInfo->cancel) {
1297 if (selectInfo->selectID) XtRemoveTimeOut(selectInfo->selectID);
1298 selectInfo->selectID = 0;
1302 position = xyToPos(tw, selectInfo->extend.x, selectInfo->extend.y);
1304 if (!(_DtTermPrimSelectGetSelection(w, &begin, &end)) ||
1309 if ( selectInfo->anchor <0) selectInfo->anchor = position;
1310 selectInfo->origBegin = selectInfo->anchor;
1311 selectInfo->origEnd = selectInfo->anchor;
1312 midPoint = (float)selectInfo->anchor;
1317 (((float)(selectInfo->origEnd -
1318 selectInfo->origBegin) / 2.0) +
1319 (float)selectInfo->origBegin);
1323 ** shift anchor and direction to opposite end of the selection
1325 if ((float)(position) <= midPoint)
1327 selectInfo->anchor = selectInfo->origEnd;
1328 if (!selectInfo->extending)
1330 selectInfo->extendDir = scanLeft;
1333 else if ((float)(position) > midPoint)
1335 selectInfo->anchor = selectInfo->origBegin;
1336 if (!selectInfo->extending)
1338 selectInfo->extendDir = scanRight;
1342 selectInfo->extending = TRUE;
1345 ** check for change in extend direction
1347 if ((selectInfo->extendDir == scanRight &&
1348 position < selectInfo->anchor) ||
1349 (selectInfo->extendDir == scanLeft &&
1350 position > selectInfo->anchor))
1352 selectInfo->extendDir = (selectInfo->extendDir == scanRight) ?
1353 scanLeft : scanRight;
1355 begin = selectInfo->begin;
1356 end = selectInfo->end;
1360 if (selectInfo->extendDir == scanRight)
1362 cursorPos = scan(tw, position, selectInfo->scanType, scanRight, 1,
1363 selectInfo->scanType == XmSELECT_LINE);
1365 begin = selectInfo->anchor;
1369 cursorPos = scan(tw, position, selectInfo->scanType, scanLeft, 1,
1372 end = selectInfo->anchor;
1373 if (selectInfo->scanType == XmSELECT_WORD &&
1374 (int)tw->term.tpd->cellWidth > 1)
1376 if (position == scan (tw, begin, selectInfo->scanType, scanRight, 1,
1379 begin = cursorPos = position;
1384 setSelection(tw, begin, end, eventTime, False);
1388 _DtTermPrimSelectExtendStart(
1392 Cardinal *num_params )
1394 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1395 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1397 selectInfo->cancel = False;
1398 tw->term.allowOsfKeysyms = True ;
1400 _DtTermPrimSelectExtend(w, event, params, num_params);
1405 _DtTermPrimSelectExtend
1410 Cardinal *paramCount
1413 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1414 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1416 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectExtend() starting\n"));
1418 /* turn off the cursor */
1419 _DtTermPrimCursorOff(w);
1421 if (_XmGetFocusPolicy(w) == XmEXPLICIT)
1422 (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
1424 if (selectInfo->cancel) return ;
1426 if ((selectInfo->hint.x > 0) || (selectInfo->hint.y > 0))
1428 if (dragged(selectInfo->hint, event, selectInfo->threshold))
1431 ** extend the selection
1433 handleSelection(tw,selectInfo->hint.x,selectInfo->hint.y,
1434 event->xbutton.time);
1435 selectInfo->hint.x = 0;
1436 selectInfo->hint.y = 0;
1437 selectInfo->extending = True;
1448 ** check for timer scrolling here
1449 ** NOTE: CheckTimerScrolling(w,event) will set extend.[x|y]
1450 * selectInfo->extend.x = event->xbutton.x;
1451 * selectInfo->extend.y = event->xbutton.y;
1453 if (!CheckTimerScrolling(w,event) )
1454 doExtendedSelection(w, event->xbutton.time);
1459 _DtTermPrimSelectExtendEnd
1464 Cardinal *paramCount
1467 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1468 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
1470 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectExtendEnd() starting\n"));
1472 selectInfo->cancel = True; /* used by scroll selection */
1473 tw->term.allowOsfKeysyms = False;
1475 if (selectInfo->extending)
1477 _DtTermPrimSelectGetSelection(w, &selectInfo->origBegin,
1478 &selectInfo->origEnd);
1479 setSelection(tw, selectInfo->origBegin, selectInfo->origEnd,
1480 event->xbutton.time, False);
1481 /* _DtTermPrimSelectExtend(w, event, params, paramCount);*/
1484 if (selectInfo->selectID > 0)
1486 XtRemoveTimeOut(selectInfo->selectID);
1487 selectInfo->selectID = 0;
1490 selectInfo->extend.x = 0;
1491 selectInfo->extend.y = 0;
1492 selectInfo->extending = False;
1493 selectInfo->hint.x = 0;
1494 selectInfo->hint.y = 0;
1496 /* turn off the cursor */
1497 _DtTermPrimCursorOn(w);
1509 unsigned long *length,
1513 _TermSelectPrimaryRec *primSelect = (_TermSelectPrimaryRec *) closure;
1514 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
1515 DtTermPrimData tpd = tw->term.tpd;
1516 TermSelectInfo selectInfo = tpd->selectInfo;
1517 XTextProperty tmpProp;
1518 XmTextBlockRec block;
1523 int malloc_size=0 , numVals ;
1524 char *total_tmp_value ;
1527 Debug('c', fprintf(stderr, ">>doHandleTargets() starting\n"));
1529 if (_XmGetFocusPolicy(w) == XmEXPLICIT)
1531 (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
1534 if (*type == XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False) ||
1538 tmpProp.value = (unsigned char *) value;
1539 tmpProp.encoding = *type;
1540 tmpProp.format = *format;
1541 tmpProp.nitems = *length;
1543 status = XmbTextPropertyToTextList(XtDisplay(w), &tmpProp,
1544 &tmp_value, &numVals );
1547 ** if no conversions, numVals doesn't change
1549 if (numVals && (status == Success || status > 0))
1551 for (i = 0; i < numVals ; i++)
1553 malloc_size += strlen(tmp_value[i]);
1555 total_tmp_value = XtMalloc ((unsigned) malloc_size + 1);
1556 total_tmp_value[0] = '\0';
1557 for (i = 0; i < numVals ; i++)
1559 strcat(total_tmp_value, tmp_value[i]);
1561 block.ptr = total_tmp_value;
1562 block.length = strlen(total_tmp_value);
1563 block.format = XmFMT_8_BIT;
1564 XFreeStringList(tmp_value);
1568 malloc_size = 1; /* to force space to be freed */
1569 total_tmp_value = XtMalloc ((unsigned)1);
1570 *total_tmp_value = '\0';
1571 block.ptr = total_tmp_value;
1573 block.format = XmFMT_8_BIT;
1577 block.ptr = (char*)value;
1578 block.length = (int) *length; /* NOTE: this causes a truncation on
1579 some architectures */
1580 block.format = XmFMT_8_BIT;
1583 pCharEnd = block.ptr + block.length;
1584 pCharFollow = (char *)block.ptr;
1586 for (pChar = (char *)block.ptr; pChar < pCharEnd; pChar++)
1591 DtTermSubprocSend(w, (unsigned char *) pCharFollow,
1592 pChar - pCharFollow + 1);
1593 pCharFollow = pChar + 1;
1596 if (pCharFollow < pCharEnd)
1598 DtTermSubprocSend(w, (unsigned char *) pCharFollow,
1599 pCharEnd - pCharFollow);
1602 if (malloc_size != 0) XtFree(total_tmp_value);
1603 XtFree((char *)value);
1604 if (primSelect && (--primSelect->ref_count == 0))
1606 XtFree((char *)primSelect);
1612 ** Look at the target list and determine what target to place in the
1613 ** pair. it will then do any necessary conversions before "thrusting"
1614 ** the selection value onto the receiver. this will guarantee the
1615 ** best chance at a successful exchange.
1626 unsigned long *length,
1632 Boolean supportsLocaleData;
1633 Boolean supportsCompoundText;
1635 _TermSelectRec *tmpAction;
1636 _TermSelectPrimaryRec *primSelect;
1638 XTextProperty tmpProp;
1640 XtPointer closures[2];
1645 ** make sure we have something to do...
1647 tmpAction = (_TermSelectRec *) closure;
1648 if (!length || *length == 0) {
1649 XtFree((char *)value);
1651 XtFree((char *)tmpAction->event);
1652 XtFree((char *)tmpAction);
1656 COMPOUND_TEXT = XmInternAtom(XtDisplay(w),"COMPOUND_TEXT", False);
1657 supportsLocaleData = False;
1658 supportsCompoundText = False;
1659 abcString = "ABC"; /* characters in XPCS, so... safe */
1660 atomPtr = (Atom *)value;
1662 tmpProp.value = NULL;
1663 status = XmbTextListToTextProperty(XtDisplay(w), &abcString, 1,
1664 (XICCEncodingStyle)XTextStyle, &tmpProp);
1665 if (status == Success)
1667 CS_OF_LOCALE = tmpProp.encoding;
1672 ** Kludge for failure of XmbText... to
1673 ** handle XPCS characters. Should never
1674 ** happen, but this prevents a core dump
1675 ** if X11 is broken.
1677 CS_OF_LOCALE = (Atom)9999;
1679 if (tmpProp.value != NULL)
1681 XFree((char *)tmpProp.value);
1684 for (i = 0; i < *length; i++, atomPtr++)
1686 if (*atomPtr == CS_OF_LOCALE)
1688 supportsLocaleData = True;
1691 if (*atomPtr == COMPOUND_TEXT)
1693 supportsCompoundText = True;
1696 primSelect = (_TermSelectPrimaryRec *)
1697 XtMalloc((unsigned) sizeof(_TermSelectPrimaryRec));
1700 ** If owner and I are using the same codeset, ask for it. If not,
1701 ** and if the owner supports compound text, ask for compound text.
1702 ** If not, fall back position is to ask for STRING and try to
1703 ** convert it locally.
1705 if (supportsLocaleData)
1707 primSelect->target = targets[0] = CS_OF_LOCALE;
1709 else if (supportsCompoundText)
1711 primSelect->target = targets[0] = COMPOUND_TEXT;
1715 primSelect->target = targets[0] = XA_STRING;
1717 closures[0] = (char *)primSelect;
1719 primSelect->ref_count = 1;
1721 ** Make request to call doHandleTargets() with the primary selection.
1723 XtGetSelectionValue(w, XA_PRIMARY, targets[0], doHandleTargets,
1724 (XtPointer)primSelect,
1725 tmpAction->event->xbutton.time);
1727 XtFree((char *)value);
1729 XtFree((char *)tmpAction->event);
1730 XtFree((char *)tmpAction);
1737 XmTextPosition begin,
1739 Boolean needWideChar
1742 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
1743 DtTermPrimData tpd = tw->term.tpd;
1744 TermSelectInfo selectInfo = tpd->selectInfo;
1756 beginRow = begin / (selectInfo->columns + 1);
1757 beginCol = begin - (beginRow * (selectInfo->columns + 1));
1758 endRow = end / (selectInfo->columns + 1);
1759 endCol = end - (endRow * (selectInfo->columns + 1));
1760 numRows = endRow - beginRow + 1;
1763 ** we need to store end - begin characters, a terminating byte, plus
1764 ** a new line for each line...
1766 ** NOTE: end - begin could result in a truncated long.
1768 buffer = XtMalloc(((int)(end - begin) + 1 + numRows) * sizeof(char)
1769 * BYTES_PER_CHAR(tpd->termBuffer));
1772 ** return a null string if there is nothing to do
1781 ** Accomodate the history buffer as necessary
1783 if (tpd->useHistoryBuffer)
1785 beginRow -= tpd->lastUsedHistoryRow;
1786 endRow -= tpd->lastUsedHistoryRow;
1790 ** get the first (and possibly only) line of text
1793 if (beginRow == endRow)
1797 tb = tpd->historyBuffer;
1798 thisRow = beginRow + tpd->lastUsedHistoryRow;
1802 tb = tpd->termBuffer;
1805 len = _DtTermPrimBufferGetText(tb, thisRow, beginCol,
1806 endCol - beginCol, pBuf, needWideChar);
1813 tb = tpd->historyBuffer;
1814 thisRow = beginRow + tpd->lastUsedHistoryRow;
1818 tb = tpd->termBuffer;
1821 len = _DtTermPrimBufferGetText(tb, thisRow, beginCol,
1822 selectInfo->columns - beginCol, pBuf,
1826 if ( !_DtTermPrimBufferTestLineWrapFlag(tb,thisRow) ) {
1827 *pBuf = '\n'; /* newline */
1832 ** get the middle block (if there is one)
1835 while(beginRow < endRow)
1839 tb = tpd->historyBuffer;
1840 thisRow = beginRow + tpd->lastUsedHistoryRow;
1844 tb = tpd->termBuffer;
1847 len = _DtTermPrimBufferGetText(tb, thisRow, 0,
1848 selectInfo->columns , pBuf,
1852 /* if (len != 0 && len < selectInfo->columns ) { */
1853 if ( !_DtTermPrimBufferTestLineWrapFlag(tb,thisRow) ) {
1854 *pBuf = '\n'; /* newline */
1861 ** get the last line
1865 tb = tpd->historyBuffer;
1866 thisRow = endRow + tpd->lastUsedHistoryRow;
1870 tb = tpd->termBuffer;
1873 len = _DtTermPrimBufferGetText(tb, thisRow, 0, endCol, pBuf,
1883 ** Request targets from selection owner.
1891 Cardinal *paramCount
1894 _TermSelectRec *tmp;
1896 tmp = (_TermSelectRec*)XtMalloc(sizeof(_TermSelectRec));
1899 ** Request targets from the selection owner so you can decide what to
1900 ** request. The decision process and request for the selection is
1901 ** taken care of in handleTargets().
1904 tmp->event = (XEvent *) XtMalloc(sizeof(XEvent));
1905 memcpy((void *)tmp->event, (void *)event, sizeof(XEvent));
1907 tmp->params = params;
1908 tmp->num_params = paramCount;
1910 XtGetSelectionValue(w, XA_PRIMARY,
1911 XmInternAtom(XtDisplay(w), "TARGETS", False),
1912 handleTargets, (XtPointer)tmp, event->xbutton.time);
1916 _DtTermPrimSelectConvert
1923 unsigned long *length,
1927 Atom TARGETS = XmInternAtom(XtDisplay(w), "TARGETS", False);
1929 Atom COMPOUND_TEXT = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
1930 Atom TEXT = XmInternAtom(XtDisplay(w), "TEXT", False);
1931 Atom MOTIF_DROP = XmInternAtom(XtDisplay(w), "_MOTIF_DROP", False);
1932 int maxTargets = 10;
1937 XmTextPosition begin;
1940 char *tmpString = "ABC"; /* characters in XPCS, so... safe */
1941 XTextProperty tmpProp;
1944 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectConvert() starting\n"));
1946 if (*selection == MOTIF_DROP) {
1947 XtSetArg(args[0], XmNclientData, &c_ptr);
1948 XtGetValues(w, args, 1);
1949 widget = (Widget)c_ptr;
1953 if (widget == NULL) return False;
1955 tmpProp.value = NULL;
1956 status = XmbTextListToTextProperty(XtDisplay(widget), &tmpString, 1,
1957 (XICCEncodingStyle)XTextStyle, &tmpProp);
1958 if (status == Success)
1960 CS_OF_LOCALE = tmpProp.encoding;
1965 ** XmbTextList... SHOULD never fail for
1966 ** XPCS character. But if it does, this
1967 ** prevents a core dump.
1969 CS_OF_LOCALE = (Atom) 9999;
1972 if (tmpProp.value != NULL)
1973 XFree((char *) tmpProp.value);
1976 if (*selection == XA_PRIMARY || *selection == MOTIF_DROP)
1978 ownPrimary = _DtTermPrimSelectGetSelection(widget, &begin, &end);
1985 if (*target == TARGETS)
1987 Atom *targets = (Atom *)XtMalloc((unsigned)(maxTargets * sizeof(Atom)));
1990 ** Xt should take care of TIME_STAMP for us.
1993 *value = (XtPointer)targets;
1994 *targets++ = TARGETS; targetCount++;
1995 if (!isDebugFSet('s', 1)) {
1996 *targets++ = COMPOUND_TEXT; targetCount++;
1998 if (!isDebugFSet('s', 2)) {
1999 *targets++ = CS_OF_LOCALE; targetCount++;
2001 if (!isDebugFSet('s', 3)) {
2002 *targets++ = TEXT; targetCount++;
2004 if (!isDebugFSet('s', 4)) {
2005 *targets++ = XA_STRING; targetCount++;
2008 *length = (targetCount * sizeof(Atom)) >> 2; /* convert to work count */
2011 else if (!ownPrimary)
2015 else if ((*target == XA_STRING && !isDebugFSet('s', 4)) ||
2016 (*target == COMPOUND_TEXT && !isDebugFSet('s', 1)))
2018 tmpValue = getString(widget, begin, end, False);
2019 tmpProp.value = NULL;
2020 if ((*target == XA_STRING) && !isDebugFSet('s', 4)) {
2021 *type = (Atom) XA_STRING;
2023 status = XmbTextListToTextProperty(XtDisplay(widget), &tmpValue, 1,
2024 (XICCEncodingStyle)XStringStyle,
2027 else if ((*target == COMPOUND_TEXT) && !isDebugFSet('s',1)) {
2028 *type = COMPOUND_TEXT;
2030 status = XmbTextListToTextProperty(XtDisplay(widget), &tmpValue, 1,
2031 (XICCEncodingStyle)XCompoundTextStyle,
2035 if (status == Success || status > 0)
2038 ** NOTE: casting tmpProp.nitems could result in a truncated long.
2040 if (tmpProp.nitems > 0)
2041 *value = (XtPointer) XtMalloc((unsigned)tmpProp.nitems);
2043 *value = (XtPointer) XtMalloc(1);
2045 *length = tmpProp.nitems;
2046 memcpy((void*)*value, (void*)tmpProp.value,
2047 (unsigned)tmpProp.nitems);
2048 if (tmpProp.value != NULL)
2049 XFree((char*)tmpProp.value);
2055 if (tmpProp.value != NULL)
2056 XFree((char*)tmpProp.value);
2060 else if ((*target == CS_OF_LOCALE) && !isDebugFSet('s', 2) ||
2061 (*target == TEXT && !isDebugFSet('s', 3)))
2063 *type = CS_OF_LOCALE;
2065 *value = (XtPointer)getString(widget, begin, end, False);
2066 *length = strlen((char*) *value);
2074 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectConvert() exiting\n"));
2079 _DtTermPrimSelectLoseSelection
2085 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2086 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2087 Boolean restoreCursor = False;
2089 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectLoseSelection() starting\n"));
2091 if (*selection == XA_PRIMARY && selectInfo->ownPrimary)
2095 ** We've lost the primary selection, make a dummy call to
2096 ** setSelection (with begin > end) to clear things up...
2098 /* turn off the cursor */
2099 if (tw->term.tpd->cursorState != CURSORoff) {
2100 _DtTermPrimCursorOff(w);
2101 restoreCursor = True;
2104 setSelection(tw, 1, -99, XtLastTimestampProcessed(XtDisplay(w)), True);
2106 /* turn on the cursor */
2107 if (restoreCursor) {
2108 _DtTermPrimCursorOn(w);
2111 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectLoseSelection() exiting\n"));
2115 _DtTermPrimSelectBDragRelease
2120 Cardinal *paramCount
2123 TermSelectInfo selectInfo =
2124 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
2125 XButtonEvent *btnEvent = (XButtonEvent *) event;
2127 Debug('c', fprintf(stderr, ">>_DtTermPrimSelectBDragRelease() starting\n"));
2129 /* Work around for intrinsic bug. Remove once bug is fixed.
2130 ** this is for drag/drop
2132 XtUngrabPointer(w, btnEvent->time);
2134 if ( selectInfo->sel_start ) getTargets(w, event, params, paramCount);
2139 _DtTermPrimSelectInsert
2144 Cardinal *paramCount
2147 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2148 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2150 if (!selectInfo->cancel)
2151 _DtTermPrimSelectBDragRelease(w, event, params, paramCount);
2153 selectInfo->cancel = True ;
2155 /* turn on the cursor */
2156 _DtTermPrimCursorOn(w);
2160 _DtTermPrimSelectIsAboveSelection
2167 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2168 DtTermPrimData tpd = tw->term.tpd;
2169 TermSelectInfo selectInfo = tpd->selectInfo;
2170 XmTextPosition curPos, endPos;
2172 endPos = selectInfo->end ;
2173 curPos = rowColToPos(tw,row,col) ;
2175 if ( curPos < endPos )
2182 _DtTermPrimSelectResize
2187 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2188 DtTermPrimData tpd = tw->term.tpd;
2189 TermSelectInfo selectInfo = tpd->selectInfo;
2191 _DtTermPrimSelectDisown(w) ;
2192 selectInfo->columns = tw->term.columns ;
2196 _DtTermPrimSelectMoveLines
2204 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2205 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2206 short selectLineBegin;
2207 short selectLineEnd;
2211 posToBufferRowCol (tw, selectInfo->begin, &pb, &row, &col);
2213 /* if there are no lines, etc. return... */
2214 if ((len <= 0) || (src == dest) || !selectInfo->ownPrimary ||
2215 pb == tw->term.tpd->historyBuffer ) {
2218 if (row >= src && row < (src + len)) {
2219 selectInfo->begin -= (src - dest) * (selectInfo->columns + 1);
2220 selectInfo->end -= (src - dest) * (selectInfo->columns + 1);
2225 _DtTermPrimSelectDeleteLines
2232 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2233 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2234 short selectLineBegin;
2235 short selectLineEnd;
2239 posToBufferRowCol (tw, selectInfo->begin, &pb, &row, &col);
2241 /* if there are no lines, etc. return... */
2242 if ((len <= 0) || !selectInfo->ownPrimary ||
2243 ((tw->term.tpd->scrollLockTopRow > 0 ||
2244 tw->term.tpd->scrollLockBottomRow < tw->term.rows-1)) &&
2245 row < tw->term.tpd->scrollLockTopRow) {
2250 /* figure out what the begin and end lines are... */
2251 selectLineBegin = selectInfo->begin / (selectInfo->columns + 1);
2252 selectLineEnd = (selectInfo->end - 1) / (selectInfo->columns + 1);
2254 /* if the beginning of the selection is after the source, we need to
2255 * move the selection up...
2257 if (selectLineBegin > src) {
2258 selectInfo->begin -= len * (selectInfo->columns + 1);
2259 selectInfo->end -= len * (selectInfo->columns + 1);
2260 if (selectInfo->begin < 0) {
2261 (void) _DtTermPrimSelectDisown(w);
2267 _DtTermPrimSelectInsertLines
2274 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2275 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
2276 short selectLineBegin;
2277 short selectLineEnd;
2279 /* if there are no lines, return... */
2280 if ((len <= 0) || !selectInfo->ownPrimary) {
2284 /* figure out what the begin and end lines are... */
2285 selectLineBegin = selectInfo->begin / (selectInfo->columns + 1);
2286 selectLineEnd = (selectInfo->end - 1) / (selectInfo->columns + 1);
2288 /* if the beginning of the selection is at or after the source, we need to
2289 * move the selection up...
2291 if (selectLineBegin >= src) {
2292 selectInfo->begin += len * (selectInfo->columns + 1);
2293 selectInfo->end += len * (selectInfo->columns + 1);
2298 _DtTermPrimSelectAll
2303 Cardinal *paramCount
2306 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2307 DtTermPrimData tpd = tw->term.tpd;
2308 TermSelectInfo selectInfo = tpd->selectInfo;
2309 XButtonEvent *btnEvent = (XButtonEvent *) event;
2310 XmTextPosition begin;
2313 /* position not used in XmSELECT_ALL case */
2314 begin = scan(tw, (XmTextPosition) 0, XmSELECT_ALL, scanLeft,
2316 end = scan(tw, (XmTextPosition) 0, XmSELECT_ALL, scanRight,
2317 1, selectInfo->scanType == XmSELECT_LINE);
2319 /* turn off the cursor */
2320 _DtTermPrimCursorOff(w);
2322 setSelection(tw, begin, end, event->xbutton.time, False);
2324 /* turn on the cursor */
2325 _DtTermPrimCursorOn(w);
2329 _DtTermPrimSelectPage
2334 Cardinal *paramCount
2337 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2338 DtTermPrimData tpd = tw->term.tpd;
2339 TermSelectInfo selectInfo = tpd->selectInfo;
2340 XButtonEvent *btnEvent = (XButtonEvent *) event;
2341 XmTextPosition begin, end;
2342 short lastRow, width;
2345 begin = xyToPos(tw, 1, 1);
2346 end = xyToPos(tw, tw->core.width-1, tw->core.height-1);
2348 /* turn off the cursor */
2349 _DtTermPrimCursorOff(w);
2351 setSelection(tw, begin, end, event->xbutton.time, False);
2353 /* turn on the cursor */
2354 _DtTermPrimCursorOn(w);
2361 static XContext _DtTermDNDContext = 0;
2364 DropTransferCallback(
2370 unsigned long *length,
2373 _DtTermDropTransferRec *transfer_rec = (_DtTermDropTransferRec *) closure;
2374 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)transfer_rec->widget;
2375 DtTermPrimData tpd = tw->term.tpd;
2376 TermSelectInfo selectInfo = tpd->selectInfo;
2378 /* When type = NULL, we are assuming a DELETE request has been requested */
2381 XtFree((char *)value);
2386 doHandleTargets((Widget)tw,NULL,seltype,type,value,length,format) ;
2387 if (transfer_rec->move) {
2388 XmDropTransferEntryRec transferEntries[1];
2389 XmDropTransferEntryRec *transferList = NULL;
2391 transferEntries[0].client_data = (XtPointer) transfer_rec;
2392 transferEntries[0].target = XmInternAtom(XtDisplay(w),"DELETE",
2394 transferList = transferEntries;
2395 XmDropTransferAdd(w, transferEntries, 1);
2403 Display *display = XtDisplay(w);
2404 Screen *screen = XtScreen(w);
2406 XDeleteContext(display, (Window)screen, _DtTermDNDContext);
2413 Display *display = XtDisplay(w);
2414 Screen *screen = XtScreen(w);
2416 _DtTermProcessLock();
2417 if (_DtTermDNDContext == 0)
2418 _DtTermDNDContext = XUniqueContext();
2419 _DtTermProcessUnlock();
2421 XSaveContext(display, (Window)screen,
2422 _DtTermDNDContext, (XPointer)w);
2425 typedef struct _dropDestroyCBClientData {
2426 _DtTermDropTransferRec *transfer_rec;
2427 XtCallbackRec *dropDestroyCB; }
2428 dropDestroyCBClientData;
2434 XtPointer clientData,
2435 XtPointer callData )
2437 dropDestroyCBClientData *ptr = (dropDestroyCBClientData *) clientData;
2439 DeleteDropContext(w);
2442 if (ptr->transfer_rec) XtFree((char *) ptr->transfer_rec);
2443 if (ptr->dropDestroyCB) XtFree((char *) ptr->dropDestroyCB);
2444 XtFree((char *) ptr);
2449 HandleDrop( Widget w, XmDropProcCallbackStruct *cb )
2451 Widget drag_cont, initiator;
2452 /* XmTextWidget tw = (XmTextWidget) w; */
2453 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2454 DtTermPrimData tpd = tw->term.tpd;
2455 TermSelectInfo selectInfo = tpd->selectInfo;
2456 Cardinal numExportTargets, n;
2457 Atom *exportTargets;
2459 XmTextPosition insert_pos, left, right;
2460 XtCallbackRec *dropDestroyCB, *dd_cb;
2461 dropDestroyCBClientData *clientData;
2463 clientData = (dropDestroyCBClientData *) XtMalloc(sizeof(dropDestroyCBClientData));
2464 dropDestroyCB = dd_cb = (XtCallbackRec *) XtMalloc(2 * sizeof (XtCallbackRec));
2466 clientData->dropDestroyCB = dropDestroyCB;
2467 dd_cb->callback = DropDestroyCB;
2468 dd_cb->closure = NULL;
2470 dd_cb->callback = (XtCallbackProc) NULL;
2471 dd_cb->closure = NULL;
2473 drag_cont = cb->dragContext;
2476 XtSetArg(args[n], XmNsourceWidget, &initiator); n++;
2477 XtSetArg(args[n], XmNexportTargets, &exportTargets); n++;
2478 XtSetArg(args[n], XmNnumExportTargets, &numExportTargets); n++;
2479 XtGetValues((Widget) drag_cont, args, n);
2482 XmDropTransferEntryRec transferEntries[2];
2483 XmDropTransferEntryRec *transferList = NULL;
2484 Atom TEXT = XmInternAtom(XtDisplay(w), "TEXT", False);
2485 Atom COMPOUND_TEXT = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
2487 char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
2488 XTextProperty tmp_prop;
2489 _DtTermDropTransferRec *transfer_rec;
2490 Cardinal numTransfers = 0;
2491 Boolean locale_found = False;
2492 Boolean c_text_found = False;
2493 Boolean string_found = False;
2494 Boolean text_found = False;
2497 tmp_prop.value = NULL;
2499 status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
2500 (XICCEncodingStyle)XTextStyle, &tmp_prop);
2501 if (status == Success)
2502 CS_OF_LOCALE = tmp_prop.encoding;
2504 CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
2505 * characters. But just in case someones
2506 * Xlib is broken, this prevents a core dump.
2509 if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
2511 /* intialize data to send to drop transfer callback */
2512 transfer_rec = (_DtTermDropTransferRec *)
2513 XtMalloc(sizeof(_DtTermDropTransferRec));
2514 clientData->transfer_rec = transfer_rec;
2515 transfer_rec->widget = w;
2516 /* don't actually need all of this for dtterm - it was from Text widget
2517 *transfer_rec->insert_pos = insert_pos;
2518 *transfer_rec->num_chars = 0;
2519 *transfer_rec->timestamp = cb->timeStamp;
2523 if (cb->operation & XmDROP_MOVE) {
2524 transfer_rec->move = True;
2526 transfer_rec->move = False;
2529 transferEntries[0].client_data = (XtPointer) transfer_rec;
2530 transferList = transferEntries;
2533 for (n = 0; n < numExportTargets; n++) {
2534 if (exportTargets[n] == CS_OF_LOCALE) {
2535 transferEntries[0].target = CS_OF_LOCALE;
2536 locale_found = True;
2539 if (exportTargets[n] == COMPOUND_TEXT) c_text_found = True;
2540 if (exportTargets[n] == XA_STRING) string_found = True;
2541 if (exportTargets[n] == TEXT) text_found = True;
2545 if (locale_found || c_text_found || string_found || text_found) {
2546 if (!locale_found) {
2548 transferEntries[0].target = COMPOUND_TEXT;
2549 else if (string_found)
2550 transferEntries[0].target = XA_STRING;
2552 transferEntries[0].target = TEXT;
2555 if ( cb->operation & (XmDROP_COPY|XmDROP_MOVE) ) {
2556 XtSetArg(args[n], XmNdropTransfers, transferList); n++;
2557 XtSetArg(args[n], XmNnumDropTransfers, numTransfers); n++;
2559 XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
2560 XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
2563 XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
2564 XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
2566 dropDestroyCB->closure = (XtPointer) clientData;
2567 XtSetArg(args[n], XmNdestroyCallback, dropDestroyCB); n++;
2568 XtSetArg(args[n], XmNtransferProc, DropTransferCallback); n++;
2571 XmDropTransferStart(drag_cont, args, n);
2581 XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *) call;
2583 if (cb->dropAction != XmDROP_HELP) {
2588 XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
2589 XtSetArg(args[1], XmNnumDropTransfers, 0);
2590 XmDropTransferStart(cb->dragContext, args, 2);
2601 char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
2602 XTextProperty tmp_prop;
2605 tmp_prop.value = NULL;
2606 status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
2607 (XICCEncodingStyle)XTextStyle, &tmp_prop);
2608 if (status == Success)
2609 targets[0] = tmp_prop.encoding;
2611 targets[0] = 99999; /* XmbTextList... should never fail for XPCS
2612 * characters. But just in case someones
2613 * Xlib is broken, this prevents a core dump.
2616 if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
2618 targets[1] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
2619 targets[2] = XA_STRING;
2620 targets[3] = XmInternAtom(XtDisplay(w), "TEXT", False);
2623 XtSetArg(args[n], XmNimportTargets, targets); n++;
2624 XtSetArg(args[n], XmNnumImportTargets, 4); n++;
2625 /* XtSetArg(args[n], XmNdragProc, DragProcCallback); n++; */
2626 XtSetArg(args[n], XmNdropProc, DropProcCallback); n++;
2627 XmDropSiteRegister(w, args, n);
2641 Cardinal *num_params )
2643 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2645 char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
2646 XTextProperty tmp_prop;
2648 Cardinal num_targets = 0;
2653 tmp_prop.value = NULL;
2654 status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
2655 (XICCEncodingStyle)XTextStyle, &tmp_prop);
2656 if (status == Success)
2657 targets[num_targets++] = tmp_prop.encoding;
2659 targets[num_targets++] = 99999; /* XmbTextList... should never fail
2660 * for XPCS characters. But just in
2661 * case someones Xlib is broken,
2662 * this prevents a core dump.
2665 if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
2667 targets[num_targets++] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
2668 targets[num_targets++] = XA_STRING;
2669 targets[num_targets++] = XmInternAtom(XtDisplay(w), "TEXT", False);
2671 drag_icon = (Widget) XmeGetTextualDragIcon(w);
2674 XtSetArg(args[n], XmNcursorBackground, tw->core.background_pixel); n++;
2675 XtSetArg(args[n], XmNcursorForeground, tw->primitive.foreground); n++;
2676 XtSetArg(args[n], XmNsourceCursorIcon, drag_icon); n++;
2677 XtSetArg(args[n], XmNexportTargets, targets); n++;
2678 XtSetArg(args[n], XmNnumExportTargets, num_targets); n++;
2679 XtSetArg(args[n], XmNconvertProc, _DtTermPrimSelectConvert); n++;
2680 XtSetArg(args[n], XmNclientData, w); n++;
2681 XtSetArg(args[n], XmNdragOperations, ( XmDROP_COPY)); n++;
2682 (void) XmDragStart(w, event, args, n);
2686 GetXFromPos(Widget w, XmTextPosition pos)
2688 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2689 DtTermPrimData tpd = tw->term.tpd;
2692 TermCharInfoRec charInfoRec ;
2694 posToBufferRowCol(tw,pos,&pb,&row,&col) ;
2695 return(tpd->offsetX+col*tpd->cellWidth);
2700 _DtTermPrimSelectProcessBDrag(
2704 Cardinal *num_params )
2706 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
2707 TermSelectInfo selectInfo =
2708 ((DtTermPrimitiveWidget)w)->term.tpd->selectInfo;
2709 XmTextPosition position, left, right;
2710 Position left_x, left_y, right_x, right_y;
2711 /* InputData data = tw->text.input->data; */
2713 selectInfo->cancel = False;
2714 position = xyToPos(tw, event->xbutton.x, event->xbutton.y);
2716 if (_DtTermPrimSelectGetSelection(w, &left, &right) &&
2718 if ((position > left && position < right)
2719 || (position == left &&
2720 event->xbutton.x > GetXFromPos(w, left))
2721 || (position == right &&
2722 event->xbutton.x < GetXFromPos(w, right))) {
2723 selectInfo->sel_start = False;
2724 StartDrag(w, event, params, num_params);
2728 selectInfo->sel_start = True ;
2731 else selectInfo->sel_start = True ;
2735 /* This is the menu interface for copy clipboard */
2737 _DtTermPrimSelectCopyClipboard
2743 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
2744 XmTextPosition begin;
2747 char *selected_string = NULL; /* text selection */
2748 long item_id = 0L; /* clipboard item id */
2749 long data_id = 0L; /* clipboard data id */
2750 int status; /* clipboard status */
2751 XmString clip_label;
2752 XTextProperty tmp_prop;
2753 Display *display = XtDisplay(w);
2754 Window window = XtWindow(w);
2757 if ( _DtTermPrimSelectGetSelection(w, &begin, &end) && begin != end ) {
2758 selected_string = getString(w, begin, end, False);
2761 * Using the Xm clipboard facilities,
2762 * copy the selected text to the clipboard
2764 tmp_prop.value = NULL;
2765 if (selected_string != NULL) {
2766 clip_label = XmStringCreateLocalized ("XM_TERM");
2767 /* start copy to clipboard */
2768 status = XmClipboardStartCopy(display, window, clip_label, copy_time,
2771 if (status != ClipboardSuccess) {
2772 XtFree(selected_string);
2773 XmStringFree(clip_label);
2777 status = XmbTextListToTextProperty(display, &selected_string, 1,
2778 (XICCEncodingStyle)XStdICCTextStyle,
2781 if (status != Success && status <= 0) {
2782 XmClipboardCancelCopy(display, window, item_id);
2783 XtFree(selected_string);
2784 XmStringFree(clip_label);
2788 atom_name = XGetAtomName(display, tmp_prop.encoding);
2790 /* move the data to the clipboard */
2791 status = XmClipboardCopy(display, window, item_id, atom_name,
2792 (XtPointer)tmp_prop.value, tmp_prop.nitems,
2797 if (status != ClipboardSuccess) {
2798 XmClipboardCancelCopy(display, window, item_id);
2799 XFree((char*)tmp_prop.value);
2800 XmStringFree(clip_label);
2804 /* end the copy to the clipboard */
2805 status = XmClipboardEndCopy (display, window, item_id);
2807 XtFree((char*)tmp_prop.value);
2808 XmStringFree(clip_label);
2810 if (status != ClipboardSuccess) return False;
2814 if (selected_string!=NULL)
2815 XtFree(selected_string);
2819 /* This is the event interface for copy clipboard */
2821 _DtTermPrimSelectCopyClipboardEventIF
2826 Cardinal *num_params
2829 _DtTermPrimSelectCopyClipboard(w,event->xkey.time) ;
2833 * Retrieves the current data from the clipboard
2834 * and paste it at the current cursor position
2837 _DtTermPrimSelectPasteClipboard
2842 XmTextPosition sel_left = 0;
2843 XmTextPosition sel_right = 0;
2844 XmTextPosition paste_pos_left, paste_pos_right, cursorPos;
2845 int status; /* clipboard status */
2846 char * buffer; /* temporary text buffer */
2847 unsigned long length; /* length of buffer */
2848 unsigned long outlength = 0L; /* length of bytes copied */
2849 long private_id = 0L; /* id of item on clipboard */
2850 Boolean dest_disjoint = True;
2851 XmTextBlockRec block, newblock;
2852 Display *display = XtDisplay(w);
2853 Window window = XtWindow(w);
2854 Boolean get_ct = False;
2856 XTextProperty tmp_prop;
2857 int malloc_size = 0;
2860 char * total_tmp_value = NULL;
2863 status = XmClipboardInquireLength(display, window, "STRING", &length);
2865 if (status == ClipboardNoData || length == 0) {
2866 status = XmClipboardInquireLength(display, window, "COMPOUND_TEXT",
2868 if (status == ClipboardNoData || length == 0) return False;
2872 /* malloc length of clipboard data */
2873 buffer = XtMalloc((unsigned) length);
2876 status = XmClipboardRetrieve(display, window, "STRING", buffer,
2877 length, &outlength, &private_id);
2879 status = XmClipboardRetrieve(display, window, "COMPOUND_TEXT",
2880 buffer, length, &outlength, &private_id);
2884 if (status != ClipboardSuccess) {
2885 XmClipboardEndRetrieve(display, window);
2890 tmp_prop.value = (unsigned char *) buffer;
2892 tmp_prop.encoding = XA_STRING;
2894 tmp_prop.encoding = XmInternAtom(display, "COMPOUND_TEXT", False);
2896 tmp_prop.format = 8;
2897 tmp_prop.nitems = outlength;
2900 status = XmbTextPropertyToTextList(display, &tmp_prop, &tmp_value,
2903 /* if no conversions, num_vals doesn't change */
2904 if (num_vals && (status == Success || status > 0)) {
2905 for (i = 0; i < num_vals ; i++)
2906 malloc_size += strlen(tmp_value[i]);
2908 total_tmp_value = XtMalloc ((unsigned) malloc_size + 1);
2909 total_tmp_value[0] = '\0';
2910 for (i = 0; i < num_vals ; i++)
2911 strcat(total_tmp_value, tmp_value[i]);
2912 block.ptr = total_tmp_value;
2913 block.length = strlen(total_tmp_value);
2914 block.format = XmFMT_8_BIT;
2915 XFreeStringList(tmp_value);
2917 malloc_size = 1; /* to force space to be freed */
2918 total_tmp_value = XtMalloc ((unsigned)1);
2919 *total_tmp_value = '\0';
2920 block.ptr = total_tmp_value;
2922 block.format = XmFMT_8_BIT;
2928 char *pChar, *pCharEnd, *pCharFollow;
2930 pCharEnd = block.ptr + block.length;
2931 pCharFollow = (char *)block.ptr;
2933 for (pChar = (char *)block.ptr; pChar < pCharEnd; pChar++)
2938 DtTermSubprocSend(w, (unsigned char *) pCharFollow,
2939 pChar - pCharFollow + 1);
2940 pCharFollow = pChar + 1;
2943 if (pCharFollow < pCharEnd)
2945 DtTermSubprocSend(w, (unsigned char *) pCharFollow,
2946 pCharEnd - pCharFollow);
2950 if (malloc_size != 0) XtFree(total_tmp_value);
2952 (void) _DtTermPrimCursorOn(w);
2955 /* This is the event interface for paste clipboard */
2957 _DtTermPrimSelectPasteClipboardEventIF
2962 Cardinal *num_params
2965 _DtTermPrimSelectPasteClipboard(w) ;
2969 * This is for the SUN two button mouse
2979 #define ABS_DELTA(x1, x2) (x1 < x2 ? x2 - x1 : x1 - x2)
2981 if( event->type == MotionNotify) {
2982 XEvent * press = (XEvent *) arg;
2984 if (ABS_DELTA(press->xbutton.x_root, event->xmotion.x_root) > DAMPING ||
2985 ABS_DELTA(press->xbutton.y_root, event->xmotion.y_root) > DAMPING)
2988 else if (event->type == ButtonRelease)
2999 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
3000 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
3001 XmTextPosition position, left, right;
3002 Position left_x, right_x, dummy;
3004 position = xyToPos(tw, event->xbutton.x, event->xbutton.y);
3006 if (!(_DtTermPrimSelectGetSelection(w, &left, &right) &&
3007 left != right && (position > left && position < right)
3008 || (position == left &&
3009 event->xbutton.x > GetXFromPos(w, left))
3010 || (position == right &&
3011 event->xbutton.x < GetXFromPos(w, right)))
3013 /* or if it is part of a multiclick sequence */
3014 (event->xbutton.time > selectInfo->lastTime &&
3015 event->xbutton.time - selectInfo->lastTime <
3016 XtGetMultiClickTime(XtDisplay((Widget)w))) )
3019 /* The determination of whether this is a transfer drag cannot be made
3020 until a Motion event comes in. It is not a drag as soon as a
3021 ButtonUp event happens or the MultiClickTimeout expires. */
3024 XPeekIfEvent(XtDisplay(w), &new, LookForButton, (XPointer)event);
3037 #define SELECTION_ACTION 0
3038 #define TRANSFER_ACTION 1
3042 _DtTermPrimSelect2ButtonMouse(
3046 Cardinal *num_params )
3048 /* This action happens when Button1 is pressed and the Selection
3049 and Transfer are integrated on Button1. It is passed two
3050 parameters: the action to call when the event is a selection,
3051 and the action to call when the event is a transfer. */
3053 if (*num_params != 2 /* || !XmIsTextField(w) */)
3055 if (XmTestInSelection(w, event))
3056 XtCallActionProc(w, params[TRANSFER_ACTION], event, params, *num_params);
3058 XtCallActionProc(w, params[SELECTION_ACTION], event, params, *num_params);
3063 _DtTermPrimSelectProcessCancel(
3067 Cardinal *num_params )
3069 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
3070 TermSelectInfo selectInfo = tw->term.tpd->selectInfo;
3071 XmTextPosition left_x, right_x;
3073 XmParentInputActionRec p_event ;
3075 if (!tw->term.allowOsfKeysyms) {
3076 _DtTermPrimActionKeyInput(w,event,params,num_params);
3080 selectInfo->cancel = True ;
3082 /* turn off the cursor */
3083 _DtTermPrimCursorOff(w);
3085 /* reset to origLeft and origRight */
3086 setSelection (tw, selectInfo->origBegin, selectInfo->origEnd,
3087 event->xkey.time, False) ;
3089 /* turn on the cursor */
3090 _DtTermPrimCursorOn(w);
3092 if (selectInfo->selectID) {
3093 XtRemoveTimeOut(selectInfo->selectID);
3094 selectInfo->selectID = 0;