Search

"mlx.h"

Created
2021/04/09
tag
C
cub3d
miniRT
miniLibX
mlx.h

Subjects

โ€ข
์ž‘์„ฑ๋œ ๊ธ€์€ 42์˜ cub3d, miniRT์™€ ๊ฐ™์€ Graphics ๊ณผ์ œ์—์„œ ์‚ฌ์šฉ๋˜๋Š” "mlx.h"๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃฌ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ง€์›ํ•˜๋Š” ํ•จ์ˆ˜๋“ค๊ณผ ๊ทธ ํŠน์„ฑ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผ ๊ฒƒ์ด๊ณ , ๋Œ€๋ถ€๋ถ„์˜ ๋‚ด์šฉ์€ ๋งค๋‰ด์–ผ ํŒŒ์ผ์—์„œ ๊ฐ€์ ธ์™”๊ธฐ ๋•Œ๋ฌธ์— ๋งค๋‰ด์–ผ ํŒŒ์ผ์„ ์ฝ๋Š” ๊ฒƒ์ด ํŽธํ•˜๋‹ค๋ฉด ์ด๋ฅผ ๋” ๊ถŒ์žฅํ•œ๋‹ค. ๊ฐ ํ•จ์ˆ˜์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณธ ๋’ค์—๋Š” ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜๋“ค์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฐ„๋‹จํžˆ ์†Œ๊ฐœํ•  ์˜ˆ์ •์ด๋‹ค.

1. mlx

1) ๊ฐœ๋…

"mlx.h"๋Š” MiniLibX๋ผ๊ณ  ํ•˜์—ฌ, Unix ๊ณ„์—ด์˜ X-Window(X11)์— ๋Œ€ํ•œ ์ง€์‹๊ณผ Mac OS X์˜ AppKit์˜ ์ง€์‹์ด ์—†์–ด๋„ ์‰ฝ๊ฒŒ ๊ทธ๋ž˜ํ”ฝ ๊ด€๋ จ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก 42 ํ•™์ƒ๋“ค์—๊ฒŒ ์ œ๊ณต๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. "mlx.h"๋ฅผ include ํ•จ์œผ๋กœ์จ ๊ฐ„๋‹จํ•œ Window ์ƒ์„ฑ, ๊ทธ๋ฆฌ๊ธฐ ๋„๊ตฌ, Image ๋ฐ Event์— ๋Œ€ํ•œ ๊ด€๋ฆฌ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. "mlx.h"์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ๋“ค์€ ๋‚ด๋ถ€์ ์œผ๋กœ Mac OS X์˜ OpenGL๊ณผ AppKit์„ ์ด์šฉํ•œ๋‹ค. ๋”ฐ๋ผ์„œ "mlx.h"๋ฅผ ์ด์šฉํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์„ ์ƒ์„ฑํ•  ๋•, OpenGL๊ณผ AppKit์„ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ์จ ์ด์šฉํ•˜๊ฒ ๋‹ค๊ณ  ๋ช…์‹œํ•˜์—ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ Link ํ•ด์•ผํ•œ๋‹ค.
X-Window (X11) X-Window๋Š” ํ”ํžˆ X11์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•œ๋‹ค. X-Window๋Š” Unix ๊ณ„์—ด์˜ ์šด์˜์ฒด์ œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” Window ์‹œ์Šคํ…œ ๋ฐ Window์— ๋Œ€ํ•œ GUI ํ™˜๊ฒฝ์ด๋‹ค. X-Window๋Š” ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— Window๋ฅผ ํ‘œ์‹œํ•˜๋ฉฐ, ๋งˆ์šฐ์Šค ๋ฐ ํ‚ค๋ณด๋“œ์™€ ๊ฐ™์€ ์ž…๋ ฅ ์žฅ์น˜์™€ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•˜๋Š” ๋“ฑ GUI ํ™˜๊ฒฝ ๊ตฌํ˜„์„ ์œ„ํ•œ ๊ธฐ๋ณธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. X-Window๋Š” Microsoft์˜ Windows์—์„œ์˜ GUI ์‹œ์Šคํ…œ๊ณผ๋Š” ๋‹ฌ๋ฆฌ ๋„คํŠธ์›Œํฌ ํ”„๋กœํ† ์ฝœ์— ๊ธฐ๋ฐ˜ํ•œ GUI ์‹œ์Šคํ…œ์ด๋‹ค. Client-Server Model์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Client์™€ Server๊ฐ„์˜ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์ด ์š”๊ตฌ๋œ๋‹ค. ์„œ๋กœ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์ด ๋˜์—ˆ๋‹ค๋ฉด, Client์—๊ฒŒ ์š”์ฒญ์„ ๋ฐ›์•˜์„ ๋•Œ Server์—์„œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์‹์œผ๋กœ GUI๋ฅผ ์กฐ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋…๋ฆฝ์ ์ธ ์„ฑ๊ฒฉ์„ ๊ฐ–๋Š”๋‹ค. ์ด๋Š” ๊ณง ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ชจ์Šต์— ๊ด€์—ฌํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ X-Window๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๋“ค์˜ ํ™˜๊ฒฝ์ด ๋งค์šฐ ๋‹ค์–‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•”์‹œํ•œ๋‹ค. ์œ„์˜ Client-Server Model์— ๋Œ€ํ•ด์„œ ๊ฐ„๋‹จํ•œ ์ƒํ™ฉ์„ ๋“ค์–ด๋ณด๋ฉด, ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ๋ฅผ ์—ฌ๊ธฐ๋กœ ์›€์ง์—ฌ๋ผ ๋ผ๊ณ  Client๊ฐ€ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด X-Window์˜ Server๊ฐ€ ์š”์ฒญ์„ ๋ฐ›์•„ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ์ถœ๋ ฅํ•ด์ฃผ๋Š” ์‹์ด ๋˜๊ฒ ๋‹ค. ์—ฌ๊ธฐ์„œ์˜ Server๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ Client์˜ ๋จธ์‹ ์—์„œ ๋™์ž‘ํ•˜๊ฒŒ ๋˜๋ฉฐ, ๋จธ์‹ ์˜ System Boot File์— ์˜ํ•ด์„œ ๊ตฌ๋™๋œ๋‹ค.
AppKit AppKit์€ Application Kit์˜ ์ค„์ž„๋ง๋กœ์จ GUI๋ฅผ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค. NeXTSTEP์— ์˜ํ•ด์„œ ๋งŒ๋“ค์–ด์กŒ์œผ๋ฉฐ, NeXTSTEP์€ 1996๋…„์— Apple์— ์ธ์ˆ˜๋˜์—ˆ๋‹ค. AppKit์€ Foundation์ด๋ผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์™€ ํ•จ๊ป˜ ์ƒ์†๋˜์–ด Cocoa๋ผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ์ด์šฉ๋˜์—ˆ์œผ๋ฉฐ, AppKit์˜ ์ฃผ์š” ๊ธฐ๋Šฅ์ด Cocoa์˜ ์ฃผ์š” ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. (Apple์—์„œ ๋งŒ๋“  Cocoa๋Š” ๊ฐ์ฒด์ง€ํ–ฅ์„ ๋”ฐ๋ฅด๋Š” API๋กœ, Mac OS X ์ƒ์˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“œ๋Š”๋ฐ ์ฃผ๋กœ ์ด์šฉ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.) AppKit์€ GUI๋ฅผ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ธ ๋งŒํผ, ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ Window, Button, Scroll Bar, Font, Color์™€ ๊ฐ™์€ ๋ชจ๋“  ๊ทธ๋ž˜ํ”ฝ์  ์š”์†Œ๋“ค์„ ๋ฌธ์„œ ๊ด€๋ฆฌ์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ์™€ ํ•จ๊ป˜ ํด๋ž˜์Šค๋กœ ์ œ๊ณตํ•œ๋‹ค. AppKit์€ ๊ธฐ๋ณธ์ ์œผ๋กœ OpenGL์„ ์ง€์›ํ•œ๋‹ค. ๋†€๋ž๊ฒŒ๋„ AppKit์—์„œ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ๋“ค ์ค‘์—๋Š” Grammar Correction, Dragging, Copy, Cut, Paste ๋“ฑ์˜ ๊ธฐ๋Šฅ๋“ค๋„ ์žˆ๋‹ค. ์ด์™ธ์—๋„ ๋งŽ์€ ๊ธฐ๋Šฅ๋“ค์„ ์‰ฝ๊ณ  ํŽธํ•˜๊ฒŒ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Apple์˜ ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ตฌํ˜„ํ•ด๋‘์—ˆ๋‹ค. AppKit์„ ์ด์šฉํ•˜์—ฌ ๋งŒ๋“  Software๋Š” ํ•˜๋‚˜์˜ Screen์—์„œ ๋‹ค๋ฅธ Software ํ˜น์€ Event System๊ณผ ํ•จ๊ป˜ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ๋„๋ก Mac OS X์˜ Window Server์™€ ์ง์ ‘์ ์œผ๋กœ ์ƒํ˜ธ์ž‘์šฉํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, Software ๋‚ด๋ถ€์—์„œ Render ๋˜์–ด์•ผํ•˜๋Š” ๊ฒƒ๋“ค์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก Mac OS X์— ์—ฐ๊ฒฐ๋œ GPU์™€ ์ง์ ‘์ ์œผ๋กœ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

2)mlx_init

ํ•จ์ˆ˜ ์›ํ˜•

void *mlx_init();
C

ํ•จ์ˆ˜ ์ธ์ž

์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์™€์˜ ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ ์‹๋ณ„์ž๋ฅผ void * ํƒ€์ž…์˜ ํฌ์ธํ„ฐ๋กœ ๋ฐ˜ํ™˜ (๋ฐ˜ํ™˜๋œ ํฌ์ธํ„ฐ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์˜ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์™€์˜ ์—ฐ๊ฒฐ์— ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.)

์ฐธ๊ณ 

"mlx.h"๋ฅผ ํ†ตํ•ด ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๋“ค์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  ํ˜„์žฌ Software์™€ ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜๋ฅผ ์—ฐ๊ฒฐํ•ด์ค˜์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š๊ณ ์„  ์ œ๊ณต๋˜๋Š” ํ•จ์ˆ˜๋“ค์„ ์ด์šฉํ•  ์ˆ˜ ์—†๋‹ค. mlx_init์ด Software์™€ ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•ด์ฃผ๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค. ์‹๋ณ„์ž๋ฅผ ์ง€์นญํ•˜๋Š” mlx_init์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ mlx_ptr๋กœ ์ด์šฉ๋˜๋ฉฐ, Screen Connection Identifier๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค.

