1 /* 2 * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de> 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without restriction, 7 * including without limitation the rights to use, copy, modify, 8 * merge, publish, distribute, sublicense, and/or sell copies of 9 * the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include "MainWin.h" 26 #include "MainApp.h" 27 #include "Controller.h" 28 #include "config.h" 29 #include "DeviceRoster.h" 30 31 #include <stdio.h> 32 #include <string.h> 33 34 #include <Application.h> 35 #include <Alert.h> 36 #include <Menu.h> 37 #include <MenuBar.h> 38 #include <MenuItem.h> 39 #include <Messenger.h> 40 #include <PopUpMenu.h> 41 #include <Screen.h> 42 #include <String.h> 43 #include <View.h> 44 45 46 #undef B_TRANSLATION_CONTEXT 47 #define B_TRANSLATION_CONTEXT "MainWin" 48 49 B_TRANSLATE_MARK_VOID("TV"); 50 B_TRANSLATE_MARK_VOID("unknown"); 51 B_TRANSLATE_MARK_VOID("DVB - Digital Video Broadcasting TV"); 52 53 enum 54 { 55 M_DUMMY = 0x100, 56 M_FILE_QUIT, 57 M_SCALE_TO_NATIVE_SIZE, 58 M_TOGGLE_FULLSCREEN, 59 M_TOGGLE_NO_BORDER, 60 M_TOGGLE_NO_MENU, 61 M_TOGGLE_NO_BORDER_NO_MENU, 62 M_TOGGLE_ALWAYS_ON_TOP, 63 M_TOGGLE_KEEP_ASPECT_RATIO, 64 M_PREFERENCES, 65 M_CHANNEL_NEXT, 66 M_CHANNEL_PREV, 67 M_VOLUME_UP, 68 M_VOLUME_DOWN, 69 M_ASPECT_100000_1, 70 M_ASPECT_106666_1, 71 M_ASPECT_109091_1, 72 M_ASPECT_141176_1, 73 M_ASPECT_720_576, 74 M_ASPECT_704_576, 75 M_ASPECT_544_576, 76 M_SELECT_INTERFACE = 0x00000800, 77 M_SELECT_INTERFACE_END = 0x00000fff, 78 M_SELECT_CHANNEL = 0x00010000, 79 M_SELECT_CHANNEL_END = 0x000fffff, 80 // this limits possible channel count to 0xeffff = 983039 81 }; 82 83 //#define printf(a...) 84 85 86 MainWin::MainWin(BRect frame_rect) 87 : 88 BWindow(frame_rect, B_TRANSLATE_SYSTEM_NAME(NAME), B_TITLED_WINDOW, 89 B_ASYNCHRONOUS_CONTROLS /* | B_WILL_ACCEPT_FIRST_CLICK */) 90 , fController(new Controller) 91 , fIsFullscreen(false) 92 , fKeepAspectRatio(true) 93 , fAlwaysOnTop(false) 94 , fNoMenu(false) 95 , fNoBorder(false) 96 , fSourceWidth(720) 97 , fSourceHeight(576) 98 , fWidthScale(1.0) 99 , fHeightScale(1.0) 100 , fMouseDownTracking(false) 101 , fFrameResizedTriggeredAutomatically(false) 102 , fIgnoreFrameResized(false) 103 , fFrameResizedCalled(true) 104 { 105 BRect rect = Bounds(); 106 107 // background 108 fBackground = new BView(rect, "background", B_FOLLOW_ALL, 109 B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE); 110 fBackground->SetViewColor(0,0,0); 111 AddChild(fBackground); 112 113 // menu 114 fMenuBar = new BMenuBar(fBackground->Bounds(), "menu"); 115 CreateMenu(); 116 fBackground->AddChild(fMenuBar); 117 fMenuBar->ResizeToPreferred(); 118 fMenuBarHeight = (int)fMenuBar->Frame().Height() + 1; 119 fMenuBar->SetResizingMode(B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT); 120 121 // video view 122 BRect video_rect = BRect(0, fMenuBarHeight, rect.right, rect.bottom); 123 fVideoView = new VideoView(video_rect, "video display", B_FOLLOW_ALL, 124 B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE); 125 fBackground->AddChild(fVideoView); 126 127 fVideoView->MakeFocus(); 128 129 // SetSizeLimits(fControlViewMinWidth - 1, 32767, 130 // fMenuBarHeight + fControlViewHeight - 1, fMenuBarHeight 131 // + fControlViewHeight - 1); 132 133 // SetSizeLimits(320 - 1, 32767, 240 + fMenuBarHeight - 1, 32767); 134 135 SetSizeLimits(0, 32767, fMenuBarHeight - 1, 32767); 136 137 fController->SetVideoView(fVideoView); 138 fController->SetVideoNode(fVideoView->Node()); 139 140 fVideoView->IsOverlaySupported(); 141 142 SetupInterfaceMenu(); 143 SelectInitialInterface(); 144 SetInterfaceMenuMarker(); 145 SetupChannelMenu(); 146 SetChannelMenuMarker(); 147 148 VideoFormatChange(fSourceWidth, fSourceHeight, fWidthScale, fHeightScale); 149 150 CenterOnScreen(); 151 } 152 153 154 MainWin::~MainWin() 155 { 156 printf("MainWin::~MainWin\n"); 157 fController->DisconnectInterface(); 158 delete fController; 159 } 160 161 162 void 163 MainWin::CreateMenu() 164 { 165 fFileMenu = new BMenu(B_TRANSLATE(NAME)); 166 fChannelMenu = new BMenu(B_TRANSLATE("Channel")); 167 fInterfaceMenu = new BMenu(B_TRANSLATE("Interface")); 168 fSettingsMenu = new BMenu(B_TRANSLATE("Settings")); 169 fDebugMenu = new BMenu(B_TRANSLATE("Debug")); 170 171 fMenuBar->AddItem(fFileMenu); 172 fMenuBar->AddItem(fChannelMenu); 173 fMenuBar->AddItem(fInterfaceMenu); 174 fMenuBar->AddItem(fSettingsMenu); 175 fMenuBar->AddItem(fDebugMenu); 176 177 fFileMenu->AddItem(new BMenuItem(B_TRANSLATE("Quit"), 178 new BMessage(M_FILE_QUIT), 'Q', B_COMMAND_KEY)); 179 180 /* 181 fChannelMenu->AddItem(new BMenuItem(B_TRANSLATE("Next channel"), 182 new BMessage(M_CHANNEL_NEXT), '+', B_COMMAND_KEY)); 183 fChannelMenu->AddItem(new BMenuItem(B_TRANSLATE("Previous channel"), 184 new BMessage(M_CHANNEL_PREV), '-', B_COMMAND_KEY)); 185 fChannelMenu->AddSeparatorItem(); 186 fChannelMenu->AddItem(new BMenuItem("RTL", new BMessage(M_DUMMY), '0', 187 B_COMMAND_KEY)); 188 fChannelMenu->AddItem(new BMenuItem("Pro7", new BMessage(M_DUMMY), '1', 189 B_COMMAND_KEY)); 190 191 fInterfaceMenu->AddItem(new BMenuItem(B_TRANSLATE("none"), 192 new BMessage(M_DUMMY))); 193 fInterfaceMenu->AddItem(new BMenuItem(B_TRANSLATE("none 1"), 194 new BMessage(M_DUMMY))); 195 fInterfaceMenu->AddItem(new BMenuItem(B_TRANSLATE("none 2"), 196 new BMessage(M_DUMMY))); 197 */ 198 199 fSettingsMenu->AddItem(new BMenuItem(B_TRANSLATE("Scale to native size"), 200 new BMessage(M_SCALE_TO_NATIVE_SIZE), 'N', B_COMMAND_KEY)); 201 fSettingsMenu->AddItem(new BMenuItem(B_TRANSLATE("Full screen"), 202 new BMessage(M_TOGGLE_FULLSCREEN), 'F', B_COMMAND_KEY)); 203 fSettingsMenu->AddSeparatorItem(); 204 fSettingsMenu->AddItem(new BMenuItem(B_TRANSLATE("No menu"), 205 new BMessage(M_TOGGLE_NO_MENU), 'M', B_COMMAND_KEY)); 206 fSettingsMenu->AddItem(new BMenuItem(B_TRANSLATE("No border"), 207 new BMessage(M_TOGGLE_NO_BORDER), 'B', B_COMMAND_KEY)); 208 fSettingsMenu->AddItem(new BMenuItem(B_TRANSLATE("Always on top"), 209 new BMessage(M_TOGGLE_ALWAYS_ON_TOP), 'T', B_COMMAND_KEY)); 210 fSettingsMenu->AddItem(new BMenuItem(B_TRANSLATE("Keep aspect ratio"), 211 new BMessage(M_TOGGLE_KEEP_ASPECT_RATIO), 'K', B_COMMAND_KEY)); 212 fSettingsMenu->AddSeparatorItem(); 213 fSettingsMenu->AddItem(new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS) 214 , new BMessage(M_PREFERENCES), ',', B_COMMAND_KEY)); 215 216 const char* pixel_ratio = B_TRANSLATE("pixel aspect ratio"); 217 BString str1 = pixel_ratio; 218 str1 << " 1.00000:1"; 219 fDebugMenu->AddItem(new BMenuItem(str1.String(), 220 new BMessage(M_ASPECT_100000_1))); 221 BString str2 = pixel_ratio; 222 str2 << " 1.06666:1"; 223 fDebugMenu->AddItem(new BMenuItem(str2.String(), 224 new BMessage(M_ASPECT_106666_1))); 225 BString str3 = pixel_ratio; 226 str3 << " 1.09091:1"; 227 fDebugMenu->AddItem(new BMenuItem(str3.String(), 228 new BMessage(M_ASPECT_109091_1))); 229 BString str4 = pixel_ratio; 230 str4 << " 1.41176:1"; 231 fDebugMenu->AddItem(new BMenuItem(str4.String(), 232 new BMessage(M_ASPECT_141176_1))); 233 fDebugMenu->AddItem(new BMenuItem(B_TRANSLATE_COMMENT( 234 "force 720 × 576, display aspect 4:3", 235 "The '×' is the Unicode multiplication sign U+00D7"), 236 new BMessage(M_ASPECT_720_576))); 237 fDebugMenu->AddItem(new BMenuItem(B_TRANSLATE_COMMENT( 238 "force 704 × 576, display aspect 4:3", 239 "The '×' is the Unicode multiplication sign U+00D7"), 240 new BMessage(M_ASPECT_704_576))); 241 fDebugMenu->AddItem(new BMenuItem(B_TRANSLATE_COMMENT( 242 "force 544 × 576, display aspect 4:3", 243 "The '×' is the Unicode multiplication sign U+00D7"), 244 new BMessage(M_ASPECT_544_576))); 245 246 fSettingsMenu->ItemAt(1)->SetMarked(fIsFullscreen); 247 fSettingsMenu->ItemAt(3)->SetMarked(fNoMenu); 248 fSettingsMenu->ItemAt(4)->SetMarked(fNoBorder); 249 fSettingsMenu->ItemAt(5)->SetMarked(fAlwaysOnTop); 250 fSettingsMenu->ItemAt(6)->SetMarked(fKeepAspectRatio); 251 fSettingsMenu->ItemAt(8)->SetEnabled(false); 252 // XXX disable unused preference menu 253 } 254 255 256 void 257 MainWin::SetupInterfaceMenu() 258 { 259 fInterfaceMenu->RemoveItems(0, fInterfaceMenu->CountItems(), true); 260 261 fInterfaceMenu->AddItem(new BMenuItem(B_TRANSLATE("None"), 262 new BMessage(M_SELECT_INTERFACE))); 263 264 int count = gDeviceRoster->DeviceCount(); 265 266 if (count > 0) 267 fInterfaceMenu->AddSeparatorItem(); 268 269 for (int i = 0; i < count; i++) { 270 // 1 gets subtracted in MessageReceived, so -1 is Interface None, 271 // and 0 == Interface 0 in SelectInterface() 272 fInterfaceMenu->AddItem(new BMenuItem(gDeviceRoster->DeviceName(i), 273 new BMessage(M_SELECT_INTERFACE + i + 1))); 274 } 275 } 276 277 278 void 279 MainWin::SetupChannelMenu() 280 { 281 fChannelMenu->RemoveItems(0, fChannelMenu->CountItems(), true); 282 283 int interface = fController->CurrentInterface(); 284 printf("MainWin::SetupChannelMenu: interface %d\n", interface); 285 286 int channels = fController->ChannelCount(); 287 288 if (channels == 0) { 289 fChannelMenu->AddItem(new BMenuItem(B_TRANSLATE("None"), 290 new BMessage(M_DUMMY))); 291 } else { 292 fChannelMenu->AddItem(new BMenuItem(B_TRANSLATE("Next channel"), 293 new BMessage(M_CHANNEL_NEXT), '+', B_COMMAND_KEY)); 294 fChannelMenu->AddItem(new BMenuItem(B_TRANSLATE("Previous channel"), 295 new BMessage(M_CHANNEL_PREV), '-', B_COMMAND_KEY)); 296 fChannelMenu->AddSeparatorItem(); 297 } 298 299 for (int i = 0; i < channels; i++) { 300 BString string; 301 string.SetToFormat("%s%d %s", (i < 9) ? " " : "", i + 1, 302 fController->ChannelName(i)); 303 fChannelMenu->AddItem(new BMenuItem(string, 304 new BMessage(M_SELECT_CHANNEL + i))); 305 } 306 } 307 308 309 void 310 MainWin::SetInterfaceMenuMarker() 311 { 312 BMenuItem *item; 313 314 int interface = fController->CurrentInterface(); 315 printf("MainWin::SetInterfaceMenuMarker: interface %d\n", interface); 316 317 // remove old marker 318 item = fInterfaceMenu->FindMarked(); 319 if (item) 320 item->SetMarked(false); 321 322 // set new marker 323 int index = (interface < 0) ? 0 : interface + 2; 324 item = fInterfaceMenu->ItemAt(index); 325 if (item) 326 item->SetMarked(true); 327 } 328 329 330 void 331 MainWin::SetChannelMenuMarker() 332 { 333 BMenuItem *item; 334 335 int channel = fController->CurrentChannel(); 336 printf("MainWin::SetChannelMenuMarker: channel %d\n", channel); 337 338 // remove old marker 339 item = fChannelMenu->FindMarked(); 340 if (item) 341 item->SetMarked(false); 342 343 // set new marker 344 int index = (channel < 0) ? 0 : channel + 3; 345 item = fChannelMenu->ItemAt(index); 346 if (item) 347 item->SetMarked(true); 348 } 349 350 351 void 352 MainWin::SelectChannel(int i) 353 { 354 printf("MainWin::SelectChannel %d\n", i); 355 356 if (B_OK != fController->SelectChannel(i)) 357 return; 358 359 SetChannelMenuMarker(); 360 } 361 362 363 void 364 MainWin::SelectInterface(int i) 365 { 366 printf("MainWin::SelectInterface %d\n", i); 367 printf(" CurrentInterface %d\n", fController->CurrentInterface()); 368 printf(" CurrentChannel %d\n", fController->CurrentChannel()); 369 370 // i = -1 means "None" 371 372 if (i < 0) { 373 fController->DisconnectInterface(); 374 goto done; 375 } 376 377 if (!fController->IsInterfaceAvailable(i)) { 378 BString s; 379 s << B_TRANSLATE("Error, interface is busy:\n\n"); 380 s << gDeviceRoster->DeviceName(i); 381 BAlert* alert = new BAlert("error", s.String(), B_TRANSLATE("OK")); 382 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 383 alert->Go(); 384 return; 385 } 386 387 fController->DisconnectInterface(); 388 if (fController->ConnectInterface(i) != B_OK) { 389 BString s; 390 s << B_TRANSLATE("Error, connecting to interface failed:\n\n"); 391 s << gDeviceRoster->DeviceName(i); 392 BAlert* alert = new BAlert("error", s.String(), B_TRANSLATE("OK")); 393 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 394 alert->Go(); 395 } 396 397 done: 398 printf("MainWin::SelectInterface done:\n"); 399 printf(" CurrentInterface %d\n", fController->CurrentInterface()); 400 printf(" CurrentChannel %d\n", fController->CurrentChannel()); 401 402 SetInterfaceMenuMarker(); 403 SetupChannelMenu(); 404 SetChannelMenuMarker(); 405 } 406 407 408 void 409 MainWin::SelectInitialInterface() 410 { 411 printf("MainWin::SelectInitialInterface enter\n"); 412 413 int count = gDeviceRoster->DeviceCount(); 414 for (int i = 0; i < count; i++) { 415 if (fController->IsInterfaceAvailable(i) 416 && B_OK == fController->ConnectInterface(i)) { 417 printf("MainWin::SelectInitialInterface connected to interface " 418 "%d\n", i); 419 break; 420 } 421 } 422 423 printf("MainWin::SelectInitialInterface leave\n"); 424 } 425 426 427 bool 428 MainWin::QuitRequested() 429 { 430 be_app->PostMessage(B_QUIT_REQUESTED); 431 return true; 432 } 433 434 435 void 436 MainWin::MouseDown(BMessage *msg) 437 { 438 BPoint screen_where; 439 uint32 buttons = msg->FindInt32("buttons"); 440 441 // On Zeta, only "screen_where" is relyable, "where" and "be:view_where" 442 // seem to be broken 443 if (B_OK != msg->FindPoint("screen_where", &screen_where)) { 444 // Workaround for BeOS R5, it has no "screen_where" 445 fVideoView->GetMouse(&screen_where, &buttons, false); 446 fVideoView->ConvertToScreen(&screen_where); 447 } 448 449 // msg->PrintToStream(); 450 451 // if (1 == msg->FindInt32("buttons") && msg->FindInt32("clicks") == 1) { 452 453 if (1 == buttons && msg->FindInt32("clicks") % 2 == 0) { 454 BRect r(screen_where.x - 1, screen_where.y - 1, screen_where.x + 1, 455 screen_where.y + 1); 456 if (r.Contains(fMouseDownMousePos)) { 457 PostMessage(M_TOGGLE_FULLSCREEN); 458 return; 459 } 460 } 461 462 if (2 == buttons && msg->FindInt32("clicks") % 2 == 0) { 463 BRect r(screen_where.x - 1, screen_where.y - 1, screen_where.x + 1, 464 screen_where.y + 1); 465 if (r.Contains(fMouseDownMousePos)) { 466 PostMessage(M_TOGGLE_NO_BORDER_NO_MENU); 467 return; 468 } 469 } 470 471 /* 472 // very broken in Zeta: 473 fMouseDownMousePos = fVideoView->ConvertToScreen( 474 msg->FindPoint("where")); 475 */ 476 fMouseDownMousePos = screen_where; 477 fMouseDownWindowPos = Frame().LeftTop(); 478 479 if (buttons == 1 && !fIsFullscreen) { 480 // start mouse tracking 481 fVideoView->SetMouseEventMask(B_POINTER_EVENTS | B_NO_POINTER_HISTORY 482 /* | B_LOCK_WINDOW_FOCUS */); 483 fMouseDownTracking = true; 484 } 485 486 // pop up a context menu if right mouse button is down for 200 ms 487 488 if ((buttons & 2) == 0) 489 return; 490 bigtime_t start = system_time(); 491 bigtime_t delay = 200000; 492 BPoint location; 493 do { 494 fVideoView->GetMouse(&location, &buttons); 495 if ((buttons & 2) == 0) 496 break; 497 snooze(1000); 498 } while (system_time() - start < delay); 499 500 if (buttons & 2) 501 ShowContextMenu(screen_where); 502 } 503 504 505 void 506 MainWin::MouseMoved(BMessage *msg) 507 { 508 // msg->PrintToStream(); 509 510 BPoint mousePos; 511 uint32 buttons = msg->FindInt32("buttons"); 512 513 if (1 == buttons && fMouseDownTracking && !fIsFullscreen) { 514 /* 515 // very broken in Zeta: 516 BPoint mousePos = msg->FindPoint("where"); 517 printf("view where: %.0f, %.0f => ", mousePos.x, mousePos.y); 518 fVideoView->ConvertToScreen(&mousePos); 519 */ 520 // On Zeta, only "screen_where" is relyable, "where" and 521 // "be:view_where" seem to be broken 522 if (B_OK != msg->FindPoint("screen_where", &mousePos)) { 523 // Workaround for BeOS R5, it has no "screen_where" 524 fVideoView->GetMouse(&mousePos, &buttons, false); 525 fVideoView->ConvertToScreen(&mousePos); 526 } 527 // printf("screen where: %.0f, %.0f => ", mousePos.x, mousePos.y); 528 float delta_x = mousePos.x - fMouseDownMousePos.x; 529 float delta_y = mousePos.y - fMouseDownMousePos.y; 530 float x = fMouseDownWindowPos.x + delta_x; 531 float y = fMouseDownWindowPos.y + delta_y; 532 // printf("move window to %.0f, %.0f\n", x, y); 533 MoveTo(x, y); 534 } 535 } 536 537 538 void 539 MainWin::MouseUp(BMessage *msg) 540 { 541 // msg->PrintToStream(); 542 fMouseDownTracking = false; 543 } 544 545 546 void 547 MainWin::ShowContextMenu(const BPoint &screen_point) 548 { 549 printf("Show context menu\n"); 550 BPopUpMenu *menu = new BPopUpMenu("context menu", false, false); 551 BMenuItem *item; 552 menu->AddItem(new BMenuItem(B_TRANSLATE("Scale to native size"), 553 new BMessage(M_SCALE_TO_NATIVE_SIZE), 'N', B_COMMAND_KEY)); 554 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Full screen"), 555 new BMessage(M_TOGGLE_FULLSCREEN), 'F', B_COMMAND_KEY)); 556 item->SetMarked(fIsFullscreen); 557 menu->AddSeparatorItem(); 558 menu->AddItem(item = new BMenuItem(B_TRANSLATE("No menu"), 559 new BMessage(M_TOGGLE_NO_MENU), 'M', B_COMMAND_KEY)); 560 item->SetMarked(fNoMenu); 561 menu->AddItem(item = new BMenuItem(B_TRANSLATE("No border"), 562 new BMessage(M_TOGGLE_NO_BORDER), 'B', B_COMMAND_KEY)); 563 item->SetMarked(fNoBorder); 564 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Always on top"), 565 new BMessage(M_TOGGLE_ALWAYS_ON_TOP), 'T', B_COMMAND_KEY)); 566 item->SetMarked(fAlwaysOnTop); 567 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Keep aspect ratio"), 568 new BMessage(M_TOGGLE_KEEP_ASPECT_RATIO), 'K', B_COMMAND_KEY)); 569 item->SetMarked(fKeepAspectRatio); 570 menu->AddSeparatorItem(); 571 menu->AddItem(new BMenuItem(B_TRANSLATE("Quit"), 572 new BMessage(M_FILE_QUIT), 'Q', B_COMMAND_KEY)); 573 574 menu->AddSeparatorItem(); 575 const char* pixel_aspect = "pixel aspect ratio"; 576 BString str1 = pixel_aspect; 577 str1 << " 1.00000:1"; 578 menu->AddItem(new BMenuItem(str1.String(), 579 new BMessage(M_ASPECT_100000_1))); 580 BString str2 = pixel_aspect; 581 str2 << " 1.06666:1"; 582 menu->AddItem(new BMenuItem(str2.String(), 583 new BMessage(M_ASPECT_106666_1))); 584 BString str3 = pixel_aspect; 585 str3 << " 1.09091:1"; 586 menu->AddItem(new BMenuItem(str3.String(), 587 new BMessage(M_ASPECT_109091_1))); 588 BString str4 = pixel_aspect; 589 str4 << " 1.41176:1"; 590 menu->AddItem(new BMenuItem(str4.String(), 591 new BMessage(M_ASPECT_141176_1))); 592 menu->AddItem(new BMenuItem(B_TRANSLATE_COMMENT( 593 "force 720 × 576, display aspect 4:3", 594 "The '×' is the Unicode multiplication sign U+00D7"), 595 new BMessage(M_ASPECT_720_576))); 596 menu->AddItem(new BMenuItem(B_TRANSLATE_COMMENT( 597 "force 704 × 576, display aspect 4:3", 598 "The '×' is the Unicode multiplication sign U+00D7"), 599 new BMessage(M_ASPECT_704_576))); 600 menu->AddItem(new BMenuItem(B_TRANSLATE_COMMENT( 601 "force 544 × 576, display aspect 4:3", 602 "The '×' is the Unicode multiplication sign U+00D7"), 603 new BMessage(M_ASPECT_544_576))); 604 605 menu->SetTargetForItems(this); 606 BRect r(screen_point.x - 5, screen_point.y - 5, screen_point.x + 5, 607 screen_point.y + 5); 608 menu->Go(screen_point, true, true, r, true); 609 } 610 611 612 void 613 MainWin::VideoFormatChange(int width, int height, float width_scale, 614 float height_scale) 615 { 616 // called when video format or aspect ratio changes 617 618 printf("VideoFormatChange enter: width %d, height %d, width_scale %.6f, " 619 "height_scale %.6f\n", width, height, width_scale, height_scale); 620 621 if (width_scale < 1.0 && height_scale >= 1.0) { 622 width_scale = 1.0 / width_scale; 623 height_scale = 1.0 / height_scale; 624 printf("inverting! new values: width_scale %.6f, height_scale %.6f\n", 625 width_scale, height_scale); 626 } 627 628 fSourceWidth = width; 629 fSourceHeight = height; 630 fWidthScale = width_scale; 631 fHeightScale = height_scale; 632 633 // ResizeWindow(Bounds().Width() + 1, Bounds().Height() + 1, true); 634 635 if (fIsFullscreen) { 636 AdjustFullscreenRenderer(); 637 } else { 638 AdjustWindowedRenderer(false); 639 } 640 641 printf("VideoFormatChange leave\n"); 642 643 } 644 645 646 void 647 MainWin::Zoom(BPoint rec_position, float rec_width, float rec_height) 648 { 649 PostMessage(M_TOGGLE_FULLSCREEN); 650 } 651 652 653 void 654 MainWin::FrameResized(float new_width, float new_height) 655 { 656 // called when the window got resized 657 fFrameResizedCalled = true; 658 659 if (new_width != Bounds().Width() || new_height != Bounds().Height()) { 660 debugger("size wrong\n"); 661 } 662 663 664 printf("FrameResized enter: new_width %.0f, new_height %.0f, bounds width " 665 "%.0f, bounds height %.0f\n", new_width, new_height, Bounds().Width(), 666 Bounds().Height()); 667 668 if (fIsFullscreen) { 669 670 printf("FrameResized in fullscreen mode\n"); 671 672 fIgnoreFrameResized = false; 673 AdjustFullscreenRenderer(); 674 675 } else { 676 677 if (fFrameResizedTriggeredAutomatically) { 678 fFrameResizedTriggeredAutomatically = false; 679 printf("FrameResized triggered automatically\n"); 680 681 fIgnoreFrameResized = false; 682 683 AdjustWindowedRenderer(false); 684 } else { 685 printf("FrameResized by user in window mode\n"); 686 687 if (fIgnoreFrameResized) { 688 fIgnoreFrameResized = false; 689 printf("FrameResized ignored\n"); 690 return; 691 } 692 693 AdjustWindowedRenderer(true); 694 } 695 696 } 697 698 printf("FrameResized leave\n"); 699 } 700 701 702 703 void 704 MainWin::UpdateWindowTitle() 705 { 706 BString title; 707 title.SetToFormat(B_TRANSLATE_COMMENT("%s - %d × %d, %.3f:%.3f => %.0f × %.0f", 708 "The '×' is the Unicode multiplication sign U+00D7"), 709 B_TRANSLATE_SYSTEM_NAME(NAME), 710 fSourceWidth, fSourceHeight, fWidthScale, fHeightScale, 711 fVideoView->Bounds().Width() + 1, fVideoView->Bounds().Height() + 1); 712 SetTitle(title); 713 } 714 715 716 void 717 MainWin::AdjustFullscreenRenderer() 718 { 719 // n.b. we don't have a menu in fullscreen mode! 720 721 if (fKeepAspectRatio) { 722 723 // Keep aspect ratio, place render inside 724 // the background area (may create black bars). 725 float max_width = fBackground->Bounds().Width() + 1.0f; 726 float max_height = fBackground->Bounds().Height() + 1.0f; 727 float scaled_width = fSourceWidth * fWidthScale; 728 float scaled_height = fSourceHeight * fHeightScale; 729 float factor = min_c(max_width / scaled_width, max_height 730 / scaled_height); 731 int render_width = int(scaled_width * factor); 732 int render_height = int(scaled_height * factor); 733 int x_ofs = (int(max_width) - render_width) / 2; 734 int y_ofs = (int(max_height) - render_height) / 2; 735 736 printf("AdjustFullscreenRenderer: background %.1f x %.1f, src video " 737 "%d x %d, scaled video %.3f x %.3f, factor %.3f, render %d x %d, " 738 "x-ofs %d, y-ofs %d\n", max_width, max_height, fSourceWidth, 739 fSourceHeight, scaled_width, scaled_height, factor, render_width, 740 render_height, x_ofs, y_ofs); 741 742 fVideoView->MoveTo(x_ofs, y_ofs); 743 fVideoView->ResizeTo(render_width - 1, render_height - 1); 744 745 } else { 746 747 printf("AdjustFullscreenRenderer: using whole background area\n"); 748 749 // no need to keep aspect ratio, make 750 // render cover the whole background 751 fVideoView->MoveTo(0, 0); 752 fVideoView->ResizeTo(fBackground->Bounds().Width(), 753 fBackground->Bounds().Height()); 754 755 } 756 } 757 758 759 void 760 MainWin::AdjustWindowedRenderer(bool user_resized) 761 { 762 printf("AdjustWindowedRenderer enter - user_resized %d\n", user_resized); 763 764 // In windowed mode, the renderer always covers the 765 // whole background, accounting for the menu 766 fVideoView->MoveTo(0, fNoMenu ? 0 : fMenuBarHeight); 767 fVideoView->ResizeTo(fBackground->Bounds().Width(), 768 fBackground->Bounds().Height() - (fNoMenu ? 0 : fMenuBarHeight)); 769 770 if (fKeepAspectRatio) { 771 // To keep the aspect ratio correct, we 772 // do resize the window as required 773 774 float max_width = Bounds().Width() + 1.0f; 775 float max_height = Bounds().Height() + 1.0f - (fNoMenu ? 0 776 : fMenuBarHeight); 777 float scaled_width = fSourceWidth * fWidthScale; 778 float scaled_height = fSourceHeight * fHeightScale; 779 780 if (!user_resized && (scaled_width > max_width 781 || scaled_height > max_height)) { 782 // A format switch occured, and the window was 783 // smaller then the video source. As it was not 784 // initiated by the user resizing the window, we 785 // enlarge the window to fit the video. 786 fIgnoreFrameResized = true; 787 ResizeTo(scaled_width - 1, scaled_height - 1 788 + (fNoMenu ? 0 : fMenuBarHeight)); 789 // Sync(); 790 return; 791 } 792 793 float display_aspect_ratio = scaled_width / scaled_height; 794 int new_width = int(max_width); 795 int new_height = int(max_width / display_aspect_ratio + 0.5); 796 797 printf("AdjustWindowedRenderer: old display %d x %d, src video " 798 "%d x %d, scaled video %.3f x %.3f, aspect ratio %.3f, new " 799 "display %d x %d\n", int(max_width), int(max_height), 800 fSourceWidth, fSourceHeight, scaled_width, scaled_height, 801 display_aspect_ratio, new_width, new_height); 802 803 fIgnoreFrameResized = true; 804 ResizeTo(new_width - 1, new_height - 1 + (fNoMenu ? 0 805 : fMenuBarHeight)); 806 // Sync(); 807 } 808 809 printf("AdjustWindowedRenderer leave\n"); 810 } 811 812 813 void 814 MainWin::ToggleNoBorderNoMenu() 815 { 816 if (!fNoMenu && fNoBorder) { 817 // if no border, switch of menu, too 818 PostMessage(M_TOGGLE_NO_MENU); 819 } else 820 if (fNoMenu && !fNoBorder) { 821 // if no menu, switch of border, too 822 PostMessage(M_TOGGLE_NO_BORDER); 823 } else { 824 // both are either on or off, toggle both 825 PostMessage(M_TOGGLE_NO_MENU); 826 PostMessage(M_TOGGLE_NO_BORDER); 827 } 828 } 829 830 831 void 832 MainWin::ToggleFullscreen() 833 { 834 printf("ToggleFullscreen enter\n"); 835 836 if (!fFrameResizedCalled) { 837 printf("ToggleFullscreen - ignoring, as FrameResized wasn't called " 838 "since last switch\n"); 839 return; 840 } 841 fFrameResizedCalled = false; 842 843 844 fIsFullscreen = !fIsFullscreen; 845 846 if (fIsFullscreen) { 847 // switch to fullscreen 848 849 // Sync here is probably not required 850 // Sync(); 851 852 fSavedFrame = Frame(); 853 printf("saving current frame: %d %d %d %d\n", int(fSavedFrame.left), 854 int(fSavedFrame.top), int(fSavedFrame.right), 855 int(fSavedFrame.bottom)); 856 BScreen screen(this); 857 BRect rect(screen.Frame()); 858 859 Hide(); 860 if (!fNoMenu) { 861 // if we have a menu, remove it now 862 fMenuBar->Hide(); 863 } 864 fFrameResizedTriggeredAutomatically = true; 865 MoveTo(rect.left, rect.top); 866 ResizeTo(rect.Width(), rect.Height()); 867 Show(); 868 869 // Sync(); 870 871 } else { 872 // switch back from full screen mode 873 874 Hide(); 875 // if we need a menu, show it now 876 if (!fNoMenu) { 877 fMenuBar->Show(); 878 } 879 fFrameResizedTriggeredAutomatically = true; 880 MoveTo(fSavedFrame.left, fSavedFrame.top); 881 ResizeTo(fSavedFrame.Width(), fSavedFrame.Height()); 882 Show(); 883 884 // We *must* make sure that the window is at 885 // the correct position before continuing, or 886 // rapid fullscreen switching by holding down 887 // the TAB key will expose strange bugs. 888 // Never remove this Sync! 889 // Sync(); 890 } 891 892 // FrameResized() will do the required adjustments 893 894 printf("ToggleFullscreen leave\n"); 895 } 896 897 898 void 899 MainWin::ToggleNoMenu() 900 { 901 printf("ToggleNoMenu enter\n"); 902 903 fNoMenu = !fNoMenu; 904 905 if (fIsFullscreen) { 906 // fullscreen is always without menu 907 printf("ToggleNoMenu leave, doing nothing, we are fullscreen\n"); 908 return; 909 } 910 911 // fFrameResizedTriggeredAutomatically = true; 912 fIgnoreFrameResized = true; 913 914 if (fNoMenu) { 915 fMenuBar->Hide(); 916 fVideoView->MoveTo(0, 0); 917 fVideoView->ResizeBy(0, fMenuBarHeight); 918 MoveBy(0, fMenuBarHeight); 919 ResizeBy(0, - fMenuBarHeight); 920 // Sync(); 921 } else { 922 fMenuBar->Show(); 923 fVideoView->MoveTo(0, fMenuBarHeight); 924 fVideoView->ResizeBy(0, -fMenuBarHeight); 925 MoveBy(0, - fMenuBarHeight); 926 ResizeBy(0, fMenuBarHeight); 927 // Sync(); 928 } 929 930 printf("ToggleNoMenu leave\n"); 931 } 932 933 934 void 935 MainWin::ToggleNoBorder() 936 { 937 printf("ToggleNoBorder enter\n"); 938 fNoBorder = !fNoBorder; 939 // SetLook(fNoBorder ? B_NO_BORDER_WINDOW_LOOK : B_TITLED_WINDOW_LOOK); 940 SetLook(fNoBorder ? B_BORDERED_WINDOW_LOOK : B_TITLED_WINDOW_LOOK); 941 printf("ToggleNoBorder leave\n"); 942 } 943 944 945 void 946 MainWin::ToggleAlwaysOnTop() 947 { 948 printf("ToggleAlwaysOnTop enter\n"); 949 fAlwaysOnTop = !fAlwaysOnTop; 950 SetFeel(fAlwaysOnTop ? B_FLOATING_ALL_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL); 951 printf("ToggleAlwaysOnTop leave\n"); 952 } 953 954 955 void 956 MainWin::ToggleKeepAspectRatio() 957 { 958 printf("ToggleKeepAspectRatio enter\n"); 959 fKeepAspectRatio = !fKeepAspectRatio; 960 961 fFrameResizedTriggeredAutomatically = true; 962 FrameResized(Bounds().Width(), Bounds().Height()); 963 // if (fIsFullscreen) { 964 // AdjustFullscreenRenderer(); 965 // } else { 966 // AdjustWindowedRenderer(false); 967 // } 968 printf("ToggleKeepAspectRatio leave\n"); 969 } 970 971 972 /* Trap keys that are about to be send to background or renderer view. 973 * Return B_OK if it shouldn't be passed to the view 974 */ 975 status_t 976 MainWin::KeyDown(BMessage *msg) 977 { 978 // msg->PrintToStream(); 979 980 uint32 key = msg->FindInt32("key"); 981 uint32 raw_char = msg->FindInt32("raw_char"); 982 uint32 modifiers = msg->FindInt32("modifiers"); 983 984 printf("key 0x%" B_PRIx32 ", raw_char 0x%" B_PRIx32 ", modifiers 0x%" B_PRIx32 "\n", key, raw_char, 985 modifiers); 986 987 switch (raw_char) { 988 case B_SPACE: 989 PostMessage(M_TOGGLE_NO_BORDER_NO_MENU); 990 return B_OK; 991 992 case B_ESCAPE: 993 if (fIsFullscreen) { 994 PostMessage(M_TOGGLE_FULLSCREEN); 995 return B_OK; 996 } else 997 break; 998 999 case B_ENTER: // Enter / Return 1000 if (modifiers & B_COMMAND_KEY) { 1001 PostMessage(M_TOGGLE_FULLSCREEN); 1002 return B_OK; 1003 } else 1004 break; 1005 1006 case B_TAB: 1007 if ((modifiers & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY 1008 | B_MENU_KEY)) == 0) { 1009 PostMessage(M_TOGGLE_FULLSCREEN); 1010 return B_OK; 1011 } else 1012 break; 1013 1014 case B_UP_ARROW: 1015 if (modifiers & B_COMMAND_KEY) { 1016 PostMessage(M_CHANNEL_NEXT); 1017 } else { 1018 PostMessage(M_VOLUME_UP); 1019 } 1020 return B_OK; 1021 1022 case B_DOWN_ARROW: 1023 if (modifiers & B_COMMAND_KEY) { 1024 PostMessage(M_CHANNEL_PREV); 1025 } else { 1026 PostMessage(M_VOLUME_DOWN); 1027 } 1028 return B_OK; 1029 1030 case B_RIGHT_ARROW: 1031 if (modifiers & B_COMMAND_KEY) { 1032 PostMessage(M_VOLUME_UP); 1033 } else { 1034 PostMessage(M_CHANNEL_NEXT); 1035 } 1036 return B_OK; 1037 1038 case B_LEFT_ARROW: 1039 if (modifiers & B_COMMAND_KEY) { 1040 PostMessage(M_VOLUME_DOWN); 1041 } else { 1042 PostMessage(M_CHANNEL_PREV); 1043 } 1044 return B_OK; 1045 1046 case B_PAGE_UP: 1047 PostMessage(M_CHANNEL_NEXT); 1048 return B_OK; 1049 1050 case B_PAGE_DOWN: 1051 PostMessage(M_CHANNEL_PREV); 1052 return B_OK; 1053 } 1054 1055 switch (key) { 1056 case 0x3a: // numeric keypad + 1057 if ((modifiers & B_COMMAND_KEY) == 0) { 1058 printf("if\n"); 1059 PostMessage(M_VOLUME_UP); 1060 return B_OK; 1061 } else { 1062 printf("else\n"); 1063 break; 1064 } 1065 1066 case 0x25: // numeric keypad - 1067 if ((modifiers & B_COMMAND_KEY) == 0) { 1068 PostMessage(M_VOLUME_DOWN); 1069 return B_OK; 1070 } else { 1071 break; 1072 } 1073 1074 case 0x38: // numeric keypad up arrow 1075 PostMessage(M_VOLUME_UP); 1076 return B_OK; 1077 1078 case 0x59: // numeric keypad down arrow 1079 PostMessage(M_VOLUME_DOWN); 1080 return B_OK; 1081 1082 case 0x39: // numeric keypad page up 1083 case 0x4a: // numeric keypad right arrow 1084 PostMessage(M_CHANNEL_NEXT); 1085 return B_OK; 1086 1087 case 0x5a: // numeric keypad page down 1088 case 0x48: // numeric keypad left arrow 1089 PostMessage(M_CHANNEL_PREV); 1090 return B_OK; 1091 } 1092 1093 return B_ERROR; 1094 } 1095 1096 1097 void 1098 MainWin::DispatchMessage(BMessage *msg, BHandler *handler) 1099 { 1100 if ((msg->what == B_MOUSE_DOWN) && (handler == fBackground 1101 || handler == fVideoView)) 1102 MouseDown(msg); 1103 if ((msg->what == B_MOUSE_MOVED) && (handler == fBackground 1104 || handler == fVideoView)) 1105 MouseMoved(msg); 1106 if ((msg->what == B_MOUSE_UP) && (handler == fBackground 1107 || handler == fVideoView)) 1108 MouseUp(msg); 1109 1110 if ((msg->what == B_KEY_DOWN) && (handler == fBackground 1111 || handler == fVideoView)) { 1112 1113 // special case for PrintScreen key 1114 if (msg->FindInt32("key") == B_PRINT_KEY) { 1115 fVideoView->OverlayScreenshotPrepare(); 1116 BWindow::DispatchMessage(msg, handler); 1117 fVideoView->OverlayScreenshotCleanup(); 1118 return; 1119 } 1120 1121 // every other key gets dispatched to our KeyDown first 1122 if (KeyDown(msg) == B_OK) { 1123 // it got handled, don't pass it on 1124 return; 1125 } 1126 } 1127 1128 BWindow::DispatchMessage(msg, handler); 1129 } 1130 1131 1132 void 1133 MainWin::MessageReceived(BMessage *msg) 1134 { 1135 switch (msg->what) { 1136 case B_ACQUIRE_OVERLAY_LOCK: 1137 printf("B_ACQUIRE_OVERLAY_LOCK\n"); 1138 fVideoView->OverlayLockAcquire(); 1139 break; 1140 1141 case B_RELEASE_OVERLAY_LOCK: 1142 printf("B_RELEASE_OVERLAY_LOCK\n"); 1143 fVideoView->OverlayLockRelease(); 1144 break; 1145 1146 case B_MOUSE_WHEEL_CHANGED: 1147 { 1148 printf("B_MOUSE_WHEEL_CHANGED\n"); 1149 float dx = msg->FindFloat("be:wheel_delta_x"); 1150 float dy = msg->FindFloat("be:wheel_delta_y"); 1151 bool inv = modifiers() & B_COMMAND_KEY; 1152 if (dx > 0.1) PostMessage(inv ? M_VOLUME_DOWN : M_CHANNEL_PREV); 1153 if (dx < -0.1) PostMessage(inv ? M_VOLUME_UP : M_CHANNEL_NEXT); 1154 if (dy > 0.1) PostMessage(inv ? M_CHANNEL_PREV : M_VOLUME_DOWN); 1155 if (dy < -0.1) PostMessage(inv ? M_CHANNEL_NEXT : M_VOLUME_UP); 1156 break; 1157 } 1158 1159 case M_CHANNEL_NEXT: 1160 { 1161 printf("M_CHANNEL_NEXT\n"); 1162 int chan = fController->CurrentChannel(); 1163 if (chan != -1) { 1164 chan++; 1165 if (chan < fController->ChannelCount()) 1166 SelectChannel(chan); 1167 } 1168 break; 1169 } 1170 1171 case M_CHANNEL_PREV: 1172 { 1173 printf("M_CHANNEL_PREV\n"); 1174 int chan = fController->CurrentChannel(); 1175 if (chan != -1) { 1176 chan--; 1177 if (chan >= 0) 1178 SelectChannel(chan); 1179 } 1180 break; 1181 } 1182 1183 case M_VOLUME_UP: 1184 printf("M_VOLUME_UP\n"); 1185 fController->VolumeUp(); 1186 break; 1187 1188 case M_VOLUME_DOWN: 1189 printf("M_VOLUME_DOWN\n"); 1190 fController->VolumeDown(); 1191 break; 1192 1193 case M_ASPECT_100000_1: 1194 VideoFormatChange(fSourceWidth, fSourceHeight, 1.0, 1.0); 1195 break; 1196 1197 case M_ASPECT_106666_1: 1198 VideoFormatChange(fSourceWidth, fSourceHeight, 1.06666, 1.0); 1199 break; 1200 1201 case M_ASPECT_109091_1: 1202 VideoFormatChange(fSourceWidth, fSourceHeight, 1.09091, 1.0); 1203 break; 1204 1205 case M_ASPECT_141176_1: 1206 VideoFormatChange(fSourceWidth, fSourceHeight, 1.41176, 1.0); 1207 break; 1208 1209 case M_ASPECT_720_576: 1210 VideoFormatChange(720, 576, 1.06666, 1.0); 1211 break; 1212 1213 case M_ASPECT_704_576: 1214 VideoFormatChange(704, 576, 1.09091, 1.0); 1215 break; 1216 1217 case M_ASPECT_544_576: 1218 VideoFormatChange(544, 576, 1.41176, 1.0); 1219 break; 1220 1221 case B_REFS_RECEIVED: 1222 printf("MainWin::MessageReceived: B_REFS_RECEIVED\n"); 1223 // RefsReceived(msg); 1224 break; 1225 1226 case B_SIMPLE_DATA: 1227 printf("MainWin::MessageReceived: B_SIMPLE_DATA\n"); 1228 // if (msg->HasRef("refs")) 1229 // RefsReceived(msg); 1230 break; 1231 1232 case M_FILE_QUIT: 1233 // be_app->PostMessage(B_QUIT_REQUESTED); 1234 PostMessage(B_QUIT_REQUESTED); 1235 break; 1236 1237 case M_SCALE_TO_NATIVE_SIZE: 1238 printf("M_SCALE_TO_NATIVE_SIZE\n"); 1239 if (fIsFullscreen) { 1240 ToggleFullscreen(); 1241 } 1242 ResizeTo(int(fSourceWidth * fWidthScale), 1243 int(fSourceHeight * fHeightScale) + (fNoMenu ? 0 1244 : fMenuBarHeight)); 1245 // Sync(); 1246 break; 1247 1248 case M_TOGGLE_FULLSCREEN: 1249 ToggleFullscreen(); 1250 fSettingsMenu->ItemAt(1)->SetMarked(fIsFullscreen); 1251 break; 1252 1253 case M_TOGGLE_NO_MENU: 1254 ToggleNoMenu(); 1255 fSettingsMenu->ItemAt(3)->SetMarked(fNoMenu); 1256 break; 1257 1258 case M_TOGGLE_NO_BORDER: 1259 ToggleNoBorder(); 1260 fSettingsMenu->ItemAt(4)->SetMarked(fNoBorder); 1261 break; 1262 1263 case M_TOGGLE_ALWAYS_ON_TOP: 1264 ToggleAlwaysOnTop(); 1265 fSettingsMenu->ItemAt(5)->SetMarked(fAlwaysOnTop); 1266 break; 1267 1268 case M_TOGGLE_KEEP_ASPECT_RATIO: 1269 ToggleKeepAspectRatio(); 1270 fSettingsMenu->ItemAt(6)->SetMarked(fKeepAspectRatio); 1271 break; 1272 1273 case M_TOGGLE_NO_BORDER_NO_MENU: 1274 ToggleNoBorderNoMenu(); 1275 break; 1276 1277 case M_PREFERENCES: 1278 break; 1279 1280 default: 1281 if (msg->what >= M_SELECT_CHANNEL 1282 && msg->what <= M_SELECT_CHANNEL_END) { 1283 SelectChannel(msg->what - M_SELECT_CHANNEL); 1284 break; 1285 } 1286 if (msg->what >= M_SELECT_INTERFACE 1287 && msg->what <= M_SELECT_INTERFACE_END) { 1288 SelectInterface(msg->what - M_SELECT_INTERFACE - 1); 1289 break; 1290 } 1291 1292 BWindow::MessageReceived(msg); 1293 } 1294 } 1295 1296