You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
4.6 KiB

2 years ago
// mlx_init_loop.m
// By Ol
#import <Cocoa/Cocoa.h>
#import <OpenGL/gl3.h>
#import <AppKit/NSOpenGLView.h>
#include "mlx_int.h"
#include "mlx_new_window.h"
#include "font.c"
void do_loop_hook2(CFRunLoopTimerRef observer, void * info)
{
((mlx_ptr_t *)info)->loop_hook(((mlx_ptr_t *)info)->loop_hook_data);
}
void do_loop_flush(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void * info)
{
mlx_ptr_t *mlx_ptr;
mlx_win_list_t *win;
mlx_ptr = (mlx_ptr_t *)info;
win = mlx_ptr->win_list;
while (win)
{
if (win->nb_flush > 0 && win->pixmgt)
{
[(id)win->winid selectGLContext];
[(id)win->winid mlx_gl_draw];
glFlush();
win->nb_flush = 0;
}
win = win->next;
}
}
void *mlx_init()
{
mlx_ptr_t *new_mlx;
int bidon;
int i;
if ((new_mlx = malloc(sizeof(*new_mlx))) == NULL)
return ((void *)0);
new_mlx->win_list = NULL;
new_mlx->img_list = NULL;
new_mlx->loop_hook = NULL;
new_mlx->loop_hook_data = NULL;
new_mlx->main_loop_active = 0;
new_mlx->appid = [NSApplication sharedApplication];
// super magic trick to detach app from terminal, get menubar & key input events
for (NSRunningApplication * app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.finder"])
{
[app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
break;
}
usleep(100000);
ProcessSerialNumber psn = { 0, kCurrentProcess };
(void) TransformProcessType(&psn, kProcessTransformToForegroundApplication);
usleep(100000);
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
// load font
new_mlx->font = mlx_new_image(new_mlx, (FONT_WIDTH+2)*95, FONT_HEIGHT);
i = 0;
while (i < 4*(FONT_WIDTH+2)*95*FONT_HEIGHT)
{
new_mlx->font->buffer[i+0] = font_atlas.pixel_data[i+2];
new_mlx->font->buffer[i+1] = font_atlas.pixel_data[i+1];
new_mlx->font->buffer[i+2] = font_atlas.pixel_data[i+0];
((unsigned char *)new_mlx->font->buffer)[i+3] = 0xFF-font_atlas.pixel_data[i+3];
i += 4;
}
#ifdef STRINGPUTX11
new_mlx->font->vertexes[2] = FONT_WIDTH/1.4;
new_mlx->font->vertexes[4] = FONT_WIDTH/1.4;
new_mlx->font->vertexes[5] = (-FONT_HEIGHT-1)/1.4;
new_mlx->font->vertexes[7] = (-FONT_HEIGHT-1)/1.4;
#else
new_mlx->font->vertexes[2] = FONT_WIDTH;
new_mlx->font->vertexes[4] = FONT_WIDTH;
new_mlx->font->vertexes[5] = -FONT_HEIGHT-1;
new_mlx->font->vertexes[7] = -FONT_HEIGHT-1;
#endif
return ((void *)new_mlx);
}
void mlx_loop(mlx_ptr_t *mlx_ptr)
{
CFRunLoopObserverRef observer;
CFRunLoopObserverContext ocontext = {.version = 0, .info = mlx_ptr, .retain = NULL, .release = NULL, .copyDescription = NULL};
mlx_ptr->main_loop_active = 1;
observer = CFRunLoopObserverCreate(NULL, kCFRunLoopBeforeTimers, true, 0, do_loop_flush, &ocontext);
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
// [[[MlxLoopHookObj alloc] initWithPtr:mlx_ptr] performSelector:@selector(do_loop_hook) withObject:nil afterDelay:0.0];
[NSApp run];
}
void mlx_pixel_put(mlx_ptr_t *mlx_ptr, mlx_win_list_t *win_ptr, int x, int y, int color)
{
if (!win_ptr->pixmgt)
return ;
[(id)(win_ptr->winid) selectGLContext];
[(id)(win_ptr->winid) pixelPutColor:color X:x Y:y];
win_ptr->nb_flush ++;
}
void mlx_int_loop_once()
{
NSEvent *event;
NSDate *thedate;
thedate = [NSDate dateWithTimeIntervalSinceNow:0.1];
while (42)
{
event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:thedate
inMode:NSDefaultRunLoopMode
dequeue:YES];
if (event == nil)
{
[thedate release];
return ;
}
[NSApp sendEvent:event];
[NSApp updateWindows];
}
}
int mlx_do_sync(mlx_ptr_t *mlx_ptr)
{
mlx_win_list_t *win;
win = mlx_ptr->win_list;
while (win)
{
if (win->pixmgt)
{
[(id)(win->winid) selectGLContext];
[(id)(win->winid) mlx_gl_draw];
glFlush();
if (!mlx_ptr->main_loop_active)
mlx_int_loop_once();
}
win = win->next;
}
return (0);
}
int mlx_loop_hook(mlx_ptr_t *mlx_ptr, void (*fct)(void *), void *param)
{
CFRunLoopTimerContext tcontext = {0, mlx_ptr, NULL, NULL, NULL};
CFRunLoopTimerRef timer;
if (mlx_ptr->loop_hook != NULL)
{
CFRunLoopTimerInvalidate(mlx_ptr->loop_timer);
[(id)(mlx_ptr->loop_timer) release];
}
mlx_ptr->loop_hook = fct;
mlx_ptr->loop_hook_data = param;
if (fct)
{
timer = CFRunLoopTimerCreate(kCFAllocatorDefault, 0.0, 0.0001, 0, 0, &do_loop_hook2, &tcontext);
mlx_ptr->loop_timer = timer;
CFRunLoopAddTimer(CFRunLoopGetMain(), timer, kCFRunLoopCommonModes);
}
return (0);
}