2. mlx_new_window

mlx_new_window ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์€ Window์— ๋Œ€ํ•œ ์ œ์–ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

1) mlx_new_window

ํ•จ์ˆ˜ ์›ํ˜•

void *mlx_new_window(void *mlx_ptr, int size_x, int size_y, char *title);
C

ํ•จ์ˆ˜ ์ธ์ž

size_x๋Š” Window์˜ Width๋ฅผ, size_y๋Š” Window์˜ Height๋ฅผ ์˜๋ฏธํ•œ๋‹ค. title๋กœ ์ฃผ์–ด์ง€๋Š” ๋ฌธ์ž์—ด์€ Window์˜ ์ œ๋ชฉ์œผ๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค. mlx_ptr์€ mlx_init ํ•จ์ˆ˜๋กœ๋ถ€ํ„ฐ ๋ฐ˜ํ™˜ ๋ฐ›์€ Screen Connection Identifier์ด๋ฉฐ, mlx_ptr๋กœ ์ง€์นญ๋˜๋Š” ์—ฐ๊ฒฐ์— ํ•ด๋‹นํ•˜๋Š” Window๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ด์šฉ๋œ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

Window์— ๋Œ€ํ•œ ์‹๋ณ„์ž๋ฅผ void * ํƒ€์ž…์˜ ํฌ์ธํ„ฐ๋กœ ๋ฐ˜ํ™˜ (๋ฐ˜ํ™˜๋œ ํฌ์ธํ„ฐ๋Š” mlx_init์˜ ๋ฐ˜ํ™˜ ๊ฐ’๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์˜ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. Window ์ƒ์„ฑ์— ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.)

์ฐธ๊ณ 

MiniLibX๋Š” ํ•˜๋‚˜์˜ Window๋งŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ž„์˜์˜ ์—ฌ๋Ÿฌ Window๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. mlx_new_window์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ win_ptr๋กœ ์ด์šฉ๋˜๋ฉฐ, Window Identifier๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค.

2) mlx_clear_window

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_clear_window(void *mlx_ptr, void *win_ptr);
C

ํ•จ์ˆ˜ ์ธ์ž

Screen Connection Identifier๋ฅผ ์˜๋ฏธํ•˜๋Š” mlx_ptr, Window Identifier๋ฅผ ์˜๋ฏธํ•˜๋Š” win_ptr์„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, ๋งค๋‰ด์–ผ์— ๋”ฐ๋ฅด๋ฉด ์•„๋ฌด๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค. Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์•„๋ฌด๋Ÿฐ ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_clear_window") public func mlx_clear_window_swift(_ mlxptr:UnsafeRawPointer, _ winptr:UnsafeRawPointer) { let win:MlxWin = _mlx_bridge(ptr:winptr) win.clearWin() }
Swift

์ฐธ๊ณ 

mlx_clear_window ํ•จ์ˆ˜๋Š” Window๋ฅผ ๊ฒ€์€์ƒ‰์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

3) mlx_destroy_window

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_destory_window(void *mlx_ptr, void *win_ptr);
C

ํ•จ์ˆ˜ ์ธ์ž

Screen Connection Identifier๋ฅผ ์˜๋ฏธํ•˜๋Š” mlx_ptr, Window Identifier๋ฅผ ์˜๋ฏธํ•˜๋Š” win_ptr์„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, ๋งค๋‰ด์–ผ์— ๋”ฐ๋ฅด๋ฉด ์•„๋ฌด๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค. Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋‹จ์ˆœํžˆ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_destroy_window") public func mlx_destroy_window_swift(_ mlxptr:UnsafeRawPointer, _ winptr:UnsafeRawPointer) -> Int32 { let mlx:MlxMain = _mlx_bridge(ptr:mlxptr) /// bridge_transfer to get the retain, at end of this func should release the MlxWin object, because no ref anymore. let win:MlxWin = _mlx_bridge_transfer(ptr:winptr) win.delNotifs() win.flushImages() win.waitForGPU() win.destroyWinE() mlx.winList.removeAll(where: { $0 === win} ) return Int32(0) }
Swift

์ฐธ๊ณ 

mlx_destroy_window ํ•จ์ˆ˜๋Š” Window๋ฅผ ์†Œ๋ฉธ์‹œํ‚ค๋Š” ํ•จ์ˆ˜์ด๋‹ค.

3. mlx_new_image

mlx_new_image ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์€ Image๋ฅผ ์กฐ์ž‘ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
Image File Format Image File Format์€ Image๋ฅผ ๋””์ง€ํ„ธ๋กœ ๊ตฌ์„ฑํ•˜๊ณ  ์ €์žฅํ•˜๋Š” ํ‘œ์ค€ํ™”๋œ ๋ฐฉ๋ฒ•์„ ์˜๋ฏธํ•˜๋Š”๋ฐ, ์ด ํ˜•์‹์— ๋”ฐ๋ผ์„œ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์••์ถ•๋˜์ง€ ์•Š์€ ํ˜•์‹, ์••์ถ•๋œ ํ˜•์‹, ๋ฒกํ„ฐ ํ˜•์‹ ๋“ฑ์œผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ํ˜•์‹์— ๋งž๊ฒŒ ๊ฐ–์ถฐ์ง„ Image ํŒŒ์ผ์€ ์ปดํ“จํ„ฐ ๋””์Šคํ”Œ๋ ˆ์ด ํ˜น์€ ํ”„๋ฆฐํ„ฐ์—์„œ ํŒŒ์ผ ๋‚ด์˜ ๋ฐ์ดํ„ฐ๋ฅผ Rasteringํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. Rastering์„ ํ•˜๋Š” ๊ฒƒ์„ Rasterization์ด๋ผ ํ•˜๋Š”๋ฐ, ์ด๋Š” Image์˜ ๋ฐ์ดํ„ฐ๋ฅผ Pixel Grid๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ๊ฐ Pixel์€ ์ƒ‰์ƒ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ์—ฌ๋Ÿฌ ๋น„ํŠธ๋“ค์„ ๊ฐ–๊ณ  ์žˆ๋Š”๋ฐ, ํŠน์ • ์žฅ์น˜์—์„œ Rasterization์„ ํ•˜๊ฒŒ ๋˜๋ฉด ์žฅ์น˜ ๋‚ด์˜ bits_per_pixel์„ ์ฝ์–ด Pixel์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค.
PNG (Portable Network Graphics) PNG๋Š” ๋น„์†์‹ค Image File Format ์ค‘ ํ•˜๋‚˜์ด๋‹ค. GIF๋ผ๋Š” Image File Format์€ LZW๋ผ๋Š” ๋ฐ์ดํ„ฐ ์••์ถ• ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ด์šฉํ•˜๋Š”๋ฐ, ์ด๋ฅผ ์†Œํ”„ํŠธ์›จ์–ด ํŠนํ—ˆ๋กœ ๋“ฑ๋กํ•˜๋ฉด์„œ ์ƒˆ๋กญ๊ฒŒ ๊ณ ์•ˆ๋œ ๊ฒƒ์ด PNG์ด๋‹ค. ์ด ๋•Œ PNG๋Š” GIF๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ์—ฌ๋Ÿฌ ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ๋‹ค. ์ธํ„ฐ๋„ท ์ƒ์˜ ์ž๋ฃŒ๋“ค์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ๊ฐœ๋ฐœ๋˜์–ด C (Cyan), M (Magenta), Y (Yellow), K (Black)๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. GIF PNG ์••์ถ•๋ฅ ์ด ์ƒ๋Œ€์ ์œผ๋กœ ๋‚ฎ์Œ ์••์ถ•๋ฅ ์ด ์ƒ๋Œ€์ ์œผ๋กœ ๋†’์Œ ๋‹จ์ผ ํˆฌ๋ช…๋„ ์˜ต์…˜ ๋‹ค์–‘ํ•œ ํˆฌ๋ช…๋„ ์˜ต์…˜ 256๊ฐ€์ง€ ์ƒ‰์„ ์ง€์› Truecolor๋ผ๋Š”16777216๊ฐ€์ง€ ์ƒ‰์„ ์ง€์› ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ œ๊ณตํ•จ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Œ JPEG PNG ํŒŒ์ผ์˜ ํฌ๊ธฐ๊ฐ€ ์ƒ๋Œ€์ ์œผ๋กœ ์ž‘์Œ ํŒŒ์ผ์˜ ํฌ๊ธฐ๊ฐ€ ์ƒ๋Œ€์ ์œผ๋กœ ํผ ์†์‹ค Image File Format ๋น„์†์‹ค Image File Format ๋ญ‰๊ฐœ์ง์ด ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Œ ๋ญ‰๊ฐœ์ง์ด ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Œ
XPM (X Pix Map) X11 ์ƒ์—์„œ ์‚ฌ์šฉ๋˜๋Š” Image File Format์„ ์˜๋ฏธํ•œ๋‹ค. XPM ํŒŒ์ผ์€ .XPM์˜ ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง€๋ฉฐ, .XBM ํŒŒ์ผ์„ ํ™•์žฅํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ๋‹ค. XPM ํŒŒ์ผ ๋‚ด๋ถ€์˜ ๋ฐ์ดํ„ฐ๋Š” C ์–ธ์–ด์˜ ์ •์  ๋ฌธ์ž ๋ฐฐ์—ด๋กœ ๋˜์–ด ์žˆ๊ฑฐ๋‚˜ Plain Text๋กœ ๋˜์–ด ์žˆ๋‹ค. XPM์€ XPM, XPM2, XPM3๋กœ ๋‚˜๋‰˜๋Š”๋ฐ, ์ฃผ์–ด์ง„ 3๊ฐœ์˜ XPM ์ค‘ XPM2๋Š” C ์–ธ์–ด ํ˜•์‹์„ ์ด์šฉํ•˜์ง€ ์•Š๊ณ  Plain Text๋กœ ์ด์šฉ๋œ๋‹ค. ๋‚ด๋ถ€์˜ ๋ฐ์ดํ„ฐ๊ฐ€ C ์–ธ์–ด์˜ ์ •์  ๋ฌธ์ž ๋ฐฐ์—ด๋กœ ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” .XPM๊ณผ .XBM ๋ชจ๋‘ C ์–ธ์–ด๋กœ ์ด๋ค„์ง„ ์ฝ”๋“œ์— ํฌํ•จ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ์ง์ ‘ ์ปดํŒŒ์ผ์ด ๋˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. XPM์˜ ํ˜•์‹์€ ์•„๋ž˜์™€ ๊ฐ™์ด 6๊ฐœ์˜ ์˜์—ญ์œผ๋กœ ๋ถ„๋ฅ˜๋œ๋‹ค.
/* XPM Format on C */ static char* <variable_name>[] = { <Values> <Colors> <Pixels> <Extensions> }; /* XPM */ static char * XFACE[] = { /* <Values> */ /* <width/columns> <height/rows> <colors> <chars per pixel>*/ "48 4 2 1", /* <Colors> */ /* <c/color> <m/monochrome> <g/grayscale> <s/symbolic> */ "a c #ffffff", // none indicates transparency "b c #000000", // none indicates transparency /* <Pixels> */ "abaabaababaaabaabababaabaabaababaabaaababaabaaab", "abaabaababaaabaabababaabaabaababaabaaababaabaaab", "abaabaababaaabaabababaabaabaababaabaaababaabaaab", "abaabaababaaabaabababaabaabaababaabaaababaabaaab" };
C

1) mlx_new_image

