xref: /haiku/src/preferences/keymap/KeymapWindow.cpp (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2 //
3 //	Copyright (c) 2004, Haiku
4 //
5 //  This software is part of the Haiku distribution and is covered
6 //  by the Haiku license.
7 //
8 //
9 //  File:        KeymapWindow.cpp
10 //  Author:      Sandor Vroemisse, Jérôme Duval
11 //  Description: Keymap Preferences
12 //  Created :    July 12, 2004
13 //
14 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
15 
16 #include <Alert.h>
17 #include <Application.h>
18 #include <Box.h>
19 #include <Button.h>
20 #include <Clipboard.h>
21 #include <Debug.h>
22 #include <Directory.h>
23 #include <FindDirectory.h>
24 #include <GraphicsDefs.h>
25 #include <ListView.h>
26 #include <MenuItem.h>
27 #include <Path.h>
28 #include <ScrollView.h>
29 #include <StringView.h>
30 #include <TextView.h>
31 #include <View.h>
32 #include <string.h>
33 #include "KeymapWindow.h"
34 #include "KeymapListItem.h"
35 #include "KeymapApplication.h"
36 
37 #define MENU_FILE_OPEN		'mMFO'
38 #define MENU_FILE_SAVE		'mMFS'
39 #define MENU_FILE_SAVE_AS	'mMFA'
40 #define MENU_EDIT_UNDO		'mMEU'
41 #define MENU_EDIT_CUT		'mMEX'
42 #define MENU_EDIT_COPY		'mMEC'
43 #define MENU_EDIT_PASTE		'mMEV'
44 #define MENU_EDIT_CLEAR		'mMEL'
45 #define MENU_EDIT_SELECT_ALL 'mMEA'
46 #define MENU_FONT_CHANGED	'mMFC'
47 #define SYSTEM_MAP_SELECTED	'SmST'
48 #define USER_MAP_SELECTED	'UmST'
49 #define	USE_KEYMAP			'UkyM'
50 #define REVERT				'Rvrt'
51 
52 KeymapWindow::KeymapWindow()
53 	:	BWindow(BRect(80,25,692,281), "Keymap", B_TITLED_WINDOW,
54 			B_NOT_ZOOMABLE|B_NOT_RESIZABLE|B_ASYNCHRONOUS_CONTROLS )
55 {
56 	// Add the menu bar
57 	BMenuBar *menubar = AddMenuBar();
58 
59 	// The view to hold all but the menu bar
60 	BRect bounds = Bounds();
61 	bounds.top = menubar->Bounds().bottom + 1;
62 	BBox *placeholderView = new BBox(bounds, "placeholderView",
63 		B_FOLLOW_ALL);
64 	placeholderView->SetBorder(B_NO_BORDER);
65 	AddChild( placeholderView );
66 
67 	// Create the Maps box and contents
68 	AddMaps(placeholderView);
69 
70 	fMapView = new MapView(BRect(150,9,600,189), "mapView", &fCurrentMap);
71 	placeholderView->AddChild(fMapView);
72 	SetPulseRate(10000);
73 
74 	BMenuItem *item = fFontMenu->FindMarked();
75 	if (item) {
76 		fMapView->SetFontFamily(item->Label());
77 	}
78 
79 	// The 'Use' button
80 	fUseButton = new BButton(BRect(527,200, 600,220), "useButton", "Use",
81 		new BMessage( USE_KEYMAP ));
82 	placeholderView->AddChild( fUseButton );
83 
84 	// The 'Revert' button
85 	fRevertButton = new BButton(BRect(442,200, 515,220), "revertButton", "Revert",
86 		new BMessage( REVERT ));
87 	placeholderView->AddChild( fRevertButton );
88 
89 	BPath path;
90 	find_directory(B_USER_SETTINGS_DIRECTORY, &path);
91 	path.Append("Keymap");
92 
93 	entry_ref ref;
94 	get_ref_for_path(path.Path(), &ref);
95 
96 	fOpenPanel = new BFilePanel(B_OPEN_PANEL, new BMessenger(this), &ref,
97 		B_FILE_NODE, false, NULL);
98 	fSavePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this), &ref,
99 		B_FILE_NODE, false, NULL);
100 }
101 
102 
103 KeymapWindow::~KeymapWindow(void)
104 {
105 	delete fOpenPanel;
106 	delete fSavePanel;
107 }
108 
109 
110 BMenuBar *
111 KeymapWindow::AddMenuBar()
112 {
113 	BRect		bounds;
114 	BMenu		*menu;
115 	BMenuItem	*currentItem;
116 	BMenuBar	*menubar;
117 
118 	bounds = Bounds();
119 	menubar = new BMenuBar( bounds, "menubar" );
120 	AddChild( menubar );
121 
122 	// Create the File menu
123 	menu = new BMenu( "File" );
124 	menu->AddItem( new BMenuItem( "Open" B_UTF8_ELLIPSIS,
125 		new BMessage( MENU_FILE_OPEN ), 'O' ) );
126 	menu->AddSeparatorItem();
127 	currentItem = new BMenuItem( "Save",
128 		new BMessage( MENU_FILE_SAVE ), 'S' );
129 	currentItem->SetEnabled( false );
130 	menu->AddItem( currentItem );
131 	menu->AddItem( new BMenuItem( "Save As" B_UTF8_ELLIPSIS,
132 		new BMessage( MENU_FILE_SAVE_AS )));
133 	menu->AddSeparatorItem();
134 	menu->AddItem( new BMenuItem( "Quit",
135 		new BMessage( B_QUIT_REQUESTED ), 'Q' ));
136 	menubar->AddItem( menu );
137 
138 	// Create the Edit menu
139 	menu = new BMenu( "Edit" );
140 	currentItem = new BMenuItem( "Undo",
141 		new BMessage( MENU_EDIT_UNDO ), 'Z' );
142 	currentItem->SetEnabled( false );
143 	menu->AddItem( currentItem );
144 	menu->AddSeparatorItem();
145 	menu->AddItem( new BMenuItem( "Cut",
146 		new BMessage( MENU_EDIT_CUT ), 'X' ));
147 	menu->AddItem( new BMenuItem( "Copy",
148 		new BMessage( MENU_EDIT_COPY ), 'C' ));
149 	menu->AddItem( new BMenuItem( "Paste",
150 		new BMessage( MENU_EDIT_PASTE ), 'V' ));
151 	menu->AddItem( new BMenuItem( "Clear",
152 		new BMessage( MENU_EDIT_CLEAR )));
153 	menu->AddSeparatorItem();
154 	menu->AddItem( new BMenuItem( "Select All",
155 		new BMessage( MENU_EDIT_SELECT_ALL ), 'A' ));
156 	menubar->AddItem( menu );
157 
158 	// Create the Font menu
159 	fFontMenu = new BMenu( "Font" );
160 	fFontMenu->SetRadioMode(true);
161 	int32 numFamilies = count_font_families();
162 	font_family family, current_family;
163 	font_style current_style;
164 	uint32 flags;
165 
166 	be_plain_font->GetFamilyAndStyle(&current_family, &current_style);
167 
168 	for (int32 i = 0; i < numFamilies; i++ )
169 		if ( get_font_family(i, &family, &flags) == B_OK ) {
170 			BMenuItem *item =
171 				new BMenuItem(family, new BMessage( MENU_FONT_CHANGED));
172 			fFontMenu->AddItem(item);
173 			if(strcmp(family, current_family) == 0)
174 				item->SetMarked(true);
175 		}
176 	menubar->AddItem( fFontMenu );
177 
178 	return menubar;
179 }
180 
181 
182 void
183 KeymapWindow::AddMaps(BView *placeholderView)
184 {
185 	// The Maps box
186 	BRect bounds = BRect(9,11,140,226);
187 	BBox *mapsBox = new BBox(bounds);
188 	mapsBox->SetLabel("Maps");
189 	placeholderView->AddChild( mapsBox );
190 
191 	// The System list
192 	BStringView *systemLabel = new BStringView(BRect(13,13,113,33), "system", "System");
193 	mapsBox->AddChild(systemLabel);
194 
195 	bounds = BRect( 13,35, 103,105 );
196 	fSystemListView = new BListView( bounds, "systemList" );
197 
198 	mapsBox->AddChild( new BScrollView( "systemScrollList", fSystemListView,
199 		B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true ));
200 	fSystemListView->SetSelectionMessage( new BMessage( SYSTEM_MAP_SELECTED ));
201 
202 	// The User list
203 	BStringView *userLabel = new BStringView(BRect(13,110,113,128), "user", "User");
204 	mapsBox->AddChild(userLabel);
205 
206 	bounds = BRect(13,130,103,200);
207 	fUserListView = new BListView( bounds, "userList" );
208 	// '(Current)'
209 	KeymapListItem *currentKeymapItem = (KeymapListItem*)fUserListView->FirstItem();
210 	if( currentKeymapItem != NULL )
211 		fUserListView->AddItem( currentKeymapItem );
212 	// Saved keymaps
213 	mapsBox->AddChild( new BScrollView( "userScrollList", fUserListView,
214 		B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true ));
215 	fUserListView->SetSelectionMessage( new BMessage( USER_MAP_SELECTED ));
216 
217 	FillSystemMaps();
218 
219 	FillUserMaps();
220 }
221 
222 
223 bool
224 KeymapWindow::QuitRequested()
225 {
226 	if (!IsActive())
227 		return false;
228 	be_app->PostMessage( B_QUIT_REQUESTED );
229 	return true;
230 }
231 
232 
233 void
234 KeymapWindow::MessageReceived( BMessage* message )
235 {
236 	switch( message->what ) {
237 		case B_SIMPLE_DATA:
238 		case B_REFS_RECEIVED:
239 		{
240 			entry_ref ref;
241 			int32 i = 0;
242 			while (message->FindRef("refs", i++, &ref) == B_OK) {
243 				fCurrentMap.Load(ref);
244 			}
245 			fMapView->Invalidate();
246 			fSystemListView->DeselectAll();
247 			fUserListView->DeselectAll();
248 		}
249 			break;
250 		case B_SAVE_REQUESTED:
251 		{
252 			entry_ref ref;
253 			const char *name;
254 			if ((message->FindRef("directory", &ref) == B_OK)
255 				&& (message->FindString("name", &name) == B_OK)) {
256 
257 				BDirectory directory(&ref);
258 				BEntry entry(&directory, name);
259 				entry.GetRef(&ref);
260 				fCurrentMap.Save(ref);
261 
262 				FillUserMaps();
263 			}
264 		}
265 			break;
266 		case MENU_FILE_OPEN:
267 			fOpenPanel->Show();
268 			break;
269 		case MENU_FILE_SAVE:
270 			break;
271 		case MENU_FILE_SAVE_AS:
272 			fSavePanel->Show();
273 			break;
274 		case MENU_EDIT_UNDO:
275 		case MENU_EDIT_CUT:
276 		case MENU_EDIT_COPY:
277 		case MENU_EDIT_PASTE:
278 		case MENU_EDIT_CLEAR:
279 		case MENU_EDIT_SELECT_ALL:
280 			fMapView->MessageReceived(message);
281 			break;
282 		case MENU_FONT_CHANGED:
283 		{
284 			BMenuItem *item = fFontMenu->FindMarked();
285 			if (item) {
286 				fMapView->SetFontFamily(item->Label());
287 				fMapView->Invalidate();
288 			}
289 		}
290 			break;
291 		case SYSTEM_MAP_SELECTED:
292 		{
293 			KeymapListItem *keymapListItem =
294 				(KeymapListItem*)fSystemListView->ItemAt(fSystemListView->CurrentSelection());
295 			if (keymapListItem) {
296 				fCurrentMap.Load(keymapListItem->KeymapEntry());
297 				fMapView->Invalidate();
298 
299 				// Deselect item in other BListView
300 				fUserListView->DeselectAll();
301 			}
302 		}
303 			break;
304 		case USER_MAP_SELECTED:
305 		{
306 			KeymapListItem *keymapListItem =
307 				(KeymapListItem*)fUserListView->ItemAt(fUserListView->CurrentSelection());
308 			if (keymapListItem) {
309 				fCurrentMap.Load(keymapListItem->KeymapEntry());
310 				fMapView->Invalidate();
311 
312 				// Deselect item in other BListView
313 				fSystemListView->DeselectAll();
314 			}
315 		}
316 			break;
317 		case USE_KEYMAP:
318 			UseKeymap();
319 			break;
320 		case REVERT:	// do nothing, just like the original
321 			break;
322 		default:
323 			BWindow::MessageReceived( message );
324 			break;
325 	}
326 }
327 
328 
329 void
330 KeymapWindow::UseKeymap()
331 {
332 	BPath path;
333 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path)!=B_OK)
334 		return;
335 
336 	path.Append("Key_map");
337 
338 	entry_ref ref;
339 	get_ref_for_path(path.Path(), &ref);
340 
341 	status_t err;
342 	if ((err = fCurrentMap.Save(ref)) != B_OK) {
343 		printf("error when saving : %s", strerror(err));
344 		return;
345 	}
346 	fCurrentMap.Use();
347 
348 	fUserListView->Select(0);
349 }
350 
351 
352 void
353 KeymapWindow::FillSystemMaps()
354 {
355 	BListItem *item;
356 	while ((item = fSystemListView->RemoveItem((int32)0)))
357 		delete item;
358 
359 	BPath path;
360 	if (find_directory(B_BEOS_ETC_DIRECTORY, &path)!=B_OK)
361 		return;
362 
363 	path.Append("Keymap");
364 
365 	BDirectory directory;
366 	entry_ref ref;
367 
368 	if (directory.SetTo(path.Path()) == B_OK)
369 		while( directory.GetNextRef(&ref) == B_OK ) {
370 			fSystemListView->AddItem(new KeymapListItem(ref));
371 		}
372 }
373 
374 
375 void
376 KeymapWindow::FillUserMaps()
377 {
378 	BListItem *item;
379 	while ((item = fUserListView->RemoveItem((int32)0)))
380 		delete item;
381 
382 	BPath path;
383 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path)!=B_OK)
384 		return;
385 
386 	path.Append("Key_map");
387 
388 	entry_ref ref;
389 	get_ref_for_path(path.Path(), &ref);
390 
391 	fUserListView->AddItem(new KeymapListItem(ref, "(Current)"));
392 
393 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path)!=B_OK)
394 		return;
395 
396 	path.Append("Keymap");
397 
398 	BDirectory directory;
399 
400 	if (directory.SetTo(path.Path()) == B_OK)
401 		while( directory.GetNextRef(&ref) == B_OK ) {
402 			fUserListView->AddItem(new KeymapListItem(ref));
403 		}
404 
405 	fUserListView->Select(0);
406 }
407 
408 
409 BEntry*
410 KeymapWindow::CurrentMap()
411 {
412 	return NULL;
413 }
414 
415 
416 MapView::MapView(BRect rect, const char *name, Keymap* keymap)
417 	: BControl(rect, name, NULL, NULL, B_FOLLOW_LEFT|B_FOLLOW_TOP, B_WILL_DRAW|B_PULSE_NEEDED),
418 		fCurrentFont(*be_plain_font),
419 		fCurrentMap(keymap),
420 		fCurrentMouseKey(0)
421 {
422 	SetViewColor(B_TRANSPARENT_COLOR);
423 
424 	BRect frameRect = BRect(14, 16, Bounds().right-12, 30);
425 	BRect textRect = frameRect;
426 	textRect.OffsetTo(B_ORIGIN);
427 	textRect.InsetBy(1,1);
428 	fTextView = new KeymapTextView(frameRect, "testzone", textRect,
429 		B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS);
430 	fTextView->MakeEditable(true);
431 	fTextView->MakeSelectable(true);
432 
433 	AddChild(fTextView);
434 
435 	for (uint32 j = 0; j<128; j++)
436 		fKeysToDraw[j] = false;
437 
438 	BRect keyRect = BRect(11,50,29,68);
439 	uint32 i = 1;
440 	fKeysRect[i] = keyRect;
441 	fKeysToDraw[i] = true;
442 
443 	// Fx keys
444 	i++;
445 	keyRect.OffsetBySelf(36,0);
446 	fKeysRect[i] = keyRect;
447 	fKeysToDraw[i] = true;
448 	i++;
449 	keyRect.OffsetBySelf(18,0);
450 	fKeysRect[i] = keyRect;
451 	fKeysToDraw[i] = true;
452 	i++;
453 	keyRect.OffsetBySelf(18,0);
454 	fKeysRect[i] = keyRect;
455 	fKeysToDraw[i] = true;
456 	i++;
457 	keyRect.OffsetBySelf(18,0);
458 	fKeysRect[i] = keyRect;
459 	fKeysToDraw[i] = true;
460 
461 	i++;
462 	keyRect.OffsetBySelf(27,0);
463 	fKeysRect[i] = keyRect;
464 	fKeysToDraw[i] = true;
465 	i++;
466 	keyRect.OffsetBySelf(18,0);
467 	fKeysRect[i] = keyRect;
468 	fKeysToDraw[i] = true;
469 	i++;
470 	keyRect.OffsetBySelf(18,0);
471 	fKeysRect[i] = keyRect;
472 	fKeysToDraw[i] = true;
473 	i++;
474 	keyRect.OffsetBySelf(18,0);
475 	fKeysRect[i] = keyRect;
476 	fKeysToDraw[i] = true;
477 
478 	i++;
479 	keyRect.OffsetBySelf(27,0);
480 	fKeysRect[i] = keyRect;
481 	fKeysToDraw[i] = true;
482 	i++;
483 	keyRect.OffsetBySelf(18,0);
484 	fKeysRect[i] = keyRect;
485 	fKeysToDraw[i] = true;
486 	i++;
487 	keyRect.OffsetBySelf(18,0);
488 	fKeysRect[i] = keyRect;
489 	fKeysToDraw[i] = true;
490 	i++;
491 	keyRect.OffsetBySelf(18,0);
492 	fKeysRect[i] = keyRect;
493 	fKeysToDraw[i] = true;
494 
495 	// Pause, PrintScreen, ...
496 	i++;
497 	keyRect.OffsetBySelf(35,0);
498 	fKeysRect[i] = keyRect;
499 	fKeysToDraw[i] = true;
500 	i++;
501 	keyRect.OffsetBySelf(18,0);
502 	fKeysRect[i] = keyRect;
503 	fKeysToDraw[i] = true;
504 	i++;
505 	keyRect.OffsetBySelf(18,0);
506 	fKeysRect[i] = keyRect;
507 	fKeysToDraw[i] = true;
508 
509 	// 1st line : numbers and backspace
510 	i++;
511 	keyRect = BRect(11,78,29,96);
512 	fKeysRect[i] = keyRect;
513 	fKeysToDraw[i] = true;
514 	i++;
515 	keyRect.OffsetBySelf(18,0);
516 	fKeysRect[i] = keyRect;
517 	fKeysToDraw[i] = true;
518 	i++;
519 	keyRect.OffsetBySelf(18,0);
520 	fKeysRect[i] = keyRect;
521 	fKeysToDraw[i] = true;
522 	i++;
523 	keyRect.OffsetBySelf(18,0);
524 	fKeysRect[i] = keyRect;
525 	fKeysToDraw[i] = true;
526 	i++;
527 	keyRect.OffsetBySelf(18,0);
528 	fKeysRect[i] = keyRect;
529 	fKeysToDraw[i] = true;
530 	i++;
531 	keyRect.OffsetBySelf(18,0);
532 	fKeysRect[i] = keyRect;
533 	fKeysToDraw[i] = true;
534 	i++;
535 	keyRect.OffsetBySelf(18,0);
536 	fKeysRect[i] = keyRect;
537 	fKeysToDraw[i] = true;
538 	i++;
539 	keyRect.OffsetBySelf(18,0);
540 	fKeysRect[i] = keyRect;
541 	fKeysToDraw[i] = true;
542 	i++;
543 	keyRect.OffsetBySelf(18,0);
544 	fKeysRect[i] = keyRect;
545 	fKeysToDraw[i] = true;
546 	i++;
547 	keyRect.OffsetBySelf(18,0);
548 	fKeysRect[i] = keyRect;
549 	fKeysToDraw[i] = true;
550 	i++;
551 	keyRect.OffsetBySelf(18,0);
552 	fKeysRect[i] = keyRect;
553 	fKeysToDraw[i] = true;
554 	i++;
555 	keyRect.OffsetBySelf(18,0);
556 	fKeysRect[i] = keyRect;
557 	fKeysToDraw[i] = true;
558 	i++;
559 	keyRect.OffsetBySelf(18,0);
560 	fKeysRect[i] = keyRect;
561 	fKeysToDraw[i] = true;
562 	i++;
563 	keyRect.OffsetBySelf(18,0);
564 	keyRect.right += 18;
565 	fKeysRect[i] = keyRect;
566 	fKeysToDraw[i] = true;
567 	keyRect.left += 18;
568 
569 	// Insert, pg up ...
570 	i++;
571 	keyRect.OffsetBySelf(35,0);
572 	fKeysRect[i] = keyRect;
573 	fKeysToDraw[i] = true;
574 	i++;
575 	keyRect.OffsetBySelf(18,0);
576 	fKeysRect[i] = keyRect;
577 	fKeysToDraw[i] = true;
578 	i++;
579 	keyRect.OffsetBySelf(18,0);
580 	fKeysRect[i] = keyRect;
581 	fKeysToDraw[i] = true;
582 
583 	// 2nd line : tab and azerty ...
584 	i = 0x26;
585 	keyRect = BRect(11,96,38,114);
586 	fKeysRect[i] = keyRect;
587 	fKeysToDraw[i] = true;
588 	i++;
589 	keyRect.OffsetBySelf(27,0);
590 	keyRect.right -= 9;
591 	fKeysRect[i] = keyRect;
592 	fKeysToDraw[i] = true;
593 	i++;
594 	keyRect.OffsetBySelf(18,0);
595 	fKeysRect[i] = keyRect;
596 	fKeysToDraw[i] = true;
597 	i++;
598 	keyRect.OffsetBySelf(18,0);
599 	fKeysRect[i] = keyRect;
600 	fKeysToDraw[i] = true;
601 	i++;
602 	keyRect.OffsetBySelf(18,0);
603 	fKeysRect[i] = keyRect;
604 	fKeysToDraw[i] = true;
605 	i++;
606 	keyRect.OffsetBySelf(18,0);
607 	fKeysRect[i] = keyRect;
608 	fKeysToDraw[i] = true;
609 	i++;
610 	keyRect.OffsetBySelf(18,0);
611 	fKeysRect[i] = keyRect;
612 	fKeysToDraw[i] = true;
613 	i++;
614 	keyRect.OffsetBySelf(18,0);
615 	fKeysRect[i] = keyRect;
616 	fKeysToDraw[i] = true;
617 	i++;
618 	keyRect.OffsetBySelf(18,0);
619 	fKeysRect[i] = keyRect;
620 	fKeysToDraw[i] = true;
621 	i++;
622 	keyRect.OffsetBySelf(18,0);
623 	fKeysRect[i] = keyRect;
624 	fKeysToDraw[i] = true;
625 	i++;
626 	keyRect.OffsetBySelf(18,0);
627 	fKeysRect[i] = keyRect;
628 	fKeysToDraw[i] = true;
629 	i++;
630 	keyRect.OffsetBySelf(18,0);
631 	fKeysRect[i] = keyRect;
632 	fKeysToDraw[i] = true;
633 	i++;
634 	keyRect.OffsetBySelf(18,0);
635 	fKeysRect[i] = keyRect;
636 	fKeysToDraw[i] = true;
637 	i++;
638 	keyRect.OffsetBySelf(18,0);
639 	keyRect.right += 9;
640 	fKeysRect[i] = keyRect;
641 	fKeysToDraw[i] = true;
642 	keyRect.left += 9;
643 
644 	// Suppr, pg down ...
645 	i++;
646 	keyRect.OffsetBySelf(35,0);
647 	fKeysRect[i] = keyRect;
648 	fKeysToDraw[i] = true;
649 	i++;
650 	keyRect.OffsetBySelf(18,0);
651 	fKeysRect[i] = keyRect;
652 	fKeysToDraw[i] = true;
653 	i++;
654 	keyRect.OffsetBySelf(18,0);
655 	fKeysRect[i] = keyRect;
656 	fKeysToDraw[i] = true;
657 
658 	// 3rd line : caps and qsdfg ...
659 	i = 0x3b;
660 	keyRect = BRect(11,114,47,132);
661 	fKeysRect[i] = keyRect;
662 	fKeysToDraw[i] = true;
663 	i++;
664 	keyRect.OffsetBySelf(36,0);
665 	keyRect.right -= 18;
666 	fKeysRect[i] = keyRect;
667 	fKeysToDraw[i] = true;
668 	i++;
669 	keyRect.OffsetBySelf(18,0);
670 	fKeysRect[i] = keyRect;
671 	fKeysToDraw[i] = true;
672 	i++;
673 	keyRect.OffsetBySelf(18,0);
674 	fKeysRect[i] = keyRect;
675 	fKeysToDraw[i] = true;
676 	i++;
677 	keyRect.OffsetBySelf(18,0);
678 	fKeysRect[i] = keyRect;
679 	fKeysToDraw[i] = true;
680 	i++;
681 	keyRect.OffsetBySelf(18,0);
682 	fKeysRect[i] = keyRect;
683 	fKeysToDraw[i] = true;
684 	i++;
685 	keyRect.OffsetBySelf(18,0);
686 	fKeysRect[i] = keyRect;
687 	fKeysToDraw[i] = true;
688 	i++;
689 	keyRect.OffsetBySelf(18,0);
690 	fKeysRect[i] = keyRect;
691 	fKeysToDraw[i] = true;
692 	i++;
693 	keyRect.OffsetBySelf(18,0);
694 	fKeysRect[i] = keyRect;
695 	fKeysToDraw[i] = true;
696 	i++;
697 	keyRect.OffsetBySelf(18,0);
698 	fKeysRect[i] = keyRect;
699 	fKeysToDraw[i] = true;
700 	i++;
701 	keyRect.OffsetBySelf(18,0);
702 	fKeysRect[i] = keyRect;
703 	fKeysToDraw[i] = true;
704 	i++;
705 	keyRect.OffsetBySelf(18,0);
706 	fKeysRect[i] = keyRect;
707 	fKeysToDraw[i] = true;
708 	i++;
709 	keyRect.OffsetBySelf(18,0);
710 	keyRect.right += 18;
711 	fKeysRect[i] = keyRect;
712 	fKeysToDraw[i] = true;
713 	keyRect.left += 18;
714 
715 	// 4th line : shift and wxcv ...
716 	i = 0x4b;
717 	keyRect = BRect(11,132,56,150);
718 	fKeysRect[i] = keyRect;
719 	fKeysToDraw[i] = true;
720 	i++;
721 	keyRect.OffsetBySelf(45,0);
722 	keyRect.right -= 27;
723 	fKeysRect[i] = keyRect;
724 	fKeysToDraw[i] = true;
725 	i++;
726 	keyRect.OffsetBySelf(18,0);
727 	fKeysRect[i] = keyRect;
728 	fKeysToDraw[i] = true;
729 	i++;
730 	keyRect.OffsetBySelf(18,0);
731 	fKeysRect[i] = keyRect;
732 	fKeysToDraw[i] = true;
733 	i++;
734 	keyRect.OffsetBySelf(18,0);
735 	fKeysRect[i] = keyRect;
736 	fKeysToDraw[i] = true;
737 	i++;
738 	keyRect.OffsetBySelf(18,0);
739 	fKeysRect[i] = keyRect;
740 	fKeysToDraw[i] = true;
741 	i++;
742 	keyRect.OffsetBySelf(18,0);
743 	fKeysRect[i] = keyRect;
744 	fKeysToDraw[i] = true;
745 	i++;
746 	keyRect.OffsetBySelf(18,0);
747 	fKeysRect[i] = keyRect;
748 	fKeysToDraw[i] = true;
749 	i++;
750 	keyRect.OffsetBySelf(18,0);
751 	fKeysRect[i] = keyRect;
752 	fKeysToDraw[i] = true;
753 	i++;
754 	keyRect.OffsetBySelf(18,0);
755 	fKeysRect[i] = keyRect;
756 	fKeysToDraw[i] = true;
757 	i++;
758 	keyRect.OffsetBySelf(18,0);
759 	fKeysRect[i] = keyRect;
760 	fKeysToDraw[i] = true;
761 	i++;
762 	keyRect.OffsetBySelf(18,0);
763 	keyRect.right += 27;
764 	fKeysRect[i] = keyRect;
765 	fKeysToDraw[i] = true;
766 	keyRect.left += 27;
767 
768 	//5th line : Ctrl, Alt, Space ...
769 	i = 0x5c;
770 	keyRect = BRect(11,150,38,168);
771 	fKeysRect[i] = keyRect;
772 	fKeysToDraw[i] = true;
773 	i++;
774 	keyRect.OffsetBySelf(27,0);
775 	keyRect.OffsetBySelf(26,0);
776 	fKeysRect[i] = keyRect;
777 	fKeysToDraw[i] = true;
778 	i++;
779 	keyRect.OffsetBySelf(27,0);
780 	keyRect.right += 92;
781 	fKeysRect[i] = keyRect;
782 	fKeysToDraw[i] = true;
783 	i++;
784 	keyRect.right -= 92;
785 	keyRect.OffsetBySelf(92,0);
786 	keyRect.OffsetBySelf(27,0);
787 	fKeysRect[i] = keyRect;
788 	fKeysToDraw[i] = true;
789 	i++;
790 	keyRect.OffsetBySelf(26,0);
791 	keyRect.OffsetBySelf(18,0);
792 	fKeysRect[i] = keyRect;
793 	fKeysToDraw[i] = true;
794 
795 	// Arrows
796 	i++;
797 	keyRect = BRect(298,150,316,168);
798 	fKeysRect[i] = keyRect;
799 	fKeysToDraw[i] = true;
800 	i++;
801 	keyRect.OffsetBySelf(18,0);
802 	fKeysRect[i] = keyRect;
803 	fKeysToDraw[i] = true;
804 	i++;
805 	keyRect.OffsetBySelf(18,0);
806 	fKeysRect[i] = keyRect;
807 	fKeysToDraw[i] = true;
808 	i = 0x57;
809 	keyRect.OffsetBySelf(-18,-18);
810 	fKeysRect[i] = keyRect;
811 	fKeysToDraw[i] = true;
812 
813 	// numkeys
814 	i = 0x22;
815 	keyRect = BRect(369,78,387,96);
816 	fKeysRect[i] = keyRect;
817 	fKeysToDraw[i] = true;
818 	i++;
819 	keyRect.OffsetBySelf(18,0);
820 	fKeysRect[i] = keyRect;
821 	fKeysToDraw[i] = true;
822 	i++;
823 	keyRect.OffsetBySelf(18,0);
824 	fKeysRect[i] = keyRect;
825 	fKeysToDraw[i] = true;
826 	i++;
827 	keyRect.OffsetBySelf(18,0);
828 	fKeysRect[i] = keyRect;
829 	fKeysToDraw[i] = true;
830 	i = 0x37;
831 	keyRect.OffsetBySelf(-54, 18);
832 	fKeysRect[i] = keyRect;
833 	fKeysToDraw[i] = true;
834 	i++;
835 	keyRect.OffsetBySelf(18,0);
836 	fKeysRect[i] = keyRect;
837 	fKeysToDraw[i] = true;
838 	i++;
839 	keyRect.OffsetBySelf(18,0);
840 	fKeysRect[i] = keyRect;
841 	fKeysToDraw[i] = true;
842 	i++;
843 	keyRect.OffsetBySelf(18,0);
844 	keyRect.bottom += 18;
845 	fKeysRect[i] = keyRect;
846 	fKeysToDraw[i] = true;
847 	i = 0x48;
848 	keyRect.bottom -= 18;
849 	keyRect.OffsetBySelf(-54, 18);
850 	fKeysRect[i] = keyRect;
851 	fKeysToDraw[i] = true;
852 	i++;
853 	keyRect.OffsetBySelf(18,0);
854 	fKeysRect[i] = keyRect;
855 	fKeysToDraw[i] = true;
856 	i++;
857 	keyRect.OffsetBySelf(18,0);
858 	fKeysRect[i] = keyRect;
859 	fKeysToDraw[i] = true;
860 	i = 0x58;
861 	keyRect.OffsetBySelf(-36, 18);
862 	fKeysRect[i] = keyRect;
863 	fKeysToDraw[i] = true;
864 	i++;
865 	keyRect.OffsetBySelf(18,0);
866 	fKeysRect[i] = keyRect;
867 	fKeysToDraw[i] = true;
868 	i++;
869 	keyRect.OffsetBySelf(18,0);
870 	fKeysRect[i] = keyRect;
871 	fKeysToDraw[i] = true;
872 	i++;
873 	keyRect.OffsetBySelf(18,0);
874 	keyRect.bottom += 18;
875 	fKeysRect[i] = keyRect;
876 	fKeysToDraw[i] = true;
877 	i = 0x64;
878 	keyRect.bottom -= 18;
879 	keyRect.OffsetBySelf(-54, 18);
880 	keyRect.right += 18;
881 	fKeysRect[i] = keyRect;
882 	fKeysToDraw[i] = true;
883 	i++;
884 	keyRect.right -= 18;
885 	keyRect.OffsetBySelf(36,0);
886 	fKeysRect[i] = keyRect;
887 	fKeysToDraw[i] = true;
888 
889 	for (uint32 j = 0; j<128; j++)
890 		fKeysVertical[j] = false;
891 
892 	fKeysVertical[0x5e] = true;
893 
894 	fActiveDeadKey = 0;
895 
896 	for (int8 j=0; j<16; j++)
897 		fOldKeyInfo.key_states[j] = 0;
898 	fOldKeyInfo.modifiers = 0;
899 }
900 
901 
902 void
903 MapView::AttachedToWindow()
904 {
905 	SetEventMask(B_KEYBOARD_EVENTS, 0);
906 	fTextView->SetViewColor(255,255,255);
907 	BView::AttachedToWindow();
908 }
909 
910 
911 void
912 MapView::Draw(BRect rect)
913 {
914 	BRect r = Bounds();
915 	SetHighColor(0,0,0);
916 	StrokeRect(r);
917 
918 	r.InsetBySelf(1,1);
919 	SetHighColor(168,168,168);
920 	StrokeRect(r);
921 	SetHighColor(80,80,80);
922 	StrokeLine(BPoint(r.left+2, r.bottom), r.RightBottom());
923 	StrokeLine(r.RightTop());
924 
925 	r.InsetBySelf(1,1);
926 	SetHighColor(255,255,255);
927 	StrokeRect(r);
928 	SetHighColor(112,112,112);
929 	StrokeLine(BPoint(r.left+1, r.bottom), r.RightBottom());
930 	StrokeLine(r.RightTop());
931 
932 	r.InsetBySelf(1,1);
933 	SetHighColor(168,168,168);
934 	FillRect(r);
935 
936 	SetHighColor(255,255,255);
937 	FillRect(BRect(r.right-1, r.bottom-1, r.right, r.bottom));
938 	SetHighColor(184,184,184);
939 	StrokeLine(BPoint(r.right-9, r.bottom), BPoint(r.right-2, r.bottom));
940 	StrokeLine(BPoint(r.right, r.bottom-9), BPoint(r.right, r.bottom-2));
941 
942 	InvalidateKeys();
943 
944 	// Esc key
945 	DrawBorder(BRect(10,49,30,69));
946 
947 	// Fx keys
948 	DrawBorder(BRect(46, 49, 120, 69));
949 
950 	DrawBorder(BRect(127, 49, 201, 69));
951 
952 	DrawBorder(BRect(208, 49, 282, 69));
953 
954 	// Pause, PrintScreen, ...
955 	DrawBorder(BRect(297, 49, 353, 69));
956 
957 	// Insert, pg up ...
958 	DrawBorder(BRect(297, 77, 353, 115));
959 
960 	SetHighColor(80,80,80);
961 	StrokeLine(BPoint(10,169), BPoint(10,77));
962 	StrokeLine(BPoint(282,77));
963 	SetHighColor(255,255,255);
964 	StrokeLine(BPoint(282,169));
965 	StrokeLine(BPoint(253,169));
966 	SetHighColor(80,80,80);
967 	StrokeLine(BPoint(253,151));
968 	SetHighColor(255,255,255);
969 	StrokeLine(BPoint(238,151));
970 	StrokeLine(BPoint(238,169));
971 	StrokeLine(BPoint(63,169));
972 	SetHighColor(80,80,80);
973 	StrokeLine(BPoint(63,151));
974 	SetHighColor(255,255,255);
975 	StrokeLine(BPoint(39,151));
976 	StrokeLine(BPoint(39,169));
977 	StrokeLine(BPoint(11,169));
978 
979 	// Arrows
980 	SetHighColor(80,80,80);
981 	StrokeLine(BPoint(297,169), BPoint(297,149));
982 	StrokeLine(BPoint(315,149));
983 	StrokeLine(BPoint(315,131));
984 	StrokeLine(BPoint(335,131));
985 	StrokeLine(BPoint(336,149), BPoint(353,149));
986 	SetHighColor(255,255,255);
987 	StrokeLine(BPoint(335,132), BPoint(335,149));
988 	StrokeLine(BPoint(353,150), BPoint(353,169));
989 	StrokeLine(BPoint(298,169));
990 
991 	// numkeys
992 	DrawBorder(BRect(368, 77, 442, 169));
993 
994 	DrawLocks();
995 
996 	// the line separator
997 	r = BRect(11, 40, 353, 43);
998 	SetHighColor(255,255,255);
999 	StrokeLine(r.LeftBottom(), r.LeftTop());
1000 	StrokeLine(r.RightTop());
1001 	SetHighColor(80,80,80);
1002 	StrokeLine(r.RightBottom());
1003 	StrokeLine(r.LeftBottom());
1004 	r.OffsetBySelf(2,4);
1005 	r.bottom = r.top + 1;
1006 	SetHighColor(136,136,136);
1007 	FillRect(r);
1008 	FillRect(BRect(354,41,355,43));
1009 
1010 	// around the textview
1011 	SetHighColor(0,0,0);
1012 	r = BRect(11, 13, Bounds().right-11, 31);
1013 	StrokeLine(r.LeftBottom(), r.LeftTop());
1014 	StrokeLine(r.RightTop());
1015 	SetHighColor(80,80,80);
1016 	StrokeLine(r.LeftBottom()+BPoint(1,0), r.LeftTop()+BPoint(1,1));
1017 	StrokeLine(r.RightTop()+BPoint(0,1));
1018 	SetHighColor(136,136,136);
1019 	StrokeLine(r.LeftBottom()+BPoint(2,-1), r.LeftTop()+BPoint(2,2));
1020 	StrokeLine(r.RightTop()+BPoint(0,2));
1021 	StrokeLine(r.LeftBottom()+BPoint(1,0), r.LeftBottom()+BPoint(1,0));
1022 	SetHighColor(255,255,255);
1023 	StrokeLine(r.RightTop()+BPoint(0,1), r.RightBottom());
1024 	StrokeLine(r.LeftBottom()+BPoint(2,0));
1025 	BView::Draw(rect);
1026 }
1027 
1028 
1029 void
1030 MapView::DrawLocks()
1031 {
1032 	// lights
1033 #define isLighted(i) (fOldKeyInfo.modifiers & i)
1034 
1035 	DrawBorder(BRect(368, 49, 442, 69));
1036 
1037 	escapement_delta delta;
1038 	delta.nonspace = 0.0;
1039 	BFont font(be_plain_font);
1040 	font.SetSize(9.0);
1041 	font.SetFlags(B_DISABLE_ANTIALIASING);
1042 	font.SetSpacing(B_CHAR_SPACING);
1043 	SetFont(&font);
1044 	BRect lightRect = BRect(372,53,386,56);
1045 
1046 	SetHighColor(80,80,80);
1047 	StrokeLine(lightRect.LeftBottom(), lightRect.RightBottom());
1048 	StrokeLine(lightRect.RightTop());
1049 	SetHighColor(255,255,255);
1050 	StrokeLine(BPoint(lightRect.right-1, lightRect.top), lightRect.LeftTop());
1051 	StrokeLine(BPoint(lightRect.left, lightRect.bottom-1));
1052 	SetHighColor(0,55,0);
1053 	if (isLighted(B_NUM_LOCK))
1054 		SetHighColor(0,178,0);
1055 	FillRect(lightRect.InsetByCopy(1,1));
1056 	SetHighColor(64,64,64);
1057 	DrawString("num", BPoint(lightRect.left-2, 65), &delta);
1058 
1059 	lightRect.OffsetBy(26,0);
1060 	SetHighColor(80,80,80);
1061 	StrokeLine(lightRect.LeftBottom(), lightRect.RightBottom());
1062 	StrokeLine(lightRect.RightTop());
1063 	SetHighColor(255,255,255);
1064 	StrokeLine(BPoint(lightRect.right-1, lightRect.top), lightRect.LeftTop());
1065 	StrokeLine(BPoint(lightRect.left, lightRect.bottom-1));
1066 	SetHighColor(0,55,0);
1067 	if (isLighted(B_CAPS_LOCK))
1068 		SetHighColor(0,178,0);
1069 	FillRect(lightRect.InsetByCopy(1,1));
1070 	SetHighColor(64,64,64);
1071 	DrawString("caps", BPoint(lightRect.left-3, 65), &delta);
1072 
1073 	lightRect.OffsetBy(26,0);
1074 	SetHighColor(80,80,80);
1075 	StrokeLine(lightRect.LeftBottom(), lightRect.RightBottom());
1076 	StrokeLine(lightRect.RightTop());
1077 	SetHighColor(255,255,255);
1078 	StrokeLine(BPoint(lightRect.right-1, lightRect.top), lightRect.LeftTop());
1079 	StrokeLine(BPoint(lightRect.left, lightRect.bottom-1));
1080 	SetHighColor(0,55,0);
1081 	if (isLighted(B_SCROLL_LOCK))
1082 		SetHighColor(0,178,0);
1083 	FillRect(lightRect.InsetByCopy(1,1));
1084 	SetHighColor(64,64,64);
1085 	DrawString("scroll", BPoint(lightRect.left-4, 65), &delta);
1086 }
1087 
1088 
1089 void
1090 MapView::InvalidateKeys()
1091 {
1092 	for (uint32 i=0; i<128; i++)
1093 		if (fKeysToDraw[i+1])
1094 			DrawKey(i+1);
1095 }
1096 
1097 
1098 void
1099 MapView::DrawKey(uint32 keyCode)
1100 {
1101 	BRect r = fKeysRect[keyCode];
1102 	SetHighColor(0,0,0);
1103 	StrokeRect(r);
1104 
1105 	bool pressed = (fOldKeyInfo.key_states[keyCode>>3] & (1 << (7 - keyCode%8))) || (keyCode == fCurrentMouseKey);
1106 	bool vertical = fKeysVertical[keyCode];
1107 	int32 deadKey = fCurrentMap->IsDeadKey(keyCode, fOldKeyInfo.modifiers);
1108 	bool secondDeadKey = fCurrentMap->IsDeadSecondKey(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey);
1109 
1110 	if (!pressed) {
1111 		r.InsetBySelf(1,1);
1112 		if (secondDeadKey) {
1113 			SetHighColor(255,0,0);
1114 			StrokeRect(r);
1115 			r.InsetBySelf(1,1);
1116 			StrokeRect(r);
1117 		} else if (deadKey>0) {
1118 			SetHighColor(255,255,0);
1119 			StrokeRect(r);
1120 			r.InsetBySelf(1,1);
1121 			StrokeRect(r);
1122 		} else {
1123 
1124 			SetHighColor(64,64,64);
1125 			StrokeRect(r);
1126 
1127 			BeginLineArray(14);
1128 			rgb_color color1 = {200,200,200};
1129 			AddLine(BPoint(r.left, r.bottom-1), r.LeftTop(), color1);
1130 			AddLine(r.LeftTop(), BPoint(r.left+3, r.top), color1);
1131 			rgb_color color2 = {184,184,184};
1132 			AddLine(BPoint(r.left+3, r.top), BPoint(r.left+6, r.top), color2);
1133 			rgb_color color3 = {168,168,168};
1134 			AddLine(BPoint(r.left+6, r.top), BPoint(r.left+9, r.top), color3);
1135 			rgb_color color4 = {152,152,152};
1136 			AddLine(BPoint(r.left+9, r.top), BPoint(r.right-1, r.top), color4);
1137 
1138 			r.InsetBySelf(1,1);
1139 			SetHighColor(255,255,255);
1140 			StrokeRect(r);
1141 
1142 			rgb_color color6 = {96,96,96};
1143 			AddLine(r.LeftBottom(), r.RightBottom(), color6);
1144 			rgb_color color5 = {160,160,160};
1145 			AddLine(r.LeftBottom(), r.LeftBottom(), color5);
1146 			rgb_color color7 = {64,64,64};
1147 			AddLine(r.RightBottom(), BPoint(r.right, r.bottom-1), color7);
1148 			AddLine(BPoint(r.right, r.bottom-1), BPoint(r.right, r.top-1), color6);
1149 			AddLine(BPoint(r.right, r.top-1), r.RightTop(), color5);
1150 			rgb_color color8 = {255,255,255};
1151 			AddLine(BPoint(r.left+1, r.bottom-1), BPoint(r.left+2, r.bottom-1), color8);
1152 			AddLine(BPoint(r.left+2, r.bottom-1), BPoint(r.right-1, r.bottom-1), color1);
1153 			AddLine(BPoint(r.right-1, r.bottom-1), BPoint(r.right-1, r.bottom-2), color5);
1154 			AddLine(BPoint(r.right-1, r.bottom-2), BPoint(r.right-1, r.top+1), color1);
1155 			EndLineArray();
1156 		}
1157 
1158 		r.InsetBySelf(1,1);
1159 		r.bottom -= 1;
1160 		BRect fillRect = r;
1161 
1162 		if (!vertical) {
1163 			int32 w1 = 4;
1164 			int32 w2 = 3;
1165 			if(fKeysRect[keyCode].Width() > 20) {
1166 				w1 = 6;
1167 				w2 = 6;
1168 			}
1169 
1170 			fillRect.right = fillRect.left + w1;
1171 			SetHighColor(152,152,152);
1172 			FillRect(fillRect);
1173 			fillRect.left += w1;
1174 			fillRect.right = fillRect.left + w2;
1175 			SetHighColor(168,168,168);
1176 			FillRect(fillRect);
1177 			fillRect.left += w2;
1178 			fillRect.right = r.right-1;
1179 			SetHighColor(184,184,184);
1180 			FillRect(fillRect);
1181 		} else {
1182 			SetHighColor(200,200,200);
1183 			fillRect.right -= 1;
1184 			fillRect.bottom = fillRect.top + 2;
1185 			FillRect(fillRect);
1186 			SetHighColor(184,184,184);
1187 			fillRect.OffsetBySelf(0,3);
1188 			FillRect(fillRect);
1189 			SetHighColor(168,168,168);
1190 			fillRect.OffsetBySelf(0,3);
1191 			FillRect(fillRect);
1192 			SetHighColor(152,152,152);
1193 			fillRect.OffsetBySelf(0,3);
1194 			FillRect(fillRect);
1195 		}
1196 	} else {
1197 		r.InsetBySelf(1,1);
1198 
1199 		if (secondDeadKey) {
1200 			SetHighColor(255,0,0);
1201 			StrokeRect(r);
1202 			r.InsetBySelf(1,1);
1203 			StrokeRect(r);
1204 		} else if (deadKey>0) {
1205 			SetHighColor(255,255,0);
1206 			StrokeRect(r);
1207 			r.InsetBySelf(1,1);
1208 			StrokeRect(r);
1209 		} else {
1210 			SetHighColor(48,48,48);
1211 			StrokeRect(r);
1212 
1213 			BeginLineArray(2);
1214 			rgb_color color1 = {136,136,136};
1215 			AddLine(BPoint(r.left+1, r.bottom), r.RightBottom(), color1);
1216 			AddLine(r.RightBottom(), BPoint(r.right, r.top+1), color1);
1217 			EndLineArray();
1218 
1219 			r.InsetBySelf(1,1);
1220 			SetHighColor(72,72,72);
1221 			StrokeRect(r);
1222 
1223 			BeginLineArray(4);
1224 			rgb_color color2 = {48,48,48};
1225 			AddLine(r.LeftTop(), r.LeftTop(), color2);
1226 			rgb_color color3 = {152,152,152};
1227 			AddLine(BPoint(r.left+1, r.bottom), r.RightBottom(), color3);
1228 			AddLine(r.RightBottom(), r.RightTop(), color3);
1229 			rgb_color color4 = {160,160,160};
1230 			AddLine(r.RightTop(), r.RightTop(), color4);
1231 			EndLineArray();
1232 		}
1233 
1234 		r.InsetBySelf(1,1);
1235 		SetHighColor(112,112,112);
1236 		FillRect(r);
1237 		SetHighColor(136,136,136);
1238 		StrokeLine(r.LeftTop(), r.LeftTop());
1239 
1240 	}
1241 
1242 	char *str = NULL;
1243 	int32 numBytes;
1244 	fCurrentMap->GetChars(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1245 	if (str) {
1246 		bool hasGlyphs;
1247 		if (deadKey>0) {
1248 			delete str;
1249 			switch (deadKey) {
1250 				case 1: str = strdup("'"); break;
1251 				case 2: str = strdup("`"); break;
1252 				case 3: str = strdup("^"); break;
1253 				case 4: str = strdup("\""); break;
1254 				case 5: str = strdup("~"); break;
1255 			}
1256 		}
1257 		fCurrentFont.GetHasGlyphs(str, 1, &hasGlyphs);
1258 
1259 		if (hasGlyphs) {
1260 			SetFont(&fCurrentFont);
1261 			SetDrawingMode(B_OP_COPY);
1262 			SetHighColor(0,0,0);
1263 			SetLowColor(184,184,184);
1264 			BPoint point = fKeysRect[keyCode].LeftBottom();
1265 			point.x += 4;
1266 			point.y -= 5;
1267 			DrawString(str, point);
1268 			SetDrawingMode(B_OP_OVER);
1269 		}
1270 		delete str;
1271 	}
1272 }
1273 
1274 
1275 void
1276 MapView::DrawBorder(BRect bRect)
1277 {
1278 	rgb_color gray = {80,80,80};
1279 	rgb_color white = {255,255,255};
1280 
1281 	BeginLineArray(4);
1282 	AddLine(bRect.LeftTop(), bRect.LeftBottom(), gray);
1283 	AddLine(bRect.LeftTop(), bRect.RightTop(), gray);
1284 	AddLine(BPoint(bRect.left + 1, bRect.bottom), bRect.RightBottom(), white);
1285 	AddLine(bRect.RightBottom(), BPoint(bRect.right, bRect.top + 1), white);
1286 	EndLineArray();
1287 }
1288 
1289 
1290 void
1291 MapView::MessageReceived(BMessage *msg)
1292 {
1293 	switch (msg->what) {
1294 		case MENU_EDIT_UNDO:
1295 			fTextView->Undo(be_clipboard);
1296 			break;
1297 		case MENU_EDIT_CUT:
1298 			fTextView->Cut(be_clipboard);
1299 			break;
1300 		case MENU_EDIT_COPY:
1301 			fTextView->Copy(be_clipboard);
1302 			break;
1303 		case MENU_EDIT_PASTE:
1304 			fTextView->Paste(be_clipboard);
1305 			break;
1306 		case MENU_EDIT_CLEAR:
1307 			fTextView->Clear();
1308 			break;
1309 		case MENU_EDIT_SELECT_ALL:
1310 			fTextView->SelectAll();
1311 			break;
1312 		case B_KEY_DOWN:
1313 		case B_KEY_UP:
1314 		case B_UNMAPPED_KEY_DOWN:
1315 		case B_UNMAPPED_KEY_UP:
1316 		case B_MODIFIERS_CHANGED: {
1317 			key_info info;
1318 			const uint8 *states;
1319 			ssize_t size;
1320 
1321 			if ((msg->FindData("states", B_UINT8_TYPE, (const void **)&states, &size)!=B_OK)
1322 				|| (msg->FindInt32("modifiers", (int32 *)&info.modifiers)!=B_OK))
1323 				break;
1324 
1325 			if (fOldKeyInfo.modifiers != info.modifiers) {
1326 				fOldKeyInfo.modifiers = info.modifiers;
1327 				for (int8 i=0; i<16; i++)
1328 					fOldKeyInfo.key_states[i] = states[i];
1329 				InvalidateKeys();
1330 				DrawLocks();
1331 			} else {
1332 
1333 				int32 keyCode = -1;
1334 				for (int8 i=0; i<16; i++)
1335 					if (fOldKeyInfo.key_states[i] != states[i]) {
1336 						uint8 stbits = fOldKeyInfo.key_states[i] ^ states[i];
1337 						fOldKeyInfo.key_states[i] = states[i];
1338 						for (int8 j=7; stbits; j--,stbits>>=1)
1339 							if (stbits & 1) {
1340 								keyCode = i*8 + j;
1341 								DrawKey(keyCode);
1342 							}
1343 
1344 					}
1345 
1346 				if (keyCode<0)
1347 					for (int8 i=0; i<16; i++) {
1348 						uint8 stbits = states[i];
1349 						for (int8 j=7; stbits; j--,stbits>>=1)
1350 							if (stbits & 1) {
1351 								keyCode = i*8 + j;
1352 								if (!fCurrentMap->IsModifierKey(keyCode)) {
1353 									i = 16;
1354 									break;
1355 								}
1356 							}
1357 					}
1358 
1359 
1360 				if (Window()->IsActive()
1361 					&& msg->what == B_KEY_DOWN) {
1362 					fTextView->MakeFocus();
1363 					char *str = NULL;
1364 					int32 numBytes;
1365 					if (fActiveDeadKey) {
1366 						fCurrentMap->GetChars(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1367 						if (numBytes>0) {
1368 							fTextView->FakeKeyDown(str, numBytes);
1369 						}
1370 						fActiveDeadKey = 0;
1371 						InvalidateKeys();
1372 					} else {
1373 						fCurrentMap->GetChars(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1374 						fActiveDeadKey = fCurrentMap->IsDeadKey(keyCode, fOldKeyInfo.modifiers);
1375 						if (fActiveDeadKey)
1376 							InvalidateKeys();
1377 						else if (numBytes>0) {
1378 							fTextView->FakeKeyDown(str, numBytes);
1379 						}
1380 					}
1381 					delete str;
1382 				}
1383 			}
1384 			break;
1385 		}
1386 		default:
1387 			BView::MessageReceived(msg);
1388 	}
1389 
1390 }
1391 
1392 
1393 void
1394 MapView::KeyDown(const char* bytes, int32 numBytes)
1395 {
1396 	MessageReceived(Window()->CurrentMessage());
1397 }
1398 
1399 
1400 void
1401 MapView::KeyUp(const char* bytes, int32 numBytes)
1402 {
1403 	MessageReceived(Window()->CurrentMessage());
1404 }
1405 
1406 
1407 void
1408 MapView::MouseDown(BPoint point)
1409 {
1410 	uint32 buttons;
1411 	GetMouse(&point, &buttons);
1412 	if(buttons & B_PRIMARY_MOUSE_BUTTON) {
1413 		fCurrentMouseKey = 0;
1414 		for (int32 i=0; i<128; i++) {
1415 			if (fKeysRect[i].Contains(point)) {
1416 				fCurrentMouseKey = i;
1417 				DrawKey(fCurrentMouseKey);
1418 				char *str = NULL;
1419 				int32 numBytes;
1420 				fCurrentMap->GetChars(fCurrentMouseKey, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1421 				if (numBytes>0) {
1422 					fTextView->FakeKeyDown(str, numBytes);
1423 					delete str;
1424 				}
1425 				SetTracking(true);
1426 				SetMouseEventMask(B_POINTER_EVENTS,
1427 					B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY);
1428 				break;
1429 			}
1430 		}
1431 	}
1432 }
1433 
1434 
1435 void
1436 MapView::MouseUp(BPoint point)
1437 {
1438 	if (IsTracking())
1439 		SetTracking(false);
1440 	uint32 value = fCurrentMouseKey;
1441 	fCurrentMouseKey = 0;
1442 	DrawKey(value);
1443 }
1444 
1445 
1446 void
1447 MapView::MouseMoved(BPoint point, uint32 transit, const BMessage *msg)
1448 {
1449 	if (IsTracking()) {
1450 		uint32 value = fCurrentMouseKey;
1451 		for (int32 i=0; i<128; i++) {
1452 			if (fKeysRect[i].Contains(point) && !fKeysRect[value].Contains(point)) {
1453 				fCurrentMouseKey = i;
1454 				DrawKey(value);
1455 				DrawKey(fCurrentMouseKey);
1456 				char *str = NULL;
1457 				int32 numBytes;
1458 				fCurrentMap->GetChars(fCurrentMouseKey, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1459 				if (numBytes>0) {
1460 					fTextView->FakeKeyDown(str, numBytes);
1461 					delete str;
1462 				}
1463 				break;
1464 			}
1465 		}
1466 	}
1467 	BControl::MouseMoved(point, transit, msg);
1468 }
1469 
1470 
1471 void
1472 MapView::SetFontFamily(const font_family family)
1473 {
1474 	fCurrentFont.SetFamilyAndStyle(family, NULL);
1475 	fTextView->SetFontAndColor(&fCurrentFont);
1476 };
1477