카테고리 없음

[FdF] MiniLibX mlx_key_hook

Or71nH 2022. 6. 20. 19:38

 

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(&param);
	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, &param);
	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