ํ•จ์ˆ˜ ์›ํ˜•

void *mlx_new_image(void *mlx_ptr, int width, int height);
C

ํ•จ์ˆ˜ ์ธ์ž

Image์˜ ๊ฐ Width์™€ Height์— ํ•ด๋‹นํ•˜๋Š” width์™€ height๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ์ด๋ ‡๊ฒŒ ์ƒ์„ฑ๋œ Image๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋Š Screen Connection์— ํ•ด๋‹นํ•˜๋Š” Image์ธ์ง€ ์•Œ๊ธฐ ์œ„ํ•ด์„œ, ์ƒ์„ฑ๋œ Image๋ฅผ Screen Connection์— ๊ธฐ๋กํ•ด๋‘ฌ์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ Screen Connection Identifier์ธ mlx_ptr์„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. (Swift๋กœ Forwarding๋œ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด mlx_ptr์„ ์ด์šฉํ•˜์—ฌ Image๋ฅผ ๊ธฐ๋กํ•ด๋‘๋Š” ๊ฒƒ์„ ์•Œ์ˆ˜ ์žˆ๋‹ค.)
@_cdecl("mlx_new_image") public func mlx_new_image(_ mlxptr:UnsafeRawPointer, _ width:Int32, _ height:Int32) -> UnsafeRawPointer { let mlx:MlxMain = _mlx_bridge(ptr:mlxptr) let img = MlxImg(d:mlx.device, w:Int(width), h:Int(height)) mlx.addImgToList(img) /// print(CFGetRetainCount(img)) return (_mlx_bridge_retained(obj:img)) }
C

๋ฐ˜ํ™˜ ๊ฐ’

Image ์— ๋Œ€ํ•œ ์‹๋ณ„์ž๋ฅผ void * ํƒ€์ž…์˜ ํฌ์ธํ„ฐ๋กœ ๋ฐ˜ํ™˜ (๋ฐ˜ํ™˜๋œ ํฌ์ธํ„ฐ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์˜ Image ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. Image ์ƒ์„ฑ์— ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.)

์ฐธ๊ณ 

mlx_new_image์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ img_ptr๋กœ ์ด์šฉ๋˜๋ฉฐ, Image Identifier๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค. ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋งž๋Š” ์ •๋ณด๋“ค์„ ์ด์šฉํ•˜์—ฌ Image๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

2) mlx_get_data_addr

ํ•จ์ˆ˜ ์›ํ˜•

char *mlx_get_data_addr(void *img_ptr, int *bits_per_pixel, int *size_line, int *endian);
C

ํ•จ์ˆ˜ ์ธ์ž

Image Identifier์ธ img_ptr์„ ์ด์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์กด์žฌํ•˜๋Š” Image์— ๋Œ€ํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค. ์ด์–ด์ง„ 3๊ฐœ์˜ ์ธ์ž bits_per_pixel, size_line, endian์€ ํฌ์ธํ„ฐ๋กœ ๋„˜๊ฒจ ๋ฐ›์•˜๊ธฐ ๋•Œ๋ฌธ์—, ์—ญ์ฐธ์กฐ ํ•œ ํ›„ ๊ทธ ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋ฉด mlx_get_data_addr์„ ํ˜ธ์ถœํ•œ ๊ณณ์—์„œ๋„ ์ด ์ •๋ณด๋ฅผ ๊ทธ๋Œ€๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. bits_per_pixel์—๋Š” ํ•˜๋‚˜์˜ Pixel์— ์ƒ‰์ƒ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ๋ช‡ ๋น„ํŠธ๊ฐ€ ํ•„์š”ํ•œ์ง€ ์ฑ„์›Œ์ง„๋‹ค. (์ด๋ฅผ Depth of the Image๋ผ๊ณ ๋„ ๋ถ€๋ฅธ๋‹ค.) size_line์—๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ƒ์—์„œ Image์˜ ํ•œ ํ–‰์„ ํ‘œํ˜„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ ๋ฐ”์ดํŠธ ๊ฐ’์ด ์ฑ„์›Œ์ง„๋‹ค. (์ด ๊ฐ’์€ Offset์œผ๋กœ Image์˜ ๋‹ค๋ฅธ ํ–‰์„ ์ ‘๊ทผํ•  ๋•Œ ๊ณ„์‚ฐ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.) endian์€ Image ์ƒ์˜ Pixel์— ์ƒ‰์ƒ ๊ฐ’์ด Little Endian์œผ๋กœ ์ €์žฅ๋˜์–ด ์žˆ๋Š”์ง€ Big Endian์œผ๋กœ ์ €์žฅ๋˜์–ด ์žˆ๋Š”์ง€ ์•Œ๋ ค์ค€๋‹ค. (Little Endian์€ 0, Big Endian์€ 1๋กœ ๋งค๊ฒจ์ง„๋‹ค.)
Endian (Endianness) ๋ฉ”๋ชจ๋ฆฌ์ฒ˜๋Ÿผ 1์ฐจ์› ๊ณต๊ฐ„์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ์š”์†Œ๋“ค์„ ์—ฐ์†์ ์œผ๋กœ ๋ฐฐ์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ Endian์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ด ๋•Œ ๋ฐ”์ดํŠธ ๋‹จ์œ„๋กœ ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์„ Byte Order๋ผ๊ณ  ํ•œ๋‹ค. Byte Order๋กœ ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์š”์†Œ๋“ค์„ ๋‘๋ ค๊ณ  ํ•  ๋•Œ, ํฐ ๋‹จ์œ„๊ฐ€ ๋จผ์ € ํ‘œํ˜„๋˜๋Š” ๊ฒƒ์ด Big Endian์ด๊ณ  ์ž‘์€ ๋‹จ์œ„๊ฐ€ ๋จผ์ € ํ‘œํ˜„๋˜๋Š” ๊ฒƒ์ด Little Endian์ด ๋œ๋‹ค. ๋‘˜ ๋‹ค ์ง€์›์„ ํ•˜๊ฑฐ๋‚˜ ๋‘˜ ๋‹ค ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋Š” Middle Endian์ด๋ผ ๋ถ€๋ฅธ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ๋žŒ๋“ค์ด ์ˆซ์ž๋ฅผ ํ‘œ๊ธฐํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด Big Endian์ด๋‹ค. Byte Order์— ๋”ฐ๋ฅธ Big Endian๊ณผ Little Endian์˜ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด์ž. Big Endian Little Endian 0x1234 โ†’ 12 34 34 12 0x12345678 โ†’ 12 34 56 78 78 56 34 12

๋ฐ˜ํ™˜ ๊ฐ’

๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์žˆ๋Š” Image์˜ ์ฃผ์†Œ๋ฅผ ๋ฐ˜ํ™˜ (mlx_new_image๊ฐ€ Image Identifier๋ฅผ ๋ฐ˜ํ™˜ํ–ˆ๋˜ ๊ฒƒ๊ณผ ๋‹ค๋ฅธ ๊ฒƒ์ด๋‹ค.)

์ฐธ๊ณ 

mlx_get_data_addr ํ•จ์ˆ˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์กด์žฌํ•˜๋„๋ก ์ƒ์„ฑ๋œ Image์˜ bits_per_pixel, size_line, endian๊ณผ ๊ฐ™์€ ์—ฌ๋Ÿฌ ์ •๋ณด๋“ค์„ ๊ฐ–๋‹ค์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค. ๋„˜๊ฒจ ๋ฐ›์€ ์ •๋ณด๋“ค์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ Image๋ฅผ ์กฐ์ž‘ํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด bits_per_pixel์˜ ๊ฐ’์ด 8์ด๋ผ๊ณ  ํ•œ๋‹ค๋ฉด, mlx_get_data_addr๋กœ ๋ฐ˜ํ™˜ ๋ฐ›์€ Image์˜ ์ฃผ์†Œ ๊ฐ’์—์„œ 8 ๋น„ํŠธ๋งŒํผ์ด Image์˜ ์ฒซ ํ–‰์˜ ์ฒซ Pixel์˜ ์ƒ‰์ƒ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’์ด ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๊ทธ ๋‹ค์Œ 8 ๋น„ํŠธ๋Š” Image์˜ ์ฒซ ํ–‰์˜ ๋‘ ๋ฒˆ์งธ Pixel์˜ ์ƒ‰์ƒ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’์œผ๋กœ ์ด์–ด์ง„๋‹ค. ๋ฐ˜ํ™˜๋œ Image ์ฃผ์†Œ ๊ฐ’์— size_line๋งŒํผ์„ ๋”ํ•˜๊ฒŒ ๋˜๋ฉด Image์˜ ๋‘ ๋ฒˆ์งธ ํ–‰์˜ ์‹œ์ž‘ ์ง€์ ์ด ๋œ๋‹ค. ๋”ฐ๋ผ์„œ bits_per_pixel๊ณผ size_line์„ ์ด์šฉํ•˜๋ฉด Image์— ์กด์žฌํ•˜๋Š” ์–ด๋–ค Pixel์—๋„ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค.

3) mlx_put_image_to_window

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_put_image_to_window(void *mlx_ptr, void *win_ptr, void *img_ptr, int x, int y);
C

ํ•จ์ˆ˜ ์ธ์ž

