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