aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/doc/contributions.txt3
-rw-r--r--linden/indra/llui/llclipboard.cpp41
-rw-r--r--linden/indra/llui/llclipboard.h11
-rw-r--r--linden/indra/llui/llfloater.cpp6
-rw-r--r--linden/indra/llui/llfloater.h2
-rw-r--r--linden/indra/llui/lllineeditor.cpp83
-rw-r--r--linden/indra/llui/lllineeditor.h13
-rw-r--r--linden/indra/llui/lltexteditor.cpp91
-rw-r--r--linden/indra/llui/lltexteditor.h8
-rw-r--r--linden/indra/llui/llview.cpp78
-rw-r--r--linden/indra/llui/llview.h4
-rw-r--r--linden/indra/llwindow/CMakeLists.txt1
-rw-r--r--linden/indra/llwindow/llmousehandler.cpp59
-rw-r--r--linden/indra/llwindow/llmousehandler.h21
-rw-r--r--linden/indra/llwindow/llwindow.cpp16
-rw-r--r--linden/indra/llwindow/llwindow.h6
-rw-r--r--linden/indra/llwindow/llwindowsdl.cpp570
-rw-r--r--linden/indra/llwindow/llwindowsdl.h13
-rw-r--r--linden/indra/newview/lltool.cpp15
-rw-r--r--linden/indra/newview/lltool.h3
-rw-r--r--linden/indra/newview/llviewertexteditor.cpp79
-rw-r--r--linden/indra/newview/llviewertexteditor.h2
-rw-r--r--linden/indra/newview/llviewerwindow.cpp479
-rw-r--r--linden/indra/newview/llviewerwindow.h9
24 files changed, 696 insertions, 917 deletions
diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt
index 9886640..a1c8624 100644
--- a/linden/doc/contributions.txt
+++ b/linden/doc/contributions.txt
@@ -61,11 +61,14 @@ Alissa Sabre
61 VWR-7168 61 VWR-7168
62 VWR-7087 62 VWR-7087
63 VWR-7086 63 VWR-7086
64 VWR-9190
64 VWR-10728 65 VWR-10728
65Angus Boyd 66Angus Boyd
66 VWR-592 67 VWR-592
67Argent Stonecutter 68Argent Stonecutter
68 VWR-68 69 VWR-68
70Armin Weatherwax
71 VWR-8436
69Asuka Neely 72Asuka Neely
70 VWR-3434 73 VWR-3434
71Balp Allen 74Balp Allen
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
97void 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
105const 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
132BOOL 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 &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null ); 51 void copyFromSubstring(const LLWString &copy_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 &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null );
56 BOOL canPastePrimaryString() const;
57 const LLWString& getPastePrimaryWString(LLUUID* source_id = NULL);
58
50private: 59private:
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
1190BOOL 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
1192BOOL LLFloater::handleDoubleClick(S32 x, S32 y, MASK mask) 1198BOOL 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
581BOOL 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
579BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) 593BOOL 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
950void LLLineEditor::paste() 970void LLLineEditor::paste()
951{ 971{
952 if (canPaste()) 972 bool is_primary = false;
973 pasteHelper(is_primary);
974}
975
976void 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)
983void 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
1063void 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
1073BOOL LLLineEditor::canPastePrimary() const
1074{
1075 return !mReadOnly && gClipboard.canPastePrimaryString();
1076}
1077
1078void LLLineEditor::updatePrimary()
1079{
1080 if(canCopy() )
1081 {
1082 copyPrimary();
1083 }
1084}
1085
1019BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) 1086BOOL 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
220private: 224private:
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
1206BOOL 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
1206BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) 1218BOOL 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
1873void LLTextEditor::paste() 1900void LLTextEditor::paste()
1874{ 1901{
1875 if (!canPaste()) 1902 bool is_primary = false;
1903 pasteHelper(is_primary);
1904}
1905
1906// paste from primary
1907void LLTextEditor::pastePrimary()
1908{
1909 bool is_primary = true;
1910 pasteHelper(is_primary);
1911}
1912
1913// paste from primary (itsprimary==true) or clipboard (itsprimary==false)
1914void 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
1974void 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
1985BOOL LLTextEditor::canPastePrimary() const
1986{
1987 return !mReadOnly && gClipboard.canPastePrimaryString();
1988}
1989
1990void LLTextEditor::updatePrimary()
1991{
1992 if (canCopy())
1993 {
1994 copyPrimary();
1995 }
1996}
1997
1920BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask) 1998BOOL 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
985BOOL 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
998BOOL 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
985LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) 1009LLView* 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
1169LLView* 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
1145LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask) 1197LLView* 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
1282LLView* 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
1231void LLView::draw() 1309void 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
47set(viewer_SOURCE_FILES 47set(viewer_SOURCE_FILES
48 llwindow.cpp 48 llwindow.cpp
49 llmousehandler.cpp
49 ) 50 )
50 51
51set(viewer_HEADER_FILES 52set(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
35BOOL 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
311BOOL LLWindow::isPrimaryTextAvailable()
312{
313 return FALSE; // no
314}
315//virtual
316BOOL LLWindow::pasteTextFromPrimary(LLWString &dst)
317{
318 return FALSE; // fail
319}
320// virtual
321BOOL LLWindow::copyTextToPrimary(const LLWString &src)
322{
323 return FALSE; // fail
324}
325
310// static 326// static
311std::string LLWindow::getFontListSans() 327std::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
190LLWindowSDL::LLWindowSDL(const std::string& title, S32 x, S32 y, S32 width, 190LLWindowSDL::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
763void LLWindowSDL::destroyContext() 788void 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 */ 1245BOOL 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
1225typedef 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 */
1239static x11clipboard_type get_x11_readwrite_clipboard_type(void)
1240{
1241 return XInternAtom(LLWindowSDL::get_SDL_Display(), "CLIPBOARD", False);
1242}
1243
1244static 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. */
1252static 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 */
1258static Atom get_x11_targets_atom(void)
1259{
1260 return XInternAtom(LLWindowSDL::get_SDL_Display(), "TARGETS", False);
1261}
1262
1263static 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
1275static
1276x11clipboard_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 1257BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &text)
1308 purposes this is pretty trivial right now. */
1309static int
1310convert_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 1274BOOL LLWindowSDL::copyTextToClipboard(const LLWString &text)
1343 pretty trivial for our needs right now, and just about identical
1344 to above. */
1345static int
1346convert_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
1378int
1379LLWindowSDL::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
1390void 1287BOOL LLWindowSDL::isPrimaryTextAvailable()
1391LLWindowSDL::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
1437void 1299BOOL LLWindowSDL::pasteTextFromPrimary(LLWString &text)
1438LLWindowSDL::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
1523int 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
1602int 1316BOOL LLWindowSDL::copyTextToPrimary(const LLWString &text)
1603LLWindowSDL::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
1637void
1638LLWindowSDL::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
1650BOOL LLWindowSDL::isClipboardTextAvailable() 1331BOOL LLWindowSDL::isClipboardTextAvailable()
1651{ 1332{
1652 return !is_empty_x11clipboard(); 1333 return FALSE; // unsupported
1653} 1334}
1654 1335
1655BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &dst) 1336BOOL 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
1690BOOL LLWindowSDL::copyTextToClipboard(const LLWString &s) 1342BOOL 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
1717BOOL LLWindowSDL::isClipboardTextAvailable() 1347BOOL LLWindowSDL::isPrimaryTextAvailable()
1718{ 1348{
1719 return FALSE; // unsupported 1349 return FALSE; // unsupported
1720} 1350}
1721 1351
1722BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &dst) 1352BOOL LLWindowSDL::pasteTextFromPrimary(LLWString &dst)
1723{ 1353{
1724 return FALSE; // unsupported 1354 return FALSE; // unsupported
1725} 1355}
1726 1356
1727BOOL LLWindowSDL::copyTextToClipboard(const LLWString &s) 1357BOOL 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
1733LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_resolutions) 1364LLWindow::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
208private: 213private:
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
68BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask) 67BOOL 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
127BOOL 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
134BOOL 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
128BOOL LLTool::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) 141BOOL 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
894BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) 894BOOL 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
967BOOL 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
978BOOL LLViewerTextEditor::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
979{
980 BOOL handled = childrenHandleMiddleMouseUp(x, y, mask) != NULL;
981
982 return handled;
983}
984
1002BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) 985BOOL 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
550BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) 550BOOL 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
654BOOL 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 ) ) 708BOOL 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 714BOOL 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
734BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) 723BOOL 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
932BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) 756BOOL 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
1022BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) 762BOOL 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
1030BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) 772BOOL 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
51class LLView; 52class LLView;
52class LLViewerObject; 53class LLViewerObject;
@@ -57,7 +58,6 @@ class LLVelocityBar;
57class LLTextBox; 58class LLTextBox;
58class LLImageRaw; 59class LLImageRaw;
59class LLHUDIcon; 60class LLHUDIcon;
60class 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;