Screen Connection์— ํ•ด๋‹นํ•˜๋Š” Window๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด mlx_ptr๊ณผ win_ptr์ด ์‚ฌ์šฉ๋œ๋‹ค. mlx_ptr๊ณผ Image Identifier์ธ img_ptr์„ ์ด์šฉํ•˜์—ฌ Screen Connection์— ์œ ์ง€ ์ค‘์ธ Image๋ฅผ ์ฐพ์•„๋‚ธ๋‹ค. Window์™€ Image๋ฅผ ์ฐพ์•„๋ƒˆ์œผ๋ฉด, Image๋ฅผ Window์˜ (x,y)(x, y) ์ขŒํ‘œ์— ์œ„์น˜์‹œํ‚ค๋ฉด์„œ ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋‹จ์ˆœํžˆ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_put_image_to_window") public func mlx_put_image_to_window_swift(_ mlxptr:UnsafeRawPointer, _ winptr:UnsafeRawPointer, _ imgptr:UnsafeRawPointer, _ x:Int32, _ y:Int32) -> Int32 { let win:MlxWin = _mlx_bridge(ptr:winptr) let img:MlxImg = _mlx_bridge(ptr:imgptr) win.putImage(image:img, x:x, y:y) return Int32(0) }
Swift

์ฐธ๊ณ 

mlx_put_image_to_window ํ•จ์ˆ˜๋Š” ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋‚˜ํƒ€๋‚œ Window์— Image๋ฅผ ์ž…ํžˆ๋Š” ํ•จ์ˆ˜์ด๋‹ค.

4) mlx_get_color_value

ํ•จ์ˆ˜ ์›ํ˜•

unsigned int mlx_get_color_value(void *mlx_ptr, int color);
C

ํ•จ์ˆ˜ ์ธ์ž

mlx_pixel_put ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์ด ์‚ฌ์šฉํ•˜๋Š” R, G, B์— ๋Œ€ํ•œ 4 ๋ฐ”์ดํŠธ ํ‘œ์ค€ ํ‘œํ˜„์ธ color๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋”ฐ๋ผ Pixel์˜ ์ƒ‰์ƒ์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋น„ํŠธ ์ˆ˜๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์–ด์„œ ๋‚ด๋ถ€์ ์œผ๋กœ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด Screen Connection Identifier์ธ mlx_ptr์„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

์ธ์ž๋กœ ๋ฐ›์€ color ๊ฐ’์„ ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์˜ ์ •๋ณด๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ Image๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” bits_per_pixel๋งŒํผ์˜ ํฌ๊ธฐ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ unsigned int ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜ (๋ฐ˜ํ™˜๋œ ๊ฐ’์ด ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์—์„œ ์‹ค์ œ๋กœ ์ด์šฉ๋˜๋Š” ์ƒ‰์ƒ ๊ฐ’์ด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.)

์ฐธ๊ณ 

mlx_get_color_value ํ•จ์ˆ˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํ‘œ์ค€์„ ๋”ฐ๋ฅด๋„๋ก ์ •์˜ํ•œ color ๊ฐ’์ด ์‹ค์ œ ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์—์„œ ์–ด๋–ค ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š”์ง€ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜์ด๋‹ค.
Image ์ž์ฒด๊ฐ€ ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋Œ€ํ•œ ์ •๋ณด๋“ค๋กœ ์ƒ์„ฑ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— bits_per_pixel์€ Image์—๋„ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
mlx_pixel_put ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์ด ์ด์šฉํ•˜๋Š” ์ƒ‰์ƒ ๊ฐ’์€ 4 ๋ฐ”์ดํŠธ์ด์ง€๋งŒ ํˆฌ๋ช…๋„๋ฅผ ์ด์šฉํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, bits_per_pixel์ด 24 ๋น„ํŠธ ํ˜น์€ 32 ๋น„ํŠธ๋ผ๋ฉด ๋ณ„๋„์˜ ๋ณ€ํ™˜์ด ํ•„์š” ์—†๋‹ค. ์ฆ‰, ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” mlx_get_color_value๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง„๋‹ค.
X11๊ณผ ๊ฐ™์ด Image์˜ Endian๊ณผ ๋กœ์ปฌ ๋จธ์‹ ์˜ Endian์ด ๋‹ค๋ฅด๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ์—๋Š”, Endian ๊ฐ’์„ ์ ์ ˆํžˆ ๋ณ€ํ™˜ ํ•ด์ค˜์•ผ ํ•ด๋‹น ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ฟ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์ž‘์—…์— ๋Œ€ํ•ด์„œ๋„ ์˜ฌ๋ฐ”๋ฅธ ๊ฒฐ๊ณผ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

5) mlx_xpm_to_image

ํ•จ์ˆ˜ ์›ํ˜•

void *mlx_xpm_to_image(void *mlx_ptr, char **xpm_data, int *width, int *height);
C

ํ•จ์ˆ˜ ์ธ์ž

mlx_xmp_to_image์˜ ํ•จ์ˆ˜ ์ •์˜๋ฅผ ์‚ดํŽด๋ณด๋ฉด, xpm_data๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹จ์ˆœํžˆ mlx_int_parse_xpm์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  mlx_int_parse_xpm์„ ํ™•์ธํ•ด๋ณด๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ mlx_new_image๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, mlx_ptr์€ mlx_new_image ํ˜ธ์ถœ์— ์‚ฌ์šฉ๋œ๋‹ค. Image์˜ ํฌ๊ธฐ๋Š” width์™€ height ๋งŒํผ์œผ๋กœ ์œ ์ง€๋œ๋‹ค.
void *mlx_int_parse_xpm(void *xvar,void *info,int info_size,char *(*f)(), int *width, int *height) { // ... ์ค‘๋žต if (!(img = mlx_new_image(xvar,*width,*height))) RETURN; // ... ์ค‘๋žต } void *mlx_xpm_to_image(void *xvar,char **xpm_data,int *width,int *height) { return (mlx_int_parse_xpm(xvar,xpm_data,0,mlx_int_static_line, width, height)); }
C

๋ฐ˜ํ™˜ ๊ฐ’

xpm_data๋ฅผ ์ด์šฉํ•˜์—ฌ Image ๋‚ด๋ถ€๋ฅผ ์ฑ„์šฐ๊ณ , ํ•ด๋‹น Image ์— ๋Œ€ํ•œ ์‹๋ณ„์ž๋ฅผ void * ํƒ€์ž…์˜ ํฌ์ธํ„ฐ๋กœ ๋ฐ˜ํ™˜ (๋ฐ˜ํ™˜๋œ ํฌ์ธํ„ฐ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์˜ Image ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. Image ์ƒ์„ฑ์— ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.)

์ฐธ๊ณ 

mlx_xpm_to_image์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ img_ptr๋กœ ์ด์šฉ๋˜๋ฉฐ, Image Identifier๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค. ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋งž๋Š” ์ •๋ณด๋“ค์„ ์ด์šฉํ•˜์—ฌ Image๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
MiniLibX๋Š” XPM ํŒŒ์ผ์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ํ‘œ์ค€ XPM ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ ์„ ์œ ์˜ํ•œ๋‹ค. (ํˆฌ๋ช…๋„์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋Š” ๊ฐ€๋Šฅํ•˜๋‚˜ ๋ชจ๋“  XPM ํŒŒ์ผ์„ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.)

6) mlx_xpm_file_to_image

ํ•จ์ˆ˜ ์›ํ˜•

void * mlx_xpm_file_to_image(void *mlx_ptr, char *filename, int *width, int *height);
C

ํ•จ์ˆ˜ ์ธ์ž

mlx_xmp_file_to_image์˜ ํ•จ์ˆ˜ ์ •์˜๋ฅผ ์‚ดํŽด๋ณด๋ฉด, filename์— ํ•ด๋‹นํ•˜๋Š” ํŒŒ์ผ๋กœ๋ถ€ํ„ฐ ์ฃผ์„์„ ์ œ๊ฑฐํ•œ ๋ฐ์ดํ„ฐ๋“ค์„ ์–ป์–ด์„œ mlx_int_parse_xpm์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  mlx_int_parse_xpm์„ ํ™•์ธํ•ด๋ณด๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ mlx_new_image๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, mlx_ptr์€ mlx_new_image ํ˜ธ์ถœ์— ์‚ฌ์šฉ๋œ๋‹ค. Image์˜ ํฌ๊ธฐ๋Š” width์™€ height ๋งŒํผ์œผ๋กœ ์œ ์ง€๋œ๋‹ค.
void *mlx_int_parse_xpm(void *xvar,void *info,int info_size,char *(*f)(), int *width, int *height) { // ... ์ค‘๋žต if (!(img = mlx_new_image(xvar,*width,*height))) RETURN; // ... ์ค‘๋žต } void *mlx_xpm_file_to_image(void *xvar,char *file,int *width,int *height) { int fd; int size; char *ptr; void *img; if ((fd = open(file,O_RDONLY))==-1 || (size = lseek(fd,0,SEEK_END))==-1 || (ptr = mmap(0,size,PROT_WRITE|PROT_READ,MAP_PRIVATE,fd,0))== (void *)MAP_FAILED) { if (fd>=0) close(fd); return ((void *)0); } mlx_int_file_get_rid_comment(ptr, size); img = mlx_int_parse_xpm(xvar,ptr,size,mlx_int_get_line, width, height); munmap(ptr,size); close(fd); return (img); }
C

๋ฐ˜ํ™˜ ๊ฐ’

filename์„ ์ด์šฉํ•˜์—ฌ Image ๋‚ด๋ถ€๋ฅผ ์ฑ„์šฐ๊ณ , ํ•ด๋‹น Image ์— ๋Œ€ํ•œ ์‹๋ณ„์ž๋ฅผ void * ํƒ€์ž…์˜ ํฌ์ธํ„ฐ๋กœ ๋ฐ˜ํ™˜ (๋ฐ˜ํ™˜๋œ ํฌ์ธํ„ฐ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์˜ Image ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. Image ์ƒ์„ฑ์— ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.)

์ฐธ๊ณ 

mlx_xpm_file_to_image์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ img_ptr๋กœ ์ด์šฉ๋˜๋ฉฐ, Image Identifier๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค. ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋งž๋Š” ์ •๋ณด๋“ค์„ ์ด์šฉํ•˜์—ฌ Image๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
MiniLibX๋Š” XPM ํŒŒ์ผ์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ํ‘œ์ค€ XPM ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ ์„ ์œ ์˜ํ•œ๋‹ค. (ํˆฌ๋ช…๋„์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋Š” ๊ฐ€๋Šฅํ•˜๋‚˜ ๋ชจ๋“  XPM ํŒŒ์ผ์„ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.)

7) mlx_png_file_to_image

ํ•จ์ˆ˜ ์›ํ˜•

void *mlx_png_file_to_image(void *mlx_ptr, char *filename, int *width, int *height);
C

ํ•จ์ˆ˜ ์ธ์ž

