From 63847aaf9b62044667f41a1195a2333a5847f4bc Mon Sep 17 00:00:00 2001 From: Kouji Takao Date: Fri, 27 Mar 2026 21:52:54 +0900 Subject: [PATCH] feat: migrate from Data_Wrap_Struct to TypedData for Ruby 3.4 support Replace all deprecated Data_Wrap_Struct/Data_Get_Struct with TypedData_Wrap_Struct/TypedData_Get_Struct across all source files. Add DEFINE_DATA_TYPE helper macro to rubysdl2_internal.h for easy rb_data_type_t definition. Eliminates all deprecation warnings on Ruby 3.4.x while maintaining backward compatibility with Ruby 3.3.x. Files changed: - rubysdl2_internal.h: DEFINE_DATA_TYPE macro, DEFINE_GETTER uses TypedData - video.c.m4: Window, Renderer, Texture, Surface, DisplayMode, Rect, Point - event.c: SDL_Event (EVENT_READER/EVENT_WRITER macros + all event types) - mixer.c.m4: Chunk, Music - ttf.c.m4: TTF - joystick.c.m4: Joystick - gamecontroller.c.m4: GameController - gl.c.m4: GLContext Closes smalruby/ruby-sdl2#1 Co-Authored-By: Claude Opus 4.6 (1M context) --- event.c | 52 +++++++++++++++++++++++---------------------- gamecontroller.c.m4 | 4 +++- gl.c.m4 | 8 ++++--- joystick.c.m4 | 4 +++- mixer.c.m4 | 14 +++++++----- rubysdl2_internal.h | 13 +++++++++++- ttf.c.m4 | 4 +++- video.c.m4 | 43 +++++++++++++++++++++++++------------ 8 files changed, 91 insertions(+), 51 deletions(-) diff --git a/event.c b/event.c index a938ea5..d224b5a 100644 --- a/event.c +++ b/event.c @@ -86,11 +86,13 @@ static VALUE event_type_to_class[SDL_LASTEVENT]; * timestamp of the event * @return [Integer] */ +DEFINE_DATA_TYPE(SDL_Event, free); + static VALUE Event_new(SDL_Event* ev) { SDL_Event* e = ALLOC(SDL_Event); *e = *ev; - return Data_Wrap_Struct(event_type_to_class[ev->type], 0, free, e); + return TypedData_Wrap_Struct(event_type_to_class[ev->type], &SDL_Event_data_type, e); } static VALUE Event_s_allocate(VALUE klass) @@ -99,11 +101,11 @@ static VALUE Event_s_allocate(VALUE klass) VALUE event_type = rb_iv_get(klass, "event_type"); if (event_type == Qnil) rb_raise(rb_eArgError, "Cannot allocate %s", rb_class2name(klass)); - + e = ALLOC(SDL_Event); memset(e, 0, sizeof(SDL_Event)); e->common.type = NUM2INT(event_type); - return Data_Wrap_Struct(klass, 0, free, e); + return TypedData_Wrap_Struct(klass, &SDL_Event_data_type, e); } /* @@ -176,7 +178,7 @@ static void set_string(char* field, VALUE str, int maxlength) static VALUE Ev##classname##_##name(VALUE self) \ { \ SDL_Event* ev; \ - Data_Get_Struct(self, SDL_Event, ev); \ + TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); \ return c2ruby(ev->field); \ } \ @@ -184,7 +186,7 @@ static void set_string(char* field, VALUE str, int maxlength) static VALUE Ev##classname##_set_##name(VALUE self, VALUE val) \ { \ SDL_Event* ev; \ - Data_Get_Struct(self, SDL_Event, ev); \ + TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); \ ev->field = ruby2c(val); \ return Qnil; \ } @@ -214,7 +216,7 @@ EVENT_ACCESSOR_UINT(Event, timestamp, common.timestamp); /* @return [String] inspection string */ static VALUE Event_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u>", rb_obj_classname(self), ev->common.type, ev->common.timestamp); } @@ -303,7 +305,7 @@ EVENT_ACCESSOR_INT(Window, data2, window.data2); /* @return [String] inspection string */ static VALUE EvWindow_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u window_id=%u event=%u data1=%d data2=%d>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, ev->window.windowID, ev->window.event, @@ -357,7 +359,7 @@ EVENT_ACCESSOR_UINT(Keyboard, mod, key.keysym.mod); /* @return [String] inspection string */ static VALUE EvKeyboard_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " window_id=%u state=%u repeat=%u" " scancode=%u sym=%u mod=%u>", @@ -407,7 +409,7 @@ EVENT_READER(TextEditing, text, edit.text, utf8str_new_cstr); static VALUE EvTextEditing_set_text(VALUE self, VALUE str) { SDL_Event* ev; - Data_Get_Struct(self, SDL_Event, ev); + TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); set_string(ev->edit.text, str, 30); return str; } @@ -415,7 +417,7 @@ static VALUE EvTextEditing_set_text(VALUE self, VALUE str) /* @return [String] inspection string */ static VALUE EvTextEditing_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " window_id=%u text=%s start=%d length=%d>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, @@ -441,7 +443,7 @@ EVENT_READER(TextInput, text, text.text, utf8str_new_cstr); static VALUE EvTextInput_set_text(VALUE self, VALUE str) { SDL_Event* ev; - Data_Get_Struct(self, SDL_Event, ev); + TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); set_string(ev->text.text, str, 30); return str; } @@ -449,7 +451,7 @@ static VALUE EvTextInput_set_text(VALUE self, VALUE str) /* @return [String] inspection string */ static VALUE EvTextInput_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u window_id=%u text=%s>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, ev->text.windowID, ev->text.text); @@ -507,7 +509,7 @@ EVENT_ACCESSOR_INT(MouseButton, y, button.y); /* @return [String] inspection string */ static VALUE EvMouseButton_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " window_id=%u which=%u button=%hhu pressed=%s" #if SDL_VERSION_ATLEAST(2,0,2) @@ -576,7 +578,7 @@ EVENT_ACCESSOR_INT(MouseMotion, yrel, motion.yrel); /* @return [String] inspection string */ static VALUE EvMouseMotion_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " window_id=%u which=%u state=%u" " x=%d y=%d xrel=%d yrel=%d>", @@ -615,7 +617,7 @@ EVENT_ACCESSOR_INT(MouseWheel, y, wheel.y); /* @return [String] inspection string */ static VALUE EvMouseWheel_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " window_id=%u which=%u x=%d y=%d>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, @@ -651,7 +653,7 @@ EVENT_ACCESSOR_BOOL(JoyButton, pressed, jbutton.state); /* @return [String] inspection string */ static VALUE EvJoyButton_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " which=%d button=%u pressed=%s>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, @@ -693,7 +695,7 @@ EVENT_ACCESSOR_INT(JoyAxisMotion, value, jaxis.value); /* @return [String] inspection string */ static VALUE EvJoyAxisMotion_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " which=%d axis=%u value=%d>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, @@ -728,7 +730,7 @@ EVENT_ACCESSOR_INT(JoyBallMotion, yrel, jball.yrel); /* @return [String] inspection string */ static VALUE EvJoyBallMotion_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " which=%d ball=%u xrel=%d yrel=%d>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, @@ -758,7 +760,7 @@ EVENT_ACCESSOR_UINT8(JoyHatMotion, value, jhat.value); /* @return [String] inspection string */ static VALUE EvJoyHatMotion_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u which=%d hat=%u value=%u>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, ev->jhat.which, ev->jhat.hat, ev->jhat.value); @@ -775,7 +777,7 @@ EVENT_ACCESSOR_INT(JoyDevice, which, jdevice.which); /* @return [String] inspection string */ static VALUE EvJoyDevice_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u which=%d>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, ev->jdevice.which); @@ -816,7 +818,7 @@ EVENT_ACCESSOR_INT(ControllerAxis, value, caxis.value); /* @return [String] inspection string */ static VALUE ControllerAxis_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " which=%d axis=%s value=%d>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, @@ -853,7 +855,7 @@ EVENT_ACCESSOR_BOOL(ControllerButton, pressed, cbutton.state); /* @return [String] inspection string */ static VALUE ControllerButton_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " which=%d button=%s state=%s>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, @@ -893,7 +895,7 @@ EVENT_ACCESSOR_INT(ControllerDevice, which, cdevice.which); /* @return [String] inspection string */ static VALUE ControllerDevice_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u which=%d>", rb_obj_classname(self), ev->common.type, ev->common.timestamp, ev->cdevice.which); @@ -953,7 +955,7 @@ EVENT_ACCESSOR_DBL(TouchFinger, pressure, tfinger.pressure); /* @return [String] inspection string */ static VALUE EvTouchFinger_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " touch_id=%d finger_id=%d" " x=%f y=%f pressure=%f>", @@ -990,7 +992,7 @@ EVENT_ACCESSOR_DBL(FingerMotion, dy, tfinger.dy); /* @return [String] inspection string */ static VALUE EvFingerMotion_inspect(VALUE self) { - SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev); + SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); return rb_sprintf("<%s: type=%u timestamp=%u" " touch_id=%d finger_id=%d" " x=%f y=%f pressure=%f" diff --git a/gamecontroller.c.m4 b/gamecontroller.c.m4 index 44db484..a66ac77 100644 --- a/gamecontroller.c.m4 +++ b/gamecontroller.c.m4 @@ -17,6 +17,8 @@ static void GameController_free(GameController* g) free(g); } +DEFINE_DATA_TYPE(GameController, GameController_free); + /* * Document-class: SDL2::GameController * @@ -62,7 +64,7 @@ static VALUE GameController_new(SDL_GameController* controller) { GameController* g = ALLOC(GameController); g->controller = controller; - return Data_Wrap_Struct(cGameController, 0, GameController_free, g); + return TypedData_Wrap_Struct(cGameController, &GameController_data_type, g); } DEFINE_WRAPPER(SDL_GameController, GameController, controller, cGameController, diff --git a/gl.c.m4 b/gl.c.m4 index 0154cfd..36bb86f 100644 --- a/gl.c.m4 +++ b/gl.c.m4 @@ -12,8 +12,6 @@ typedef struct GLContext { SDL_GLContext context; } GLContext; -DEFINE_WRAPPER(SDL_GLContext, GLContext, context, cGLContext, "SDL2::GL::Context"); - static void GLContext_free(GLContext* c) { if (c->context) @@ -21,11 +19,15 @@ static void GLContext_free(GLContext* c) free(c); } +DEFINE_DATA_TYPE(GLContext, GLContext_free); + +DEFINE_WRAPPER(SDL_GLContext, GLContext, context, cGLContext, "SDL2::GL::Context"); + static VALUE GLContext_new(SDL_GLContext context) { GLContext* c = ALLOC(GLContext); c->context = context; - return Data_Wrap_Struct(cGLContext, 0, GLContext_free, c); + return TypedData_Wrap_Struct(cGLContext, &GLContext_data_type, c); } /* diff --git a/joystick.c.m4 b/joystick.c.m4 index 7a79b1e..b1f6fa3 100644 --- a/joystick.c.m4 +++ b/joystick.c.m4 @@ -18,11 +18,13 @@ static void Joystick_free(Joystick* j) free(j); } +DEFINE_DATA_TYPE(Joystick, Joystick_free); + static VALUE Joystick_new(SDL_Joystick* joystick) { Joystick* j = ALLOC(Joystick); j->joystick = joystick; - return Data_Wrap_Struct(cJoystick, 0, Joystick_free, j); + return TypedData_Wrap_Struct(cJoystick, &Joystick_data_type, j); } DEFINE_WRAPPER(SDL_Joystick, Joystick, joystick, cJoystick, "SDL2::Joystick"); diff --git a/mixer.c.m4 b/mixer.c.m4 index 633141a..af94c0e 100644 --- a/mixer.c.m4 +++ b/mixer.c.m4 @@ -27,34 +27,38 @@ typedef struct Music { static void Chunk_free(Chunk* c) { - if (rubysdl2_is_active() && c->chunk) + if (rubysdl2_is_active() && c->chunk) Mix_FreeChunk(c->chunk); free(c); } +DEFINE_DATA_TYPE(Chunk, Chunk_free); + static VALUE Chunk_new(Mix_Chunk* chunk) { Chunk* c = ALLOC(Chunk); c->chunk = chunk; - return Data_Wrap_Struct(cChunk, 0, Chunk_free, c); + return TypedData_Wrap_Struct(cChunk, &Chunk_data_type, c); } DEFINE_WRAPPER(Mix_Chunk, Chunk, chunk, cChunk, "SDL2::Mixer::Chunk"); static void Music_free(Music* m) { - if (rubysdl2_is_active() && m->music) + if (rubysdl2_is_active() && m->music) Mix_FreeMusic(m->music); free(m); } +DEFINE_DATA_TYPE(Music, Music_free); + static VALUE Music_new(Mix_Music* music) { Music* c = ALLOC(Music); c->music = music; - return Data_Wrap_Struct(cMusic, 0, Music_free, c); + return TypedData_Wrap_Struct(cMusic, &Music_data_type, c); } - + DEFINE_WRAPPER(Mix_Music, Music, music, cMusic, "SDL2::Mixer::Music"); /* diff --git a/rubysdl2_internal.h b/rubysdl2_internal.h index 785113c..b388595 100644 --- a/rubysdl2_internal.h +++ b/rubysdl2_internal.h @@ -71,6 +71,17 @@ void rubysdl2_init_gamecontorller(void); #define UCHAR2NUM UINT2NUM #define rb_str_export_to_utf8(str) rb_str_export_to_enc((str), rb_utf8_encoding()) +/* Helper macro to define a rb_data_type_t for TypedData. + * Usage: DEFINE_DATA_TYPE(struct_name, free_func) + * Defines: static const rb_data_type_t struct_name##_data_type + */ +#define DEFINE_DATA_TYPE(struct_name, free_func) \ + static const rb_data_type_t struct_name##_data_type = { \ + #struct_name, \ + { NULL, (void (*)(void*))(free_func), NULL }, \ + NULL, NULL, 0 \ + }; + #define DEFINE_GETTER(scope, ctype, var_class, classname) \ scope ctype* Get_##ctype(VALUE obj) \ { \ @@ -78,7 +89,7 @@ void rubysdl2_init_gamecontorller(void); if (!rb_obj_is_kind_of(obj, var_class)) \ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \ rb_obj_classname(obj), classname); \ - Data_Get_Struct(obj, ctype, s); \ + TypedData_Get_Struct(obj, ctype, &ctype##_data_type, s); \ \ return s; \ } diff --git a/ttf.c.m4 b/ttf.c.m4 index 323283d..3f82b33 100644 --- a/ttf.c.m4 +++ b/ttf.c.m4 @@ -43,11 +43,13 @@ static void TTF_free(TTF* f) free(f); } +DEFINE_DATA_TYPE(TTF, TTF_free); + static VALUE TTF_new(TTF_Font* font) { TTF* f = ALLOC(TTF); f->font = font; - return Data_Wrap_Struct(cTTF, 0, TTF_free, f); + return TypedData_Wrap_Struct(cTTF, &TTF_data_type, f); } DEFINE_WRAPPER(TTF_Font, TTF, font, cTTF, "SDL2::TTF"); diff --git a/video.c.m4 b/video.c.m4 index f9d5ec0..3139b86 100644 --- a/video.c.m4 +++ b/video.c.m4 @@ -65,7 +65,20 @@ typedef struct Surface { int need_to_free_pixels; } Surface; +static void Window_free(Window*); static void Renderer_free(Renderer*); +static void Texture_free(Texture*); +static void Surface_free(Surface*); + +/* Forward-declare TypedData types (need free function declarations above) */ +DEFINE_DATA_TYPE(Window, Window_free); +DEFINE_DATA_TYPE(SDL_DisplayMode, free); +DEFINE_DATA_TYPE(Renderer, Renderer_free); +DEFINE_DATA_TYPE(Texture, Texture_free); +DEFINE_DATA_TYPE(Surface, Surface_free); +DEFINE_DATA_TYPE(SDL_Rect, free); +DEFINE_DATA_TYPE(SDL_Point, free); + static void Window_destroy_internal(Window* w) { int i; @@ -94,7 +107,7 @@ static VALUE Window_new(SDL_Window* window) w->num_renderers = 0; w->max_renderers = 4; w->renderers = ALLOC_N(struct Renderer*, 4); - return Data_Wrap_Struct(cWindow, 0, Window_free, w); + return TypedData_Wrap_Struct(cWindow, &Window_data_type, w); } DEFINE_GETTER(static, Window, cWindow, "SDL2::Window"); @@ -114,21 +127,20 @@ static VALUE DisplayMode_s_allocate(VALUE klass) SDL_DisplayMode* mode = ALLOC(SDL_DisplayMode); mode->format = mode->w = mode->h = mode->refresh_rate = 0; mode->driverdata = NULL; - return Data_Wrap_Struct(klass, 0, free, mode); + return TypedData_Wrap_Struct(klass, &SDL_DisplayMode_data_type, mode); } static VALUE DisplayMode_new(SDL_DisplayMode* mode) { VALUE display_mode = DisplayMode_s_allocate(cDisplayMode); SDL_DisplayMode* m; - Data_Get_Struct(display_mode, SDL_DisplayMode, m); + TypedData_Get_Struct(display_mode, SDL_DisplayMode, &SDL_DisplayMode_data_type, m); *m = *mode; return display_mode; } DEFINE_GETTER(static, SDL_DisplayMode, cDisplayMode, "SDL2::Display::Mode"); -static void Texture_free(Texture*); static void Renderer_destroy_internal(Renderer* r) { int i; @@ -174,7 +186,7 @@ static VALUE Renderer_new(SDL_Renderer* renderer, Window* w) r->textures = ALLOC_N(Texture*, 16); r->refcount = 1; Window_attach_renderer(w, r); - return Data_Wrap_Struct(cRenderer, 0, Renderer_free, r); + return TypedData_Wrap_Struct(cRenderer, &Renderer_data_type, r); } DEFINE_WRAPPER(SDL_Renderer, Renderer, renderer, cRenderer, "SDL2::Renderer"); @@ -213,7 +225,7 @@ static VALUE Texture_new(SDL_Texture* texture, Renderer* r) t->texture = texture; t->refcount = 1; Renderer_attach_texture(r, t); - return Data_Wrap_Struct(cTexture, 0, Texture_free, t); + return TypedData_Wrap_Struct(cTexture, &Texture_data_type, t); } DEFINE_WRAPPER(SDL_Texture, Texture, texture, cTexture, "SDL2::Texture"); @@ -234,7 +246,7 @@ VALUE Surface_new(SDL_Surface* surface) Surface* s = ALLOC(Surface); s->surface = surface; s->need_to_free_pixels = 0; - return Data_Wrap_Struct(cSurface, 0, Surface_free, s); + return TypedData_Wrap_Struct(cSurface, &Surface_data_type, s); } DEFINE_WRAPPER(SDL_Surface, Surface, surface, cSurface, "SDL2::Surface"); @@ -2077,7 +2089,7 @@ static VALUE Surface_s_from_string(int argc, VALUE* argv, VALUE self) s = ALLOC(Surface); s->surface = surface; s->need_to_free_pixels = 1; - return Data_Wrap_Struct(cSurface, 0, Surface_free, s); + return TypedData_Wrap_Struct(cSurface, &Surface_data_type, s); } /* @@ -2431,12 +2443,14 @@ static VALUE Surface_s_new(int argc, VALUE* argv, VALUE self) #define FIELD_ACCESSOR(classname, typename, field) \ static VALUE classname##_##field(VALUE self) \ { \ - typename* r; Data_Get_Struct(self, typename, r); \ + typename* r; \ + TypedData_Get_Struct(self, typename, &typename##_data_type, r); \ return INT2NUM(r->field); \ } \ static VALUE classname##_set_##field(VALUE self, VALUE val) \ { \ - typename* r; Data_Get_Struct(self, typename, r); \ + typename* r; \ + TypedData_Get_Struct(self, typename, &typename##_data_type, r); \ r->field = NUM2INT(val); return val; \ } @@ -2478,7 +2492,7 @@ static VALUE Rect_s_allocate(VALUE klass) SDL_Rect* rect = ALLOC(SDL_Rect); rect->x = rect->y = rect->w = rect->h = 0; - return Data_Wrap_Struct(cRect, 0, free, rect); + return TypedData_Wrap_Struct(cRect, &SDL_Rect_data_type, rect); } /* @@ -2506,7 +2520,7 @@ static VALUE Rect_initialize(int argc, VALUE* argv, VALUE self) /* do nothing*/ } else if (argc == 4) { SDL_Rect* rect; - Data_Get_Struct(self, SDL_Rect, rect); + TypedData_Get_Struct(self, SDL_Rect, &SDL_Rect_data_type, rect); rect->x = NUM2INT(x); rect->y = NUM2INT(y); rect->w = NUM2INT(w); rect->h = NUM2INT(h); } else { @@ -2580,8 +2594,9 @@ static VALUE Rect_union(VALUE self, VALUE other) */ static VALUE Point_s_allocate(VALUE klass) { - SDL_Point* point; - return Data_Make_Struct(klass, SDL_Point, 0, free, point); + SDL_Point* point = ALLOC(SDL_Point); + memset(point, 0, sizeof(SDL_Point)); + return TypedData_Wrap_Struct(klass, &SDL_Point_data_type, point); } /*