The based version of this minilibx use Cocoa (AppKit) and OpenGL without X11. It was a fast writing library which try to reproduce partial X11 usage. Too partial for me, that why I decided to add some part for my project.
I have decided to customize minilibx to improve support of functionnalities and system events.
Changes:
- Add argument to set the maximum of FPS with
mlx_put_image_to_window
. - Added
mlx_toggle_cursor
function to hide/unhide cursor. - Added
mlx_set_cursor
function to change the cursor icon. - Better mousewheel listener with speed (deltaX and deltaY), we only had the direction without the speed before my change.
- News&fix events (because the minilibx macOS update without X11 was a partial copy of X11 api).
- Shared define of mlx structures to use them directly (and replace
void
by the proper type).mlx_get_data_addr
is deprecated. - mlx_hook prototype: remove deprecated
x_mask
argument. - Remove useless argument
mlx_ptr
for mlx_put_image_to_window, mlx_clear_window and mlx_pixel_put - Better Makefile & no relinks.
Include ./mlx.h
.
all: libs $(NAME)
# [...]
MINILIBX = vendor/minilibx/
libs: $(MINILIBX)libmlx.a
$(MINILIBX)libmlx.a:
make -C $(MINILIBX)
libs_clean:
make -C $(MINILIBX) clean
libs_fclean: libs_clean
make -C $(MINILIBX) fclean
# [...]
fclean: libs_fclean clean
rm -f $(NAME)
Add this flag: -L$(MINILIBX) -lmlx -framework OpenGL -framework AppKit
to compile your application.
Add libs libs_clean libs_fclean
to .PHONY
rule.
Add fps
argument. New prototype:
int mlx_loop_hook(mlx_ptr_t *mlx_ptr, int fps, int (*funct_ptr)(), void *param);
Remove unused/deprecated x_mask
argument in mlx_hook. New prototype:
int mlx_hook(void *win_ptr, int x_event, int (*funct)(), void *param);
New event system/code. See mlx_event.h:
/*
** ON_EVENT
*/
enum {
ON_KEYDOWN,
ON_KEYUP,
ON_MOUSEDOWN,
ON_MOUSEUP,
ON_MOUSEMOVE,
ON_MOUSEWHEEL,
ON_FOCUSCHANGE,
ON_KEYFOCUSCHANGE,
ON_VISIBILITYCHANGE,
ON_DESTROY
};
Note: ON_FOCUSCHANGE
is fired when the main window change, and ON_KEYFOCUSCHANGE
is fired when the key window change.
Remove useless mlx_ptr
argument.
int mlx_put_image_to_window(mlx_win_list_t *win_ptr, mlx_img_list_t *img_ptr, int x, int y);
int mlx_clear_window(mlx_win_list_t *win_ptr);
int mlx_pixel_put(mlx_win_list_t *win_ptr, int x, int y, int color);
Hide or display the cursor.
void mlx_toggle_cursor(int display);
Change the actual cursor icon, according to appkit documentation.
void mlx_set_cursor(int cursor);
NOTE: All app on your mac use the same API to change cursor, if your app loses the focus, you have to recall this function (to be sure to have the good cursor).
/*
** CURSOR ICON
*/
enum {
ARROW_CURSOR,
IBEAM_CURSOR,
CROSSHAIR_CURSOR,
CLOSEDHAND_CURSOR,
OPENHAND_CURSOR,
POINTINGHAND_CURSOR,
RESIZELEFT_CURSOR,
RESIZERIGHT_CURSOR,
RESIZELEFTRIGHT_CURSOR,
RESIZEUP_CURSOR,
RESIZEDOWN_CURSOR,
RESIZEUPDOWN_CURSOR,
DISAPPEARINGITEM_CURSOR,
IBEAM_CURSOR_FORVERTICALLAYOUT,
OPERATIONNOTALLOWED_CURSOR,
DRAGLINK_CURSOR,
DRAGCOPY_CURSOR,
CONTEXTUALMENU_CURSOR
};
int onmousemove(t_xpoint point, void *vars)
{
mlx_set_cursor(OPENHAND_CURSOR);
(void) point;
(void) vars;
return (0);
}
Add several pixels.
void mlx_pixels_put(mlx_win_list_t *win_ptr, t_xpoint pos, t_xpoint size, int *colors);
NOTE: mlx_put_image_to_window
is fastest.
// MINILIBX WHEEL EVENT / SCROLL EVENT
int onmousewheel(t_xwheel wheel, t_xpoint point, void *vars)
{
printf("wheel:%f %f pos: %d %d \n", wheel.dx, wheel.dy, point.x, point.y);
(void) vars;
return (0);
}
// wheel:-0.917145 0.000000 pos: 319 449
// wheel:-3.855789 0.000000 pos: 321 449
// wheel:-5.527893 0.000000 pos: 325 450
int onfocuschange(int visible, t_app *app)
{
printf("focus change: %d\n", visible);
low_mode(app);
return (0);
}
int onvisiblitychange(int visible, t_app *app)
{
printf("visiblity change: %d\n", visible);
low_mode(app);
return (0);
}
int close(t_app *app)
{
(void) app;
exit(0);
return (0);
}
mlx_hook(app.win, ON_MOUSEWHEEL, onmousewheel, &app);
mlx_hook(app.win, ON_FOCUSCHANGE, onfocuschange, &app);
mlx_hook(app.win, ON_VISIBILITYCHANGE, onvisiblitychange, &app);
mlx_hook(app.win, ON_DESTROY, close, &app);
With this version, we can access to app->mlx
properties and make an advanced usage of the minilibx.
void draw_char(t_img *img, t_point pos, char letter)
{
t_app *app;
int i;
t_point font;
int destid;
int srcid;
app = get_app();
i = FONT_WIDTH * FONT_HEIGHT;
if (!(32 < letter && letter <= 127))
return ;
while (i-- > 0)
{
font = (t_point){i % FONT_WIDTH, i / FONT_WIDTH};
destid = (font.x + pos.x) + (font.y + pos.y) * img->width;
srcid = font.x + font.y * IMG_FONT_SIZE
+ (FONT_WIDTH + 2) * (letter - 32);
pixel_add_color(&img->buffer[4 * destid],
&app->mlx->font->buffer[4 * srcid], (t_uchar *)&color);
// *((int *) img->buffer[4 * destid]) = *((int *) app->mlx->font->buffer[4 * srcid]);
}
}
draw_char(img, (t_point){4, 2}, 'A');
We can directly use the mlx_img_list_t
to get easiest api than before without declaring another structure.
typedef struct s_dimg {
void *img;
char *addr;
int bits_per_pixel;
int line_length;
int endian;
} t_dimg;
void draw_stats(t_app *app)
{
t_img *img;
dimg.img = mlx_new_image(app->mlx, STATS_W, STATS_H);
dimg.addr = mlx_get_data_addr(dimg.img, &dimg.bits_per_pixel,
&dimg.line_length, &dimg.endian);
draw_stats_bg(&dimg);
mlx_put_image_to_window(app->mlx, app->win, img.img, 0, 0);
}
typedef mlx_img_list_t t_img;
void draw_stats(t_app *app)
{
t_img *img;
img = mlx_new_image(app->mlx, STATS_W, STATS_H);
draw_stats_bg(img);
mlx_put_image_to_window(app->win, img, 0, 0);
}
typedef struct s_dimg {
void *img;
char *addr;
int bits_per_pixel;
int line_length;
int endian;
} t_dimg;
static void draw(t_dimg *img)
{
int *dpixel;
int x;
int i;
i = 0;
while (i < STATS_H * img->line_length)
{
dpixel = img->addr + i;
x = i % img->line_length / (img.bits_per_pixel / 8);
if (x < 10)
{
dpixel = ((int *)img->addr) + i;
*dpixel = GRAPH_BG;
}
i += (img.bits_per_pixel / 8);
}
}
typedef mlx_img_list_t t_img;
static void draw(t_img *img)
{
int *dpixel;
int x;
int i;
i = 0;
while (i < img->width * img->height)
{
x = i % img->width;
if (x < 10)
{
dpixel = ((int *)img->buffer) + i;
*dpixel = GRAPH_BG;
}
i++;
}
}