[FdF] MiniLibX mlx_key_hook
void mlx_key_hook(mlx_win_list_t *win_ptr, int (*funct_ptr)(), void *param)
{
[(id)(win_ptr->winid) setEvent:3 andFunc:funct_ptr andParam:param];
}
키를 입력받아 넣은 함수를 실행하는거
https://iangeli.com/2020/04/24/Complete-list-of-AppleScript-key-codes.html
Complete list of AppleScript key codes | 若然何如
Complete list of AppleScript key codes 2020 - 04 - 24 Posted by Christopher Kielty All of the key codes. All of them. Ever. Maybe. I tested this out on a MacBook Air and also a MacBook Pro. If I missed something, please let me know. Key code 49 in this exa
iangeli.com
키 코드에 대하여 잘 정리되있다
함수를 만들어줘서 그어떻게 실행할지 정하는건데
파라미터를 정해준다
왜 setEvent가 2개인데 잘되는지 모르겟네..
- (void) setEvent:(int)event andFunc:(func_t)func andParam:(void *)param
{
[win setEvent:event andFunc:func andParam:param];
}
- (void) setEvent:(int)event andFunc:(func_t)func andParam:(void *)param
{
event_funct[event] = func;
event_param[event] = param;
if (event == 6) // motion notify //음??? 6은없는데?
{
if (func == NULL)
[self setAcceptsMouseMovedEvents:NO];
else
[self setAcceptsMouseMovedEvents:YES];
}
}
이런 함수를 작동한다고 하면
#include <stdio.h> // printf()
#include <stdlib.h> // exit()
#include <mlx.h>
#define X_EVENT_KEY_PRESS 2 // mlx_hook 함수의 두 번째 인자인
#define X_EVENT_KEY_RELEASE 3 // x_event에 들어가는 값
#define KEY_W 13 // MacOS의 키보드 코드들이다.
#define KEY_A 0 //
#define KEY_S 1 // 위에서 부터 차례대로
#define KEY_D 2 //
#define KEY_ESC 53 // 'W' 'A' 'S' 'D' 'ESC'들의 키보드 코드이다.
typedef struct s_param // 키 값을 입력 받고 정해진 동작을 수행했는지
{ // 여부를 판단하기 위해 선언하였다.
int x; // x값
int y; // y값
int z; // y값
void *mlx_ptr;
void *win_ptr;
} t_param;
void param_init(t_param *param) // 구조체 param 초기화 함수
{
param->x = 0;
param->y = 0;
param->z = 0;
param->mlx_ptr = 0;
param->win_ptr = 0;
}
int key_press(int keycode, t_param *param) // 어떤 키가 눌렸는지 판단하고,
{ // 정의된 행동을 수행하는 함수
if (keycode == KEY_W) // W 키를 누르면 param.x값이 1 증가한다.
param->x++;
else if (keycode == KEY_S) // S 키를 누르면 param.x값이 1 감소한다.
param->x--;
else if (keycode == KEY_A) // A 키를 누르면 param.y값이 1 증가한다.
param->y++;
else if (keycode == KEY_D) // D 키를 누르면 param.y값이 1 감소한다.
param->y--;
else if (keycode == KEY_ESC) // ESC 키를 누르면 프로그램 종료
exit(0);
printf("(x, y): (%d, %d)\n", param->x, param->y); // param의 값 확인
return (0);
}
int main(void)
{
void *mlx_ptr;
t_param param;
mlx_ptr = mlx_init();
param_init(¶m);
param.mlx_ptr = mlx_ptr;
param.win_ptr = mlx_new_window(mlx_ptr, 300, 300, "Hello, World!");
printf("======\n");
mlx_key_hook(param.win_ptr, &key_press, ¶m);
printf("======\n");
mlx_pixel_put ( param.mlx_ptr, param.win_ptr,1 ,1, 0xFFFFFFFF);
printf("======\n");
mlx_loop(param.mlx_ptr);
int a = mlx_clear_window(param.mlx_ptr, param.win_ptr);
printf("%d",a);
return (0);
}
//음 이러면 되려나??
/ bonus /
key option에대한 자세한 내용
mlx_new_window.m 파일을 보면
- (void) setEvent:(int)event andFunc:(func_t)func andParam:(void *)param
{
event_funct[event] = func;
event_param[event] = param;
if (event == 6) // motion notify
{
if (func == NULL)
[self setAcceptsMouseMovedEvents:NO];
else
[self setAcceptsMouseMovedEvents:YES];
}
}
- (void) setKeyRepeat:(int)mode
{
keyrepeat = mode;
}
- (BOOL) acceptsFirstResponder
{
return (YES);
}
- (void) keyDown:(NSEvent *)theEvent
{
if (keyrepeat==0 && [theEvent isARepeat])
return ;
printf("Key Down: %d\n", [theEvent keyCode]);
if (event_funct[2] != NULL)
event_funct[2]([theEvent keyCode], event_param[2]);
// else [super keyDown: theEvent];
}
- (void) keyUp:(NSEvent *)theEvent
{
printf("Key Up: %d\n", [theEvent keyCode]);
if (event_funct[3] != NULL)
event_funct[3]([theEvent keyCode], event_param[3]);
// else [super keyUp: theEvent];
}
- (void) mouseDown:(NSEvent *)theEvent
{
NSPoint thepoint;
int button;
thepoint = [theEvent locationInWindow];
button = get_mouse_button([theEvent type]);
// printf("Mouse pressed bt %d pos: %f, %f\n", button, thepoint.x, thepoint.y);
if (event_funct[4] != NULL)
event_funct[4](button, (int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[4]);
}
- (void) rightMouseDown:(NSEvent *)theEvent
{
NSPoint thepoint;
int button;
thepoint = [theEvent locationInWindow];
button = get_mouse_button([theEvent type]);
// printf("Mouse pressed bt %d pos: %f, %f\n", button, thepoint.x, thepoint.y);
if (event_funct[4] != NULL)
event_funct[4](button, (int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[4]);
}
- (void) otherMouseDown:(NSEvent *)theEvent
{
NSPoint thepoint;
int button;
thepoint = [theEvent locationInWindow];
button = get_mouse_button([theEvent type]);
// printf("Mouse pressed bt %d pos: %f, %f\n", button, thepoint.x, thepoint.y);
if (event_funct[4] != NULL)
event_funct[4](button, (int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[4]);
}
- (void) mouseUp:(NSEvent *)theEvent
{
NSPoint thepoint;
int button;
thepoint = [theEvent locationInWindow];
button = get_mouse_button([theEvent type]);
// printf("Mouse release bt %d pos: %f, %f\n", button, thepoint.x, thepoint.y);
if (event_funct[5] != NULL)
event_funct[5](button, (int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[5]);
}
- (void) rightMouseUp:(NSEvent *)theEvent
{
NSPoint thepoint;
int button;
thepoint = [theEvent locationInWindow];
button = get_mouse_button([theEvent type]);
// printf("Mouse release bt %d pos: %f, %f\n", button, thepoint.x, thepoint.y);
if (event_funct[5] != NULL)
event_funct[5](button, (int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[5]);
}
- (void) otherMouseUp:(NSEvent *)theEvent
{
NSPoint thepoint;
int button;
thepoint = [theEvent locationInWindow];
button = get_mouse_button([theEvent type]);
// printf("Mouse release bt %d pos: %f, %f\n", button, thepoint.x, thepoint.y);
if (event_funct[5] != NULL)
event_funct[5](button, (int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[5]);
}
- (void) mouseMoved:(NSEvent *)theEvent
{
NSPoint thepoint;
thepoint = [theEvent locationInWindow];
// printf("Mouse moved pos: %f, %f\n", thepoint.x, thepoint.y);
if (event_funct[6] != NULL)
event_funct[6]((int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[6]);
}
- (void) mouseDragged:(NSEvent *)theEvent
{
NSPoint thepoint;
thepoint = [theEvent locationInWindow];
// printf("Mouse moved pos: %f, %f\n", thepoint.x, thepoint.y);
if (event_funct[6] != NULL)
event_funct[6]((int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[6]);
}
- (void) rightMouseDragged:(NSEvent *)theEvent
{
NSPoint thepoint;
thepoint = [theEvent locationInWindow];
// printf("Mouse moved pos: %f, %f\n", thepoint.x, thepoint.y);
if (event_funct[6] != NULL)
event_funct[6]((int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[6]);
}
- (void) otherMouseDragged:(NSEvent *)theEvent
{
NSPoint thepoint;
thepoint = [theEvent locationInWindow];
// printf("Mouse moved pos: %f, %f\n", thepoint.x, thepoint.y);
if (event_funct[6] != NULL)
event_funct[6]((int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[6]);
}
- (void) scrollWheel:(NSEvent *)theEvent
{
NSPoint thepoint;
int button;
float sens;
if (event_funct[4] == NULL)
return ;
button = 0;
thepoint = [theEvent locationInWindow];
sens = [theEvent deltaY];
if (sens > 0.2)
button = 4;
if (sens < -0.2)
button = 5;
sens = [theEvent deltaX];
if (sens > 0.2)
button = 6;
if (sens < -0.2)
button = 7;
if (button != 0)
event_funct[4](button, (int)(thepoint.x), size_y - 1 - (int)(thepoint.y), event_param[4]);
}
- (void) exposeNotification:(NSNotification *)note
{
// printf("Expose...\n");
if (event_funct[12] != NULL)
event_funct[12](event_param[12]);
// printf("Expose done.\n");
}
- (void) closeNotification:(NSNotification *)note
{
if (event_funct[17] != NULL)
event_funct[17](event_param[17]);
}
이부분들이 event_funct에 숫자를 알수 있게 된다
https://harm-smits.github.io/42docs/libs/minilibx/events.html
Events
Find code examples, optimization tricks, and much more.
harm-smits.github.io
여기와 다른 몇가지가 보인다
키를 누르는 것은
02 | - (void) keyDown:(NSEvent *)theEvent | KeyPress |
03 | - (void) keyUp:(NSEvent *)theEvent | KeyRelease |
04 | - (void) mouseDown:(NSEvent *)theEvent - (void) rightMouseDown:(NSEvent *)theEvent - (void) otherMouseDown:(NSEvent *)theEvent - (void) scrollWheel:(NSEvent *)theEvent |
ButtonPress |
05 | - (void) mouseUp:(NSEvent *)theEvent - (void) rightMouseUp:(NSEvent *)theEvent - (void) otherMouseUp:(NSEvent *)theEvent |
ButtonRelease |
06 | - (void) mouseMoved:(NSEvent *)theEvent - (void) mouseDragged:(NSEvent *)theEvent - (void) rightMouseDragged:(NSEvent *)theEvent - (void) otherMouseDragged:(NSEvent *)theEvent |
MotionNotify |
07 | 없음 | EnterNotify |
08 | 없음 | LeaveNotify |
09 | 없음 | FocusIn |
10 | 없음 | FocusOut |
11 | 없음 | KeymapNotify |
12 | - (void) exposeNotification:(NSNotification *)note | Expose |
13 | 없음 | GraphicsExpose |
14 | 없음 | NoExpose |
15 | 없음 | VisibilityNotify |
16 | 없음 | CreateNotify |
17 | - (void) closeNotification:(NSNotification *)note | DestroyNotify |
18 | 없음 | UnmapNotify |
19 | 없음 | MapNotify |
20 | 없음 | MapRequest |
21 | 없음 | ReparentNotify |
22 | 없음 | ConfigureNotify |
23 | 없음 | ConfigureRequest |
24 | 없음 | GravityNotify |
25 | 없음 | ResizeRequest |
이런식으로 함수들이 정의되어있는 것들이 있다
그리고 key입력을 키고 끄는 방법은
int mlx_do_key_autorepeatoff(mlx_ptr_t *mlx_ptr)
{
mlx_win_list_t *win;
win = mlx_ptr->win_list;
while (win)
{
[(id)(win->winid) setKeyRepeat:0];
win = win->next;
}
return (0);
}
int mlx_do_key_autorepeaton(mlx_ptr_t *mlx_ptr)
{
mlx_win_list_t *win;
win = mlx_ptr->win_list;
while (win)
{
[(id)(win->winid) setKeyRepeat:1];
win = win->next;
}
return (0);
}
@implementation MlxWin
- (id) initWithRect: (NSRect)rect andTitle: (NSString *)title pfaAttrs: (NSOpenGLPixelFormatAttribute *)attrs
{
NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
if ((self = [super initWithFrame:rect pixelFormat:pixFmt]) != nil)
{
NSUInteger windowStyle = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
win = [[NSWindowEvent alloc] initWithContentRect:rect
styleMask:windowStyle
backing:NSBackingStoreBuffered // NSBackingStoreNonretained
defer:NO];
// 많은 부분을 생략하엿음
// **** **** **** //
[win setKeyRepeat:1];
// 이부분에서 키입력을 켜줌
// **** **** **** //
}
}
이 부분도 궁금해서 찾아 보앗다

//////////// ================= mlx_new_window.m ================= /////////
옌 x_mask 안씀..
void mlx_hook(mlx_win_list_t *win_ptr, int x_event, int x_mask, int (*funct_ptr)(), void *param)
{
[(id)(win_ptr->winid) setEvent:x_event andFunc:funct_ptr andParam:param];
}
/////////// ================ swift type 쓰는부분 ================ //////////////
@_cdecl("mlx_hook")
public func mlx_hook_swift(_ winptr:UnsafeRawPointer, _ xevent:Int32, _ xmask:Int32, _ fctptr:UnsafeMutableRawPointer, _ paramptr:UnsafeMutableRawPointer) -> Int32
{
let win:MlxWin = _mlx_bridge(ptr:winptr)
win.addHook(index: Int(xevent), fct: fctptr, param: paramptr)
return (Int32(0));
}
안씀..
가끔 6이벤트일때만 알아서 1을넣어줌
override func mouseDown(with event: NSEvent) { mouse(with:event, index:4, type:0) }
override func rightMouseDown(with event: NSEvent) { mouse(with:event, index:4, type:0) }
override func otherMouseDown(with event: NSEvent) { mouse(with:event, index:4, type:0) }
override func mouseUp(with event: NSEvent) { mouse(with:event, index:5, type:0) }
override func rightMouseUp(with event: NSEvent) { mouse(with:event, index:5, type:0) }
override func otherMouseUp(with event: NSEvent) { mouse(with:event, index:5, type:0) }
override func mouseMoved(with event: NSEvent) { mouse(with:event, index:6, type:1) }
override func mouseDragged(with event: NSEvent) { mouse(with:event, index:6, type:1) }
override func rightMouseDragged(with event: NSEvent) { mouse(with:event, index:6, type:1) }
override func otherMouseDragged(with event: NSEvent) { mouse(with:event, index:6, type:1) }
func mouse(with event: NSEvent, index idx:Int, type t:Int)
{
var thepoint:NSPoint
var button:Int
thepoint = event.locationInWindow
button = get_mouse_button(with:event)
/// button = event.buttonNumber
/// print(" mouse down button \(event.buttonNumber) at location \(thepoint.x) x \(thepoint.y)")
if (eventFuncts[idx] != nil)
{
if (t == 0)
{ _ = unsafeBitCast(eventFuncts[idx],to:(@convention(c)(Int32, Int32, Int32, UnsafeRawPointer)->Int32).self)(Int32(button), Int32(thepoint.x), Int32(size_y-1-Int(thepoint.y)), eventParams[idx]) }
if (t == 1)
{ _ = unsafeBitCast(eventFuncts[idx],to:(@convention(c)(Int32, Int32, UnsafeRawPointer)->Int32).self)(Int32(thepoint.x), Int32(size_y-1-Int(thepoint.y)), eventParams[idx]) }
}
}
func get_mouse_button(with ev:NSEvent) -> Int
{
switch (ev.type) {
case NSEvent.EventType.leftMouseDown,
NSEvent.EventType.leftMouseUp,
NSEvent.EventType.leftMouseDragged:
return 1;
case NSEvent.EventType.rightMouseDown,
NSEvent.EventType.rightMouseUp,
NSEvent.EventType.rightMouseDragged:
return 2;
case NSEvent.EventType.otherMouseDown,
NSEvent.EventType.otherMouseUp,
NSEvent.EventType.otherMouseDragged:
return 3;
default:
return 0;
}
}
확인 해본 결과 0 일때만 마우스 get_mouse_button 에서 값을 가져온다
즉 우리가 쓰는 minimlx 와
오리지널 mlx 는 큰 차이점을 보인다
https://tronche.com/gui/x/xlib/
https://refspecs.linuxfoundation.org/LSB_1.3.0/gLSB/gLSB/libx11-ddefs.html