mlx_png_file_to_image์˜ ํ•จ์ˆ˜ ์ •์˜๋ฅผ ์‚ดํŽด๋ณด๋ฉด, filename์— ํ•ด๋‹นํ•˜๋Š” ํŒŒ์ผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋“ค์„ ์–ป์–ด์„œ mlx_int_parse_png์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  mlx_int_parse_png์„ ํ™•์ธํ•ด๋ณด๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ mlx_new_image๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, mlx_ptr์€ mlx_new_image ํ˜ธ์ถœ์— ์‚ฌ์šฉ๋œ๋‹ค. Image์˜ ํฌ๊ธฐ๋Š” width์™€ height ๋งŒํผ์œผ๋กœ ์œ ์ง€๋œ๋‹ค.
void *mlx_int_parse_png(void *xvar, unsigned char *fptr, int size, int *width, int *height) { // ... ์ค‘๋žต if (!(img = mlx_new_image(xvar, pi.width, pi.height))) { warnx("mlx PNG error : Can't create mlx image"); return ((void *)0); } // ... ์ค‘๋žต } void *mlx_png_file_to_image(void *xvar, char *file, int *width, int *height) { int fd; int size; unsigned char *ptr; void *img; if ((fd = open(file, O_RDONLY)) == -1 || (size = lseek(fd, 0, SEEK_END)) == -1 || (ptr = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0)) == (void *)MAP_FAILED) { if (fd >= 0) close(fd); warnx("Can't map png file '%s'", file); return ((void *)0); } if (!(img = mlx_int_parse_png(xvar, ptr, size, width, height))) { *width = 0; *height = 0; } munmap(ptr,size); close(fd); return (img); }
C

๋ฐ˜ํ™˜ ๊ฐ’

filename์„ ์ด์šฉํ•˜์—ฌ Image ๋‚ด๋ถ€๋ฅผ ์ฑ„์šฐ๊ณ , ํ•ด๋‹น Image ์— ๋Œ€ํ•œ ์‹๋ณ„์ž๋ฅผ void * ํƒ€์ž…์˜ ํฌ์ธํ„ฐ๋กœ ๋ฐ˜ํ™˜ (๋ฐ˜ํ™˜๋œ ํฌ์ธํ„ฐ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์˜ Image ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. Image ์ƒ์„ฑ์— ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.)

์ฐธ๊ณ 

mlx_png_file_to_image์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ img_ptr๋กœ ์ด์šฉ๋˜๋ฉฐ, Image Identifier๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค. ๋””์Šคํ”Œ๋ ˆ์ด ์žฅ์น˜์— ๋งž๋Š” ์ •๋ณด๋“ค์„ ์ด์šฉํ•˜์—ฌ Image๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
MiniLibX๋Š” PNG ํŒŒ์ผ์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ํ‘œ์ค€ PNG ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ ์„ ์œ ์˜ํ•œ๋‹ค. (ํˆฌ๋ช…๋„์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋Š” ๊ฐ€๋Šฅํ•˜๋‚˜ ๋ชจ๋“  PNG ํŒŒ์ผ์„ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.)

8) mlx_destroy_image

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_destroy_image(void *mlx_ptr, void *img_ptr);
C

ํ•จ์ˆ˜ ์ธ์ž

Screen Connection ์ƒ์—์„œ ์œ ์ง€ ์ค‘์ธ Image๋ฅผ ์ง€์šธ ์ˆ˜ ์žˆ๋„๋ก, mlx_ptr๊ณผ img_ptr์„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋‹จ์ˆœํžˆ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_destroy_image") public func mlx_destroy_image_swift(_ mlxptr:UnsafeRawPointer, _ imgptr:UnsafeRawPointer) -> Int32 { let mlx:MlxMain = _mlx_bridge(ptr:mlxptr) /// bridge_transfer to get the retain, at end of this func should release the MlxImg object, because no ref anymore. let img:MlxImg = _mlx_bridge_transfer(ptr:imgptr) mlx.winList.forEach { $0.flushImages() } while img.onGPU > 0 {} mlx.imgList.removeAll(where: { $0 === img} ) return Int32(0) }
Swift

์ฐธ๊ณ 

mlx_destroy_image ํ•จ์ˆ˜๋Š” Image๋ฅผ ์†Œ๋ฉธ์‹œํ‚ค๋Š” ํ•จ์ˆ˜์ด๋‹ค.

4. mlx_pixel_put

mlx_pixel_put ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์€ Window ๋‚ด๋ถ€๋ฅผ ๊ทธ๋ ค๋‚ด๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

1) ์ƒ‰์ƒ ๊ด€๋ฆฌ

mlx๋ฅผ ์ด์šฉํ•˜์—ฌ ์ƒ‰์ƒ์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„  ์‚ฌ์ „์— ์ •์˜๋œ ํ˜•์‹์— ๋งž์ถฐ int ํƒ€์ž…์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. int ํƒ€์ž…์œผ๋กœ ๋งŒ๋“  ์ƒ‰์ƒ์€ ์ด๋ฅผ ์ด๋ฃจ๋Š” 3๊ฐ€์ง€ ๊ธฐ๋ณธ ์ƒ‰์ƒ์ธ R (๋นจ๊ฐ•), G (์ดˆ๋ก), B (ํŒŒ๋ž‘)์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ๋‹ค. ๊ฐ R, G, B๋Š” 0โ‰คxโ‰ค2550 โ‰ค x โ‰ค 255์˜ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ๊ฐ’์€ ์› ์ƒ‰์ƒ์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์–ผ๋งŒํผ์˜ ๋น„์ค‘์„ ์ฐจ์ง€ํ•˜๋Š”์ง€๋ฅผ ์˜๋ฏธํ•œ๋‹ค. 0โ‰คxโ‰ค2550 โ‰ค x โ‰ค 255๋Š” ์ด 256๊ฐœ๋ฏ€๋กœ 282^8์ธ 8 ๋น„ํŠธ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” ๊ณง ๊ฐ R, G, B๊ฐ€ 1 ๋ฐ”์ดํŠธ์”ฉ ์ฐจ์ง€ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. int ํƒ€์ž…์€ ์ผ๋ฐ˜์ ์œผ๋กœ 4 ๋ฐ”์ดํŠธ์ด๋ฏ€๋กœ, R, G, B์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ํ˜•์‹์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
ํ•˜๋“œ์›จ์–ด ๋Šฅ๋ ฅ์— ๋”ฐ๋ผ์„œ ์•„๋ž˜ ํ˜•์‹์˜ MSB์— ํ•ด๋‹นํ•˜๋Š” 0์ด ํˆฌ๋ช…๋„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š”๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์ง€๋งŒ, ํด๋ž˜์‹ํ•œ OpenGL๊ณผ๋Š” ๋‹ฌ๋ฆฌ ์—ฌ๊ธฐ์„  ํˆฌ๋ช…๋„๋ฅผ ๋‚˜ํƒ€๋‚ด์ง€ ์•Š๋Š”๋‹ค. ํˆฌ๋ช…๋„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฉ๋ฒ•์€ Opacity์™€ Transparency (Alpha)๊ฐ€ ์žˆ๋‹ค. Opacity๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ 0.0โ‰คxโ‰ค1.00.0 โ‰ค x โ‰ค 1.0์˜ ๊ฐ’์„ ๊ฐ–๊ณ  ์ด๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ์‹์„ RGBO๋ผ๊ณ  ํ•œ๋‹ค. Alpha๋Š” 0โ‰คxโ‰ค2550 โ‰ค x โ‰ค 255์˜ ๊ฐ’์„ ๊ฐ–๊ณ  ์ด๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ์‹์„ ARGB๋ผ๊ณ  ํ•œ๋‹ค.
| 0 | R | G | B | color integer +---+---+---+---+ MSB LSB 0x 00 RR GG BB R 0x 00 FF 00 00 G 0x 00 00 FF 00 B 0x 00 00 00 FF
C
์ด๋ฅผ ํ†ตํ•ด ์ƒ‰์ƒ์„ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ํŠน์ • ์ƒ‰์ƒ ์š”์†Œ๋ฅผ ์ถ”์ถœํ•˜๋Š” ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.
int encode_rgb(int r, int g, int b) { return (r << 16 | g << 8 | b); }
C
int decode_r(int color) { return (color & 0x00FF0000); } int decode_g(int color) { return (color & 0x0000FF00); } int decode_b(int color) { return (color & 0x000000FF); }
C
encode_rgb์˜ ํ˜ธ์ถœ๋ถ€์—์„œ r, g, b ์ธ์ž ๊ฐ’์„ 0โ‰คxโ‰ค2550 โ‰ค x โ‰ค 255์˜ ๊ฐ’์„ ์ฃผ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ Opacity์ฒ˜๋Ÿผ Normalize๋œ 0.0โ‰คxโ‰ค1.00.0 โ‰ค x โ‰ค 1.0์˜ ๊ฐ’์„ ์ฃผ๋Š” ๊ฒฝ์šฐ๊ฐ€ ํ—ˆ๋‹คํ•œ๋ฐ ์ด ๋•Œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด 0โ‰คxโ‰ค2550 โ‰ค x โ‰ค 255์˜ ๊ฐ’์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Scale ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
RT ๊ตฌํ˜„์— ๋”ฐ๋ผ์„œ ์ƒ‰์ƒ ๊ฐ’์„ Gamma Correction์— ๋”ฐ๋ผ Scaleํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์œ„์™€ ๊ฐ™์ด Normalize๋œ ๊ฐ’์„ ์ด์šฉํ•  ๋•Œ ์ตœ๋Œ€ ๋ฐ ์ตœ์†Œ ๋ฒ”์œ„๋ฅผ ๋„˜์–ด๊ฐ€๋Š” ๊ฐ’์ด ๋“ค์–ด์˜ค๋ฉด ์ด๋ฅผ Clampํ•  ์ˆ˜๋„ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ด์— ๋Œ€ํ•œ ๊ตฌํ˜„์€ encode_rgb ํ•จ์ˆ˜ ํ˜น์€ ์ƒ‰์ƒ ๊ฐ’์„ ์ง์ ‘์ ์œผ๋กœ ์“ฐ๋Š” ํ•จ์ˆ˜์—์„œ ์ถ”๊ฐ€์ ์œผ๋กœ ์ž‘์„ฑํ•˜์—ฌ ์ƒ‰์ƒ ๊ฐ’ ์ด์šฉ์— ๋Œ€ํ•œ ์—„๊ฒฉํ•œ ๊ด€๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
int r; int g; int b; int color; // set r, g, b value // r = 0.1; // g = 0.2; // b = 0.3; color = encode_rgb(255.999 * r, 255.999 * g, 255.999 * b);
C

