diff options
Diffstat (limited to '')
23 files changed, 693 insertions, 917 deletions
diff --git a/linden/indra/llui/llclipboard.cpp b/linden/indra/llui/llclipboard.cpp index d5255e7..f33f3fa 100644 --- a/linden/indra/llui/llclipboard.cpp +++ b/linden/indra/llui/llclipboard.cpp | |||
@@ -92,3 +92,44 @@ BOOL LLClipboard::canPasteString() const | |||
92 | { | 92 | { |
93 | return LLView::getWindow()->isClipboardTextAvailable(); | 93 | return LLView::getWindow()->isClipboardTextAvailable(); |
94 | } | 94 | } |
95 | |||
96 | |||
97 | void LLClipboard::copyFromPrimarySubstring(const LLWString &src, S32 pos, S32 len, const LLUUID& source_id ) | ||
98 | { | ||
99 | mSourceID = source_id; | ||
100 | mString = src.substr(pos, len); | ||
101 | LLView::getWindow()->copyTextToPrimary( mString ); | ||
102 | } | ||
103 | |||
104 | |||
105 | const LLWString& LLClipboard::getPastePrimaryWString( LLUUID* source_id ) | ||
106 | { | ||
107 | if( mSourceID.notNull() ) | ||
108 | { | ||
109 | LLWString temp_string; | ||
110 | LLView::getWindow()->pasteTextFromPrimary(temp_string); | ||
111 | |||
112 | if( temp_string != mString ) | ||
113 | { | ||
114 | mSourceID.setNull(); | ||
115 | mString = temp_string; | ||
116 | } | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | LLView::getWindow()->pasteTextFromPrimary(mString); | ||
121 | } | ||
122 | |||
123 | if( source_id ) | ||
124 | { | ||
125 | *source_id = mSourceID; | ||
126 | } | ||
127 | |||
128 | return mString; | ||
129 | } | ||
130 | |||
131 | |||
132 | BOOL LLClipboard::canPastePrimaryString() const | ||
133 | { | ||
134 | return LLView::getWindow()->isPrimaryTextAvailable(); | ||
135 | } | ||
diff --git a/linden/indra/llui/llclipboard.h b/linden/indra/llui/llclipboard.h index 706ed2a..7117f84 100644 --- a/linden/indra/llui/llclipboard.h +++ b/linden/indra/llui/llclipboard.h | |||
@@ -43,10 +43,19 @@ public: | |||
43 | LLClipboard(); | 43 | LLClipboard(); |
44 | ~LLClipboard(); | 44 | ~LLClipboard(); |
45 | 45 | ||
46 | /* We support two flavors of clipboard. The default is the explicitly | ||
47 | copy-and-pasted clipboard. The second is the so-called 'primary' clipboard | ||
48 | which is implicitly copied upon selection on platforms which expect this | ||
49 | (i.e. X11/Linux). */ | ||
50 | |||
46 | void copyFromSubstring(const LLWString ©_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null ); | 51 | void copyFromSubstring(const LLWString ©_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null ); |
47 | BOOL canPasteString() const; | 52 | BOOL canPasteString() const; |
48 | const LLWString& getPasteWString(LLUUID* source_id = NULL); | 53 | const LLWString& getPasteWString(LLUUID* source_id = NULL); |
49 | 54 | ||
55 | void copyFromPrimarySubstring(const LLWString ©_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null ); | ||
56 | BOOL canPastePrimaryString() const; | ||
57 | const LLWString& getPastePrimaryWString(LLUUID* source_id = NULL); | ||
58 | |||
50 | private: | 59 | private: |
51 | LLUUID mSourceID; | 60 | LLUUID mSourceID; |
52 | LLWString mString; | 61 | LLWString mString; |
diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp index 2924c29..efe49eb 100644 --- a/linden/indra/llui/llfloater.cpp +++ b/linden/indra/llui/llfloater.cpp | |||
@@ -1187,6 +1187,12 @@ BOOL LLFloater::handleRightMouseDown(S32 x, S32 y, MASK mask) | |||
1187 | return was_minimized || LLPanel::handleRightMouseDown( x, y, mask ); | 1187 | return was_minimized || LLPanel::handleRightMouseDown( x, y, mask ); |
1188 | } | 1188 | } |
1189 | 1189 | ||
1190 | BOOL LLFloater::handleMiddleMouseDown(S32 x, S32 y, MASK mask) | ||
1191 | { | ||
1192 | bringToFront( x, y ); | ||
1193 | return LLPanel::handleMiddleMouseDown( x, y, mask ); | ||
1194 | } | ||
1195 | |||
1190 | 1196 | ||
1191 | // virtual | 1197 | // virtual |
1192 | BOOL LLFloater::handleDoubleClick(S32 x, S32 y, MASK mask) | 1198 | BOOL LLFloater::handleDoubleClick(S32 x, S32 y, MASK mask) |
diff --git a/linden/indra/llui/llfloater.h b/linden/indra/llui/llfloater.h index a6fe3cc..37081c2 100644 --- a/linden/indra/llui/llfloater.h +++ b/linden/indra/llui/llfloater.h | |||
@@ -178,7 +178,7 @@ public: | |||
178 | virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); | 178 | virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); |
179 | virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); | 179 | virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); |
180 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); | 180 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); |
181 | 181 | virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); | |
182 | virtual void draw(); | 182 | virtual void draw(); |
183 | 183 | ||
184 | virtual void onOpen() {} | 184 | virtual void onOpen() {} |
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 498ef26..f905774 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp | |||
@@ -493,6 +493,9 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
493 | // delay cursor flashing | 493 | // delay cursor flashing |
494 | mKeystrokeTimer.reset(); | 494 | mKeystrokeTimer.reset(); |
495 | 495 | ||
496 | // take selection to 'primary' clipboard | ||
497 | updatePrimary(); | ||
498 | |||
496 | return TRUE; | 499 | return TRUE; |
497 | } | 500 | } |
498 | 501 | ||
@@ -575,6 +578,17 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) | |||
575 | return TRUE; | 578 | return TRUE; |
576 | } | 579 | } |
577 | 580 | ||
581 | BOOL LLLineEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask) | ||
582 | { | ||
583 | // llinfos << "MiddleMouseDown" << llendl; | ||
584 | setFocus( TRUE ); | ||
585 | if( canPastePrimary() ) | ||
586 | { | ||
587 | setCursorAtLocalPos(x); | ||
588 | pastePrimary(); | ||
589 | } | ||
590 | return TRUE; | ||
591 | } | ||
578 | 592 | ||
579 | BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) | 593 | BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) |
580 | { | 594 | { |
@@ -669,6 +683,9 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask) | |||
669 | { | 683 | { |
670 | // delay cursor flashing | 684 | // delay cursor flashing |
671 | mKeystrokeTimer.reset(); | 685 | mKeystrokeTimer.reset(); |
686 | |||
687 | // take selection to 'primary' clipboard | ||
688 | updatePrimary(); | ||
672 | } | 689 | } |
673 | 690 | ||
674 | return handled; | 691 | return handled; |
@@ -872,7 +889,12 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) | |||
872 | } | 889 | } |
873 | } | 890 | } |
874 | 891 | ||
875 | 892 | if(handled) | |
893 | { | ||
894 | // take selection to 'primary' clipboard | ||
895 | updatePrimary(); | ||
896 | } | ||
897 | |||
876 | return handled; | 898 | return handled; |
877 | } | 899 | } |
878 | 900 | ||
@@ -945,20 +967,42 @@ BOOL LLLineEditor::canPaste() const | |||
945 | return !mReadOnly && gClipboard.canPasteString(); | 967 | return !mReadOnly && gClipboard.canPasteString(); |
946 | } | 968 | } |
947 | 969 | ||
948 | |||
949 | // paste from clipboard | ||
950 | void LLLineEditor::paste() | 970 | void LLLineEditor::paste() |
951 | { | 971 | { |
952 | if (canPaste()) | 972 | bool is_primary = false; |
973 | pasteHelper(is_primary); | ||
974 | } | ||
975 | |||
976 | void LLLineEditor::pastePrimary() | ||
977 | { | ||
978 | bool is_primary = true; | ||
979 | pasteHelper(is_primary); | ||
980 | } | ||
981 | |||
982 | // paste from primary (is_primary==true) or clipboard (is_primary==false) | ||
983 | void LLLineEditor::pasteHelper(bool is_primary) | ||
984 | { | ||
985 | bool can_paste_it; | ||
986 | if (is_primary) | ||
987 | can_paste_it = canPastePrimary(); | ||
988 | else | ||
989 | can_paste_it = canPaste(); | ||
990 | |||
991 | if (can_paste_it) | ||
953 | { | 992 | { |
954 | LLWString paste = gClipboard.getPasteWString(); | 993 | LLWString paste; |
994 | if (is_primary) | ||
995 | paste = gClipboard.getPastePrimaryWString(); | ||
996 | else | ||
997 | paste = gClipboard.getPasteWString(); | ||
998 | |||
955 | if (!paste.empty()) | 999 | if (!paste.empty()) |
956 | { | 1000 | { |
957 | // Prepare for possible rollback | 1001 | // Prepare for possible rollback |
958 | LLLineEditorRollback rollback(this); | 1002 | LLLineEditorRollback rollback(this); |
959 | 1003 | ||
960 | // Delete any selected characters | 1004 | // Delete any selected characters |
961 | if (hasSelection()) | 1005 | if ((!is_primary) && hasSelection()) |
962 | { | 1006 | { |
963 | deleteSelection(); | 1007 | deleteSelection(); |
964 | } | 1008 | } |
@@ -994,7 +1038,7 @@ void LLLineEditor::paste() | |||
994 | clean_string = clean_string.substr(0, wchars_that_fit); | 1038 | clean_string = clean_string.substr(0, wchars_that_fit); |
995 | reportBadKeystroke(); | 1039 | reportBadKeystroke(); |
996 | } | 1040 | } |
997 | 1041 | ||
998 | mText.insert(getCursor(), clean_string); | 1042 | mText.insert(getCursor(), clean_string); |
999 | setCursor( getCursor() + (S32)clean_string.length() ); | 1043 | setCursor( getCursor() + (S32)clean_string.length() ); |
1000 | deselect(); | 1044 | deselect(); |
@@ -1015,7 +1059,30 @@ void LLLineEditor::paste() | |||
1015 | } | 1059 | } |
1016 | } | 1060 | } |
1017 | 1061 | ||
1018 | 1062 | // copy selection to primary | |
1063 | void LLLineEditor::copyPrimary() | ||
1064 | { | ||
1065 | if( canCopy() ) | ||
1066 | { | ||
1067 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); | ||
1068 | S32 length = abs( mSelectionStart - mSelectionEnd ); | ||
1069 | gClipboard.copyFromPrimarySubstring( mText.getWString(), left_pos, length ); | ||
1070 | } | ||
1071 | } | ||
1072 | |||
1073 | BOOL LLLineEditor::canPastePrimary() const | ||
1074 | { | ||
1075 | return !mReadOnly && gClipboard.canPastePrimaryString(); | ||
1076 | } | ||
1077 | |||
1078 | void LLLineEditor::updatePrimary() | ||
1079 | { | ||
1080 | if(canCopy() ) | ||
1081 | { | ||
1082 | copyPrimary(); | ||
1083 | } | ||
1084 | } | ||
1085 | |||
1019 | BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) | 1086 | BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) |
1020 | { | 1087 | { |
1021 | BOOL handled = FALSE; | 1088 | BOOL handled = FALSE; |
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index 11cbcd9..b11f8b9 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h | |||
@@ -89,6 +89,7 @@ public: | |||
89 | /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); | 89 | /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); |
90 | /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); | 90 | /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); |
91 | /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask); | 91 | /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask); |
92 | /*virtual*/ BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); | ||
92 | /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); | 93 | /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); |
93 | /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); | 94 | /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); |
94 | /*virtual*/ void onMouseCaptureLost(); | 95 | /*virtual*/ void onMouseCaptureLost(); |
@@ -96,13 +97,16 @@ public: | |||
96 | // LLEditMenuHandler overrides | 97 | // LLEditMenuHandler overrides |
97 | virtual void cut(); | 98 | virtual void cut(); |
98 | virtual BOOL canCut() const; | 99 | virtual BOOL canCut() const; |
99 | |||
100 | virtual void copy(); | 100 | virtual void copy(); |
101 | virtual BOOL canCopy() const; | 101 | virtual BOOL canCopy() const; |
102 | |||
103 | virtual void paste(); | 102 | virtual void paste(); |
104 | virtual BOOL canPaste() const; | 103 | virtual BOOL canPaste() const; |
105 | 104 | ||
105 | virtual void updatePrimary(); | ||
106 | virtual void copyPrimary(); | ||
107 | virtual void pastePrimary(); | ||
108 | virtual BOOL canPastePrimary() const; | ||
109 | |||
106 | virtual void doDelete(); | 110 | virtual void doDelete(); |
107 | virtual BOOL canDoDelete() const; | 111 | virtual BOOL canDoDelete() const; |
108 | 112 | ||
@@ -219,6 +223,9 @@ public: | |||
219 | 223 | ||
220 | private: | 224 | private: |
221 | // private helper methods | 225 | // private helper methods |
226 | |||
227 | void pasteHelper(bool is_primary); | ||
228 | |||
222 | void removeChar(); | 229 | void removeChar(); |
223 | void addChar(const llwchar c); | 230 | void addChar(const llwchar c); |
224 | void setCursorAtLocalPos(S32 local_mouse_x); | 231 | void setCursorAtLocalPos(S32 local_mouse_x); |
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index 3813e76..95cce60 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp | |||
@@ -1203,6 +1203,18 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) | |||
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | 1205 | ||
1206 | BOOL LLTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask) | ||
1207 | { | ||
1208 | setFocus( TRUE ); | ||
1209 | if( canPastePrimary() ) | ||
1210 | { | ||
1211 | setCursorAtLocalPos( x, y, TRUE ); | ||
1212 | pastePrimary(); | ||
1213 | } | ||
1214 | return TRUE; | ||
1215 | } | ||
1216 | |||
1217 | |||
1206 | BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) | 1218 | BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) |
1207 | { | 1219 | { |
1208 | BOOL handled = FALSE; | 1220 | BOOL handled = FALSE; |
@@ -1323,6 +1335,9 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) | |||
1323 | 1335 | ||
1324 | setCursorAtLocalPos( x, y, TRUE ); | 1336 | setCursorAtLocalPos( x, y, TRUE ); |
1325 | endSelection(); | 1337 | endSelection(); |
1338 | |||
1339 | // take selection to primary clipboard | ||
1340 | updatePrimary(); | ||
1326 | } | 1341 | } |
1327 | 1342 | ||
1328 | if( !hasSelection() ) | 1343 | if( !hasSelection() ) |
@@ -1330,6 +1345,9 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) | |||
1330 | handleMouseUpOverSegment( x, y, mask ); | 1345 | handleMouseUpOverSegment( x, y, mask ); |
1331 | } | 1346 | } |
1332 | 1347 | ||
1348 | // take selection to 'primary' clipboard | ||
1349 | updatePrimary(); | ||
1350 | |||
1333 | handled = TRUE; | 1351 | handled = TRUE; |
1334 | } | 1352 | } |
1335 | 1353 | ||
@@ -1392,8 +1410,12 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
1392 | // delay cursor flashing | 1410 | // delay cursor flashing |
1393 | resetKeystrokeTimer(); | 1411 | resetKeystrokeTimer(); |
1394 | 1412 | ||
1413 | // take selection to 'primary' clipboard | ||
1414 | updatePrimary(); | ||
1415 | |||
1395 | handled = TRUE; | 1416 | handled = TRUE; |
1396 | } | 1417 | } |
1418 | |||
1397 | return handled; | 1419 | return handled; |
1398 | } | 1420 | } |
1399 | 1421 | ||
@@ -1689,6 +1711,12 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask) | |||
1689 | } | 1711 | } |
1690 | } | 1712 | } |
1691 | 1713 | ||
1714 | if( handled ) | ||
1715 | { | ||
1716 | // take selection to 'primary' clipboard | ||
1717 | updatePrimary(); | ||
1718 | } | ||
1719 | |||
1692 | return handled; | 1720 | return handled; |
1693 | } | 1721 | } |
1694 | 1722 | ||
@@ -1868,22 +1896,46 @@ BOOL LLTextEditor::canPaste() const | |||
1868 | return !mReadOnly && gClipboard.canPasteString(); | 1896 | return !mReadOnly && gClipboard.canPasteString(); |
1869 | } | 1897 | } |
1870 | 1898 | ||
1871 | |||
1872 | // paste from clipboard | 1899 | // paste from clipboard |
1873 | void LLTextEditor::paste() | 1900 | void LLTextEditor::paste() |
1874 | { | 1901 | { |
1875 | if (!canPaste()) | 1902 | bool is_primary = false; |
1903 | pasteHelper(is_primary); | ||
1904 | } | ||
1905 | |||
1906 | // paste from primary | ||
1907 | void LLTextEditor::pastePrimary() | ||
1908 | { | ||
1909 | bool is_primary = true; | ||
1910 | pasteHelper(is_primary); | ||
1911 | } | ||
1912 | |||
1913 | // paste from primary (itsprimary==true) or clipboard (itsprimary==false) | ||
1914 | void LLTextEditor::pasteHelper(bool is_primary) | ||
1915 | { | ||
1916 | bool can_paste_it; | ||
1917 | if (is_primary) | ||
1918 | can_paste_it = canPastePrimary(); | ||
1919 | else | ||
1920 | can_paste_it = canPaste(); | ||
1921 | |||
1922 | if (!can_paste_it) | ||
1876 | { | 1923 | { |
1877 | return; | 1924 | return; |
1878 | } | 1925 | } |
1879 | LLUUID source_id; | 1926 | LLUUID source_id; |
1880 | LLWString paste = gClipboard.getPasteWString(&source_id); | 1927 | LLWString paste; |
1928 | if (is_primary) | ||
1929 | paste = gClipboard.getPastePrimaryWString(&source_id); | ||
1930 | else | ||
1931 | paste = gClipboard.getPasteWString(&source_id); | ||
1932 | |||
1881 | if (paste.empty()) | 1933 | if (paste.empty()) |
1882 | { | 1934 | { |
1883 | return; | 1935 | return; |
1884 | } | 1936 | } |
1885 | // Delete any selected characters (the paste replaces them) | 1937 | // Delete any selected characters (the paste replaces them) |
1886 | if( hasSelection() ) | 1938 | if( (!is_primary) && hasSelection() ) |
1887 | { | 1939 | { |
1888 | deleteSelection(TRUE); | 1940 | deleteSelection(TRUE); |
1889 | } | 1941 | } |
@@ -1917,6 +1969,32 @@ void LLTextEditor::paste() | |||
1917 | } | 1969 | } |
1918 | 1970 | ||
1919 | 1971 | ||
1972 | |||
1973 | // copy selection to primary | ||
1974 | void LLTextEditor::copyPrimary() | ||
1975 | { | ||
1976 | if( !canCopy() ) | ||
1977 | { | ||
1978 | return; | ||
1979 | } | ||
1980 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); | ||
1981 | S32 length = abs( mSelectionStart - mSelectionEnd ); | ||
1982 | gClipboard.copyFromPrimarySubstring(mWText, left_pos, length, mSourceID); | ||
1983 | } | ||
1984 | |||
1985 | BOOL LLTextEditor::canPastePrimary() const | ||
1986 | { | ||
1987 | return !mReadOnly && gClipboard.canPastePrimaryString(); | ||
1988 | } | ||
1989 | |||
1990 | void LLTextEditor::updatePrimary() | ||
1991 | { | ||
1992 | if (canCopy()) | ||
1993 | { | ||
1994 | copyPrimary(); | ||
1995 | } | ||
1996 | } | ||
1997 | |||
1920 | BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask) | 1998 | BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask) |
1921 | { | 1999 | { |
1922 | BOOL handled = FALSE; | 2000 | BOOL handled = FALSE; |
@@ -1992,6 +2070,11 @@ BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask) | |||
1992 | } | 2070 | } |
1993 | } | 2071 | } |
1994 | 2072 | ||
2073 | if (handled) | ||
2074 | { | ||
2075 | updatePrimary(); | ||
2076 | } | ||
2077 | |||
1995 | return handled; | 2078 | return handled; |
1996 | } | 2079 | } |
1997 | 2080 | ||
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h index 643b7c3..0777e5f 100644 --- a/linden/indra/llui/lltexteditor.h +++ b/linden/indra/llui/lltexteditor.h | |||
@@ -82,6 +82,8 @@ public: | |||
82 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); | 82 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); |
83 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); | 83 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); |
84 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); | 84 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); |
85 | virtual BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); | ||
86 | |||
85 | virtual BOOL handleKeyHere(KEY key, MASK mask ); | 87 | virtual BOOL handleKeyHere(KEY key, MASK mask ); |
86 | virtual BOOL handleUnicodeCharHere(llwchar uni_char); | 88 | virtual BOOL handleUnicodeCharHere(llwchar uni_char); |
87 | 89 | ||
@@ -117,6 +119,10 @@ public: | |||
117 | virtual BOOL canCopy() const; | 119 | virtual BOOL canCopy() const; |
118 | virtual void paste(); | 120 | virtual void paste(); |
119 | virtual BOOL canPaste() const; | 121 | virtual BOOL canPaste() const; |
122 | virtual void updatePrimary(); | ||
123 | virtual void copyPrimary(); | ||
124 | virtual void pastePrimary(); | ||
125 | virtual BOOL canPastePrimary() const; | ||
120 | virtual void doDelete(); | 126 | virtual void doDelete(); |
121 | virtual BOOL canDoDelete() const; | 127 | virtual BOOL canDoDelete() const; |
122 | virtual void selectAll(); | 128 | virtual void selectAll(); |
@@ -425,6 +431,8 @@ private: | |||
425 | // | 431 | // |
426 | // Methods | 432 | // Methods |
427 | // | 433 | // |
434 | void pasteHelper(bool is_primary); | ||
435 | |||
428 | void updateSegments(); | 436 | void updateSegments(); |
429 | void pruneSegments(); | 437 | void pruneSegments(); |
430 | 438 | ||
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp index 9cdf481..78bf168 100644 --- a/linden/indra/llui/llview.cpp +++ b/linden/indra/llui/llview.cpp | |||
@@ -981,6 +981,30 @@ BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask) | |||
981 | } | 981 | } |
982 | return handled; | 982 | return handled; |
983 | } | 983 | } |
984 | |||
985 | BOOL LLView::handleMiddleMouseDown(S32 x, S32 y, MASK mask) | ||
986 | { | ||
987 | LLView* handled_view = childrenHandleMiddleMouseDown( x, y, mask ); | ||
988 | BOOL handled = (handled_view != NULL); | ||
989 | if( !handled && blockMouseEvent(x, y) ) | ||
990 | { | ||
991 | handled = TRUE; | ||
992 | handled_view = this; | ||
993 | } | ||
994 | |||
995 | return handled; | ||
996 | } | ||
997 | |||
998 | BOOL LLView::handleMiddleMouseUp(S32 x, S32 y, MASK mask) | ||
999 | { | ||
1000 | BOOL handled = childrenHandleMiddleMouseUp( x, y, mask ) != NULL; | ||
1001 | if( !handled && blockMouseEvent(x, y) ) | ||
1002 | { | ||
1003 | handled = TRUE; | ||
1004 | } | ||
1005 | return handled; | ||
1006 | } | ||
1007 | |||
984 | 1008 | ||
985 | LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) | 1009 | LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) |
986 | { | 1010 | { |
@@ -1142,6 +1166,34 @@ LLView* LLView::childrenHandleRightMouseDown(S32 x, S32 y, MASK mask) | |||
1142 | return handled_view; | 1166 | return handled_view; |
1143 | } | 1167 | } |
1144 | 1168 | ||
1169 | LLView* LLView::childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask) | ||
1170 | { | ||
1171 | LLView* handled_view = NULL; | ||
1172 | |||
1173 | if (getVisible() && getEnabled() ) | ||
1174 | { | ||
1175 | for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) | ||
1176 | { | ||
1177 | LLView* viewp = *child_it; | ||
1178 | S32 local_x = x - viewp->getRect().mLeft; | ||
1179 | S32 local_y = y - viewp->getRect().mBottom; | ||
1180 | if (viewp->pointInView(local_x, local_y) && | ||
1181 | viewp->getVisible() && | ||
1182 | viewp->getEnabled() && | ||
1183 | viewp->handleMiddleMouseDown( local_x, local_y, mask )) | ||
1184 | { | ||
1185 | if (sDebugMouseHandling) | ||
1186 | { | ||
1187 | sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage; | ||
1188 | } | ||
1189 | handled_view = viewp; | ||
1190 | break; | ||
1191 | } | ||
1192 | } | ||
1193 | } | ||
1194 | return handled_view; | ||
1195 | } | ||
1196 | |||
1145 | LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask) | 1197 | LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask) |
1146 | { | 1198 | { |
1147 | LLView* handled_view = NULL; | 1199 | LLView* handled_view = NULL; |
@@ -1227,6 +1279,32 @@ LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask) | |||
1227 | return handled_view; | 1279 | return handled_view; |
1228 | } | 1280 | } |
1229 | 1281 | ||
1282 | LLView* LLView::childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask) | ||
1283 | { | ||
1284 | LLView* handled_view = NULL; | ||
1285 | if( getVisible() && getEnabled() ) | ||
1286 | { | ||
1287 | for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) | ||
1288 | { | ||
1289 | LLView* viewp = *child_it; | ||
1290 | S32 local_x = x - viewp->getRect().mLeft; | ||
1291 | S32 local_y = y - viewp->getRect().mBottom; | ||
1292 | if (viewp->pointInView(local_x, local_y) && | ||
1293 | viewp->getVisible() && | ||
1294 | viewp->getEnabled() && | ||
1295 | viewp->handleMiddleMouseUp( local_x, local_y, mask )) | ||
1296 | { | ||
1297 | if (sDebugMouseHandling) | ||
1298 | { | ||
1299 | sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage; | ||
1300 | } | ||
1301 | handled_view = viewp; | ||
1302 | break; | ||
1303 | } | ||
1304 | } | ||
1305 | } | ||
1306 | return handled_view; | ||
1307 | } | ||
1230 | 1308 | ||
1231 | void LLView::draw() | 1309 | void LLView::draw() |
1232 | { | 1310 | { |
diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h index 80dd348..da7f164 100644 --- a/linden/indra/llui/llview.h +++ b/linden/indra/llui/llview.h | |||
@@ -463,6 +463,8 @@ public: | |||
463 | /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); | 463 | /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); |
464 | /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); | 464 | /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); |
465 | /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); | 465 | /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); |
466 | /*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask); | ||
467 | /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); | ||
466 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); | 468 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); |
467 | /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); | 469 | /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); |
468 | /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); | 470 | /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); |
@@ -596,6 +598,8 @@ protected: | |||
596 | LLView* childrenHandleHover(S32 x, S32 y, MASK mask); | 598 | LLView* childrenHandleHover(S32 x, S32 y, MASK mask); |
597 | LLView* childrenHandleMouseUp(S32 x, S32 y, MASK mask); | 599 | LLView* childrenHandleMouseUp(S32 x, S32 y, MASK mask); |
598 | LLView* childrenHandleMouseDown(S32 x, S32 y, MASK mask); | 600 | LLView* childrenHandleMouseDown(S32 x, S32 y, MASK mask); |
601 | LLView* childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask); | ||
602 | LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask); | ||
599 | LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask); | 603 | LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask); |
600 | LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks); | 604 | LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks); |
601 | LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); | 605 | LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); |
diff --git a/linden/indra/llwindow/CMakeLists.txt b/linden/indra/llwindow/CMakeLists.txt index 95e315f..afce0c0 100644 --- a/linden/indra/llwindow/CMakeLists.txt +++ b/linden/indra/llwindow/CMakeLists.txt | |||
@@ -46,6 +46,7 @@ set(llwindows_HEADER_FILES | |||
46 | 46 | ||
47 | set(viewer_SOURCE_FILES | 47 | set(viewer_SOURCE_FILES |
48 | llwindow.cpp | 48 | llwindow.cpp |
49 | llmousehandler.cpp | ||
49 | ) | 50 | ) |
50 | 51 | ||
51 | set(viewer_HEADER_FILES | 52 | set(viewer_HEADER_FILES |
diff --git a/linden/indra/llwindow/llmousehandler.cpp b/linden/indra/llwindow/llmousehandler.cpp new file mode 100644 index 0000000..ae2f147 --- /dev/null +++ b/linden/indra/llwindow/llmousehandler.cpp | |||
@@ -0,0 +1,59 @@ | |||
1 | /** | ||
2 | * @file llmousehandler.cpp | ||
3 | * @brief LLMouseHandler class implementation | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlife.com/developers/opensource/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | #include "llmousehandler.h" | ||
33 | |||
34 | //virtual | ||
35 | BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down) | ||
36 | { | ||
37 | BOOL handled = FALSE; | ||
38 | if (down) | ||
39 | { | ||
40 | switch (clicktype) | ||
41 | { | ||
42 | case CLICK_LEFT: handled = handleMouseDown(x, y, mask); break; | ||
43 | case CLICK_RIGHT: handled = handleRightMouseDown(x, y, mask); break; | ||
44 | case CLICK_MIDDLE: handled = handleMiddleMouseDown(x, y, mask); break; | ||
45 | case CLICK_DOUBLELEFT: handled = handleDoubleClick(x, y, mask); break; | ||
46 | } | ||
47 | } | ||
48 | else | ||
49 | { | ||
50 | switch (clicktype) | ||
51 | { | ||
52 | case CLICK_LEFT: handled = handleMouseUp(x, y, mask); break; | ||
53 | case CLICK_RIGHT: handled = handleRightMouseUp(x, y, mask); break; | ||
54 | case CLICK_MIDDLE: handled = handleMiddleMouseUp(x, y, mask); break; | ||
55 | case CLICK_DOUBLELEFT: handled = handleDoubleClick(x, y, mask); break; | ||
56 | } | ||
57 | } | ||
58 | return handled; | ||
59 | } | ||
diff --git a/linden/indra/llwindow/llmousehandler.h b/linden/indra/llwindow/llmousehandler.h index dba1fc1..45f837b 100644 --- a/linden/indra/llwindow/llmousehandler.h +++ b/linden/indra/llwindow/llmousehandler.h | |||
@@ -32,9 +32,10 @@ | |||
32 | #ifndef LL_MOUSEHANDLER_H | 32 | #ifndef LL_MOUSEHANDLER_H |
33 | #define LL_MOUSEHANDLER_H | 33 | #define LL_MOUSEHANDLER_H |
34 | 34 | ||
35 | #include "llstring.h" | 35 | #include "linden_common.h" |
36 | #include "llrect.h" | ||
36 | 37 | ||
37 | // Abstract interface. | 38 | // Mostly-abstract interface. |
38 | // Intended for use via multiple inheritance. | 39 | // Intended for use via multiple inheritance. |
39 | // A class may have as many interfaces as it likes, but never needs to inherit one more than once. | 40 | // A class may have as many interfaces as it likes, but never needs to inherit one more than once. |
40 | 41 | ||
@@ -48,13 +49,23 @@ public: | |||
48 | SHOW_IF_NOT_BLOCKED, | 49 | SHOW_IF_NOT_BLOCKED, |
49 | SHOW_ALWAYS, | 50 | SHOW_ALWAYS, |
50 | } EShowToolTip; | 51 | } EShowToolTip; |
52 | typedef enum { | ||
53 | CLICK_LEFT, | ||
54 | CLICK_MIDDLE, | ||
55 | CLICK_RIGHT, | ||
56 | CLICK_DOUBLELEFT | ||
57 | } EClickType; | ||
58 | virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down); | ||
51 | virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) = 0; | 59 | virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) = 0; |
52 | virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) = 0; | 60 | virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) = 0; |
53 | virtual BOOL handleHover(S32 x, S32 y, MASK mask) = 0; | 61 | virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask) = 0; |
54 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) = 0; | 62 | virtual BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask) = 0; |
55 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask) = 0; | ||
56 | virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) = 0; | 63 | virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) = 0; |
57 | virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) = 0; | 64 | virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) = 0; |
65 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask) = 0; | ||
66 | |||
67 | virtual BOOL handleHover(S32 x, S32 y, MASK mask) = 0; | ||
68 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) = 0; | ||
58 | virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) = 0; | 69 | virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) = 0; |
59 | virtual EShowToolTip getShowToolTip() { return SHOW_IF_NOT_BLOCKED; }; | 70 | virtual EShowToolTip getShowToolTip() { return SHOW_IF_NOT_BLOCKED; }; |
60 | virtual const std::string& getName() const = 0; | 71 | virtual const std::string& getName() const = 0; |
diff --git a/linden/indra/llwindow/llwindow.cpp b/linden/indra/llwindow/llwindow.cpp index 44908fb..b4c8ff0 100644 --- a/linden/indra/llwindow/llwindow.cpp +++ b/linden/indra/llwindow/llwindow.cpp | |||
@@ -307,6 +307,22 @@ void *LLWindow::getMediaWindow() | |||
307 | return getPlatformWindow(); | 307 | return getPlatformWindow(); |
308 | } | 308 | } |
309 | 309 | ||
310 | //virtual | ||
311 | BOOL LLWindow::isPrimaryTextAvailable() | ||
312 | { | ||
313 | return FALSE; // no | ||
314 | } | ||
315 | //virtual | ||
316 | BOOL LLWindow::pasteTextFromPrimary(LLWString &dst) | ||
317 | { | ||
318 | return FALSE; // fail | ||
319 | } | ||
320 | // virtual | ||
321 | BOOL LLWindow::copyTextToPrimary(const LLWString &src) | ||
322 | { | ||
323 | return FALSE; // fail | ||
324 | } | ||
325 | |||
310 | // static | 326 | // static |
311 | std::string LLWindow::getFontListSans() | 327 | std::string LLWindow::getFontListSans() |
312 | { | 328 | { |
diff --git a/linden/indra/llwindow/llwindow.h b/linden/indra/llwindow/llwindow.h index ffc117f..821de2f 100644 --- a/linden/indra/llwindow/llwindow.h +++ b/linden/indra/llwindow/llwindow.h | |||
@@ -184,9 +184,15 @@ public: | |||
184 | virtual void captureMouse() = 0; | 184 | virtual void captureMouse() = 0; |
185 | virtual void releaseMouse() = 0; | 185 | virtual void releaseMouse() = 0; |
186 | virtual void setMouseClipping( BOOL b ) = 0; | 186 | virtual void setMouseClipping( BOOL b ) = 0; |
187 | |||
187 | virtual BOOL isClipboardTextAvailable() = 0; | 188 | virtual BOOL isClipboardTextAvailable() = 0; |
188 | virtual BOOL pasteTextFromClipboard(LLWString &dst) = 0; | 189 | virtual BOOL pasteTextFromClipboard(LLWString &dst) = 0; |
189 | virtual BOOL copyTextToClipboard(const LLWString &src) = 0; | 190 | virtual BOOL copyTextToClipboard(const LLWString &src) = 0; |
191 | |||
192 | virtual BOOL isPrimaryTextAvailable(); | ||
193 | virtual BOOL pasteTextFromPrimary(LLWString &dst); | ||
194 | virtual BOOL copyTextToPrimary(const LLWString &src); | ||
195 | |||
190 | virtual void flashIcon(F32 seconds) = 0; | 196 | virtual void flashIcon(F32 seconds) = 0; |
191 | virtual F32 getGamma() = 0; | 197 | virtual F32 getGamma() = 0; |
192 | virtual BOOL setGamma(const F32 gamma) = 0; // Set the gamma | 198 | virtual BOOL setGamma(const F32 gamma) = 0; // Set the gamma |
diff --git a/linden/indra/llwindow/llwindowsdl.cpp b/linden/indra/llwindow/llwindowsdl.cpp index 8111aaf..5209e6f 100644 --- a/linden/indra/llwindow/llwindowsdl.cpp +++ b/linden/indra/llwindow/llwindowsdl.cpp | |||
@@ -188,11 +188,12 @@ Display* LLWindowSDL::get_SDL_Display(void) | |||
188 | 188 | ||
189 | 189 | ||
190 | LLWindowSDL::LLWindowSDL(const std::string& title, S32 x, S32 y, S32 width, | 190 | LLWindowSDL::LLWindowSDL(const std::string& title, S32 x, S32 y, S32 width, |
191 | S32 height, U32 flags, | 191 | S32 height, U32 flags, |
192 | BOOL fullscreen, BOOL clearBg, | 192 | BOOL fullscreen, BOOL clearBg, |
193 | BOOL disable_vsync, BOOL use_gl, | 193 | BOOL disable_vsync, BOOL use_gl, |
194 | BOOL ignore_pixel_depth, U32 fsaa_samples) | 194 | BOOL ignore_pixel_depth, U32 fsaa_samples) |
195 | : LLWindow(fullscreen, flags), mGamma(1.0f) | 195 | : LLWindow(fullscreen, flags), Lock_Display(NULL), |
196 | Unlock_Display(NULL), mGamma(1.0f) | ||
196 | { | 197 | { |
197 | // Initialize the keyboard | 198 | // Initialize the keyboard |
198 | gKeyboard = new LLKeyboardSDL(); | 199 | gKeyboard = new LLKeyboardSDL(); |
@@ -717,9 +718,33 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B | |||
717 | #endif | 718 | #endif |
718 | 719 | ||
719 | #if LL_X11 | 720 | #if LL_X11 |
720 | init_x11clipboard(); | 721 | /* Grab the window manager specific information */ |
722 | SDL_SysWMinfo info; | ||
723 | SDL_VERSION(&info.version); | ||
724 | if ( SDL_GetWMInfo(&info) ) | ||
725 | { | ||
726 | /* Save the information for later use */ | ||
727 | if ( info.subsystem == SDL_SYSWM_X11 ) | ||
728 | { | ||
729 | mSDL_Display = info.info.x11.display; | ||
730 | mSDL_XWindowID = info.info.x11.wmwindow; | ||
731 | Lock_Display = info.info.x11.lock_func; | ||
732 | Unlock_Display = info.info.x11.unlock_func; | ||
733 | } | ||
734 | else | ||
735 | { | ||
736 | llwarns << "We're not running under X11? Wild." | ||
737 | << llendl; | ||
738 | } | ||
739 | } | ||
740 | else | ||
741 | { | ||
742 | llwarns << "We're not running under any known WM. Wild." | ||
743 | << llendl; | ||
744 | } | ||
721 | #endif // LL_X11 | 745 | #endif // LL_X11 |
722 | 746 | ||
747 | |||
723 | //make sure multisampling is disabled by default | 748 | //make sure multisampling is disabled by default |
724 | glDisable(GL_MULTISAMPLE_ARB); | 749 | glDisable(GL_MULTISAMPLE_ARB); |
725 | 750 | ||
@@ -763,8 +788,12 @@ BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL | |||
763 | void LLWindowSDL::destroyContext() | 788 | void LLWindowSDL::destroyContext() |
764 | { | 789 | { |
765 | llinfos << "destroyContext begins" << llendl; | 790 | llinfos << "destroyContext begins" << llendl; |
791 | |||
766 | #if LL_X11 | 792 | #if LL_X11 |
767 | quit_x11clipboard(); | 793 | mSDL_Display = NULL; |
794 | mSDL_XWindowID = None; | ||
795 | Lock_Display = NULL; | ||
796 | Unlock_Display = NULL; | ||
768 | #endif // LL_X11 | 797 | #endif // LL_X11 |
769 | 798 | ||
770 | // Clean up remaining GL state before blowing away window | 799 | // Clean up remaining GL state before blowing away window |
@@ -1212,523 +1241,125 @@ void LLWindowSDL::flashIcon(F32 seconds) | |||
1212 | #endif // LL_X11 | 1241 | #endif // LL_X11 |
1213 | } | 1242 | } |
1214 | 1243 | ||
1215 | #if LL_X11 | 1244 | #if LL_GTK |
1216 | /* Lots of low-level X11 stuff to handle X11 copy-and-paste */ | 1245 | BOOL LLWindowSDL::isClipboardTextAvailable() |
1217 | |||
1218 | /* Our X11 clipboard support is a bit bizarre in various | ||
1219 | organically-grown ways. Ideally it should be fixed to do | ||
1220 | real string-type negotiation (this would make pasting to | ||
1221 | xterm faster and pasting to UTF-8 emacs work properly), but | ||
1222 | right now it has the rare and desirable trait of being | ||
1223 | generally stable and working. */ | ||
1224 | |||
1225 | typedef Atom x11clipboard_type; | ||
1226 | |||
1227 | /* PRIMARY and CLIPBOARD are the two main kinds of | ||
1228 | X11 clipboard. A third are the CUT_BUFFERs which an | ||
1229 | obsolete holdover from X10 days and use a quite orthogonal | ||
1230 | mechanism. CLIPBOARD is the type whose design most | ||
1231 | closely matches SL's own win32-alike explicit copy-and-paste | ||
1232 | paradigm. | ||
1233 | |||
1234 | Pragmatically we support all three to varying degrees. When | ||
1235 | we paste into SL, it is strictly from CLIPBOARD. When we copy, | ||
1236 | we support (to as full an extent as the clipboard content type | ||
1237 | allows) CLIPBOARD, PRIMARY, and CUT_BUFFER0. | ||
1238 | */ | ||
1239 | static x11clipboard_type get_x11_readwrite_clipboard_type(void) | ||
1240 | { | ||
1241 | return XInternAtom(LLWindowSDL::get_SDL_Display(), "CLIPBOARD", False); | ||
1242 | } | ||
1243 | |||
1244 | static x11clipboard_type get_x11_write_clipboard_type(void) | ||
1245 | { | ||
1246 | return XA_PRIMARY; | ||
1247 | } | ||
1248 | |||
1249 | /* This is where our own private cutbuffer goes - we don't use | ||
1250 | a regular cutbuffer (XA_CUT_BUFFER0 etc) for intermediate | ||
1251 | storage because their use isn't really defined for holding UTF8. */ | ||
1252 | static x11clipboard_type get_x11_cutbuffer_clipboard_type(void) | ||
1253 | { | ||
1254 | return XInternAtom(LLWindowSDL::get_SDL_Display(), "SECONDLIFE_CUTBUFFER", False); | ||
1255 | } | ||
1256 | |||
1257 | /* Some X11 atom-generators */ | ||
1258 | static Atom get_x11_targets_atom(void) | ||
1259 | { | ||
1260 | return XInternAtom(LLWindowSDL::get_SDL_Display(), "TARGETS", False); | ||
1261 | } | ||
1262 | |||
1263 | static Atom get_x11_text_atom(void) | ||
1264 | { | ||
1265 | return XInternAtom(LLWindowSDL::get_SDL_Display(), "TEXT", False); | ||
1266 | } | ||
1267 | |||
1268 | /* These defines, and convert_data/convert_x11clipboard, | ||
1269 | mostly exist to support non-text or unusually-encoded | ||
1270 | clipboard data, which we don't really have a need for at | ||
1271 | the moment. */ | ||
1272 | #define SDLCLIPTYPE(A, B, C, D) (int)(((A)<<24)|((B)<<16)|((C)<<8)|((D)<<0)) | ||
1273 | #define FORMAT_PREFIX "SECONDLIFE_x11clipboard_0x" | ||
1274 | |||
1275 | static | ||
1276 | x11clipboard_type convert_format(int type) | ||
1277 | { | 1246 | { |
1278 | if (!gWindowImplementation) | 1247 | if (ll_try_gtk_init()) |
1279 | { | 1248 | { |
1280 | llwarns << "!gWindowImplementation in convert_format()" | 1249 | GtkClipboard * const clipboard = |
1281 | << llendl; | 1250 | gtk_clipboard_get(GDK_NONE); |
1282 | return XA_STRING; | 1251 | return gtk_clipboard_wait_is_text_available(clipboard) ? |
1283 | } | 1252 | TRUE : FALSE; |
1284 | |||
1285 | switch (type) | ||
1286 | { | ||
1287 | case SDLCLIPTYPE('T', 'E', 'X', 'T'): | ||
1288 | // old-style X11 clipboard, strictly only ISO 8859-1 encoding | ||
1289 | return XA_STRING; | ||
1290 | case SDLCLIPTYPE('U', 'T', 'F', '8'): | ||
1291 | // newer de-facto UTF8 clipboard atom | ||
1292 | return XInternAtom(gWindowImplementation->mSDL_Display, | ||
1293 | "UTF8_STRING", False); | ||
1294 | default: | ||
1295 | { | ||
1296 | /* completely arbitrary clipboard types... we don't actually use | ||
1297 | these right now, and support is skeletal. */ | ||
1298 | char format[sizeof(FORMAT_PREFIX)+8+1]; /* Flawfinder: ignore */ | ||
1299 | |||
1300 | snprintf(format, sizeof(format), "%s%08lx", FORMAT_PREFIX, (unsigned long)type); | ||
1301 | return XInternAtom(gWindowImplementation->mSDL_Display, | ||
1302 | format, False); | ||
1303 | } | 1253 | } |
1304 | } | 1254 | return FALSE; // failure |
1305 | } | 1255 | } |
1306 | 1256 | ||
1307 | /* convert platform string to x11 clipboard format. for our | 1257 | BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &text) |
1308 | purposes this is pretty trivial right now. */ | ||
1309 | static int | ||
1310 | convert_data(int type, char *dst, const char *src, int srclen) | ||
1311 | { | 1258 | { |
1312 | int dstlen; | 1259 | if (ll_try_gtk_init()) |
1313 | |||
1314 | dstlen = 0; | ||
1315 | switch (type) | ||
1316 | { | 1260 | { |
1317 | case SDLCLIPTYPE('T', 'E', 'X', 'T'): | 1261 | GtkClipboard * const clipboard = |
1318 | case SDLCLIPTYPE('U', 'T', 'F', '8'): | 1262 | gtk_clipboard_get(GDK_NONE); |
1319 | if (src == NULL) | 1263 | gchar * const data = gtk_clipboard_wait_for_text(clipboard); |
1320 | { | 1264 | if (data) |
1321 | break; | ||
1322 | } | ||
1323 | if ( srclen == 0 ) | ||
1324 | srclen = strlen(src); /* Flawfinder: ignore */ | ||
1325 | |||
1326 | dstlen = srclen + 1; | ||
1327 | |||
1328 | if ( dst ) // assume caller made it big enough by asking us | ||
1329 | { | 1265 | { |
1330 | memcpy(dst, src, srclen); /* Flawfinder: ignore */ | 1266 | text = LLWString(utf8str_to_wstring(data)); |
1331 | dst[srclen] = '\0'; | 1267 | g_free(data); |
1268 | return TRUE; | ||
1332 | } | 1269 | } |
1333 | break; | ||
1334 | |||
1335 | default: | ||
1336 | llwarns << "convert_data: Unknown medium type" << llendl; | ||
1337 | break; | ||
1338 | } | 1270 | } |
1339 | return(dstlen); | 1271 | return FALSE; // failure |
1340 | } | 1272 | } |
1341 | 1273 | ||
1342 | /* Convert x11clipboard data to platform string. This too is | 1274 | BOOL LLWindowSDL::copyTextToClipboard(const LLWString &text) |
1343 | pretty trivial for our needs right now, and just about identical | ||
1344 | to above. */ | ||
1345 | static int | ||
1346 | convert_x11clipboard(int type, char *dst, const char *src, int srclen) | ||
1347 | { | 1275 | { |
1348 | int dstlen; | 1276 | if (ll_try_gtk_init()) |
1349 | |||
1350 | dstlen = 0; | ||
1351 | switch (type) | ||
1352 | { | 1277 | { |
1353 | case SDLCLIPTYPE('U', 'T', 'F', '8'): | 1278 | const std::string utf8 = wstring_to_utf8str(text); |
1354 | case SDLCLIPTYPE('T', 'E', 'X', 'T'): | 1279 | GtkClipboard * const clipboard = |
1355 | if (src == NULL) | 1280 | gtk_clipboard_get(GDK_NONE); |
1356 | { | 1281 | gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length()); |
1357 | break; | 1282 | return TRUE; |
1358 | } | ||
1359 | if ( srclen == 0 ) | ||
1360 | srclen = strlen(src); /* Flawfinder: ignore */ | ||
1361 | |||
1362 | dstlen = srclen + 1; | ||
1363 | |||
1364 | if ( dst ) // assume caller made it big enough by asking us | ||
1365 | { | ||
1366 | memcpy(dst, src, srclen); /* Flawfinder: ignore */ | ||
1367 | dst[srclen] = '\0'; | ||
1368 | } | ||
1369 | break; | ||
1370 | |||
1371 | default: | ||
1372 | llwarns << "convert_x11clipboard: Unknown medium type" << llendl; | ||
1373 | break; | ||
1374 | } | 1283 | } |
1375 | return dstlen; | 1284 | return FALSE; // failure |
1376 | } | ||
1377 | |||
1378 | int | ||
1379 | LLWindowSDL::is_empty_x11clipboard(void) | ||
1380 | { | ||
1381 | int retval; | ||
1382 | |||
1383 | maybe_lock_display(); | ||
1384 | retval = ( XGetSelectionOwner(mSDL_Display, get_x11_readwrite_clipboard_type()) == None ); | ||
1385 | maybe_unlock_display(); | ||
1386 | |||
1387 | return(retval); | ||
1388 | } | 1285 | } |
1389 | 1286 | ||
1390 | void | 1287 | BOOL LLWindowSDL::isPrimaryTextAvailable() |
1391 | LLWindowSDL::put_x11clipboard(int type, int srclen, const char *src) | ||
1392 | { | 1288 | { |
1393 | x11clipboard_type format; | 1289 | if (ll_try_gtk_init()) |
1394 | int dstlen; | ||
1395 | char *dst; | ||
1396 | |||
1397 | format = convert_format(type); | ||
1398 | dstlen = convert_data(type, NULL, src, srclen); | ||
1399 | |||
1400 | dst = (char *)malloc(dstlen); | ||
1401 | if ( dst != NULL ) | ||
1402 | { | 1290 | { |
1403 | maybe_lock_display(); | 1291 | GtkClipboard * const clipboard = |
1404 | Window root = DefaultRootWindow(mSDL_Display); | 1292 | gtk_clipboard_get(GDK_SELECTION_PRIMARY); |
1405 | convert_data(type, dst, src, srclen); | 1293 | return gtk_clipboard_wait_is_text_available(clipboard) ? |
1406 | // Cutbuffers are only allowed to have STRING atom types, | 1294 | TRUE : FALSE; |
1407 | // but Emacs puts UTF8 inside them anyway. We cautiously | ||
1408 | // don't. | ||
1409 | if (type == SDLCLIPTYPE('T','E','X','T')) | ||
1410 | { | ||
1411 | // dstlen-1 so we don't include the trailing \0 | ||
1412 | llinfos << "X11: Populating cutbuffer." <<llendl; | ||
1413 | XChangeProperty(mSDL_Display, root, | ||
1414 | XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, | ||
1415 | (unsigned char*)dst, dstlen-1); | ||
1416 | } else { | ||
1417 | // Should we clear the cutbuffer if we can't put the selection in | ||
1418 | // it because it's a UTF8 selection? Eh, no great reason I think. | ||
1419 | //XDeleteProperty(SDL_Display, root, XA_CUT_BUFFER0); | ||
1420 | } | ||
1421 | // Private cutbuffer of an appropriate type. | ||
1422 | XChangeProperty(mSDL_Display, root, | ||
1423 | get_x11_cutbuffer_clipboard_type(), format, 8, PropModeReplace, | ||
1424 | (unsigned char*)dst, dstlen-1); | ||
1425 | free(dst); | ||
1426 | |||
1427 | /* Claim ownership of both PRIMARY and CLIPBOARD */ | ||
1428 | XSetSelectionOwner(mSDL_Display, get_x11_readwrite_clipboard_type(), | ||
1429 | mSDL_XWindowID, CurrentTime); | ||
1430 | XSetSelectionOwner(mSDL_Display, get_x11_write_clipboard_type(), | ||
1431 | mSDL_XWindowID, CurrentTime); | ||
1432 | |||
1433 | maybe_unlock_display(); | ||
1434 | } | 1295 | } |
1296 | return FALSE; // failure | ||
1435 | } | 1297 | } |
1436 | 1298 | ||
1437 | void | 1299 | BOOL LLWindowSDL::pasteTextFromPrimary(LLWString &text) |
1438 | LLWindowSDL::get_x11clipboard(int type, int *dstlen, char **dst) | ||
1439 | { | 1300 | { |
1440 | x11clipboard_type format; | 1301 | if (ll_try_gtk_init()) |
1441 | |||
1442 | *dstlen = 0; | ||
1443 | format = convert_format(type); | ||
1444 | |||
1445 | Window owner; | ||
1446 | Atom selection; | ||
1447 | Atom seln_type; | ||
1448 | int seln_format; | ||
1449 | unsigned long nbytes; | ||
1450 | unsigned long overflow; | ||
1451 | char *src; | ||
1452 | |||
1453 | maybe_lock_display(); | ||
1454 | owner = XGetSelectionOwner(mSDL_Display, get_x11_readwrite_clipboard_type()); | ||
1455 | maybe_unlock_display(); | ||
1456 | if (owner == None) | ||
1457 | { | ||
1458 | // Fall right back to ancient X10 cut-buffers | ||
1459 | owner = DefaultRootWindow(mSDL_Display); | ||
1460 | selection = XA_CUT_BUFFER0; | ||
1461 | } else if (owner == mSDL_XWindowID) | ||
1462 | { | ||
1463 | // Use our own uncooked opaque string property | ||
1464 | owner = DefaultRootWindow(mSDL_Display); | ||
1465 | selection = get_x11_cutbuffer_clipboard_type(); | ||
1466 | } | ||
1467 | else | ||
1468 | { | ||
1469 | // Use full-on X11-style clipboard negotiation with the owning app | ||
1470 | int selection_response = 0; | ||
1471 | SDL_Event event; | ||
1472 | |||
1473 | owner = mSDL_XWindowID; | ||
1474 | maybe_lock_display(); | ||
1475 | selection = XInternAtom(mSDL_Display, "SDL_SELECTION", False); | ||
1476 | XConvertSelection(mSDL_Display, get_x11_readwrite_clipboard_type(), format, | ||
1477 | selection, owner, CurrentTime); | ||
1478 | maybe_unlock_display(); | ||
1479 | llinfos << "X11: Waiting for clipboard to arrive." <<llendl; | ||
1480 | while ( ! selection_response ) | ||
1481 | { | ||
1482 | // Only look for SYSWMEVENTs, or we may lose keypresses | ||
1483 | // etc. | ||
1484 | SDL_PumpEvents(); | ||
1485 | if (1 == SDL_PeepEvents(&event, 1, SDL_GETEVENT, | ||
1486 | SDL_SYSWMEVENTMASK) ) | ||
1487 | { | ||
1488 | if ( event.type == SDL_SYSWMEVENT ) | ||
1489 | { | ||
1490 | XEvent xevent = | ||
1491 | event.syswm.msg->event.xevent; | ||
1492 | |||
1493 | if ( (xevent.type == SelectionNotify)&& | ||
1494 | (xevent.xselection.requestor == owner) ) | ||
1495 | selection_response = 1; | ||
1496 | } | ||
1497 | } else { | ||
1498 | llinfos << "X11: Waiting for SYSWM event..." << llendl; | ||
1499 | } | ||
1500 | } | ||
1501 | llinfos << "X11: Clipboard arrived." <<llendl; | ||
1502 | } | ||
1503 | |||
1504 | maybe_lock_display(); | ||
1505 | if ( XGetWindowProperty(mSDL_Display, owner, selection, 0, INT_MAX/4, | ||
1506 | False, format, &seln_type, &seln_format, | ||
1507 | &nbytes, &overflow, (unsigned char **)&src) == Success ) | ||
1508 | { | 1302 | { |
1509 | if ( seln_type == format ) | 1303 | GtkClipboard * const clipboard = |
1510 | { | 1304 | gtk_clipboard_get(GDK_SELECTION_PRIMARY); |
1511 | *dstlen = convert_x11clipboard(type, NULL, src, nbytes); | 1305 | gchar * const data = gtk_clipboard_wait_for_text(clipboard); |
1512 | *dst = (char *)realloc(*dst, *dstlen); | 1306 | if (data) |
1513 | if ( *dst == NULL ) | ||
1514 | *dstlen = 0; | ||
1515 | else | ||
1516 | convert_x11clipboard(type, *dst, src, nbytes); | ||
1517 | } | ||
1518 | XFree(src); | ||
1519 | } | ||
1520 | maybe_unlock_display(); | ||
1521 | } | ||
1522 | |||
1523 | int clipboard_filter_callback(const SDL_Event *event) | ||
1524 | { | ||
1525 | /* Post all non-window manager specific events */ | ||
1526 | if ( event->type != SDL_SYSWMEVENT ) | ||
1527 | { | ||
1528 | return(1); | ||
1529 | } | ||
1530 | |||
1531 | /* Handle window-manager specific clipboard events */ | ||
1532 | switch (event->syswm.msg->event.xevent.type) { | ||
1533 | /* Copy the selection from SECONDLIFE_CUTBUFFER to the requested property */ | ||
1534 | case SelectionRequest: { | ||
1535 | XSelectionRequestEvent *req; | ||
1536 | XEvent sevent; | ||
1537 | int seln_format; | ||
1538 | unsigned long nbytes; | ||
1539 | unsigned long overflow; | ||
1540 | unsigned char *seln_data; | ||
1541 | |||
1542 | req = &event->syswm.msg->event.xevent.xselectionrequest; | ||
1543 | sevent.xselection.type = SelectionNotify; | ||
1544 | sevent.xselection.display = req->display; | ||
1545 | sevent.xselection.selection = req->selection; | ||
1546 | sevent.xselection.target = None; | ||
1547 | sevent.xselection.property = None; | ||
1548 | sevent.xselection.requestor = req->requestor; | ||
1549 | sevent.xselection.time = req->time; | ||
1550 | if ( XGetWindowProperty(LLWindowSDL::get_SDL_Display(), DefaultRootWindow(LLWindowSDL::get_SDL_Display()), | ||
1551 | get_x11_cutbuffer_clipboard_type(), 0, INT_MAX/4, False, req->target, | ||
1552 | &sevent.xselection.target, &seln_format, | ||
1553 | &nbytes, &overflow, &seln_data) == Success ) | ||
1554 | { | 1307 | { |
1555 | if ( sevent.xselection.target == req->target) | 1308 | text = LLWString(utf8str_to_wstring(data)); |
1556 | { | 1309 | g_free(data); |
1557 | if ( sevent.xselection.target == XA_STRING || | 1310 | return TRUE; |
1558 | sevent.xselection.target == | ||
1559 | convert_format(SDLCLIPTYPE('U','T','F','8')) ) | ||
1560 | { | ||
1561 | if ( seln_data[nbytes-1] == '\0' ) | ||
1562 | --nbytes; | ||
1563 | } | ||
1564 | XChangeProperty(LLWindowSDL::get_SDL_Display(), req->requestor, req->property, | ||
1565 | req->target, seln_format, PropModeReplace, | ||
1566 | seln_data, nbytes); | ||
1567 | sevent.xselection.property = req->property; | ||
1568 | } else if (get_x11_targets_atom() == req->target) { | ||
1569 | /* only advertise what we currently support */ | ||
1570 | const int num_supported = 3; | ||
1571 | Atom supported[num_supported] = { | ||
1572 | XA_STRING, // will be over-written below | ||
1573 | get_x11_text_atom(), | ||
1574 | get_x11_targets_atom() | ||
1575 | }; | ||
1576 | supported[0] = sevent.xselection.target; | ||
1577 | XChangeProperty(LLWindowSDL::get_SDL_Display(), req->requestor, | ||
1578 | req->property, XA_ATOM, 32, PropModeReplace, | ||
1579 | (unsigned char*)supported, | ||
1580 | num_supported); | ||
1581 | sevent.xselection.property = req->property; | ||
1582 | llinfos << "Clipboard: An app asked us what selections format we offer." << llendl; | ||
1583 | } else { | ||
1584 | llinfos << "Clipboard: An app requested an unsupported selection format " << req->target << ", we have " << sevent.xselection.target << llendl; | ||
1585 | sevent.xselection.target = None; | ||
1586 | } | ||
1587 | XFree(seln_data); | ||
1588 | } | 1311 | } |
1589 | int sendret = | ||
1590 | XSendEvent(LLWindowSDL::get_SDL_Display(),req->requestor,False,0,&sevent); | ||
1591 | if ((sendret==BadValue) || (sendret==BadWindow)) | ||
1592 | llwarns << "Clipboard SendEvent failed" << llendl; | ||
1593 | XSync(LLWindowSDL::get_SDL_Display(), False); | ||
1594 | } | ||
1595 | break; | ||
1596 | } | 1312 | } |
1597 | 1313 | return FALSE; // failure | |
1598 | /* Post the event for X11 clipboard reading above */ | ||
1599 | return(1); | ||
1600 | } | 1314 | } |
1601 | 1315 | ||
1602 | int | 1316 | BOOL LLWindowSDL::copyTextToPrimary(const LLWString &text) |
1603 | LLWindowSDL::init_x11clipboard(void) | ||
1604 | { | 1317 | { |
1605 | SDL_SysWMinfo info; | 1318 | if (ll_try_gtk_init()) |
1606 | int retval; | ||
1607 | |||
1608 | /* Grab the window manager specific information */ | ||
1609 | retval = -1; | ||
1610 | SDL_SetError("SDL is not running on known window manager"); | ||
1611 | |||
1612 | SDL_VERSION(&info.version); | ||
1613 | if ( SDL_GetWMInfo(&info) ) | ||
1614 | { | 1319 | { |
1615 | /* Save the information for later use */ | 1320 | const std::string utf8 = wstring_to_utf8str(text); |
1616 | if ( info.subsystem == SDL_SYSWM_X11 ) | 1321 | GtkClipboard * const clipboard = |
1617 | { | 1322 | gtk_clipboard_get(GDK_SELECTION_PRIMARY); |
1618 | mSDL_Display = info.info.x11.display; | 1323 | gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length()); |
1619 | mSDL_XWindowID = info.info.x11.wmwindow; | 1324 | return TRUE; |
1620 | Lock_Display = info.info.x11.lock_func; | ||
1621 | Unlock_Display = info.info.x11.unlock_func; | ||
1622 | |||
1623 | /* Enable the special window hook events */ | ||
1624 | SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); | ||
1625 | SDL_SetEventFilter(clipboard_filter_callback); | ||
1626 | |||
1627 | retval = 0; | ||
1628 | } | ||
1629 | else | ||
1630 | { | ||
1631 | SDL_SetError("SDL is not running on X11"); | ||
1632 | } | ||
1633 | } | 1325 | } |
1634 | return(retval); | 1326 | return FALSE; // failure |
1635 | } | ||
1636 | |||
1637 | void | ||
1638 | LLWindowSDL::quit_x11clipboard(void) | ||
1639 | { | ||
1640 | mSDL_Display = NULL; | ||
1641 | mSDL_XWindowID = None; | ||
1642 | Lock_Display = NULL; | ||
1643 | Unlock_Display = NULL; | ||
1644 | |||
1645 | SDL_SetEventFilter(NULL); // Stop custom event filtering | ||
1646 | } | 1327 | } |
1647 | 1328 | ||
1648 | /************************************************/ | 1329 | #else |
1649 | 1330 | ||
1650 | BOOL LLWindowSDL::isClipboardTextAvailable() | 1331 | BOOL LLWindowSDL::isClipboardTextAvailable() |
1651 | { | 1332 | { |
1652 | return !is_empty_x11clipboard(); | 1333 | return FALSE; // unsupported |
1653 | } | 1334 | } |
1654 | 1335 | ||
1655 | BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &dst) | 1336 | BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &dst) |
1656 | { | 1337 | { |
1657 | int cliplen; // seems 1 or 2 bytes longer than expected | 1338 | return FALSE; // unsupported |
1658 | char *cliptext = NULL; | ||
1659 | get_x11clipboard(SDLCLIPTYPE('U','T','F','8'), &cliplen, &cliptext); | ||
1660 | if (cliptext) | ||
1661 | { | ||
1662 | llinfos << "X11: Got UTF8 clipboard text." << llendl; | ||
1663 | // at some future time we can use cliplen instead of relying on \0, | ||
1664 | // if we ever grok non-ascii, non-utf8 encodings on the clipboard. | ||
1665 | std::string clip_str(cliptext); | ||
1666 | // we can't necessarily trust the incoming text to be valid UTF-8, | ||
1667 | // but utf8str_to_wstring() seems to do an appropriate level of | ||
1668 | // validation for avoiding over-reads. | ||
1669 | dst = utf8str_to_wstring(clip_str); | ||
1670 | /*llinfos << "X11 pasteTextFromClipboard: cliplen=" << cliplen << | ||
1671 | " strlen(cliptext)=" << strlen(cliptext) << | ||
1672 | " clip_str.length()=" << clip_str.length() << | ||
1673 | " dst.length()=" << dst.length() << | ||
1674 | llendl;*/ | ||
1675 | free(cliptext); | ||
1676 | return TRUE; // success | ||
1677 | } | ||
1678 | get_x11clipboard(SDLCLIPTYPE('T','E','X','T'), &cliplen, &cliptext); | ||
1679 | if (cliptext) | ||
1680 | { | ||
1681 | llinfos << "X11: Got ISO 8859-1 clipboard text." << llendl; | ||
1682 | std::string clip_str(cliptext); | ||
1683 | std::string utf8_str = rawstr_to_utf8(clip_str); | ||
1684 | dst = utf8str_to_wstring(utf8_str); | ||
1685 | free(cliptext); | ||
1686 | } | ||
1687 | return FALSE; // failure | ||
1688 | } | 1339 | } |
1340 | |||
1689 | 1341 | ||
1690 | BOOL LLWindowSDL::copyTextToClipboard(const LLWString &s) | 1342 | BOOL LLWindowSDL::copyTextToClipboard(const LLWString &s) |
1691 | { | 1343 | { |
1692 | std::string utf8text = wstring_to_utf8str(s); | 1344 | return FALSE; // unsupported |
1693 | const char* cstr = utf8text.c_str(); | ||
1694 | if (cstr == NULL) | ||
1695 | { | ||
1696 | return FALSE; | ||
1697 | } | ||
1698 | int cstrlen = strlen(cstr); /* Flawfinder: ignore */ | ||
1699 | int i; | ||
1700 | for (i=0; i<cstrlen; ++i) | ||
1701 | { | ||
1702 | if (0x80 & (unsigned char)cstr[i]) | ||
1703 | { | ||
1704 | // Found an 8-bit character; use new-style UTF8 clipboard | ||
1705 | llinfos << "X11: UTF8 copyTextToClipboard" << llendl; | ||
1706 | put_x11clipboard(SDLCLIPTYPE('U','T','F','8'), cstrlen, cstr); | ||
1707 | return TRUE; | ||
1708 | } | ||
1709 | } | ||
1710 | // Didn't find any 8-bit characters; use old-style ISO 8859-1 clipboard | ||
1711 | llinfos << "X11: ISO 8859-1 copyTextToClipboard" << llendl; | ||
1712 | put_x11clipboard(SDLCLIPTYPE('T','E','X','T'), cstrlen, cstr); | ||
1713 | return TRUE; | ||
1714 | } | 1345 | } |
1715 | #else | ||
1716 | 1346 | ||
1717 | BOOL LLWindowSDL::isClipboardTextAvailable() | 1347 | BOOL LLWindowSDL::isPrimaryTextAvailable() |
1718 | { | 1348 | { |
1719 | return FALSE; // unsupported | 1349 | return FALSE; // unsupported |
1720 | } | 1350 | } |
1721 | 1351 | ||
1722 | BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &dst) | 1352 | BOOL LLWindowSDL::pasteTextFromPrimary(LLWString &dst) |
1723 | { | 1353 | { |
1724 | return FALSE; // unsupported | 1354 | return FALSE; // unsupported |
1725 | } | 1355 | } |
1726 | 1356 | ||
1727 | BOOL LLWindowSDL::copyTextToClipboard(const LLWString &s) | 1357 | BOOL LLWindowSDL::copyTextToPrimary(const LLWString &s) |
1728 | { | 1358 | { |
1729 | return FALSE; // unsupported | 1359 | return FALSE; // unsupported |
1730 | } | 1360 | } |
1731 | #endif // LL_X11 | 1361 | |
1362 | #endif // LL_GTK | ||
1732 | 1363 | ||
1733 | LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_resolutions) | 1364 | LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_resolutions) |
1734 | { | 1365 | { |
@@ -2538,8 +2169,7 @@ S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 typ | |||
2538 | buttons = GTK_BUTTONS_YES_NO; | 2169 | buttons = GTK_BUTTONS_YES_NO; |
2539 | break; | 2170 | break; |
2540 | } | 2171 | } |
2541 | win = gtk_message_dialog_new(NULL, flags, messagetype, buttons, "%s", | 2172 | win = gtk_message_dialog_new(NULL,flags, messagetype, buttons, "%s", text.c_str()); |
2542 | text.c_str()); | ||
2543 | 2173 | ||
2544 | # if LL_X11 | 2174 | # if LL_X11 |
2545 | // Make GTK tell the window manager to associate this | 2175 | // Make GTK tell the window manager to associate this |
diff --git a/linden/indra/llwindow/llwindowsdl.h b/linden/indra/llwindow/llwindowsdl.h index 36baec6..54baf01 100644 --- a/linden/indra/llwindow/llwindowsdl.h +++ b/linden/indra/llwindow/llwindowsdl.h | |||
@@ -79,9 +79,15 @@ public: | |||
79 | /*virtual*/ void captureMouse(); | 79 | /*virtual*/ void captureMouse(); |
80 | /*virtual*/ void releaseMouse(); | 80 | /*virtual*/ void releaseMouse(); |
81 | /*virtual*/ void setMouseClipping( BOOL b ); | 81 | /*virtual*/ void setMouseClipping( BOOL b ); |
82 | |||
82 | /*virtual*/ BOOL isClipboardTextAvailable(); | 83 | /*virtual*/ BOOL isClipboardTextAvailable(); |
83 | /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); | 84 | /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); |
84 | /*virtual*/ BOOL copyTextToClipboard(const LLWString & src); | 85 | /*virtual*/ BOOL copyTextToClipboard(const LLWString & src); |
86 | |||
87 | /*virtual*/ BOOL isPrimaryTextAvailable(); | ||
88 | /*virtual*/ BOOL pasteTextFromPrimary(LLWString &dst); | ||
89 | /*virtual*/ BOOL copyTextToPrimary(const LLWString & src); | ||
90 | |||
85 | /*virtual*/ void flashIcon(F32 seconds); | 91 | /*virtual*/ void flashIcon(F32 seconds); |
86 | /*virtual*/ F32 getGamma(); | 92 | /*virtual*/ F32 getGamma(); |
87 | /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma | 93 | /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma |
@@ -123,7 +129,6 @@ public: | |||
123 | // Not great that these are public, but they have to be accessible | 129 | // Not great that these are public, but they have to be accessible |
124 | // by non-class code and it's better than making them global. | 130 | // by non-class code and it's better than making them global. |
125 | #if LL_X11 | 131 | #if LL_X11 |
126 | // These are set up by the X11 clipboard initialization code | ||
127 | Window mSDL_XWindowID; | 132 | Window mSDL_XWindowID; |
128 | Display *mSDL_Display; | 133 | Display *mSDL_Display; |
129 | #endif | 134 | #endif |
@@ -206,12 +211,6 @@ protected: | |||
206 | 211 | ||
207 | #if LL_X11 | 212 | #if LL_X11 |
208 | private: | 213 | private: |
209 | // more X11 clipboard stuff | ||
210 | int init_x11clipboard(void); | ||
211 | void quit_x11clipboard(void); | ||
212 | int is_empty_x11clipboard(void); | ||
213 | void put_x11clipboard(int type, int srclen, const char *src); | ||
214 | void get_x11clipboard(int type, int *dstlen, char **dst); | ||
215 | void x11_set_urgent(BOOL urgent); | 214 | void x11_set_urgent(BOOL urgent); |
216 | BOOL mFlashing; | 215 | BOOL mFlashing; |
217 | LLTimer mFlashTimer; | 216 | LLTimer mFlashTimer; |
diff --git a/linden/indra/newview/lltool.cpp b/linden/indra/newview/lltool.cpp index 99dbe31..9dfd86b 100644 --- a/linden/indra/newview/lltool.cpp +++ b/linden/indra/newview/lltool.cpp | |||
@@ -64,7 +64,6 @@ LLTool::~LLTool() | |||
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 | ||
67 | |||
68 | BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask) | 67 | BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask) |
69 | { | 68 | { |
70 | if (gDebugClicks) | 69 | if (gDebugClicks) |
@@ -124,6 +123,20 @@ BOOL LLTool::handleRightMouseUp(S32 x, S32 y, MASK mask) | |||
124 | // llinfos << "LLTool::handleRightMouseDown" << llendl; | 123 | // llinfos << "LLTool::handleRightMouseDown" << llendl; |
125 | return FALSE; | 124 | return FALSE; |
126 | } | 125 | } |
126 | |||
127 | BOOL LLTool::handleMiddleMouseDown(S32 x,S32 y,MASK mask) | ||
128 | { | ||
129 | // by default, didn't handle it | ||
130 | // llinfos << "LLTool::handleMiddleMouseDown" << llendl; | ||
131 | return FALSE; | ||
132 | } | ||
133 | |||
134 | BOOL LLTool::handleMiddleMouseUp(S32 x, S32 y, MASK mask) | ||
135 | { | ||
136 | // by default, didn't handle it | ||
137 | // llinfos << "LLTool::handleMiddleMouseUp" << llendl; | ||
138 | return FALSE; | ||
139 | } | ||
127 | 140 | ||
128 | BOOL LLTool::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) | 141 | BOOL LLTool::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) |
129 | { | 142 | { |
diff --git a/linden/indra/newview/lltool.h b/linden/indra/newview/lltool.h index cf97fb4..73463ba 100644 --- a/linden/indra/newview/lltool.h +++ b/linden/indra/newview/lltool.h | |||
@@ -56,6 +56,9 @@ public: | |||
56 | // Virtual functions inherited from LLMouseHandler | 56 | // Virtual functions inherited from LLMouseHandler |
57 | virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); | 57 | virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); |
58 | virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); | 58 | virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); |
59 | virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); | ||
60 | virtual BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask); | ||
61 | |||
59 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); | 62 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); |
60 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); | 63 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); |
61 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); | 64 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); |
diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp index 3e2cc19..54b7743 100644 --- a/linden/indra/newview/llviewertexteditor.cpp +++ b/linden/indra/newview/llviewertexteditor.cpp | |||
@@ -893,51 +893,9 @@ BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) | |||
893 | 893 | ||
894 | BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) | 894 | BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) |
895 | { | 895 | { |
896 | BOOL handled = FALSE; | 896 | BOOL handled = FALSE; |
897 | |||
898 | // let scrollbar have first dibs | ||
899 | handled = LLView::childrenHandleMouseUp(x, y, mask) != NULL; | ||
900 | |||
901 | // Used to enable I Agree checkbox if the user scrolled through entire text | ||
902 | BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); | ||
903 | if (mOnScrollEndCallback && was_scrolled_to_bottom) | ||
904 | { | ||
905 | mOnScrollEndCallback(mOnScrollEndData); | ||
906 | } | ||
907 | |||
908 | if( !handled && mTakesNonScrollClicks) | ||
909 | { | ||
910 | if( mIsSelecting ) | ||
911 | { | ||
912 | // Finish selection | ||
913 | if( y > getTextRect().mTop ) | ||
914 | { | ||
915 | mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); | ||
916 | } | ||
917 | else | ||
918 | if( y < getTextRect().mBottom ) | ||
919 | { | ||
920 | mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); | ||
921 | } | ||
922 | |||
923 | setCursorAtLocalPos( x, y, TRUE ); | ||
924 | endSelection(); | ||
925 | |||
926 | updateScrollFromCursor(); | ||
927 | } | ||
928 | |||
929 | if( !hasSelection() ) | ||
930 | { | ||
931 | handleMouseUpOverSegment( x, y, mask ); | ||
932 | } | ||
933 | |||
934 | handled = TRUE; | ||
935 | } | ||
936 | |||
937 | // Delay cursor flashing | ||
938 | resetKeystrokeTimer(); | ||
939 | 897 | ||
940 | if( hasMouseCapture() ) | 898 | if( hasMouseCapture() ) |
941 | { | 899 | { |
942 | if (mDragItem) | 900 | if (mDragItem) |
943 | { | 901 | { |
@@ -956,8 +914,15 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) | |||
956 | } | 914 | } |
957 | } | 915 | } |
958 | mDragItem = NULL; | 916 | mDragItem = NULL; |
959 | gFocusMgr.setMouseCapture( NULL ); | 917 | } |
960 | handled = TRUE; | 918 | |
919 | handled = LLTextEditor::handleMouseUp(x,y,mask); | ||
920 | |||
921 | // Used to enable I Agree checkbox if the user scrolled through entire text | ||
922 | BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); | ||
923 | if (mOnScrollEndCallback && was_scrolled_to_bottom) | ||
924 | { | ||
925 | mOnScrollEndCallback(mOnScrollEndData); | ||
961 | } | 926 | } |
962 | 927 | ||
963 | return handled; | 928 | return handled; |
@@ -999,6 +964,24 @@ BOOL LLViewerTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask) | |||
999 | return handled; | 964 | return handled; |
1000 | } | 965 | } |
1001 | 966 | ||
967 | BOOL LLViewerTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask) | ||
968 | { | ||
969 | BOOL handled = FALSE; | ||
970 | handled = childrenHandleMiddleMouseDown(x, y, mask) != NULL; | ||
971 | if (!handled) | ||
972 | { | ||
973 | handled = LLTextEditor::handleMiddleMouseDown(x, y, mask); | ||
974 | } | ||
975 | return handled; | ||
976 | } | ||
977 | |||
978 | BOOL LLViewerTextEditor::handleMiddleMouseUp(S32 x, S32 y, MASK mask) | ||
979 | { | ||
980 | BOOL handled = childrenHandleMiddleMouseUp(x, y, mask) != NULL; | ||
981 | |||
982 | return handled; | ||
983 | } | ||
984 | |||
1002 | BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) | 985 | BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) |
1003 | { | 986 | { |
1004 | BOOL handled = FALSE; | 987 | BOOL handled = FALSE; |
@@ -1021,7 +1004,6 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
1021 | } | 1004 | } |
1022 | } | 1005 | } |
1023 | } | 1006 | } |
1024 | |||
1025 | 1007 | ||
1026 | setCursorAtLocalPos( x, y, FALSE ); | 1008 | setCursorAtLocalPos( x, y, FALSE ); |
1027 | deselect(); | 1009 | deselect(); |
@@ -1059,6 +1041,9 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
1059 | // delay cursor flashing | 1041 | // delay cursor flashing |
1060 | resetKeystrokeTimer(); | 1042 | resetKeystrokeTimer(); |
1061 | 1043 | ||
1044 | // take selection to 'primary' clipboard | ||
1045 | updatePrimary(); | ||
1046 | |||
1062 | handled = TRUE; | 1047 | handled = TRUE; |
1063 | } | 1048 | } |
1064 | return handled; | 1049 | return handled; |
diff --git a/linden/indra/newview/llviewertexteditor.h b/linden/indra/newview/llviewertexteditor.h index 4cd5850..062808a 100644 --- a/linden/indra/newview/llviewertexteditor.h +++ b/linden/indra/newview/llviewertexteditor.h | |||
@@ -58,6 +58,8 @@ public: | |||
58 | // mousehandler overrides | 58 | // mousehandler overrides |
59 | virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); | 59 | virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); |
60 | virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); | 60 | virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); |
61 | virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); | ||
62 | virtual BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask); | ||
61 | virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); | 63 | virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); |
62 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); | 64 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); |
63 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); | 65 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); |
diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index 7e6c24f..3b23bb9 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp | |||
@@ -547,19 +547,42 @@ bool LLViewerWindow::shouldShowToolTipFor(LLMouseHandler *mh) | |||
547 | return false; | 547 | return false; |
548 | } | 548 | } |
549 | 549 | ||
550 | BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) | 550 | BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) |
551 | { | 551 | { |
552 | std::string buttonname; | ||
553 | std::string buttonstatestr; | ||
554 | BOOL handled = FALSE; | ||
552 | S32 x = pos.mX; | 555 | S32 x = pos.mX; |
553 | S32 y = pos.mY; | 556 | S32 y = pos.mY; |
554 | x = llround((F32)x / mDisplayScale.mV[VX]); | 557 | x = llround((F32)x / mDisplayScale.mV[VX]); |
555 | y = llround((F32)y / mDisplayScale.mV[VY]); | 558 | y = llround((F32)y / mDisplayScale.mV[VY]); |
556 | 559 | ||
557 | LLView::sMouseHandlerMessage.clear(); | 560 | if (down) |
558 | 561 | buttonstatestr = "down" ; | |
559 | if (gDebugClicks) | 562 | else |
563 | buttonstatestr = "up" ; | ||
564 | |||
565 | switch (clicktype) | ||
560 | { | 566 | { |
561 | llinfos << "ViewerWindow left mouse down at " << x << "," << y << llendl; | 567 | case LLMouseHandler::CLICK_LEFT: |
568 | mLeftMouseDown = down; | ||
569 | buttonname = "Left"; | ||
570 | break; | ||
571 | case LLMouseHandler::CLICK_RIGHT: | ||
572 | mRightMouseDown = down; | ||
573 | buttonname = "Right"; | ||
574 | break; | ||
575 | case LLMouseHandler::CLICK_MIDDLE: | ||
576 | mMiddleMouseDown = down; | ||
577 | buttonname = "Middle"; | ||
578 | break; | ||
579 | case LLMouseHandler::CLICK_DOUBLELEFT: | ||
580 | mLeftMouseDown = down; | ||
581 | buttonname = "Left Double Click"; | ||
582 | break; | ||
562 | } | 583 | } |
584 | |||
585 | LLView::sMouseHandlerMessage.clear(); | ||
563 | 586 | ||
564 | if (gMenuBarView) | 587 | if (gMenuBarView) |
565 | { | 588 | { |
@@ -567,7 +590,10 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask | |||
567 | gMenuBarView->resetMenuTrigger(); | 590 | gMenuBarView->resetMenuTrigger(); |
568 | } | 591 | } |
569 | 592 | ||
570 | mLeftMouseDown = TRUE; | 593 | if (gDebugClicks) |
594 | { | ||
595 | llinfos << "ViewerWindow " << buttonname << " mouse " << buttonstatestr << " at " << x << "," << y << llendl; | ||
596 | } | ||
571 | 597 | ||
572 | // Make sure we get a coresponding mouseup event, even if the mouse leaves the window | 598 | // Make sure we get a coresponding mouseup event, even if the mouse leaves the window |
573 | mWindow->captureMouse(); | 599 | mWindow->captureMouse(); |
@@ -576,9 +602,9 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask | |||
576 | gMouseIdleTimer.reset(); | 602 | gMouseIdleTimer.reset(); |
577 | 603 | ||
578 | // Hide tooltips on mousedown | 604 | // Hide tooltips on mousedown |
579 | mToolTipBlocked = TRUE; | 605 | mToolTipBlocked = down; |
580 | 606 | ||
581 | // Also hide hover info on mousedown | 607 | // Also hide hover info on mousedown/mouseup |
582 | if (gHoverView) | 608 | if (gHoverView) |
583 | { | 609 | { |
584 | gHoverView->cancelHover(); | 610 | gHoverView->cancelHover(); |
@@ -587,7 +613,7 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask | |||
587 | // Don't let the user move the mouse out of the window until mouse up. | 613 | // Don't let the user move the mouse out of the window until mouse up. |
588 | if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() ) | 614 | if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() ) |
589 | { | 615 | { |
590 | mWindow->setMouseClipping(TRUE); | 616 | mWindow->setMouseClipping(down); |
591 | } | 617 | } |
592 | 618 | ||
593 | LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); | 619 | LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); |
@@ -598,10 +624,9 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask | |||
598 | mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); | 624 | mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); |
599 | if (LLView::sDebugMouseHandling) | 625 | if (LLView::sDebugMouseHandling) |
600 | { | 626 | { |
601 | llinfos << "Left Mouse Down handled by captor " << mouse_captor->getName() << llendl; | 627 | llinfos << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << llendl; |
602 | } | 628 | } |
603 | 629 | return mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down); | |
604 | return mouse_captor->handleMouseDown(local_x, local_y, mask); | ||
605 | } | 630 | } |
606 | 631 | ||
607 | // Topmost view gets a chance before the hierarchy | 632 | // Topmost view gets a chance before the hierarchy |
@@ -610,215 +635,95 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask | |||
610 | { | 635 | { |
611 | S32 local_x, local_y; | 636 | S32 local_x, local_y; |
612 | top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); | 637 | top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); |
613 | if (top_ctrl->pointInView(local_x, local_y)) | 638 | if (down) |
614 | { | 639 | { |
615 | return top_ctrl->handleMouseDown(local_x, local_y, mask); | 640 | if (top_ctrl->pointInView(local_x, local_y)) |
616 | } | 641 | { |
617 | else | 642 | return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ; |
618 | { | 643 | } |
619 | gFocusMgr.setTopCtrl(NULL); | 644 | else |
645 | { | ||
646 | gFocusMgr.setTopCtrl(NULL); | ||
647 | } | ||
620 | } | 648 | } |
621 | } | 649 | else |
650 | handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask); | ||
622 | 651 | ||
652 | |||
653 | } | ||
623 | // Give the UI views a chance to process the click | 654 | // Give the UI views a chance to process the click |
624 | if( mRootView->handleMouseDown(x, y, mask) ) | 655 | if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ) |
625 | { | 656 | { |
626 | if (LLView::sDebugMouseHandling) | 657 | if (LLView::sDebugMouseHandling) |
627 | { | 658 | { |
628 | llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl; | 659 | llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLView::sMouseHandlerMessage << llendl; |
629 | } | 660 | } |
630 | return TRUE; | 661 | return TRUE; |
631 | } | 662 | } |
632 | else if (LLView::sDebugMouseHandling) | 663 | else if (LLView::sDebugMouseHandling) |
633 | { | 664 | { |
634 | llinfos << "Left Mouse Down not handled by view" << llendl; | 665 | llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl; |
635 | } | ||
636 | |||
637 | if (gDisconnected) | ||
638 | { | ||
639 | return FALSE; | ||
640 | } | ||
641 | |||
642 | if(LLToolMgr::getInstance()->getCurrentTool()->handleMouseDown( x, y, mask ) ) | ||
643 | { | ||
644 | // This is necessary to force clicks in the world to cause edit | ||
645 | // boxes that might have keyboard focus to relinquish it, and hence | ||
646 | // cause a commit to update their value. JC | ||
647 | gFocusMgr.setKeyboardFocus(NULL); | ||
648 | return TRUE; | ||
649 | } | ||
650 | |||
651 | return FALSE; | ||
652 | } | ||
653 | |||
654 | BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask) | ||
655 | { | ||
656 | S32 x = pos.mX; | ||
657 | S32 y = pos.mY; | ||
658 | x = llround((F32)x / mDisplayScale.mV[VX]); | ||
659 | y = llround((F32)y / mDisplayScale.mV[VY]); | ||
660 | |||
661 | LLView::sMouseHandlerMessage.clear(); | ||
662 | |||
663 | if (gDebugClicks) | ||
664 | { | ||
665 | llinfos << "ViewerWindow left mouse double-click at " << x << "," << y << llendl; | ||
666 | } | 666 | } |
667 | 667 | if (down) | |
668 | mLeftMouseDown = TRUE; | ||
669 | |||
670 | // Hide tooltips | ||
671 | if( mToolTip ) | ||
672 | { | 668 | { |
673 | mToolTip->setVisible( FALSE ); | 669 | if (gDisconnected) |
674 | } | ||
675 | |||
676 | LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); | ||
677 | if( mouse_captor ) | ||
678 | { | ||
679 | S32 local_x; | ||
680 | S32 local_y; | ||
681 | mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); | ||
682 | if (LLView::sDebugMouseHandling) | ||
683 | { | 670 | { |
684 | llinfos << "Left Mouse Down handled by captor " << mouse_captor->getName() << llendl; | 671 | return FALSE; |
685 | } | ||
686 | |||
687 | return mouse_captor->handleDoubleClick(local_x, local_y, mask); | ||
688 | } | ||
689 | |||
690 | // Check for hit on UI. | ||
691 | LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); | ||
692 | if (top_ctrl) | ||
693 | { | ||
694 | S32 local_x, local_y; | ||
695 | top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); | ||
696 | if (top_ctrl->pointInView(local_x, local_y)) | ||
697 | { | ||
698 | return top_ctrl->handleDoubleClick(local_x, local_y, mask); | ||
699 | } | 672 | } |
700 | else | 673 | |
674 | if(LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) | ||
701 | { | 675 | { |
702 | gFocusMgr.setTopCtrl(NULL); | 676 | // This is necessary to force clicks in the world to cause edit |
677 | // boxes that might have keyboard focus to relinquish it, and hence | ||
678 | // cause a commit to update their value. JC | ||
679 | gFocusMgr.setKeyboardFocus(NULL); | ||
680 | return TRUE; | ||
703 | } | 681 | } |
704 | } | 682 | } |
705 | 683 | else | |
706 | if (mRootView->handleDoubleClick(x, y, mask)) | ||
707 | { | 684 | { |
708 | if (LLView::sDebugMouseHandling) | 685 | |
686 | mWindow->releaseMouse(); | ||
687 | |||
688 | LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); | ||
689 | if( !handled ) | ||
709 | { | 690 | { |
710 | llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl; | 691 | handled = mRootView->handleAnyMouseClick(x, y, mask, clicktype, down); |
692 | } | ||
693 | |||
694 | |||
695 | |||
696 | if( !handled ) | ||
697 | { | ||
698 | if (tool) | ||
699 | { | ||
700 | handled = tool->handleAnyMouseClick(x, y, mask, clicktype, down); | ||
701 | } | ||
711 | } | 702 | } |
712 | return TRUE; | ||
713 | } | ||
714 | else if (LLView::sDebugMouseHandling) | ||
715 | { | ||
716 | llinfos << "Left Mouse Down not handled by view" << llendl; | ||
717 | } | 703 | } |
718 | 704 | ||
719 | // Why is this here? JC 9/3/2002 | 705 | return (!down); |
720 | if (gNoRender) | 706 | } |
721 | { | ||
722 | return TRUE; | ||
723 | } | ||
724 | 707 | ||
725 | if(LLToolMgr::getInstance()->getCurrentTool()->handleDoubleClick( x, y, mask ) ) | 708 | BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) |
726 | { | 709 | { |
727 | return TRUE; | 710 | BOOL down = TRUE; |
728 | } | 711 | return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down); |
712 | } | ||
729 | 713 | ||
730 | // if we got this far and nothing handled a double click, pass a normal mouse down | 714 | BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask) |
731 | return handleMouseDown(window, pos, mask); | 715 | { |
716 | // try handling as a double-click first, then a single-click if that | ||
717 | // wasn't handled. | ||
718 | BOOL down = TRUE; | ||
719 | return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_DOUBLELEFT,down) || | ||
720 | handleMouseDown(window, pos, mask); | ||
732 | } | 721 | } |
733 | 722 | ||
734 | BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) | 723 | BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) |
735 | { | 724 | { |
736 | S32 x = pos.mX; | 725 | BOOL down = FALSE; |
737 | S32 y = pos.mY; | 726 | return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down); |
738 | x = llround((F32)x / mDisplayScale.mV[VX]); | ||
739 | y = llround((F32)y / mDisplayScale.mV[VY]); | ||
740 | |||
741 | LLView::sMouseHandlerMessage.clear(); | ||
742 | |||
743 | if (gDebugClicks) | ||
744 | { | ||
745 | llinfos << "ViewerWindow left mouse up" << llendl; | ||
746 | } | ||
747 | |||
748 | mLeftMouseDown = FALSE; | ||
749 | |||
750 | // Indicate mouse was active | ||
751 | gMouseIdleTimer.reset(); | ||
752 | |||
753 | // Hide tooltips on mouseup | ||
754 | if( mToolTip ) | ||
755 | { | ||
756 | mToolTip->setVisible( FALSE ); | ||
757 | } | ||
758 | |||
759 | // Also hide hover info on mouseup | ||
760 | if (gHoverView) gHoverView->cancelHover(); | ||
761 | |||
762 | BOOL handled = FALSE; | ||
763 | |||
764 | mWindow->releaseMouse(); | ||
765 | |||
766 | LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); | ||
767 | |||
768 | if( tool->clipMouseWhenDown() ) | ||
769 | { | ||
770 | mWindow->setMouseClipping(FALSE); | ||
771 | } | ||
772 | |||
773 | LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); | ||
774 | if( mouse_captor ) | ||
775 | { | ||
776 | S32 local_x; | ||
777 | S32 local_y; | ||
778 | mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); | ||
779 | if (LLView::sDebugMouseHandling) | ||
780 | { | ||
781 | llinfos << "Left Mouse Up handled by captor " << mouse_captor->getName() << llendl; | ||
782 | } | ||
783 | |||
784 | return mouse_captor->handleMouseUp(local_x, local_y, mask); | ||
785 | } | ||
786 | |||
787 | LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); | ||
788 | if (top_ctrl) | ||
789 | { | ||
790 | S32 local_x, local_y; | ||
791 | top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); | ||
792 | handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask); | ||
793 | } | ||
794 | |||
795 | if( !handled ) | ||
796 | { | ||
797 | handled = mRootView->handleMouseUp(x, y, mask); | ||
798 | } | ||
799 | |||
800 | if (LLView::sDebugMouseHandling) | ||
801 | { | ||
802 | if (handled) | ||
803 | { | ||
804 | llinfos << "Left Mouse Up" << LLView::sMouseHandlerMessage << llendl; | ||
805 | } | ||
806 | else | ||
807 | { | ||
808 | llinfos << "Left Mouse Up not handled by view" << llendl; | ||
809 | } | ||
810 | } | ||
811 | |||
812 | if( !handled ) | ||
813 | { | ||
814 | if (tool) | ||
815 | { | ||
816 | handled = tool->handleMouseUp(x, y, mask); | ||
817 | } | ||
818 | } | ||
819 | |||
820 | // Always handled as far as the OS is concerned. | ||
821 | return TRUE; | ||
822 | } | 727 | } |
823 | 728 | ||
824 | 729 | ||
@@ -829,91 +734,10 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK | |||
829 | x = llround((F32)x / mDisplayScale.mV[VX]); | 734 | x = llround((F32)x / mDisplayScale.mV[VX]); |
830 | y = llround((F32)y / mDisplayScale.mV[VY]); | 735 | y = llround((F32)y / mDisplayScale.mV[VY]); |
831 | 736 | ||
832 | LLView::sMouseHandlerMessage.clear(); | 737 | BOOL down = TRUE; |
833 | 738 | BOOL handle = handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down); | |
834 | if (gDebugClicks) | 739 | if (handle) |
835 | { | 740 | return handle; |
836 | llinfos << "ViewerWindow right mouse down at " << x << "," << y << llendl; | ||
837 | } | ||
838 | |||
839 | if (gMenuBarView) | ||
840 | { | ||
841 | // stop ALT-key access to menu | ||
842 | gMenuBarView->resetMenuTrigger(); | ||
843 | } | ||
844 | |||
845 | mRightMouseDown = TRUE; | ||
846 | |||
847 | // Make sure we get a coresponding mouseup event, even if the mouse leaves the window | ||
848 | mWindow->captureMouse(); | ||
849 | |||
850 | // Hide tooltips | ||
851 | if( mToolTip ) | ||
852 | { | ||
853 | mToolTip->setVisible( FALSE ); | ||
854 | } | ||
855 | |||
856 | // Also hide hover info on mousedown | ||
857 | if (gHoverView) | ||
858 | { | ||
859 | gHoverView->cancelHover(); | ||
860 | } | ||
861 | |||
862 | // Don't let the user move the mouse out of the window until mouse up. | ||
863 | if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() ) | ||
864 | { | ||
865 | mWindow->setMouseClipping(TRUE); | ||
866 | } | ||
867 | |||
868 | LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); | ||
869 | if( mouse_captor ) | ||
870 | { | ||
871 | S32 local_x; | ||
872 | S32 local_y; | ||
873 | mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); | ||
874 | if (LLView::sDebugMouseHandling) | ||
875 | { | ||
876 | llinfos << "Right Mouse Down handled by captor " << mouse_captor->getName() << llendl; | ||
877 | } | ||
878 | return mouse_captor->handleRightMouseDown(local_x, local_y, mask); | ||
879 | } | ||
880 | |||
881 | LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); | ||
882 | if (top_ctrl) | ||
883 | { | ||
884 | S32 local_x, local_y; | ||
885 | top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); | ||
886 | if (top_ctrl->pointInView(local_x, local_y)) | ||
887 | { | ||
888 | return top_ctrl->handleRightMouseDown(local_x, local_y, mask); | ||
889 | } | ||
890 | else | ||
891 | { | ||
892 | gFocusMgr.setTopCtrl(NULL); | ||
893 | } | ||
894 | } | ||
895 | |||
896 | if( mRootView->handleRightMouseDown(x, y, mask) ) | ||
897 | { | ||
898 | if (LLView::sDebugMouseHandling) | ||
899 | { | ||
900 | llinfos << "Right Mouse Down" << LLView::sMouseHandlerMessage << llendl; | ||
901 | } | ||
902 | return TRUE; | ||
903 | } | ||
904 | else if (LLView::sDebugMouseHandling) | ||
905 | { | ||
906 | llinfos << "Right Mouse Down not handled by view" << llendl; | ||
907 | } | ||
908 | |||
909 | if(LLToolMgr::getInstance()->getCurrentTool()->handleRightMouseDown( x, y, mask ) ) | ||
910 | { | ||
911 | // This is necessary to force clicks in the world to cause edit | ||
912 | // boxes that might have keyboard focus to relinquish it, and hence | ||
913 | // cause a commit to update their value. JC | ||
914 | gFocusMgr.setKeyboardFocus(NULL); | ||
915 | return TRUE; | ||
916 | } | ||
917 | 741 | ||
918 | // *HACK: this should be rolled into the composite tool logic, not | 742 | // *HACK: this should be rolled into the composite tool logic, not |
919 | // hardcoded at the top level. | 743 | // hardcoded at the top level. |
@@ -931,107 +755,27 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK | |||
931 | 755 | ||
932 | BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) | 756 | BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) |
933 | { | 757 | { |
934 | S32 x = pos.mX; | 758 | BOOL down = FALSE; |
935 | S32 y = pos.mY; | 759 | return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down); |
936 | x = llround((F32)x / mDisplayScale.mV[VX]); | ||
937 | y = llround((F32)y / mDisplayScale.mV[VY]); | ||
938 | |||
939 | LLView::sMouseHandlerMessage.clear(); | ||
940 | |||
941 | // Don't care about caps lock for mouse events. | ||
942 | if (gDebugClicks) | ||
943 | { | ||
944 | llinfos << "ViewerWindow right mouse up" << llendl; | ||
945 | } | ||
946 | |||
947 | mRightMouseDown = FALSE; | ||
948 | |||
949 | // Indicate mouse was active | ||
950 | gMouseIdleTimer.reset(); | ||
951 | |||
952 | // Hide tooltips on mouseup | ||
953 | if( mToolTip ) | ||
954 | { | ||
955 | mToolTip->setVisible( FALSE ); | ||
956 | } | ||
957 | |||
958 | // Also hide hover info on mouseup | ||
959 | if (gHoverView) gHoverView->cancelHover(); | ||
960 | |||
961 | BOOL handled = FALSE; | ||
962 | |||
963 | mWindow->releaseMouse(); | ||
964 | |||
965 | LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); | ||
966 | |||
967 | if( tool->clipMouseWhenDown() ) | ||
968 | { | ||
969 | mWindow->setMouseClipping(FALSE); | ||
970 | } | ||
971 | |||
972 | LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); | ||
973 | if( mouse_captor ) | ||
974 | { | ||
975 | S32 local_x; | ||
976 | S32 local_y; | ||
977 | mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); | ||
978 | if (LLView::sDebugMouseHandling) | ||
979 | { | ||
980 | llinfos << "Right Mouse Up handled by captor " << mouse_captor->getName() << llendl; | ||
981 | } | ||
982 | return mouse_captor->handleRightMouseUp(local_x, local_y, mask); | ||
983 | } | ||
984 | |||
985 | LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); | ||
986 | if (top_ctrl) | ||
987 | { | ||
988 | S32 local_x, local_y; | ||
989 | top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); | ||
990 | handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleRightMouseUp(local_x, local_y, mask); | ||
991 | } | ||
992 | |||
993 | if( !handled ) | ||
994 | { | ||
995 | handled = mRootView->handleRightMouseUp(x, y, mask); | ||
996 | } | ||
997 | |||
998 | if (LLView::sDebugMouseHandling) | ||
999 | { | ||
1000 | if (handled) | ||
1001 | { | ||
1002 | llinfos << "Right Mouse Up" << LLView::sMouseHandlerMessage << llendl; | ||
1003 | } | ||
1004 | else | ||
1005 | { | ||
1006 | llinfos << "Right Mouse Up not handled by view" << llendl; | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | if( !handled ) | ||
1011 | { | ||
1012 | if (tool) | ||
1013 | { | ||
1014 | handled = tool->handleRightMouseUp(x, y, mask); | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | // Always handled as far as the OS is concerned. | ||
1019 | return TRUE; | ||
1020 | } | 760 | } |
1021 | 761 | ||
1022 | BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) | 762 | BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) |
1023 | { | 763 | { |
764 | BOOL down = TRUE; | ||
1024 | gVoiceClient->middleMouseState(true); | 765 | gVoiceClient->middleMouseState(true); |
1025 | 766 | handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down); | |
1026 | // Always handled as far as the OS is concerned. | 767 | |
768 | // Always handled as far as the OS is concerned. | ||
1027 | return TRUE; | 769 | return TRUE; |
1028 | } | 770 | } |
1029 | 771 | ||
1030 | BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) | 772 | BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) |
1031 | { | 773 | { |
774 | BOOL down = FALSE; | ||
1032 | gVoiceClient->middleMouseState(false); | 775 | gVoiceClient->middleMouseState(false); |
1033 | 776 | handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down); | |
1034 | // Always handled as far as the OS is concerned. | 777 | |
778 | // Always handled as far as the OS is concerned. | ||
1035 | return TRUE; | 779 | return TRUE; |
1036 | } | 780 | } |
1037 | 781 | ||
@@ -1404,6 +1148,7 @@ LLViewerWindow::LLViewerWindow( | |||
1404 | mWindowRect(0, height, width, 0), | 1148 | mWindowRect(0, height, width, 0), |
1405 | mVirtualWindowRect(0, height, width, 0), | 1149 | mVirtualWindowRect(0, height, width, 0), |
1406 | mLeftMouseDown(FALSE), | 1150 | mLeftMouseDown(FALSE), |
1151 | mMiddleMouseDown(FALSE), | ||
1407 | mRightMouseDown(FALSE), | 1152 | mRightMouseDown(FALSE), |
1408 | mToolTip(NULL), | 1153 | mToolTip(NULL), |
1409 | mToolTipBlocked(FALSE), | 1154 | mToolTipBlocked(FALSE), |
diff --git a/linden/indra/newview/llviewerwindow.h b/linden/indra/newview/llviewerwindow.h index ab2dd4e..40368f8 100644 --- a/linden/indra/newview/llviewerwindow.h +++ b/linden/indra/newview/llviewerwindow.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #include "lltimer.h" | 47 | #include "lltimer.h" |
48 | #include "llstat.h" | 48 | #include "llstat.h" |
49 | #include "llalertdialog.h" | 49 | #include "llalertdialog.h" |
50 | #include "llmousehandler.h" | ||
50 | 51 | ||
51 | class LLView; | 52 | class LLView; |
52 | class LLViewerObject; | 53 | class LLViewerObject; |
@@ -57,7 +58,6 @@ class LLVelocityBar; | |||
57 | class LLTextBox; | 58 | class LLTextBox; |
58 | class LLImageRaw; | 59 | class LLImageRaw; |
59 | class LLHUDIcon; | 60 | class LLHUDIcon; |
60 | class LLMouseHandler; | ||
61 | 61 | ||
62 | #define PICK_HALF_WIDTH 5 | 62 | #define PICK_HALF_WIDTH 5 |
63 | #define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1) | 63 | #define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1) |
@@ -81,7 +81,7 @@ public: | |||
81 | 81 | ||
82 | static bool isFlora(LLViewerObject* object); | 82 | static bool isFlora(LLViewerObject* object); |
83 | 83 | ||
84 | typedef enum e_pick_type | 84 | typedef enum |
85 | { | 85 | { |
86 | PICK_OBJECT, | 86 | PICK_OBJECT, |
87 | PICK_FLORA, | 87 | PICK_FLORA, |
@@ -150,6 +150,7 @@ public: | |||
150 | /*virtual*/ BOOL handleTranslatedKeyUp(KEY key, MASK mask); | 150 | /*virtual*/ BOOL handleTranslatedKeyUp(KEY key, MASK mask); |
151 | /*virtual*/ void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level); | 151 | /*virtual*/ void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level); |
152 | /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, MASK mask); // NOT going to handle extended | 152 | /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, MASK mask); // NOT going to handle extended |
153 | /*virtual*/ BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down); | ||
153 | /*virtual*/ BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); | 154 | /*virtual*/ BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); |
154 | /*virtual*/ BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); | 155 | /*virtual*/ BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); |
155 | /*virtual*/ BOOL handleCloseRequest(LLWindow *window); | 156 | /*virtual*/ BOOL handleCloseRequest(LLWindow *window); |
@@ -212,6 +213,7 @@ public: | |||
212 | LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } | 213 | LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } |
213 | LLStat * getMouseVelocityStat() { return &mMouseVelocityStat; } | 214 | LLStat * getMouseVelocityStat() { return &mMouseVelocityStat; } |
214 | BOOL getLeftMouseDown() const { return mLeftMouseDown; } | 215 | BOOL getLeftMouseDown() const { return mLeftMouseDown; } |
216 | BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } | ||
215 | BOOL getRightMouseDown() const { return mRightMouseDown; } | 217 | BOOL getRightMouseDown() const { return mRightMouseDown; } |
216 | 218 | ||
217 | const LLPickInfo& getLastPick() const { return mLastPick; } | 219 | const LLPickInfo& getLastPick() const { return mLastPick; } |
@@ -279,7 +281,7 @@ public: | |||
279 | 281 | ||
280 | // snapshot functionality. | 282 | // snapshot functionality. |
281 | // perhaps some of this should move to llfloatershapshot? -MG | 283 | // perhaps some of this should move to llfloatershapshot? -MG |
282 | typedef enum e_snapshot_type | 284 | typedef enum |
283 | { | 285 | { |
284 | SNAPSHOT_TYPE_COLOR, | 286 | SNAPSHOT_TYPE_COLOR, |
285 | SNAPSHOT_TYPE_DEPTH, | 287 | SNAPSHOT_TYPE_DEPTH, |
@@ -397,6 +399,7 @@ protected: | |||
397 | LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame | 399 | LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame |
398 | LLStat mMouseVelocityStat; | 400 | LLStat mMouseVelocityStat; |
399 | BOOL mLeftMouseDown; | 401 | BOOL mLeftMouseDown; |
402 | BOOL mMiddleMouseDown; | ||
400 | BOOL mRightMouseDown; | 403 | BOOL mRightMouseDown; |
401 | 404 | ||
402 | LLProgressView *mProgressView; | 405 | LLProgressView *mProgressView; |