class Window {
NSWindow* window;
NSOpenGLView* view;
public:
Window() {
window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0.0, 0.0, 640.0, 480.0)
styleMask:NSTitledWindowMask | NSClosableWindowMask
bufferingType:NSBackingStoreBuffered
deferCreation:YES];
if (!window) throw std::runtime_error("could not create window.");
NSOpenGLPixelFormat format = [[NSOpenGLPixelFormat alloc] initWithAttributes:…];
view = [[NSOpenGLView alloc] initWithFrame:window.contentView.bounds pixelFormat:format];
[format release];
view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[window.contentView addSubview:view];
view.frame = window.contentView.bounds;
}
Window(Window const&) = delete;
~Window() {
[view release];
[window release];
}
void make_front_window() {
[window makeKeyAndOrderFront:nil];
}
void make_current() {
[view.openGLContext makeCurrentContext];
}
};
Y2xhc3MgV2luZG93IHsKICBOU1dpbmRvdyogd2luZG93OwogIE5TT3BlbkdMVmlldyogdmlldzsKcHVibGljOgogIFdpbmRvdygpIHsKICAgIHdpbmRvdyA9IFtbTlNXaW5kb3cgYWxsb2NdIGluaXRXaXRoQ29udGVudFJlY3Q6TlNNYWtlUmVjdCgwLjAsIDAuMCwgNjQwLjAsIDQ4MC4wKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlTWFzazpOU1RpdGxlZFdpbmRvd01hc2sgfCBOU0Nsb3NhYmxlV2luZG93TWFzawogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyaW5nVHlwZTpOU0JhY2tpbmdTdG9yZUJ1ZmZlcmVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZlckNyZWF0aW9uOllFU107CiAgICBpZiAoIXdpbmRvdykgdGhyb3cgc3RkOjpydW50aW1lX2Vycm9yKCJjb3VsZCBub3QgY3JlYXRlIHdpbmRvdy4iKTsKICAgIE5TT3BlbkdMUGl4ZWxGb3JtYXQgZm9ybWF0ID0gW1tOU09wZW5HTFBpeGVsRm9ybWF0IGFsbG9jXSBpbml0V2l0aEF0dHJpYnV0ZXM64oCmXTsKICAgIHZpZXcgPSBbW05TT3BlbkdMVmlldyBhbGxvY10gaW5pdFdpdGhGcmFtZTp3aW5kb3cuY29udGVudFZpZXcuYm91bmRzIHBpeGVsRm9ybWF0OmZvcm1hdF07CiAgICBbZm9ybWF0IHJlbGVhc2VdOwogICAgdmlldy5hdXRvcmVzaXppbmdNYXNrID0gTlNWaWV3V2lkdGhTaXphYmxlIHwgTlNWaWV3SGVpZ2h0U2l6YWJsZTsKICAgIFt3aW5kb3cuY29udGVudFZpZXcgYWRkU3Vidmlldzp2aWV3XTsKICAgIHZpZXcuZnJhbWUgPSB3aW5kb3cuY29udGVudFZpZXcuYm91bmRzOwogIH0KICAKICBXaW5kb3coV2luZG93IGNvbnN0JikgPSBkZWxldGU7CiAgCiAgfldpbmRvdygpIHsKICAgIFt2aWV3IHJlbGVhc2VdOwogICAgW3dpbmRvdyByZWxlYXNlXTsKICB9CgogIHZvaWQgbWFrZV9mcm9udF93aW5kb3coKSB7CiAgICBbd2luZG93IG1ha2VLZXlBbmRPcmRlckZyb250Om5pbF07CiAgfQoKICB2b2lkIG1ha2VfY3VycmVudCgpIHsKICAgIFt2aWV3Lm9wZW5HTENvbnRleHQgbWFrZUN1cnJlbnRDb250ZXh0XTsKICB9Cn07Cg==