2) mlx_pixel_put

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_pixel_put(void *mlx_ptr, void *win_ptr, int x, int y, int color);
C

ํ•จ์ˆ˜ ์ธ์ž

Window๋ฅผ ์˜๋ฏธํ•˜๋Š” win_ptr์„ ์ธ์ž๋กœ ๋ฐ›๊ณ , ์ด Window๋ฅผ ์ฐพ์•„์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก Window๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” mlx_ptr๋„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ์ธ์ž๋กœ ๋ฐ›์€ x์™€ y๋ฅผ ์ขŒํ‘œ๋กœ ํ•˜๋Š” Pixel ์œ„์— color์— ํ•ด๋‹นํ•˜๋Š” ์ƒ‰์ƒ์„ ์ž…ํžŒ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์•„๋ฌด๋Ÿฐ ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_pixel_put") public func mlx_pixel_put_swift(_ mlxptr:UnsafeRawPointer, _ winptr:UnsafeRawPointer, _ x:Int32, _ y:Int32, _ color:UInt32) { let win:MlxWin = _mlx_bridge(ptr:winptr) win.pixelPut(x, y, color) }
Swift

์ฐธ๊ณ 

์ขŒ์ธก ์ƒ๋‹จ์˜ ์ฝ”๋„ˆ๋ฅผ ์›์ ์ธ (0,0)(0, 0)์œผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค. (x,y)(x, y)๋Š” ์›์ ์„ ๊ธฐ์ค€์œผ๋กœ ์šฐ์ธก ํ•˜๋‹จ ์ชฝ์— ์œ„์น˜ํ•˜๊ฒŒ ๋œ๋‹ค. Window๋ฅผ ๋ฒ—์–ด๋‚œ ์œ„์น˜์— ๋Œ€ํ•œ ์ž‘์—…์€ ๋ฒ„๋ฆฌ๊ฒŒ ๋˜๊ณ , ์ด๋Ÿฐ ์ž‘์—…์€ mlx_pixel_put์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ๋Š๋ฆฌ๊ฒŒ ๋งŒ๋“ ๋‹ค. ์ผ์ผ์ด mlx_pixel_put์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” Image๋ฅผ ์ด์šฉํ•˜๋Š” ์ž‘์—…์„ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค.

3) mlx_string_put

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_string_put(void *mlx_ptr, void *win_ptr, int x, int y, int color, char *string);
C

ํ•จ์ˆ˜ ์ธ์ž

Window๋ฅผ ์˜๋ฏธํ•˜๋Š” win_ptr์„ ์ธ์ž๋กœ ๋ฐ›๊ณ , ์ด Window๋ฅผ ์ฐพ์•„์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก Window๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” mlx_ptr๋„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ์ธ์ž๋กœ ๋ฐ›์€ x์™€ y๋ฅผ ์ขŒํ‘œ๋กœ ํ•˜๋Š” Pixel ์œ„์— color์— ํ•ด๋‹นํ•˜๋Š” ์ƒ‰์ƒ์„ ์ž…ํžˆ๊ณ  string์— ํ•ด๋‹นํ•˜๋Š” ๋ฌธ์ž์—ด์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, C ์–ธ์–ด๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋‹จ์ˆœํžˆ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
int mlx_string_put(void *mlx_ptr, void *win_ptr, int x, int y, int color, char *string) { static void *font = (void *)0; static unsigned char *data = (void *)0; static int size_line = 0; int bpp; int endian; int pos; int val; int dest_w; int dest_h; if (font == (void *)0) { font = mlx_new_image(mlx_ptr, font_atlas.width, font_atlas.height); data = (unsigned char *)mlx_get_data_addr(font, &bpp, &size_line, &endian); mlx_int_fill(data, size_line); } color = (color&0xFFFFFF)|0xFF000000; // dest_w = (FONT_WIDTH*5)/7; /// ratio with X11 standard mlx_string_put // dest_h = (font_atlas.height*5)/7; dest_w = FONT_WIDTH; dest_h = font_atlas.height; y = y - (dest_h*3)/4; pos = 0; while (*string) { if (*string >= 32 && *string <= 127) val = *string - 32; else val = 31; mlx_put_image_to_window_scale(mlx_ptr, win_ptr, font, val*(FONT_WIDTH+2), 0, FONT_WIDTH, font_atlas.height, x+pos*dest_w, y, dest_w, dest_h, color); pos ++; string ++; } return (0); }
C

์ฐธ๊ณ 

์ขŒ์ธก ์ƒ๋‹จ์˜ ์ฝ”๋„ˆ๋ฅผ ์›์ ์ธ (0,0)(0, 0)์œผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค. (x,y)(x, y)๋Š” ์›์ ์„ ๊ธฐ์ค€์œผ๋กœ ์šฐ์ธก ํ•˜๋‹จ ์ชฝ์— ์œ„์น˜ํ•˜๊ฒŒ ๋œ๋‹ค. Window๋ฅผ ๋ฒ—์–ด๋‚œ ์œ„์น˜์— ๋Œ€ํ•œ ์ž‘์—…์€ ๋ฒ„๋ฆฌ๊ฒŒ ๋˜๊ณ , ์ด๋Ÿฐ ์ž‘์—…์€ mlx_string_put์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ๋Š๋ฆฌ๊ฒŒ ๋งŒ๋“ ๋‹ค. ์ผ์ผ์ด mlx_string_put์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” Image๋ฅผ ์ด์šฉํ•˜๋Š” ์ž‘์—…์„ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค.

5. mlx_loop

mlx_loop ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์€ ํ‚ค๋ณด๋“œ ํ˜น์€ ๋งˆ์šฐ์Šค์— ๋Œ€ํ•œ Event๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ์ด์šฉ๋œ๋‹ค.
Event ๊ทธ๋ž˜ํ”ฝ ์‹œ์Šคํ…œ์€ ์–‘๋ฐฉํ–ฅ์„ฑ์„ ๊ฐ–๋Š”๋‹ค. ํ•œ ์ชฝ์—์„œ๋Š” Window์— Pixel ํ˜น์€ Image ์„ ๋‚˜ํƒ€๋‚ด๋‹ฌ๋ผ๋Š” ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๊ณ , ๋‹ค๋ฅธ ํ•œ ์ชฝ์€ Window์—์„œ ์‚ฌ์šฉ๋œ ๋งˆ์šฐ์Šค ํ˜น์€ ํ‚ค๋ณด๋“œ๋ฅผ ์ด์šฉํ•œ ์ •๋ณด๋“ค์„ ์ทจ๋“ํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ ๋งˆ์šฐ์Šค ํ˜น์€ ํ‚ค๋ณด๋“œ๋ฅผ ์ด์šฉํ•œ ์ •๋ณด๋ฅผ Event๋ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํ”„๋กœ๊ทธ๋žจ์€ Event๋ฅผ ์บ์น˜ํ•ด์„œ ๊ทธ๋ž˜ํ”ฝ ์‹œ์Šคํ…œ์—๊ฒŒ ๋ณด๋‚ด Event๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผํ•˜๋Š”๋ฐ ์ด ๊ณผ์ •์„ "mlx.h"์˜ mlx_loop๊ฐ€ ๋‹ด๋‹นํ•œ๋‹ค. mlx_init๊ณผ mlx_new_window๋งŒ์œผ๋กœ๋Š” ๊ทธ๋ž˜ํ”ฝ ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋กœ Window๊ฐ€ ์ข…๋ฃŒ๋œ๋‹ค. ๋”ฐ๋ผ์„œ mlx_loop๊นŒ์ง€ ์ด์šฉํ•ด์•ผ Window์—์„œ์˜ Event๋ฅผ ๊ด€๋ฆฌ ๋ฐ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์„ ๋ฟ ์•„๋‹ˆ๋ผ ๊ทธ๋ž˜ํ”ฝ ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜์—ฌ Window๋ฅผ ์ง€์†ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. Event๋ฅผ ์บ์น˜ํ•˜์—ฌ ๊ทธ๋ž˜ํ”ฝ ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ฃผ๋Š” mlx_loop๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „, ์–ด๋–ค Event๋ฅผ ์บ์น˜ํ• ์ง€ ๋ช…์‹œํ•จ์œผ๋กœ์จ mlx_loop๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒ์‹œํ‚ค์ง€ ์•Š๊ณ  ๊ณ„์†ํ•ด์„œ ๋™์ž‘ํ•  ๋•Œ ์ •์ƒ์ ์ธ ๊ธฐ๋Šฅ์„ ํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. "mlx.h"๋Š” ๋‹ค์–‘ํ•œ Event๋“ค์„ ์บ์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ์ˆ˜๋“ค์„ ์ œ๊ณตํ•˜๋Š”๋ฐ, ์ด ํ•จ์ˆ˜๋“ค์€ mlx_*_hook์˜ ์ด๋ฆ„์„ ๊ฐ–๋Š”๋‹ค. mlx_*_hook ํ•จ์ˆ˜๋“ค์€ mlx_hook์„ ํ†ตํ•ด์„œ ๊ณตํ†ต์ ์ธ ํ˜•์‹์œผ๋กœ ์ด์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. mlx_hook์€ X11์˜ "X.h"์— ์กด์žฌํ•˜๋Š” Event์™€ Mask ๊ฐ’์„ ์ด์šฉํ•œ๋‹ค. Mac OS X์˜ Event๋“ค์€ ๋Œ€์ฒด์ ์œผ๋กœ X11์˜ Event ๊ฐ’๋“ค์— Mapping๋˜์–ด ์žˆ์œผ๋ฉฐ, Mac OS X ์ƒ์—์„œ Mask ๊ฐ’์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.
Hooking & Hook Hooking์ด๋ผ๋Š” ๊ฒƒ์€ Software๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ์žˆ๋Š” ์š”์†Œ ๊ฐ„์— ์ „๋‹ฌ๋œ Function, Message, Event ๋“ฑ์„ ๊ฐ€๋กœ์ฑ„๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๊ณ  Hooking์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ Hook์ด๋ผ ํ•œ๋‹ค. mlx_loop๊ฐ€ Event๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์–ด๋–ค Event๋ฅผ ์บ์น˜ํ• ์ง€ ๋ช…์‹œํ•  ๋•Œ mlx_*_hook์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ, mlx_*_hook์˜ ์ฝ”๋“œ๊ฐ€ Hook์„ ์˜๋ฏธํ•˜๊ณ  ํ•จ์ˆ˜์˜ ๋™์ž‘์ด ๊ณง Hooking์„ ์˜๋ฏธํ•œ๋‹ค. Hooking๋œ Function, Message, Event ๋“ฑ์€ Software์˜ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ ๋™์ž‘์— ์˜ํ–ฅ์„ ๋ผ์น˜๊ฒŒ ๋œ๋‹ค.

1) mlx_loop

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_loop(void *mlx_ptr);
C

