1 2#import <Cocoa/Cocoa.h> 3 4#include "compat.h" 5#include "baselayer.h" 6#include "build.h" 7#include "editor.h" 8#include "osxbits.h" 9 10#ifndef MAC_OS_X_VERSION_10_5 11# define NSImageScaleNone NSScaleNone 12#endif 13 14#ifndef MAC_OS_X_VERSION_10_12 15# define NSEventModifierFlagOption NSAlternateKeyMask 16# define NSEventModifierFlagCommand NSCommandKeyMask 17# define NSEventMaskAny NSAnyEventMask 18# define NSWindowStyleMaskTitled NSTitledWindowMask 19# define NSWindowStyleMaskClosable NSClosableWindowMask 20# define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask 21# define NSWindowStyleMaskResizable NSResizableWindowMask 22# define NSAlertStyleInformational NSInformationalAlertStyle 23# define NSControlSizeSmall NSSmallControlSize 24#endif 25 26#ifndef MAC_OS_X_VERSION_10_14 27# define NSButtonTypeSwitch NSSwitchButton 28# define NSBezelStyleRounded NSRoundedBezelStyle 29# define NSControlStateValueOn NSOnState 30# define NSControlStateValueOff NSOffState 31#endif 32 33static inline NSRect NSRectChangeXY(NSRect const rect, CGFloat const x, CGFloat const y) 34{ 35 return NSMakeRect(x, y, rect.size.width, rect.size.height); 36} 37static inline NSRect NSSizeAddXY(NSSize const size, CGFloat const x, CGFloat const y) 38{ 39 return NSMakeRect(x, y, size.width, size.height); 40} 41static inline CGFloat NSRightEdge(NSRect rect) 42{ 43 return rect.origin.x + rect.size.width; 44} 45static inline CGFloat NSTopEdge(NSRect rect) 46{ 47 return rect.origin.y + rect.size.height; 48} 49 50static inline void setFontToSmall(id control) 51{ 52 [control setFont:[NSFont fontWithDescriptor:[[control font] fontDescriptor] size:[NSFont smallSystemFontSize]]]; 53} 54 55static inline void setControlToSmall(id control) 56{ 57 [control setControlSize:NSControlSizeSmall]; 58} 59 60static inline NSTextField * makeLabel(NSString * labelText) 61{ 62 NSTextField *textField = [[NSTextField alloc] init]; 63 setFontToSmall(textField); 64 setControlToSmall([textField cell]); 65 [textField setStringValue:labelText]; 66 [textField setBezeled:NO]; 67 [textField setDrawsBackground:NO]; 68 [textField setEditable:NO]; 69 [textField setSelectable:NO]; 70 [textField sizeToFit]; 71 return textField; 72} 73 74static inline NSButton * makeCheckbox(NSString * labelText) 75{ 76 NSButton *checkbox = [[NSButton alloc] init]; 77 setFontToSmall(checkbox); 78 setControlToSmall([checkbox cell]); 79 [checkbox setTitle:labelText]; 80 [checkbox setButtonType:NSButtonTypeSwitch]; 81 [checkbox sizeToFit]; 82 return checkbox; 83} 84 85static inline NSPopUpButton * makeComboBox(void) 86{ 87 NSPopUpButton *comboBox = [[NSPopUpButton alloc] init]; 88 [comboBox setPullsDown:NO]; 89 setFontToSmall(comboBox); 90 setControlToSmall([comboBox cell]); 91 [comboBox setBezelStyle:NSBezelStyleRounded]; 92 [comboBox setPreferredEdge:NSMaxYEdge]; 93 [[comboBox cell] setArrowPosition:NSPopUpArrowAtCenter]; 94 [comboBox sizeToFit]; 95 return comboBox; 96} 97 98/* setAppleMenu disappeared from the headers in 10.4 */ 99@interface NSApplication(NSAppleMenu) 100- (void)setAppleMenu:(NSMenu *)menu; 101@end 102 103static inline NSString * GetApplicationName(void) 104{ 105 NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; 106 if (!appName) 107 appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]; 108 if (![appName length]) 109 appName = [[NSProcessInfo processInfo] processName]; 110 111 return appName; 112} 113 114static inline void CreateApplicationMenus(void) 115{ 116 NSString *appName; 117 NSString *title; 118 NSMenu *rootMenu; 119 NSMenu *serviceMenu; 120 NSMenuItem *menuItem; 121 122 NSMenu *mainMenu = [[NSMenu alloc] init]; 123 124 /* Create the application menu */ 125 appName = GetApplicationName(); 126 rootMenu = [[NSMenu alloc] init]; 127 128 /* Put menu into the menubar */ 129 menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; 130 [menuItem setSubmenu:rootMenu]; 131 [mainMenu addItem:menuItem]; 132 [menuItem release]; 133 134 /* Add menu items */ 135 title = [@"About " stringByAppendingString:appName]; 136 [rootMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; 137 138 [rootMenu addItem:[NSMenuItem separatorItem]]; 139 140 serviceMenu = [[NSMenu alloc] init]; 141 menuItem = (NSMenuItem *)[rootMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""]; 142 [menuItem setSubmenu:serviceMenu]; 143 144 [nsapp setServicesMenu:serviceMenu]; 145 [serviceMenu release]; 146 147 [rootMenu addItem:[NSMenuItem separatorItem]]; 148 149 title = [@"Hide " stringByAppendingString:appName]; 150 [rootMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; 151 152 menuItem = (NSMenuItem *)[rootMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; 153 [menuItem setKeyEquivalentModifierMask:(NSEventModifierFlagOption|NSEventModifierFlagCommand)]; 154 155 [rootMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; 156 157 [rootMenu addItem:[NSMenuItem separatorItem]]; 158 159 title = [@"Quit " stringByAppendingString:appName]; 160 [rootMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; 161 162 /* Create the main menu bar */ 163 [nsapp setMainMenu:mainMenu]; 164 [mainMenu release]; /* we're done with it, let NSApp own it. */ 165 166 /* Tell the application object that this is now the application menu */ 167 [nsapp setAppleMenu:rootMenu]; 168 [rootMenu release]; 169} 170 171static int retval = -1; 172 173static struct { 174 int fullscreen; 175 int xdim2d, ydim2d; 176 int xdim3d, ydim3d, bpp3d; 177 int forcesetup; 178} settings; 179 180@interface StartupWindow : NSWindow <NSWindowDelegate> 181{ 182 NSMutableArray *modeslist2d; 183 NSMutableArray *modeslist3d; 184 185 NSButton *alwaysShowButton; 186 NSButton *fullscreenButton; 187 NSTextView *messagesView; 188 NSTabView *tabView; 189 NSTabViewItem *tabViewItemSetup; 190 NSTabViewItem *tabViewItemMessageLog; 191 NSPopUpButton *videoMode2DPUButton; 192 NSPopUpButton *videoMode3DPUButton; 193 194 NSButton *cancelButton; 195 NSButton *startButton; 196} 197 198- (StartupWindow *)init; 199 200- (void)dealloc; 201- (void)populateVideoModes:(BOOL)firstTime; 202 203- (void)fullscreenClicked:(id)sender; 204 205- (void)cancel:(id)sender; 206- (void)start:(id)sender; 207 208- (void)setupRunMode; 209- (void)setupMessagesMode; 210 211- (void)putsMessage:(NSString *)str; 212 213@end 214 215@implementation StartupWindow : NSWindow 216 217- (StartupWindow *)init 218{ 219 NSUInteger const style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable; 220 NSRect const windowFrame = NSMakeRect(0, 0, 480, 280); 221 self = [super initWithContentRect:windowFrame styleMask:style backing:NSBackingStoreBuffered defer:NO]; 222 223 if (self) 224 { 225 // window properties 226 [self setDelegate:self]; 227 [self setReleasedWhenClosed:NO]; 228#if defined MAC_OS_X_VERSION_10_3 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3 229 [self setContentMinSize:[[self contentView] frame].size]; 230#else 231 [self setMinSize:[NSWindow frameRectForContentRect:[[self contentView] frame] styleMask:[self styleMask]].size]; 232#endif 233 234 235 // image on the left 236 NSRect const imageFrame = NSMakeRect(0, 0, 100, 280); 237 NSImageView * imageView = [[NSImageView alloc] initWithFrame:imageFrame]; 238 [imageView setImageScaling:NSImageScaleNone]; 239 [imageView setImage:[NSImage imageNamed:@"build"]]; 240 [[self contentView] addSubview:imageView]; 241 [imageView setAutoresizingMask:NSViewMaxXMargin | NSViewHeightSizable]; 242 243 244 // buttons 245 CGFloat const buttonWidth = 80; 246 CGFloat const buttonHeight = 32; 247 248 NSRect const startButtonFrame = NSMakeRect(windowFrame.size.width - buttonWidth, 0, buttonWidth, buttonHeight); 249 startButton = [[NSButton alloc] initWithFrame:startButtonFrame]; 250 [[self contentView] addSubview:startButton]; 251 [startButton setTitle:@"Start"]; 252 [startButton setTarget:self]; 253 [startButton setAction:@selector(start:)]; 254 [startButton setBezelStyle:NSBezelStyleRounded]; 255 [startButton setKeyEquivalent:@"\r"]; 256 [startButton setAutoresizingMask:NSViewMinXMargin | NSViewMaxYMargin]; 257 258 NSRect const cancelButtonFrame = NSMakeRect(startButtonFrame.origin.x - buttonWidth, 0, buttonWidth, buttonHeight); 259 cancelButton = [[NSButton alloc] initWithFrame:cancelButtonFrame]; 260 [[self contentView] addSubview:cancelButton]; 261 [cancelButton setTitle:@"Cancel"]; 262 [cancelButton setTarget:self]; 263 [cancelButton setAction:@selector(cancel:)]; 264 [cancelButton setBezelStyle:NSBezelStyleRounded]; 265 [cancelButton setAutoresizingMask:NSViewMinXMargin | NSViewMaxYMargin]; 266 267 268 // tab frame 269 NSRect const tabViewFrame = NSMakeRect(imageFrame.size.width, buttonHeight, windowFrame.size.width - imageFrame.size.width, windowFrame.size.height - buttonHeight - 5); 270 tabView = [[NSTabView alloc] initWithFrame:tabViewFrame]; 271 [[self contentView] addSubview:tabView]; 272 setFontToSmall(tabView); 273 setControlToSmall(tabView); 274 [tabView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; 275 276 277 // setup tab 278 279 tabViewItemSetup = [[NSTabViewItem alloc] init]; 280 [tabView addTabViewItem:tabViewItemSetup]; 281 [tabViewItemSetup setLabel:@"Setup"]; 282 NSRect const tabViewItemSetupFrame = [[tabViewItemSetup view] frame]; 283 284 285 // always show checkbox 286 alwaysShowButton = makeCheckbox(@"Always show this window at startup"); 287 [[tabViewItemSetup view] addSubview:alwaysShowButton]; 288 NSSize const alwaysShowButtonSize = [alwaysShowButton frame].size; 289 NSRect const alwaysShowButtonFrame = NSSizeAddXY(alwaysShowButtonSize, tabViewItemSetupFrame.size.width - alwaysShowButtonSize.width, 0); 290 [alwaysShowButton setFrame:alwaysShowButtonFrame]; 291 [alwaysShowButton setAutoresizingMask:NSViewMinXMargin | NSViewMaxYMargin]; 292 293 294 // video mode selectors and labels 295 NSTextField * label2DVideoMode = makeLabel(@"2D Video mode:"); 296 [[tabViewItemSetup view] addSubview:label2DVideoMode]; 297 NSSize const label2DVideoModeSize = [label2DVideoMode frame].size; 298 [label2DVideoMode setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; 299 300 NSTextField * label3DVideoMode = makeLabel(@"3D Video mode:"); 301 [[tabViewItemSetup view] addSubview:label3DVideoMode]; 302 NSSize const label3DVideoModeSize = [label3DVideoMode frame].size; 303 [label3DVideoMode setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; 304 305 fullscreenButton = makeCheckbox(@"Fullscreen"); 306 [[tabViewItemSetup view] addSubview:fullscreenButton]; 307 NSSize const fullscreenButtonSize = [fullscreenButton frame].size; 308 [fullscreenButton setAction:@selector(fullscreenClicked:)]; 309 [fullscreenButton setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin]; 310 311 CGFloat const labelsVideoModeRightEdge = max(label2DVideoModeSize.width, label3DVideoModeSize.width); 312 313 videoMode2DPUButton = makeComboBox(); 314 [[tabViewItemSetup view] addSubview:videoMode2DPUButton]; 315 NSSize const videoMode2DPUButtonSize = [videoMode2DPUButton frame].size; 316 CGFloat const videoMode2DButtonX = labelsVideoModeRightEdge; 317 NSRect const videoMode2DPUButtonFrame = NSMakeRect(videoMode2DButtonX, tabViewItemSetupFrame.size.height - videoMode2DPUButtonSize.height, tabViewItemSetupFrame.size.width - videoMode2DButtonX - fullscreenButtonSize.width, videoMode2DPUButtonSize.height); 318 [videoMode2DPUButton setFrame:videoMode2DPUButtonFrame]; 319 [videoMode2DPUButton setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; 320 321 videoMode3DPUButton = makeComboBox(); 322 [[tabViewItemSetup view] addSubview:videoMode3DPUButton]; 323 NSSize const videoMode3DPUButtonSize = [videoMode3DPUButton frame].size; 324 CGFloat const videoMode3DButtonX = labelsVideoModeRightEdge; 325 NSRect const videoMode3DPUButtonFrame = NSMakeRect(videoMode3DButtonX, videoMode2DPUButtonFrame.origin.y - videoMode3DPUButtonSize.height, tabViewItemSetupFrame.size.width - videoMode3DButtonX - fullscreenButtonSize.width, videoMode3DPUButtonSize.height); 326 [videoMode3DPUButton setFrame:videoMode3DPUButtonFrame]; 327 [videoMode3DPUButton setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; 328 329 NSRect const label2DVideoModeFrame = NSSizeAddXY(label2DVideoModeSize, 0, videoMode2DPUButtonFrame.origin.y + rintf((videoMode2DPUButtonSize.height - label2DVideoModeSize.height) * 0.5f) + 1); 330 [label2DVideoMode setFrame:label2DVideoModeFrame]; 331 332 NSRect const label3DVideoModeFrame = NSSizeAddXY(label3DVideoModeSize, 0, videoMode3DPUButtonFrame.origin.y + rintf((videoMode3DPUButtonSize.height - label3DVideoModeSize.height) * 0.5f) + 1); 333 [label3DVideoMode setFrame:label3DVideoModeFrame]; 334 335 NSRect const fullscreenButtonFrame = NSSizeAddXY(fullscreenButtonSize, tabViewItemSetupFrame.size.width - fullscreenButtonSize.width, videoMode3DPUButtonFrame.origin.y + rintf((videoMode3DPUButtonSize.height - fullscreenButtonSize.height) * 0.5f) + 1); 336 [fullscreenButton setFrame:fullscreenButtonFrame]; 337 338 339 // message log tab 340 341 tabViewItemMessageLog = [[NSTabViewItem alloc] init]; 342 [tabView addTabViewItem:tabViewItemMessageLog]; 343 [tabViewItemMessageLog setLabel:@"Message Log"]; 344 NSRect const tabViewItemMessageLogFrame = [[tabViewItemMessageLog view] frame]; 345 346 347 // message log 348 NSScrollView * messagesScrollView = [[NSScrollView alloc] initWithFrame:NSRectChangeXY(tabViewItemMessageLogFrame, 0, 0)]; 349 [[tabViewItemMessageLog view] addSubview:messagesScrollView]; 350 [messagesScrollView setBorderType:NSBezelBorder]; 351 [messagesScrollView setHasVerticalScroller:YES]; 352 [messagesScrollView setHasHorizontalScroller:NO]; 353 setControlToSmall([[messagesScrollView verticalScroller] cell]); 354 NSSize const messagesScrollViewContentSize = [messagesScrollView contentSize]; 355 [messagesScrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; 356 357 messagesView = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, messagesScrollViewContentSize.width, messagesScrollViewContentSize.height)]; 358 [messagesScrollView setDocumentView:messagesView]; 359 [messagesView setEditable:NO]; 360 [messagesView setRichText:NO]; 361 setFontToSmall(messagesView); 362 [messagesView setMinSize:NSMakeSize(0.0, messagesScrollViewContentSize.height)]; 363 [messagesView setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; 364 [messagesView setVerticallyResizable:YES]; 365 [messagesView setHorizontallyResizable:NO]; 366 [messagesView setAutoresizingMask:NSViewWidthSizable]; 367 368 [[messagesView textContainer] setContainerSize:NSMakeSize(messagesScrollViewContentSize.width, FLT_MAX)]; 369 [[messagesView textContainer] setWidthTracksTextView:YES]; 370 } 371 372 return self; 373} 374 375- (BOOL)canBecomeKeyWindow 376{ 377 return YES; 378} 379 380- (BOOL)canBecomeMainWindow 381{ 382 return YES; 383} 384 385- (BOOL) windowShouldClose:(id)sender 386{ 387 UNREFERENCED_PARAMETER(sender); 388 389 retval = 0; 390 391 return YES; 392} 393 394- (void)dealloc 395{ 396 [modeslist3d release]; 397 [super dealloc]; 398} 399 400- (void)populateVideoModes:(BOOL)firstTime 401{ 402 int i, mode3d, fullscreen = ([fullscreenButton state] == NSControlStateValueOn); 403 int mode2d, idx2d = -1; 404 int idx3d = -1; 405 int xdim2d = 0, ydim2d = 0; 406 int const bpp2d = 8; 407 int xdim = 0, ydim = 0, bpp = 0; 408 409 if (firstTime) { 410 xdim2d = settings.xdim2d; 411 ydim2d = settings.ydim2d; 412 xdim = settings.xdim3d; 413 ydim = settings.ydim3d; 414 bpp = settings.bpp3d; 415 } else { 416 mode2d = [[modeslist2d objectAtIndex:[videoMode2DPUButton indexOfSelectedItem]] intValue]; 417 if (mode2d >= 0) { 418 xdim2d = validmode[mode2d].xdim; 419 ydim2d = validmode[mode2d].ydim; 420 } 421 422 mode3d = [[modeslist3d objectAtIndex:[videoMode3DPUButton indexOfSelectedItem]] intValue]; 423 if (mode3d >= 0) { 424 xdim = validmode[mode3d].xdim; 425 ydim = validmode[mode3d].ydim; 426 bpp = validmode[mode3d].bpp; 427 } 428 } 429 430 431 mode2d = videoCheckMode(&xdim2d, &ydim2d, bpp2d, fullscreen, 1); 432 433 [modeslist2d release]; 434 [videoMode2DPUButton removeAllItems]; 435 436 modeslist2d = [[NSMutableArray alloc] init]; 437 438 for (i = 0; i < validmodecnt; i++) { 439 if (fullscreen == validmode[i].fs) { 440 if (i == mode2d) idx2d = [modeslist2d count]; 441 [modeslist2d addObject:[NSNumber numberWithInt:i]]; 442 [videoMode2DPUButton addItemWithTitle:[NSString stringWithFormat:@"%d %C %d", 443 validmode[i].xdim, 0xd7, validmode[i].ydim]]; 444 } 445 } 446 447 if (idx2d >= 0) [videoMode2DPUButton selectItemAtIndex:idx2d]; 448 449 450 mode3d = videoCheckMode(&xdim, &ydim, bpp, fullscreen, 1); 451 if (mode3d < 0) { 452 int i, cd[] = { 32, 24, 16, 15, 8, 0 }; 453 for (i=0; cd[i]; ) { if (cd[i] >= bpp) i++; else break; } 454 for ( ; cd[i]; i++) { 455 mode3d = videoCheckMode(&xdim, &ydim, cd[i], fullscreen, 1); 456 if (mode3d < 0) continue; 457 break; 458 } 459 } 460 461 [modeslist3d release]; 462 [videoMode3DPUButton removeAllItems]; 463 464 modeslist3d = [[NSMutableArray alloc] init]; 465 466 for (i = 0; i < validmodecnt; i++) { 467 if (fullscreen == validmode[i].fs) { 468 if (i == mode3d) idx3d = [modeslist3d count]; 469 [modeslist3d addObject:[NSNumber numberWithInt:i]]; 470 [videoMode3DPUButton addItemWithTitle:[NSString stringWithFormat:@"%d %C %d %d-bpp", 471 validmode[i].xdim, 0xd7, validmode[i].ydim, validmode[i].bpp]]; 472 } 473 } 474 475 if (idx3d >= 0) [videoMode3DPUButton selectItemAtIndex:idx3d]; 476} 477 478- (void)fullscreenClicked:(id)sender 479{ 480 UNREFERENCED_PARAMETER(sender); 481 482 [self populateVideoModes:NO]; 483} 484 485- (void)cancel:(id)sender 486{ 487 UNREFERENCED_PARAMETER(sender); 488 489 retval = 0; 490} 491 492- (void)start:(id)sender 493{ 494 UNREFERENCED_PARAMETER(sender); 495 496 int mode2d = [[modeslist2d objectAtIndex:[videoMode2DPUButton indexOfSelectedItem]] intValue]; 497 if (mode2d >= 0) { 498 settings.xdim2d = validmode[mode2d].xdim; 499 settings.ydim2d = validmode[mode2d].ydim; 500 settings.fullscreen = validmode[mode2d].fs; 501 } 502 503 int mode = [[modeslist3d objectAtIndex:[videoMode3DPUButton indexOfSelectedItem]] intValue]; 504 if (mode >= 0) { 505 settings.xdim3d = validmode[mode].xdim; 506 settings.ydim3d = validmode[mode].ydim; 507 settings.bpp3d = validmode[mode].bpp; 508 settings.fullscreen = validmode[mode].fs; 509 } 510 511 settings.forcesetup = [alwaysShowButton state] == NSControlStateValueOn; 512 513 retval = 1; 514} 515 516- (void)setupRunMode 517{ 518 videoGetModes(); 519 520 [fullscreenButton setState: (settings.fullscreen ? NSControlStateValueOn : NSControlStateValueOff)]; 521 [alwaysShowButton setState: (settings.forcesetup ? NSControlStateValueOn : NSControlStateValueOff)]; 522 [self populateVideoModes:YES]; 523 524 // enable all the controls on the Configuration page 525 NSEnumerator *enumerator = [[[tabViewItemSetup view] subviews] objectEnumerator]; 526 NSControl *control; 527 while ((control = [enumerator nextObject])) 528 { 529 if ([control respondsToSelector:@selector(setEnabled:)]) 530 [control setEnabled:true]; 531 } 532 533 [cancelButton setEnabled:true]; 534 [startButton setEnabled:true]; 535 536 [tabView selectTabViewItem:tabViewItemSetup]; 537 [NSCursor unhide]; // Why should I need to do this? 538} 539 540- (void)setupMessagesMode 541{ 542 [tabView selectTabViewItem:tabViewItemMessageLog]; 543 544 // disable all the controls on the Configuration page except "always show", so the 545 // user can enable it if they want to while waiting for something else to happen 546 NSEnumerator *enumerator = [[[tabViewItemSetup view] subviews] objectEnumerator]; 547 NSControl *control; 548 while ((control = [enumerator nextObject])) 549 { 550 if (control != alwaysShowButton && [control respondsToSelector:@selector(setEnabled:)]) 551 [control setEnabled:false]; 552 } 553 554 [cancelButton setEnabled:false]; 555 [startButton setEnabled:false]; 556} 557 558- (void)putsMessage:(NSString *)str 559{ 560 NSRange end; 561 NSTextStorage *text = [messagesView textStorage]; 562 BOOL shouldAutoScroll; 563 564 shouldAutoScroll = ((int)NSMaxY([messagesView bounds]) == (int)NSMaxY([messagesView visibleRect])); 565 566 end.location = [text length]; 567 end.length = 0; 568 569 [text beginEditing]; 570 [messagesView replaceCharactersInRange:end withString:str]; 571 [text endEditing]; 572 573 if (shouldAutoScroll) { 574 end.location = [text length]; 575 end.length = 0; 576 [messagesView scrollRangeToVisible:end]; 577 } 578} 579 580@end 581 582static StartupWindow *startwin = nil; 583 584int startwin_open(void) 585{ 586 if (startwin != nil) return 1; 587 588 startwin = [[StartupWindow alloc] init]; 589 if (startwin == nil) return -1; 590 591 [startwin setupMessagesMode]; 592 593 [startwin center]; 594 [startwin makeKeyAndOrderFront:nil]; 595 596 CreateApplicationMenus(); 597 598 return 0; 599} 600 601int startwin_close(void) 602{ 603 if (startwin == nil) return 1; 604 605 [startwin close]; 606 [startwin release]; 607 startwin = nil; 608 609 return 0; 610} 611 612int startwin_puts(const char *s) 613{ 614 NSString *ns; 615 616 if (!s) return -1; 617 if (startwin == nil) return 1; 618 619 ns = [NSString stringWithUTF8String:s]; 620 [startwin putsMessage:ns]; 621 [ns release]; 622 623 return 0; 624} 625 626int startwin_settitle(const char *s) 627{ 628 NSString *ns; 629 630 if (!s) return -1; 631 if (startwin == nil) return 1; 632 633 ns = [NSString stringWithUTF8String:s]; 634 [startwin setTitle:ns]; 635 [ns release]; 636 637 return 0; 638} 639 640int startwin_idle(void *v) 641{ 642 UNREFERENCED_PARAMETER(v); 643 644 if (startwin) 645 { 646 NSEvent *event; 647 do 648 { 649 event = [nsapp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate date] inMode:NSDefaultRunLoopMode dequeue:YES]; 650 [nsapp sendEvent:event]; 651 } 652 while (event != nil); 653 654 [startwin displayIfNeeded]; 655 [nsapp updateWindows]; 656 } 657 658 return 0; 659} 660 661 662int startwin_run(void) 663{ 664 if (startwin == nil) return 0; 665 666 settings.fullscreen = fullscreen; 667 settings.xdim2d = xdim2d; 668 settings.ydim2d = ydim2d; 669 settings.xdim3d = xdimgame; 670 settings.ydim3d = ydimgame; 671 settings.bpp3d = bppgame; 672 settings.forcesetup = forcesetup; 673 674 [startwin setupRunMode]; 675 676 do 677 { 678 NSEvent *event = [nsapp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES]; 679 [nsapp sendEvent:event]; 680 [nsapp updateWindows]; 681 } 682 while (retval == -1); 683 684 [startwin setupMessagesMode]; 685 [nsapp updateWindows]; 686 687 if (retval) { 688 fullscreen = settings.fullscreen; 689 xdim2d = settings.xdim2d; 690 ydim2d = settings.ydim2d; 691 xdimgame = settings.xdim3d; 692 ydimgame = settings.ydim3d; 693 bppgame = settings.bpp3d; 694 forcesetup = settings.forcesetup; 695 } 696 697 return retval; 698} 699