|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "WidgetUtils.h" |
|
8 |
|
9 #include "mozilla/TextEvents.h" |
|
10 |
|
11 #include "nsIBaseWindow.h" |
|
12 #include "nsIDocShellTreeItem.h" |
|
13 #include "nsIDocShell.h" |
|
14 #include "nsIInterfaceRequestorUtils.h" |
|
15 |
|
16 namespace mozilla { |
|
17 namespace widget { |
|
18 |
|
19 //static |
|
20 already_AddRefed<nsIWidget> |
|
21 WidgetUtils::DOMWindowToWidget(nsIDOMWindow *aDOMWindow) |
|
22 { |
|
23 nsCOMPtr<nsIWidget> widget; |
|
24 |
|
25 nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aDOMWindow); |
|
26 if (window) { |
|
27 nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(window->GetDocShell())); |
|
28 |
|
29 while (!widget && baseWin) { |
|
30 baseWin->GetParentWidget(getter_AddRefs(widget)); |
|
31 if (!widget) { |
|
32 nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(baseWin)); |
|
33 if (!docShellAsItem) |
|
34 return nullptr; |
|
35 |
|
36 nsCOMPtr<nsIDocShellTreeItem> parent; |
|
37 docShellAsItem->GetParent(getter_AddRefs(parent)); |
|
38 |
|
39 window = do_GetInterface(parent); |
|
40 if (!window) |
|
41 return nullptr; |
|
42 |
|
43 baseWin = do_QueryInterface(window->GetDocShell()); |
|
44 } |
|
45 } |
|
46 } |
|
47 |
|
48 return widget.forget(); |
|
49 } |
|
50 |
|
51 // static |
|
52 uint32_t |
|
53 WidgetUtils::ComputeKeyCodeFromChar(uint32_t aCharCode) |
|
54 { |
|
55 if (aCharCode >= 'A' && aCharCode <= 'Z') { |
|
56 return aCharCode - 'A' + NS_VK_A; |
|
57 } |
|
58 if (aCharCode >= 'a' && aCharCode <= 'z') { |
|
59 return aCharCode - 'a' + NS_VK_A; |
|
60 } |
|
61 if (aCharCode >= '0' && aCharCode <= '9') { |
|
62 return aCharCode - '0' + NS_VK_0; |
|
63 } |
|
64 switch (aCharCode) { |
|
65 case ' ': return NS_VK_SPACE; |
|
66 case '\t': return NS_VK_TAB; |
|
67 case ':': return NS_VK_COLON; |
|
68 case ';': return NS_VK_SEMICOLON; |
|
69 case '<': return NS_VK_LESS_THAN; |
|
70 case '=': return NS_VK_EQUALS; |
|
71 case '>': return NS_VK_GREATER_THAN; |
|
72 case '?': return NS_VK_QUESTION_MARK; |
|
73 case '@': return NS_VK_AT; |
|
74 case '^': return NS_VK_CIRCUMFLEX; |
|
75 case '!': return NS_VK_EXCLAMATION; |
|
76 case '"': return NS_VK_DOUBLE_QUOTE; |
|
77 case '#': return NS_VK_HASH; |
|
78 case '$': return NS_VK_DOLLAR; |
|
79 case '%': return NS_VK_PERCENT; |
|
80 case '&': return NS_VK_AMPERSAND; |
|
81 case '_': return NS_VK_UNDERSCORE; |
|
82 case '(': return NS_VK_OPEN_PAREN; |
|
83 case ')': return NS_VK_CLOSE_PAREN; |
|
84 case '*': return NS_VK_ASTERISK; |
|
85 case '+': return NS_VK_PLUS; |
|
86 case '|': return NS_VK_PIPE; |
|
87 case '-': return NS_VK_HYPHEN_MINUS; |
|
88 case '{': return NS_VK_OPEN_CURLY_BRACKET; |
|
89 case '}': return NS_VK_CLOSE_CURLY_BRACKET; |
|
90 case '~': return NS_VK_TILDE; |
|
91 case ',': return NS_VK_COMMA; |
|
92 case '.': return NS_VK_PERIOD; |
|
93 case '/': return NS_VK_SLASH; |
|
94 case '`': return NS_VK_BACK_QUOTE; |
|
95 case '[': return NS_VK_OPEN_BRACKET; |
|
96 case '\\': return NS_VK_BACK_SLASH; |
|
97 case ']': return NS_VK_CLOSE_BRACKET; |
|
98 case '\'': return NS_VK_QUOTE; |
|
99 } |
|
100 return 0; |
|
101 } |
|
102 |
|
103 // static |
|
104 void |
|
105 WidgetUtils::GetLatinCharCodeForKeyCode(uint32_t aKeyCode, |
|
106 bool aIsCapsLock, |
|
107 uint32_t* aUnshiftedCharCode, |
|
108 uint32_t* aShiftedCharCode) |
|
109 { |
|
110 MOZ_ASSERT(aUnshiftedCharCode && aShiftedCharCode, |
|
111 "aUnshiftedCharCode and aShiftedCharCode must not be NULL"); |
|
112 |
|
113 if (aKeyCode >= NS_VK_A && aKeyCode <= NS_VK_Z) { |
|
114 *aUnshiftedCharCode = *aShiftedCharCode = aKeyCode; |
|
115 if (aIsCapsLock) { |
|
116 *aShiftedCharCode += 0x20; |
|
117 } else { |
|
118 *aUnshiftedCharCode += 0x20; |
|
119 } |
|
120 return; |
|
121 } |
|
122 |
|
123 // aShiftedCharCode must be zero for non-alphabet keys. |
|
124 *aShiftedCharCode = 0; |
|
125 |
|
126 if (aKeyCode >= NS_VK_0 && aKeyCode <= NS_VK_9) { |
|
127 *aUnshiftedCharCode = aKeyCode; |
|
128 return; |
|
129 } |
|
130 |
|
131 switch (aKeyCode) { |
|
132 case NS_VK_SPACE: *aUnshiftedCharCode = ' '; break; |
|
133 case NS_VK_COLON: *aUnshiftedCharCode = ':'; break; |
|
134 case NS_VK_SEMICOLON: *aUnshiftedCharCode = ';'; break; |
|
135 case NS_VK_LESS_THAN: *aUnshiftedCharCode = '<'; break; |
|
136 case NS_VK_EQUALS: *aUnshiftedCharCode = '='; break; |
|
137 case NS_VK_GREATER_THAN: *aUnshiftedCharCode = '>'; break; |
|
138 case NS_VK_QUESTION_MARK: *aUnshiftedCharCode = '?'; break; |
|
139 case NS_VK_AT: *aUnshiftedCharCode = '@'; break; |
|
140 case NS_VK_CIRCUMFLEX: *aUnshiftedCharCode = '^'; break; |
|
141 case NS_VK_EXCLAMATION: *aUnshiftedCharCode = '!'; break; |
|
142 case NS_VK_DOUBLE_QUOTE: *aUnshiftedCharCode = '"'; break; |
|
143 case NS_VK_HASH: *aUnshiftedCharCode = '#'; break; |
|
144 case NS_VK_DOLLAR: *aUnshiftedCharCode = '$'; break; |
|
145 case NS_VK_PERCENT: *aUnshiftedCharCode = '%'; break; |
|
146 case NS_VK_AMPERSAND: *aUnshiftedCharCode = '&'; break; |
|
147 case NS_VK_UNDERSCORE: *aUnshiftedCharCode = '_'; break; |
|
148 case NS_VK_OPEN_PAREN: *aUnshiftedCharCode = '('; break; |
|
149 case NS_VK_CLOSE_PAREN: *aUnshiftedCharCode = ')'; break; |
|
150 case NS_VK_ASTERISK: *aUnshiftedCharCode = '*'; break; |
|
151 case NS_VK_PLUS: *aUnshiftedCharCode = '+'; break; |
|
152 case NS_VK_PIPE: *aUnshiftedCharCode = '|'; break; |
|
153 case NS_VK_HYPHEN_MINUS: *aUnshiftedCharCode = '-'; break; |
|
154 case NS_VK_OPEN_CURLY_BRACKET: *aUnshiftedCharCode = '{'; break; |
|
155 case NS_VK_CLOSE_CURLY_BRACKET: *aUnshiftedCharCode = '}'; break; |
|
156 case NS_VK_TILDE: *aUnshiftedCharCode = '~'; break; |
|
157 case NS_VK_COMMA: *aUnshiftedCharCode = ','; break; |
|
158 case NS_VK_PERIOD: *aUnshiftedCharCode = '.'; break; |
|
159 case NS_VK_SLASH: *aUnshiftedCharCode = '/'; break; |
|
160 case NS_VK_BACK_QUOTE: *aUnshiftedCharCode = '`'; break; |
|
161 case NS_VK_OPEN_BRACKET: *aUnshiftedCharCode = '['; break; |
|
162 case NS_VK_BACK_SLASH: *aUnshiftedCharCode = '\\'; break; |
|
163 case NS_VK_CLOSE_BRACKET: *aUnshiftedCharCode = ']'; break; |
|
164 case NS_VK_QUOTE: *aUnshiftedCharCode = '\''; break; |
|
165 default: *aUnshiftedCharCode = 0; break; |
|
166 } |
|
167 } |
|
168 |
|
169 // static |
|
170 KeyNameIndex |
|
171 WidgetUtils::GetDeadKeyNameIndex(char16_t aChar) |
|
172 { |
|
173 switch (aChar) { |
|
174 case '`': |
|
175 case 0x02CB: // MODIFIER LETTER GRAVE ACCENT |
|
176 case 0x0300: // COMBINING GRAVE ACCENT |
|
177 return KEY_NAME_INDEX_DeadGrave; |
|
178 case '\'': |
|
179 case 0x00B4: // ACUTE ACCENT |
|
180 case 0x02B9: // MODIFIER LETTER PRIME |
|
181 case 0x02CA: // MODIFIER LETTER ACUTE ACCENT |
|
182 case 0x0301: // COMBINING ACUTE ACCENT |
|
183 case 0x0384: // GREEK TONOS |
|
184 return KEY_NAME_INDEX_DeadAcute; |
|
185 case '^': |
|
186 case 0x02C6: // MODIFIER LETTER CIRCUMFLEX ACCENT |
|
187 case 0x0302: // COMBINING CIRCUMFLEX ACCENT |
|
188 return KEY_NAME_INDEX_DeadCircumflex; |
|
189 case '~': |
|
190 case 0x02DC: // SMALL TILDE |
|
191 case 0x0303: // COMBINING TILDE |
|
192 return KEY_NAME_INDEX_DeadTilde; |
|
193 case 0x00AF: // MACRON |
|
194 case 0x02C9: // MODIFIER LETTER MACRON |
|
195 case 0x0304: // COMBINING MACRON |
|
196 return KEY_NAME_INDEX_DeadMacron; |
|
197 case 0x02D8: // BRAVE |
|
198 case 0xA67C: // COMBINING CYRILLIC KAVYKA |
|
199 case 0x0306: // COMBINING BRAVE |
|
200 return KEY_NAME_INDEX_DeadBreve; |
|
201 case 0x02D9: // DOT ABOVE |
|
202 case 0x0307: // COMBINING DOT ABOVE |
|
203 return KEY_NAME_INDEX_DeadAboveDot; |
|
204 case 0x00A8: // DIAERESIS |
|
205 case 0x0308: // COMBINING DIAERESIS |
|
206 return KEY_NAME_INDEX_DeadUmlaut; |
|
207 case 0x00B0: // DEGREE SIGN |
|
208 case 0x02DA: // RING ABOVE |
|
209 case 0x030A: // COMBINING RING ABOVE |
|
210 return KEY_NAME_INDEX_DeadAboveRing; |
|
211 case '"': |
|
212 case 0x02BA: // MODIFIER LETTER DOUBLE PRIME |
|
213 case 0x02DD: // DOUBLE ACUTE ACCENT |
|
214 case 0x030B: // COMBINING DOUBLE ACUTE ACCENT |
|
215 return KEY_NAME_INDEX_DeadDoubleacute; |
|
216 case 0x02C7: // CARON |
|
217 case 0x030C: // COMBINING CARON |
|
218 return KEY_NAME_INDEX_DeadCaron; |
|
219 case 0x00B8: // CEDILLA |
|
220 case 0x0327: // COMBINING CEDILLA |
|
221 return KEY_NAME_INDEX_DeadCedilla; |
|
222 case 0x02DB: // OGONEK |
|
223 case 0x0328: // COMBINING OGONEK |
|
224 return KEY_NAME_INDEX_DeadOgonek; |
|
225 case 0x0345: // COMBINING GREEK YPOGEGRAMMENI |
|
226 case 0x037A: // GREEK YPOGEGRAMMENI |
|
227 case 0x0399: // GREEK CAPITAL LETTER IOTA |
|
228 return KEY_NAME_INDEX_DeadIota; |
|
229 case 0x3099: // COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK |
|
230 case 0x309B: // KATAKANA-HIRAGANA VOICED SOUND MARK |
|
231 return KEY_NAME_INDEX_DeadVoicedSound; |
|
232 case 0x309A: // COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK |
|
233 case 0x309C: // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK |
|
234 return KEY_NAME_INDEX_DeadSemivoicedSound; |
|
235 default: |
|
236 return KEY_NAME_INDEX_Unidentified; |
|
237 } |
|
238 } |
|
239 |
|
240 } // namespace widget |
|
241 } // namespace mozilla |