ํ•จ์ˆ˜ ์ธ์ž

์–ด๋–ค Screen Connection์˜ Event๋ฅผ ์ฒ˜๋ฆฌํ• ์ง€ Screen Connection Identifier๋ฅผ ๋ช…์‹œํ•œ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์•„๋ฌด๋Ÿฐ ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_loop") public func mlx_loop_swift(_ mlxptr:UnsafeRawPointer) { let mlx:MlxMain = _mlx_bridge(ptr:mlxptr) mlx.inLoop = true NSApp.run() }
Swift

์ฐธ๊ณ 

mlx_loop ํ•จ์ˆ˜๋Š” ๋ฐ˜ํ™˜์„ ์ ˆ๋Œ€๋กœ ํ•˜์ง€ ์•Š๋„๋ก Infinite Loop๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜์ด๋‹ค. ๋“ฑ๋ก๋œ Hook ํ•จ์ˆ˜๋“ค์— ๋”ฐ๋ผ Event๋ฅผ ์บ์น˜ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋ฌดํ•œํžˆ ๋ฐ˜๋ณตํ•œ๋‹ค. Event๋ฅผ ์บ์น˜ํ•˜๋ฉด Hook ํ•จ์ˆ˜์— ๋“ฑ๋ก๋œ Callback Function์„ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ Event๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.

2) mlx_key_hook

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_key_hook(void *win_ptr, int (*funct_ptr)(), void *param);
C

ํ•จ์ˆ˜ ์ธ์ž

ํ‚ค๋ณด๋“œ ๋ฒ„ํŠผ์— ๋Œ€ํ•œ Event๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ Callback Function์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก funct_ptr๋ผ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์ธ์ž๋กœ ์ด์šฉํ•œ๋‹ค. param์ด๋ผ๋Š” ์ธ์ž๋Š” funct_ptr์„ ํ†ตํ•ด Callback Function์ด ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ, Callback Function์˜ ์ธ์ž๋กœ์จ ์ด์šฉ๋œ๋‹ค. (ํฌ์ธํ„ฐ๋กœ param์„ ๋„˜๊ฒผ๊ธฐ ๋•Œ๋ฌธ์— Callback Function ํ˜ธ์ถœ์„ ํ†ตํ•ด ํŠน์ • ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๊ณ , param์„ ๊ตฌ์กฐ์ฒด๋กœ์จ ์ด์šฉํ•˜๋ฉด ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์˜ ์—ฌ๋Ÿฌ ๊ฐ’๋“ค์„ ์ธ์ž๋กœ์จ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.) ํ•ด๋‹น ํ•จ์ˆ˜๋Š” Window Identifier๋ฅผ ์ด์šฉํ•œ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋‹จ์ˆœํžˆ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_key_hook") public func mlx_key_hook_swift(_ winptr:UnsafeRawPointer, _ fctptr:UnsafeMutableRawPointer, _ paramptr:UnsafeMutableRawPointer) -> Int32 { let win:MlxWin = _mlx_bridge(ptr:winptr) win.addHook(index: 3, fct: fctptr, param: paramptr) return (Int32(0)); }
Swift

์ฐธ๊ณ 

ํ‚ค๋ณด๋“œ ๋ฒ„ํŠผ์— ๋Œ€ํ•œ Event๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด MiniLibX๋Š” Callback Function์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— mlx_key_hook์˜ funct_ptr์€ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ์˜ ํ•จ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ๋งŒ๋“ค์–ด ์ธ์ž๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. (ํ•จ์ˆ˜์˜ ์ด๋ฆ„์€ ์ž„์˜๋กœ ์ž‘์„ฑํ•œ ๊ฒƒ์ด๋‹ค.)
int key_hook(int keycode, void *param);
C
MiniLibX๊ฐ€ ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ ๋ฟ์ด์ง€ ์œ„์˜ ํ•จ์ˆ˜๋ฅผ MiniLibX๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” param์€ MiniLibX์˜ ๋™์ž‘์— ์˜ํ•ด ์ œ์–ด๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. ๋˜ํ•œ ์ธ์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” keycode๋Š” X11์˜ "keysymdef.h"์— ์ •์˜๋œ ๊ฐ’์„ ๋”ฐ๋ฅธ๋‹ค.
MiniLibX๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜๋“ค์€ Event๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋™์ž‘์‹œํ‚ค๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜์˜ ์›ํ˜•๋งŒ ๋‹ค๋ฅผ ๋ฟ, ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” mlx_mouse_hook, mlx_expose_hook๋„ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
๋™์ผํ•œ Screen Connection์„ ์ด์šฉํ•˜๋”๋ผ๋„, mlx_key_hook ํ•จ์ˆ˜๋Š” Screen Connection ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ Window ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ๋ฏ€๋กœ ์—ฌ๋Ÿฌ Window์— ๋Œ€ํ•ด mlx_key_hook ํ•จ์ˆ˜ ์ด์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
keycode๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ด์šฉ๋œ๋‹ค.

3) mlx_mouse_hook

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_mouse_hook(void *win_ptr, int (*funct_ptr)(), void *param);
C

ํ•จ์ˆ˜ ์ธ์ž

๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์— ๋Œ€ํ•œ Event๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ Callback Function์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก funct_ptr๋ผ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์ธ์ž๋กœ ์ด์šฉํ•œ๋‹ค. param์ด๋ผ๋Š” ์ธ์ž๋Š” funct_ptr์„ ํ†ตํ•ด Callback Function์ด ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ, Callback Function์˜ ์ธ์ž๋กœ์จ ์ด์šฉ๋œ๋‹ค. (ํฌ์ธํ„ฐ๋กœ param์„ ๋„˜๊ฒผ๊ธฐ ๋•Œ๋ฌธ์— Callback Function ํ˜ธ์ถœ์„ ํ†ตํ•ด ํŠน์ • ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๊ณ , param์„ ๊ตฌ์กฐ์ฒด๋กœ์จ ์ด์šฉํ•˜๋ฉด ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์˜ ์—ฌ๋Ÿฌ ๊ฐ’๋“ค์„ ์ธ์ž๋กœ์จ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.) ํ•ด๋‹น ํ•จ์ˆ˜๋Š” Window Identifier๋ฅผ ์ด์šฉํ•œ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋‹จ์ˆœํžˆ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_mouse_hook") public func mlx_mouse_hook_swift(_ winptr:UnsafeRawPointer, _ fctptr:UnsafeMutableRawPointer, _ paramptr:UnsafeMutableRawPointer) -> Int32 { let win:MlxWin = _mlx_bridge(ptr:winptr) win.addHook(index: 4, fct: fctptr, param: paramptr) return (Int32(0)); }
Swift

์ฐธ๊ณ 

๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์— ๋Œ€ํ•œ Event๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด MiniLibX๋Š” Callback Function์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— mlx_mouse_hook์˜ funct_ptr์€ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ์˜ ํ•จ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ๋งŒ๋“ค์–ด ์ธ์ž๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. (ํ•จ์ˆ˜์˜ ์ด๋ฆ„์€ ์ž„์˜๋กœ ์ž‘์„ฑํ•œ ๊ฒƒ์ด๋‹ค.)
int mouse_hook(int button, int x, int y, void *param);
C
MiniLibX๊ฐ€ ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ ๋ฟ์ด์ง€ ์œ„์˜ ํ•จ์ˆ˜๋ฅผ MiniLibX๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” param์€ MiniLibX์˜ ๋™์ž‘์— ์˜ํ•ด ์ œ์–ด๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. ๋˜ํ•œ ์ธ์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” x, y๋Š” Window ์ƒ์—์„œ์˜ ์ขŒํ‘œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ, button์€ ๋งˆ์šฐ์Šค์˜ ์–ด๋–ค ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €๋Š”์ง€๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
MiniLibX๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜๋“ค์€ Event๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋™์ž‘์‹œํ‚ค๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜์˜ ์›ํ˜•๋งŒ ๋‹ค๋ฅผ ๋ฟ, ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” mlx_key_hook, mlx_expose_hook๋„ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
๋™์ผํ•œ Screen Connection์„ ์ด์šฉํ•˜๋”๋ผ๋„, mlx_mouse_hook ํ•จ์ˆ˜๋Š” Screen Connection ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ Window ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ๋ฏ€๋กœ ์—ฌ๋Ÿฌ Window์— ๋Œ€ํ•ด mlx_mouse_hook ํ•จ์ˆ˜ ์ด์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

4) mlx_expose_hook

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_expose_hook(void *win_ptr, int (*funct_ptr)(), void *param);
C

ํ•จ์ˆ˜ ์ธ์ž

Window์˜ ์ผ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๊ทธ๋ ค์•ผ ํ•˜๋Š” Event๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ Callback Function์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก funct_ptr๋ผ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์ธ์ž๋กœ ์ด์šฉํ•œ๋‹ค. param์ด๋ผ๋Š” ์ธ์ž๋Š” funct_ptr์„ ํ†ตํ•ด Callback Function์ด ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ, Callback Function์˜ ์ธ์ž๋กœ์จ ์ด์šฉ๋œ๋‹ค. (ํฌ์ธํ„ฐ๋กœ param์„ ๋„˜๊ฒผ๊ธฐ ๋•Œ๋ฌธ์— Callback Function ํ˜ธ์ถœ์„ ํ†ตํ•ด ํŠน์ • ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๊ณ , param์„ ๊ตฌ์กฐ์ฒด๋กœ์จ ์ด์šฉํ•˜๋ฉด ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์˜ ์—ฌ๋Ÿฌ ๊ฐ’๋“ค์„ ์ธ์ž๋กœ์จ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.) ํ•ด๋‹น ํ•จ์ˆ˜๋Š” Window Identifier๋ฅผ ์ด์šฉํ•œ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋‹จ์ˆœํžˆ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_expose_hook") public func mlx_expose_hook_swift(_ winptr:UnsafeRawPointer, _ fctptr:UnsafeMutableRawPointer, _ paramptr:UnsafeMutableRawPointer) -> Int32 { let win:MlxWin = _mlx_bridge(ptr:winptr) win.addHook(index: 12, fct: fctptr, param: paramptr) return (Int32(0)); }
Swift

์ฐธ๊ณ 

Unix ๊ณ„์—ด์˜ ์šด์˜์ฒด์ œ์—์„œ X11์˜ GUI ํ™˜๊ฒฝ์„ ์ด์šฉํ•˜๊ฒŒ ๋˜๋ฉด Window์˜ ์ผ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๊ทธ๋ฆฌ๋Š” ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ํ”„๋กœ๊ทธ๋žจ์˜ ๋ชซ์ด๋‹ค. ํ•˜์ง€๋งŒ Mac OS X๋Š” X11์„ ์ด์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— Mac OS X ์ƒ์—์„œ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” Event์ด๋‹ค. ๋”ฐ๋ผ์„œ Mac OS X ์ƒ์—์„œ๋Š” mlx_expose_hook ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
Window์˜ ์ผ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๊ทธ๋ ค์•ผ ํ•˜๋Š” Event๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด MiniLibX๋Š” Callback Function์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— mlx_expose_hook์˜ funct_ptr์€ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ์˜ ํ•จ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ๋งŒ๋“ค์–ด ์ธ์ž๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. (ํ•จ์ˆ˜์˜ ์ด๋ฆ„์€ ์ž„์˜๋กœ ์ž‘์„ฑํ•œ ๊ฒƒ์ด๋‹ค.)
int expose_hook(void *param);
C
MiniLibX๊ฐ€ ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ ๋ฟ์ด์ง€ ์œ„์˜ ํ•จ์ˆ˜๋ฅผ MiniLibX๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” param์€ MiniLibX์˜ ๋™์ž‘์— ์˜ํ•ด ์ œ์–ด๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.
MiniLibX๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜๋“ค์€ Event๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋™์ž‘์‹œํ‚ค๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜์˜ ์›ํ˜•๋งŒ ๋‹ค๋ฅผ ๋ฟ, ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” mlx_key_hook, mlx_mouse_hook๋„ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
๋™์ผํ•œ Screen Connection์„ ์ด์šฉํ•˜๋”๋ผ๋„, mlx_expose_hook ํ•จ์ˆ˜๋Š” Screen Connection ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ Window ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ๋ฏ€๋กœ ์—ฌ๋Ÿฌ Window์— ๋Œ€ํ•ด mlx_expose_hook ํ•จ์ˆ˜ ์ด์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

5) mlx_hook

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_hook(void *win_ptr, int x_event, int x_mask, int (*funct)(), void *param);
C

ํ•จ์ˆ˜ ์ธ์ž

x_event ๋ฐ x_mask๋Š” Event๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ฐ’๋“ค์ด๋‹ค. ๋‹ค๋ฅธ Hook ํ•จ์ˆ˜๋“ค๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Event๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ Callback Function์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก funct๋ผ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์ธ์ž๋กœ ์ด์šฉํ•œ๋‹ค. param์ด๋ผ๋Š” ์ธ์ž๋Š” funct์„ ํ†ตํ•ด Callback Function์ด ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ, Callback Function์˜ ์ธ์ž๋กœ์จ ์ด์šฉ๋œ๋‹ค. (ํฌ์ธํ„ฐ๋กœ param์„ ๋„˜๊ฒผ๊ธฐ ๋•Œ๋ฌธ์— Callback Function ํ˜ธ์ถœ์„ ํ†ตํ•ด ํŠน์ • ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๊ณ , param์„ ๊ตฌ์กฐ์ฒด๋กœ์จ ์ด์šฉํ•˜๋ฉด ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์˜ ์—ฌ๋Ÿฌ ๊ฐ’๋“ค์„ ์ธ์ž๋กœ์จ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.) ํ•ด๋‹น ํ•จ์ˆ˜๋Š” Window Identifier๋ฅผ ์ด์šฉํ•œ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋‹จ์ˆœํžˆ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_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)); }
C

์ฐธ๊ณ 

๋งค๋‰ด์–ผ ํŒŒ์ผ์—๋Š” ๋ช…์‹œ๋˜์–ด ์žˆ์ง€ ์•Š์€ ํ•จ์ˆ˜์ง€๋งŒ, "mlx.h"๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. mlx_key_hook, mlx_mouse_hook, mlx_expose_hook๊ณผ ๊ฐ™์€ Hook ํ•จ์ˆ˜๋“ค์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  mlx_hook์ด๋ผ๋Š” ํ•จ์ˆ˜๋งŒ์œผ๋กœ ํ‚ค๋ณด๋“œ ๋ฒ„ํŠผ, ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ, ์ผ๋ถ€ ํ™”๋ฉด ๊ทธ๋ฆฌ๊ธฐ ๋“ฑ์˜ Event๋ฅผ ๋ชจ๋‘ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.
x_event ๋ฐ x_mask ๊ฐ’์€ X11์˜ "X.h"๋ฅผ ์ฐธ๊ณ ํ•ด๋ณด๋ฉด ๊ทธ ๊ฐ’๋“ค์ด ์ƒ์„ธํžˆ ์ •์˜๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์›ํ•˜๋Š” Event์— ๋Œ€ํ•œ ๊ฐ’์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค. ๋‹จ, Mac OS X์—์„œ๋Š” Mask ๊ฐ’์ด ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— x_mask ๊ฐ’์„ 0์œผ๋กœ ์ง€์ •ํ•˜์—ฌ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ธ์ž์ž„์„ ์•”์‹œํ•˜๋„๋ก ํ•˜์—ฌ๋„ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„ ๋™์ž‘์—๋Š” ์ง€์žฅ์ด ์—†๋‹ค. Unix ๊ณ„์—ด์˜ ์šด์˜์ฒด์ œ์™€์˜ ์ด์‹์„ฑ์„ ์œ„ํ•ด x_mask ๊ฐ’์„ ๋ช…์‹œํ•  ๊ฒƒ์ธ์ง€, Mac OS X ์ƒ์—์„œ๋งŒ ๋™์ž‘์‹œํ‚ฌ ๋ชฉ์ ์œผ๋กœ ์ด์šฉํ•˜์ง€ ์•Š๋Š” ๊ฐ’์ž„์„ ๋ช…์‹œํ•  ๊ฒƒ์ธ์ง€๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ๋ชซ์ด ๋˜๊ฒ ๋‹ค.

6) mlx_loop_hook

ํ•จ์ˆ˜ ์›ํ˜•

int mlx_loop_hook(void *mlx_ptr, int (*funct_ptr)(), void *param);
C

ํ•จ์ˆ˜ ์ธ์ž

๋“ฑ๋ก๋œ Event๋“ค์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด Callback Function์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก funct_ptr๋ผ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์ธ์ž๋กœ ์ด์šฉํ•œ๋‹ค. param์ด๋ผ๋Š” ์ธ์ž๋Š” funct_ptr์„ ํ†ตํ•ด Callback Function์ด ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ, Callback Function์˜ ์ธ์ž๋กœ์จ ์ด์šฉ๋œ๋‹ค. (ํฌ์ธํ„ฐ๋กœ param์„ ๋„˜๊ฒผ๊ธฐ ๋•Œ๋ฌธ์— Callback Function ํ˜ธ์ถœ์„ ํ†ตํ•ด ํŠน์ • ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๊ณ , param์„ ๊ตฌ์กฐ์ฒด๋กœ์จ ์ด์šฉํ•˜๋ฉด ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์˜ ์—ฌ๋Ÿฌ ๊ฐ’๋“ค์„ ์ธ์ž๋กœ์จ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.) ํ•ด๋‹น ํ•จ์ˆ˜๋Š” Screen Connection Identifier๋ฅผ ์ด์šฉํ•œ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’

ํ•จ์ˆ˜์˜ ์›ํ˜•์—์„œ๋Š” int ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•˜์ง€๋งŒ, Swift๋กœ Forwarding๋˜๊ณ  ์žˆ๋Š” Interface๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋‹จ์ˆœํžˆ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
@_cdecl("mlx_loop_hook") public func mlx_loop_hook_swift(_ mlxptr:UnsafeRawPointer, _ fctptr:UnsafeMutableRawPointer, _ paramptr:UnsafeMutableRawPointer) -> Int32 { let mlx:MlxMain = _mlx_bridge(ptr:mlxptr) mlx.addLoopHook(fctptr, paramptr) return (Int32(0)); }
Swift

์ฐธ๊ณ 

mlx_loop_hook ํ•จ์ˆ˜๋Š” Event์— ๋Œ€ํ•ด Hooking์„ ์ˆ˜ํ–‰ํ•˜๋Š” mlx_key_hook, mlx_mouse_hook, mlx_expose_hook์™€ ๋Œ€์ฒด์ ์œผ๋กœ ๋™์ผํ•œ ์ธ์ž๋ฅผ ๋ฐ›์ง€๋งŒ, mlx_ptr์„ ๋ฐ›๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์•„ Window ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ Screen Connection ๋‹จ์œ„๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๊ณ  Event๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜์„ ๋•Œ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ˜ธ์ถœ๋˜์–ด ์ˆ˜ํ–‰๋˜๋Š” ํ•จ์ˆ˜๋ผ๋Š” ์ธก๋ฉด์—์„œ Hook ํ•จ์ˆ˜๋“ค๊ณผ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
๋“ฑ๋ก๋œ Event๋“ค์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด MiniLibX๋Š” Callback Function์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— mlx_loop_hook์˜ funct_ptr์€ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ์˜ ํ•จ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ๋งŒ๋“ค์–ด ์ธ์ž๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. (ํ•จ์ˆ˜์˜ ์ด๋ฆ„์€ ์ž„์˜๋กœ ์ž‘์„ฑํ•œ ๊ฒƒ์ด๋‹ค.)
int loop_hook(void *param);
C
MiniLibX๊ฐ€ ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ ๋ฟ์ด์ง€ ์œ„์˜ ํ•จ์ˆ˜๋ฅผ MiniLibX๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” param์€ MiniLibX์˜ ๋™์ž‘์— ์˜ํ•ด ์ œ์–ด๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.
๋งค๋ฒˆ์˜ ฮด\delta (Delta-Time) ๋งˆ๋‹ค Frame ์—…๋ฐ์ดํŠธ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ํ•จ์ˆ˜๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํ•ด๋‹น ํ•จ์ˆ˜์— Rendering ๊ด€๋ จ ๋กœ์ง์„ ๋„ฃ๊ณ  ๋Œ๋ฆฌ๋ฉด Frame์ด ์—…๋ฐ์ดํŠธ ๋˜๋Š” ๋Œ€๋กœ Window์— ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

6. Reference