Started project plugin in objective-c
parent
03802b459d
commit
c446f77f97
|
@ -61,6 +61,7 @@ moo/mooedit/gtksourceview/Makefile
|
|||
moo/mooedit/gtksourceview/upstream/Makefile
|
||||
moo/mooedit/plugins/Makefile
|
||||
moo/mooedit/plugins/ctags/Makefile
|
||||
moo/mooedit/plugins/project/Makefile
|
||||
moo/mooapp/Makefile
|
||||
moo/mooapp/smclient/Makefile
|
||||
moo/moopython/Makefile
|
||||
|
|
|
@ -14,8 +14,14 @@ AC_DEFUN_ONCE([MOO_AC_OBJC],[
|
|||
if test "x$MOO_USE_OBJC" != "xno"; then
|
||||
_MOO_OBJC_CHECK([
|
||||
MOO_USE_OBJC=yes
|
||||
MOO_OBJC_LIBS="$MOO_FFI_LIBS $MOO_OBJC_LIBS"
|
||||
AC_DEFINE(MOO_USE_OBJC, 1, [Use Objective-C.])
|
||||
AC_MSG_NOTICE([Objective-C flags: $MOO_OBJCFLAGS $MOO_OBJC_LIBS])
|
||||
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_OBJC
|
||||
AC_CHECK_SIZEOF(BOOL,,[#include <objc/objc.h>])
|
||||
AC_LANG_RESTORE
|
||||
],[
|
||||
MOO_USE_OBJC=no
|
||||
MOO_OBJCFLAGS=
|
||||
|
@ -86,7 +92,7 @@ AC_DEFUN([_MOO_OBJC_CHECK_RUNTIME],[
|
|||
|
||||
AC_LANG_SAVE
|
||||
AC_LANG([Objective C])
|
||||
save_LIBS=$LIBS
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="-lobjc $LIBS"
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM(
|
||||
|
@ -117,15 +123,42 @@ AC_DEFUN([_MOO_OBJC_CHECK_RUNTIME],[
|
|||
AC_LANG_RESTORE
|
||||
])
|
||||
|
||||
AC_DEFUN([_MOO_CHECK_FFI],[
|
||||
AC_MSG_CHECKING(FFI library)
|
||||
|
||||
MOO_FFI_LIBS="-lffi"
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $MOO_FFI_LIBS"
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM(
|
||||
[#include <ffi.h>],
|
||||
[ffi_call (0, 0, 0, 0);])],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
$1
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
$2
|
||||
])
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
])
|
||||
|
||||
AC_DEFUN([_MOO_OBJC_CHECK],[
|
||||
MOO_OBJC_LIBS=
|
||||
MOO_OBJCFLAGS=
|
||||
|
||||
_MOO_OBJC_CHECK_RUNTIME([
|
||||
MOO_OBJC_USE_FOUNDATION=no
|
||||
dnl _MOO_OBJC_CHECK_FOUNDATION
|
||||
$1
|
||||
_MOO_CHECK_FFI([
|
||||
_MOO_OBJC_CHECK_RUNTIME([
|
||||
MOO_OBJC_USE_FOUNDATION=no
|
||||
dnl _MOO_OBJC_CHECK_FOUNDATION
|
||||
$1
|
||||
],[
|
||||
:
|
||||
$2
|
||||
])
|
||||
],[
|
||||
:
|
||||
$2
|
||||
])
|
||||
])
|
||||
|
|
26
moo.kdevelop
26
moo.kdevelop
|
@ -26,13 +26,13 @@
|
|||
</ignoreparts>
|
||||
<projectdirectory>.</projectdirectory>
|
||||
<absoluteprojectpath>false</absoluteprojectpath>
|
||||
<description></description>
|
||||
<description/>
|
||||
<secondaryLanguages>
|
||||
<language>C</language>
|
||||
</secondaryLanguages>
|
||||
<versioncontrol>kdevsubversion</versioncontrol>
|
||||
<projectname>moo</projectname>
|
||||
<defaultencoding></defaultencoding>
|
||||
<defaultencoding/>
|
||||
</general>
|
||||
<kdevautoproject>
|
||||
<general>
|
||||
|
@ -253,10 +253,10 @@
|
|||
<breakonloadinglibs>true</breakonloadinglibs>
|
||||
<separatetty>false</separatetty>
|
||||
<floatingtoolbar>true</floatingtoolbar>
|
||||
<gdbpath></gdbpath>
|
||||
<configGdbScript></configGdbScript>
|
||||
<runShellScript></runShellScript>
|
||||
<runGdbScript></runGdbScript>
|
||||
<gdbpath/>
|
||||
<configGdbScript/>
|
||||
<runShellScript/>
|
||||
<runGdbScript/>
|
||||
</general>
|
||||
<display>
|
||||
<staticmembers>true</staticmembers>
|
||||
|
@ -318,16 +318,16 @@
|
|||
</kdevdoctreeview>
|
||||
<kdevfilecreate>
|
||||
<filetypes>
|
||||
<type icon="source" ext="g" create="template" name="GAP source" >
|
||||
<type icon="source" ext="g" name="GAP source" create="template" >
|
||||
<descr>A new empty GAP source file</descr>
|
||||
</type>
|
||||
<type icon="source_cpp" ext="cpp" create="template" name="C++ Source" >
|
||||
<type icon="source_cpp" ext="cpp" name="C++ Source" create="template" >
|
||||
<descr>A new empty C++ file.</descr>
|
||||
</type>
|
||||
<type icon="source_h" ext="h" create="template" name="C/C++ Header" >
|
||||
<type icon="source_h" ext="h" name="C/C++ Header" create="template" >
|
||||
<descr>A new empty header file for C/C++.</descr>
|
||||
</type>
|
||||
<type icon="source_c" ext="c" create="template" name="C Source" >
|
||||
<type icon="source_c" ext="c" name="C Source" create="template" >
|
||||
<descr>A new empty C file.</descr>
|
||||
</type>
|
||||
</filetypes>
|
||||
|
@ -366,10 +366,12 @@
|
|||
<usePermanentCaching>true</usePermanentCaching>
|
||||
<alwaysIncludeNamespaces>false</alwaysIncludeNamespaces>
|
||||
<includePaths>.;</includePaths>
|
||||
<parseMissingHeadersExperimental>false</parseMissingHeadersExperimental>
|
||||
<resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental>
|
||||
</codecompletion>
|
||||
<references/>
|
||||
<creategettersetter>
|
||||
<prefixGet></prefixGet>
|
||||
<prefixGet/>
|
||||
<prefixSet>set</prefixSet>
|
||||
<prefixVariable>m_,_</prefixVariable>
|
||||
<parameterName>theValue</parameterName>
|
||||
|
@ -382,7 +384,7 @@
|
|||
<root>/usr/share/qt3</root>
|
||||
<includestyle>3</includestyle>
|
||||
<designerintegration>EmbeddedKDevDesigner</designerintegration>
|
||||
<qmake>/usr/bin/qmake-qt3</qmake>
|
||||
<qmake>/usr/bin/qmake</qmake>
|
||||
<designer>/usr/bin/designer-qt3</designer>
|
||||
<designerpluginpaths/>
|
||||
</qt>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
DIST_SUBDIRS = ctags
|
||||
DIST_SUBDIRS = ctags project
|
||||
SUBDIRS =
|
||||
|
||||
if MOO_BUILD_CTAGS
|
||||
SUBDIRS += ctags
|
||||
endif
|
||||
if MOO_USE_OBJC
|
||||
SUBDIRS += project
|
||||
endif
|
||||
|
||||
noinst_LTLIBRARIES =
|
||||
EXTRA_DIST =
|
||||
|
@ -54,6 +57,9 @@ libmooeditplugins_la_LIBADD = libfileselector.la
|
|||
if MOO_BUILD_CTAGS
|
||||
libmooeditplugins_la_LIBADD += ctags/libctags.la
|
||||
endif
|
||||
if MOO_USE_OBJC
|
||||
libmooeditplugins_la_LIBADD += project/libproject.la
|
||||
endif
|
||||
|
||||
libmooeditplugins_la_SOURCES = \
|
||||
mooeditplugins.h
|
||||
|
|
|
@ -26,6 +26,7 @@ gboolean _moo_ctags_plugin_init (void);
|
|||
gboolean _moo_active_strings_plugin_init (void);
|
||||
gboolean _moo_completion_plugin_init (void);
|
||||
gboolean _moo_file_selector_plugin_init (void);
|
||||
gboolean _moo_project_plugin_init (void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
AM_CFLAGS = \
|
||||
-I../.. \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_builddir)/moo \
|
||||
$(MOO_CFLAGS) \
|
||||
$(MOO_DEBUG_CFLAGS)
|
||||
AM_OBJCFLAGS = $(AM_CFLAGS) $(MOO_OBJCFLAGS)
|
||||
|
||||
noinst_LTLIBRARIES = libproject.la
|
||||
|
||||
# EXTRA_DIST += \
|
||||
# moofileselector.glade \
|
||||
# moofileselector-prefs.glade
|
||||
|
||||
libproject_la_SOURCES = \
|
||||
project-plugin.m \
|
||||
manager.h \
|
||||
manager.m \
|
||||
mpconfig.h \
|
||||
mpconfig.m \
|
||||
mpfile.h \
|
||||
mpfile.m \
|
||||
project.h \
|
||||
project.m
|
||||
|
||||
@MOO_GLADE_RULE@
|
||||
# nodist_libfileselector_la_SOURCES = \
|
||||
# moofileselector-glade.h \
|
||||
# moofileselector-prefs-glade.h
|
||||
|
||||
# BUILT_SOURCES += \
|
||||
# moofileselector-glade.h \
|
||||
# moofileselector-prefs-glade.h
|
||||
# CLEANFILES += \
|
||||
# moofileselector-glade.h \
|
||||
# moofileselector-prefs-glade.h
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef MOO_PROJECT_MANAGER_H
|
||||
#define MOO_PROJECT_MANAGER_H
|
||||
|
||||
#include <mooutils/moocobject.h>
|
||||
#include <mooedit/mooeditwindow.h>
|
||||
|
||||
@class MPProject;
|
||||
|
||||
@interface MPManager : MooCObject
|
||||
{
|
||||
@private
|
||||
MPProject *project;
|
||||
MooEditWindow *window;
|
||||
char *filename;
|
||||
}
|
||||
|
||||
- (void) deinit;
|
||||
- (void) attachWindow: (MooEditWindow*) window;
|
||||
- (void) detachWindow: (MooEditWindow*) window;
|
||||
|
||||
- (void) openProject: (CSTR) file;
|
||||
- (void) closeProject;
|
||||
- (void) projectOptions;
|
||||
@end
|
||||
|
||||
#endif // MOO_PROJECT_MANAGER_H
|
||||
// -*- objc -*-
|
|
@ -0,0 +1,146 @@
|
|||
#include "manager.h"
|
||||
#include "project.h"
|
||||
#include "project-plugin.h"
|
||||
#include "mpfile.h"
|
||||
#include <mooedit/mooeditor.h>
|
||||
#include <mooutils/moofiledialog.h>
|
||||
|
||||
|
||||
@interface MPManager(Private)
|
||||
- (void) doOpenProject: (CSTR) file
|
||||
error: (GError**) error;
|
||||
- (void) doCloseProject;
|
||||
@end
|
||||
|
||||
|
||||
@implementation MPManager
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
g_free (filename);
|
||||
filename = NULL;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) deinit
|
||||
{
|
||||
if (project)
|
||||
[self doCloseProject];
|
||||
}
|
||||
|
||||
- (void) attachWindow: (MooEditWindow*) win
|
||||
{
|
||||
MooEditor *editor = moo_editor_instance ();
|
||||
GtkAction *action;
|
||||
|
||||
window = win;
|
||||
|
||||
moo_editor_set_app_name (editor, project ? [project name] : NULL);
|
||||
moo_objc_signal_connect (window, "close", self, @selector(onCloseWindow));
|
||||
|
||||
if ((action = moo_window_get_action (MOO_WINDOW (window), "CloseProject")))
|
||||
g_object_set (action, "sensitive", project != NULL, NULL);
|
||||
if ((action = moo_window_get_action (MOO_WINDOW (window), "ProjectOptions")))
|
||||
g_object_set (action, "visible", project != NULL, NULL);
|
||||
|
||||
if (!project)
|
||||
{
|
||||
const char *path = moo_prefs_get_string ("Plugins/Project/last");
|
||||
|
||||
if (path && g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
[self doOpenProject:path error:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) detachWindow: (MooEditWindow*) win
|
||||
{
|
||||
g_return_if_fail (win == window);
|
||||
window = NULL;
|
||||
}
|
||||
|
||||
- (void) openProject: (CSTR) file
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
g_free (filename);
|
||||
filename = g_strdup (file);
|
||||
}
|
||||
|
||||
if (!file)
|
||||
file = moo_file_dialogp (window ? GTK_WIDGET (window) : NULL,
|
||||
MOO_FILE_DIALOG_OPEN,
|
||||
NULL, "Open Project",
|
||||
"Plugins/Project/last_dir", NULL);
|
||||
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
if (project)
|
||||
[self closeProject];
|
||||
if (project)
|
||||
return;
|
||||
|
||||
[self doOpenProject:file error:NULL];
|
||||
}
|
||||
|
||||
- (void) closeProject
|
||||
{
|
||||
}
|
||||
|
||||
- (void) projectOptions
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPManager(Private)
|
||||
|
||||
- (void) initProjectTypes
|
||||
{
|
||||
}
|
||||
|
||||
- (void) deinitProjectTypes
|
||||
{
|
||||
}
|
||||
|
||||
- (void) doOpenProject: (CSTR) file
|
||||
error: (GError**) error
|
||||
{
|
||||
g_return_if_fail (project == nil);
|
||||
g_return_if_fail (file != NULL);
|
||||
g_return_if_fail (!error || !*error);
|
||||
|
||||
MPFile *pf = [MPFile open:file error:error];
|
||||
if (!pf)
|
||||
return;
|
||||
|
||||
if ((project = [MPProject loadFile:pf error:error]))
|
||||
{
|
||||
moo_editor_set_app_name (moo_editor_instance (), [project name]);
|
||||
moo_history_list_add_filename (moo_history_list_get (MP_RECENT_LIST_ID), file);
|
||||
moo_prefs_set_filename ("Plugins/Project/last", file);
|
||||
|
||||
if (window)
|
||||
{
|
||||
GtkAction *close = moo_window_get_action (MOO_WINDOW (window), MP_ACTION_CLOSE_PROJECT);
|
||||
GtkAction *options = moo_window_get_action (MOO_WINDOW (window), MP_ACTION_PROJECT_OPTIONS);
|
||||
if (close)
|
||||
g_object_set (close, "sensitive", TRUE, NULL);
|
||||
if (options)
|
||||
g_object_set (options, "visible", TRUE, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_history_list_remove (moo_history_list_get (MP_RECENT_LIST_ID), file);
|
||||
}
|
||||
|
||||
[pf release];
|
||||
}
|
||||
|
||||
// - (void) doCloseProject;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// -*- objc -*-
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef MOO_PROJECT_CONFIG_H
|
||||
#define MOO_PROJECT_CONFIG_H
|
||||
|
||||
#include <mooutils/moocobject.h>
|
||||
|
||||
|
||||
@interface MPConfig : MooCObject
|
||||
@end
|
||||
|
||||
|
||||
#endif // MOO_PROJECT_CONFIG_H
|
||||
// -*- objc -*-
|
|
@ -0,0 +1,3 @@
|
|||
#include "mpconfig.h"
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef MOO_PROJECT_FILE_H
|
||||
#define MOO_PROJECT_FILE_H
|
||||
|
||||
#import <mooutils/moocobject.h>
|
||||
#import <mooutils/moomarkup.h>
|
||||
|
||||
#define MP_FILE_ERROR (_mp_file_error_quark ())
|
||||
|
||||
@interface MPFile : MooCObject
|
||||
{
|
||||
@private
|
||||
char *filename;
|
||||
char *project_name;
|
||||
char *project_type;
|
||||
MooMarkupDoc *xml;
|
||||
}
|
||||
|
||||
+ (id) open: (CSTR) filename
|
||||
error: (GError**) error;
|
||||
|
||||
- (CSTR) type;
|
||||
- (CSTR) name;
|
||||
|
||||
@end
|
||||
|
||||
GQuark _mp_file_error_quark (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* MOO_PROJECT_FILE_H */
|
||||
// -*- objc -*-
|
|
@ -0,0 +1,112 @@
|
|||
#import "mpfile.h"
|
||||
|
||||
#define MP_FILE_VERSION "2.0"
|
||||
|
||||
@implementation MPFile
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
project_type = NULL;
|
||||
project_name = NULL;
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
g_free (filename);
|
||||
g_free (project_type);
|
||||
g_free (project_name);
|
||||
if (xml)
|
||||
moo_markup_doc_unref (xml);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL) _open: (CSTR) filename_
|
||||
error: (GError**) error
|
||||
{
|
||||
MooMarkupNode *root;
|
||||
const char *version, *type, *name;
|
||||
|
||||
g_return_val_if_fail (filename_ != NULL, NO);
|
||||
g_return_val_if_fail (filename == NULL, NO);
|
||||
|
||||
if (!(xml = moo_markup_parse_file (filename_, error)))
|
||||
return NO;
|
||||
|
||||
if (!(root = moo_markup_get_root_element (xml, "medit-project")))
|
||||
{
|
||||
g_set_error (error, MP_FILE_ERROR, 0,
|
||||
"malformed project file");
|
||||
return NO;
|
||||
}
|
||||
|
||||
version = moo_markup_get_prop (root, "version");
|
||||
if (!version || strcmp (version, MP_FILE_VERSION) != 0)
|
||||
{
|
||||
g_set_error (error, MP_FILE_ERROR, 0,
|
||||
"invalid project version %s",
|
||||
version ? version : "<null>");
|
||||
return NO;
|
||||
}
|
||||
|
||||
type = moo_markup_get_prop (root, "type");
|
||||
if (!type || !type[0])
|
||||
{
|
||||
g_set_error (error, MP_FILE_ERROR, 0,
|
||||
"project type missing");
|
||||
return NO;
|
||||
}
|
||||
|
||||
name = moo_markup_get_prop (root, "name");
|
||||
if (!name || !name[0])
|
||||
{
|
||||
g_set_error (error, MP_FILE_ERROR, 0,
|
||||
"project name missing");
|
||||
return NO;
|
||||
}
|
||||
|
||||
filename = g_strdup (filename_);
|
||||
project_name = g_strdup (name);
|
||||
project_type = g_strdup (type);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (id) open: (CSTR) filename
|
||||
error: (GError**) error
|
||||
{
|
||||
MPFile *file = [[self alloc] init];
|
||||
|
||||
if (file && [file _open:filename error:error])
|
||||
return file;
|
||||
|
||||
if (file)
|
||||
[file release];
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
- (CSTR) type
|
||||
{
|
||||
return project_type;
|
||||
}
|
||||
|
||||
- (CSTR) name
|
||||
{
|
||||
return project_name;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
GQuark
|
||||
_mp_file_error_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("moo-project-file-error");
|
||||
}
|
||||
|
||||
// -*- objc -*-
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* project-plugin.h
|
||||
*
|
||||
* Copyright (C) 2004-2007 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef MOO_PROJECT_PLUGIN_H
|
||||
#define MOO_PROJECT_PLUGIN_H
|
||||
|
||||
#define PROJECT_PLUGIN_ID "ProjectMgr"
|
||||
#define MP_RECENT_LIST_ID "ProjectManager"
|
||||
|
||||
#define MP_ACTION_CLOSE_PROJECT "CloseProject"
|
||||
#define MP_ACTION_OPEN_PROJECT "OpenProject"
|
||||
#define MP_ACTION_PROJECT_OPTIONS "ProjectOptions"
|
||||
|
||||
#endif /* MOO_PROJECT_PLUGIN_H */
|
||||
/* -*- objc -*- */
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* project-plugin.m
|
||||
*
|
||||
* Copyright (C) 2004-2007 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "mooedit/mooplugin-macro.h"
|
||||
#include "mooedit/plugins/mooeditplugins.h"
|
||||
#include "mooedit/mooeditwindow.h"
|
||||
#include "mooutils/moostock.h"
|
||||
#include "mooutils/moomenuaction.h"
|
||||
#include "mooutils/moomarshals.h"
|
||||
#include "manager.h"
|
||||
#include "project-plugin.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef struct {
|
||||
MooPlugin parent;
|
||||
guint ui_merge_id;
|
||||
MooHistoryList *recent_list;
|
||||
MPManager *pm;
|
||||
char *project_to_open;
|
||||
} ProjectPlugin;
|
||||
|
||||
#define PROJECT_PLUGIN(mpl) ((ProjectPlugin*)mpl)
|
||||
|
||||
|
||||
static void
|
||||
project_plugin_attach_window (MooPlugin *mplugin,
|
||||
MooEditWindow *window)
|
||||
{
|
||||
ProjectPlugin *plugin = PROJECT_PLUGIN (mplugin);
|
||||
|
||||
g_return_if_fail (plugin->pm != nil);
|
||||
|
||||
moo_objc_push_autorelease_pool ();
|
||||
[plugin->pm attachWindow: window];
|
||||
moo_objc_pop_autorelease_pool ();
|
||||
}
|
||||
|
||||
static void
|
||||
project_plugin_detach_window (MooPlugin *mplugin,
|
||||
MooEditWindow *window)
|
||||
{
|
||||
ProjectPlugin *plugin = PROJECT_PLUGIN (mplugin);
|
||||
|
||||
g_return_if_fail (plugin->pm != nil);
|
||||
|
||||
moo_objc_push_autorelease_pool ();
|
||||
[plugin->pm detachWindow: window];
|
||||
moo_objc_pop_autorelease_pool ();
|
||||
}
|
||||
|
||||
static void
|
||||
open_project_cb (void)
|
||||
{
|
||||
ProjectPlugin *plugin = moo_plugin_lookup (PROJECT_PLUGIN_ID);
|
||||
g_return_if_fail (plugin && plugin->pm);
|
||||
|
||||
moo_objc_push_autorelease_pool ();
|
||||
[plugin->pm openProject:NULL];
|
||||
moo_objc_pop_autorelease_pool ();
|
||||
}
|
||||
|
||||
static void
|
||||
close_project_cb (void)
|
||||
{
|
||||
ProjectPlugin *plugin = moo_plugin_lookup (PROJECT_PLUGIN_ID);
|
||||
g_return_if_fail (plugin && plugin->pm);
|
||||
|
||||
moo_objc_push_autorelease_pool ();
|
||||
[plugin->pm closeProject];
|
||||
moo_objc_pop_autorelease_pool ();
|
||||
}
|
||||
|
||||
static void
|
||||
project_options_cb (void)
|
||||
{
|
||||
ProjectPlugin *plugin = moo_plugin_lookup (PROJECT_PLUGIN_ID);
|
||||
g_return_if_fail (plugin && plugin->pm);
|
||||
|
||||
moo_objc_push_autorelease_pool ();
|
||||
[plugin->pm projectOptions];
|
||||
moo_objc_pop_autorelease_pool ();
|
||||
}
|
||||
|
||||
static GtkAction *
|
||||
create_recent_list_action (G_GNUC_UNUSED MooWindow *window,
|
||||
ProjectPlugin *plugin)
|
||||
{
|
||||
GtkAction *action;
|
||||
|
||||
action = moo_menu_action_new ("OpenRecentProject", "Open Recent Project");
|
||||
g_object_set (action, "display-name", "Open Recent Project", NULL);
|
||||
moo_menu_action_set_mgr (MOO_MENU_ACTION (action),
|
||||
moo_history_list_get_menu_mgr (plugin->recent_list));
|
||||
moo_bind_bool_property (action, "sensitive", plugin->recent_list, "empty", TRUE);
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
static void
|
||||
recent_item_activated (G_GNUC_UNUSED MooHistoryList *list,
|
||||
MooHistoryItem *item,
|
||||
G_GNUC_UNUSED gpointer menu_data,
|
||||
ProjectPlugin *plugin)
|
||||
{
|
||||
[plugin->pm openProject:item->data];
|
||||
}
|
||||
|
||||
static void
|
||||
meth_open_project (ProjectPlugin *plugin,
|
||||
const char *filename)
|
||||
{
|
||||
g_return_if_fail (filename != NULL);
|
||||
|
||||
if (plugin->pm)
|
||||
{
|
||||
[plugin->pm openProject:filename];
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (plugin->project_to_open);
|
||||
plugin->project_to_open = g_strdup (filename);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
project_plugin_init (ProjectPlugin *plugin)
|
||||
{
|
||||
MooEditor *editor;
|
||||
MooWindowClass *klass;
|
||||
MooUIXML *xml;
|
||||
|
||||
moo_objc_push_autorelease_pool ();
|
||||
|
||||
if (!(plugin->pm = [[MPManager alloc] init]))
|
||||
{
|
||||
moo_objc_pop_autorelease_pool ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
editor = moo_editor_instance ();
|
||||
g_object_set (editor, "allow-empty-window", TRUE, "single-window", TRUE, NULL);
|
||||
|
||||
klass = g_type_class_peek (MOO_TYPE_EDIT_WINDOW);
|
||||
moo_window_class_new_action (klass, "OpenProject", NULL,
|
||||
"display-name", "Open Project",
|
||||
"label", "Open Project",
|
||||
"stock-id", MOO_STOCK_OPEN_PROJECT,
|
||||
"closure-callback", open_project_cb,
|
||||
NULL);
|
||||
moo_window_class_new_action (klass, "ProjectOptions", NULL,
|
||||
"display-name", "Project _Options",
|
||||
"label", "Project Options",
|
||||
"stock-id", MOO_STOCK_PROJECT_OPTIONS,
|
||||
"closure-callback", project_options_cb,
|
||||
NULL);
|
||||
moo_window_class_new_action (klass, "CloseProject", NULL,
|
||||
"display-name", "Close Project",
|
||||
"label", "Close Project",
|
||||
"stock-id", MOO_STOCK_CLOSE_PROJECT,
|
||||
"closure-callback", close_project_cb,
|
||||
NULL);
|
||||
|
||||
plugin->recent_list = moo_history_list_new (MP_RECENT_LIST_ID);
|
||||
g_signal_connect (plugin->recent_list, "activate-item",
|
||||
G_CALLBACK (recent_item_activated), plugin);
|
||||
moo_window_class_new_action_custom (klass, "OpenRecentProject", NULL,
|
||||
(MooWindowActionFunc) create_recent_list_action,
|
||||
plugin, NULL);
|
||||
|
||||
xml = moo_editor_get_ui_xml (editor);
|
||||
plugin->ui_merge_id = moo_ui_xml_new_merge_id (xml);
|
||||
moo_ui_xml_insert_markup_after (xml, plugin->ui_merge_id,
|
||||
"Editor/Menubar", "View",
|
||||
"<item name=\"Project\" _label=\"_Project\">"
|
||||
" <item action=\"OpenProject\"/>"
|
||||
" <item action=\"OpenRecentProject\"/>"
|
||||
" <separator/>"
|
||||
" <item action=\"ProjectOptions\"/>"
|
||||
" <separator/>"
|
||||
" <item action=\"CloseProject\"/>"
|
||||
" <separator/>"
|
||||
"</item>");
|
||||
|
||||
if (plugin->project_to_open)
|
||||
{
|
||||
[plugin->pm openProject:plugin->project_to_open];
|
||||
g_free (plugin->project_to_open);
|
||||
plugin->project_to_open = NULL;
|
||||
}
|
||||
|
||||
moo_objc_pop_autorelease_pool ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
project_plugin_deinit (ProjectPlugin *plugin)
|
||||
{
|
||||
MooWindowClass *klass = g_type_class_peek (MOO_TYPE_EDIT_WINDOW);
|
||||
|
||||
moo_window_class_remove_action (klass, "OpenProject");
|
||||
moo_window_class_remove_action (klass, "CloseProject");
|
||||
moo_window_class_remove_action (klass, "ProjectOptions");
|
||||
moo_window_class_remove_action (klass, "OpenRecentProject");
|
||||
|
||||
if (plugin->ui_merge_id)
|
||||
{
|
||||
MooEditor *editor = moo_editor_instance ();
|
||||
MooUIXML *xml = moo_editor_get_ui_xml (editor);
|
||||
moo_ui_xml_remove_ui (xml, plugin->ui_merge_id);
|
||||
plugin->ui_merge_id = 0;
|
||||
}
|
||||
|
||||
if (plugin->recent_list)
|
||||
g_object_unref (plugin->recent_list);
|
||||
plugin->recent_list = NULL;
|
||||
|
||||
if (plugin->pm)
|
||||
{
|
||||
moo_objc_push_autorelease_pool ();
|
||||
|
||||
[plugin->pm deinit];
|
||||
[plugin->pm release];
|
||||
plugin->pm = nil;
|
||||
|
||||
moo_objc_pop_autorelease_pool ();
|
||||
}
|
||||
|
||||
g_free (plugin->project_to_open);
|
||||
plugin->project_to_open = NULL;
|
||||
}
|
||||
|
||||
|
||||
MOO_PLUGIN_DEFINE_INFO (project, "Project", "Project manager",
|
||||
"Yevgen Muntyan <muntyan@tamu.edu>",
|
||||
MOO_VERSION, NULL)
|
||||
MOO_PLUGIN_DEFINE_FULL (Project, project,
|
||||
project_plugin_attach_window, project_plugin_detach_window,
|
||||
NULL, NULL, NULL, 0, 0)
|
||||
|
||||
gboolean
|
||||
_moo_project_plugin_init (void)
|
||||
{
|
||||
MooPluginParams params = {TRUE, TRUE};
|
||||
|
||||
if (!moo_plugin_register (PROJECT_PLUGIN_ID,
|
||||
project_plugin_get_type (),
|
||||
&project_plugin_info,
|
||||
¶ms))
|
||||
return FALSE;
|
||||
|
||||
moo_plugin_method_new ("open-project", project_plugin_get_type (),
|
||||
G_CALLBACK (meth_open_project),
|
||||
_moo_marshal_VOID__STRING,
|
||||
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef MOO_PROJECT_H
|
||||
#define MOO_PROJECT_H
|
||||
|
||||
#include <mooutils/moocobject.h>
|
||||
#include <mooedit/mooeditwindow.h>
|
||||
#include "mpfile.h"
|
||||
|
||||
|
||||
@interface MPProject : MooCObject
|
||||
{
|
||||
@private
|
||||
}
|
||||
|
||||
+ (id) loadFile: (MPFile*) pf
|
||||
error: (GError**) error;
|
||||
|
||||
- (BOOL) loadFile: (MPFile*) pf
|
||||
error: (GError**) error;
|
||||
|
||||
- (CSTR) name;
|
||||
|
||||
+ (void) registerProjectType: (CSTR) name;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif // MOO_PROJECT_H
|
||||
// -*- objc -*-
|
|
@ -0,0 +1,67 @@
|
|||
#include "project.h"
|
||||
#include <mooutils/mooutils-debug.h>
|
||||
|
||||
|
||||
static GHashTable *registered_types;
|
||||
|
||||
static void
|
||||
init_types (void)
|
||||
{
|
||||
if (!registered_types)
|
||||
registered_types = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
}
|
||||
|
||||
@implementation MPProject
|
||||
|
||||
+ (void) registerProjectType: (CSTR) name
|
||||
{
|
||||
Class old_class;
|
||||
|
||||
init_types ();
|
||||
|
||||
old_class = g_hash_table_lookup (registered_types, name);
|
||||
if (old_class != Nil && old_class != self)
|
||||
_moo_message ("%s: re-registering project type %s", G_STRLOC, name);
|
||||
|
||||
g_hash_table_insert (registered_types, g_strdup (name), self);
|
||||
}
|
||||
|
||||
+ (id) loadFile: (MPFile*) pf
|
||||
error: (GError**) error
|
||||
{
|
||||
const char *project_type;
|
||||
Class project_class;
|
||||
MPProject *project;
|
||||
|
||||
init_types ();
|
||||
|
||||
project_type = [pf type];
|
||||
project_class = g_hash_table_lookup (registered_types, project_type);
|
||||
if (!project_class)
|
||||
{
|
||||
g_set_error (error, MP_FILE_ERROR, 0,
|
||||
"unknown project type '%s'",
|
||||
project_type);
|
||||
return nil;
|
||||
}
|
||||
|
||||
project = [[project_class alloc] init];
|
||||
if (project && [project loadFile:pf error:error])
|
||||
return project;
|
||||
|
||||
[project release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL) loadFile: (MPFile*) pf
|
||||
error: (GError**) error
|
||||
{
|
||||
MOO_UNUSED_VAR (pf);
|
||||
MOO_UNUSED_VAR (error);
|
||||
g_return_val_if_reached (NO);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// -*- objc -*-
|
|
@ -132,8 +132,11 @@ mooobjc.lo: mooutils-fli.lo
|
|||
moopython.lo: mooutils-fli.lo
|
||||
|
||||
objc_sources = \
|
||||
moocobject-private.h \
|
||||
moocobject.h \
|
||||
moocobject.m
|
||||
moocobject.m \
|
||||
mooobjcmarshal.h \
|
||||
mooobjcmarshal.m
|
||||
|
||||
if MOO_USE_OBJC
|
||||
mooutils_sources += $(objc_sources)
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* moocobject-private.h
|
||||
*
|
||||
* Copyright (C) 2007 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef MOO_COBJECT_PRIVATE_H
|
||||
#define MOO_COBJECT_PRIVATE_H
|
||||
|
||||
#import "moocobject.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#ifndef MOO_OBJC_USE_FOUNDATION
|
||||
|
||||
@interface MooAutoreleasePool : MooCObject
|
||||
{
|
||||
@private
|
||||
MooAutoreleasePool *parent;
|
||||
MooAutoreleasePool *child;
|
||||
GSList *objects;
|
||||
}
|
||||
|
||||
+ (void) addObject: (id)anObj;
|
||||
|
||||
- (void) addObject: (id)anObj;
|
||||
- (void) emptyPool;
|
||||
@end
|
||||
|
||||
#define NSAutoreleasePool MooAutoreleasePool
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* MOO_COBJECT_PRIVATE_H */
|
||||
/* -*- objc -*- */
|
|
@ -62,6 +62,12 @@ void moo_objc_push_autorelease_pool (void);
|
|||
void moo_objc_pop_autorelease_pool (void);
|
||||
|
||||
|
||||
gulong moo_objc_signal_connect (gpointer instance,
|
||||
const char *signal,
|
||||
MooCObject *target,
|
||||
SEL sel);
|
||||
|
||||
|
||||
#ifdef CSTR
|
||||
#warning "CSTR defined"
|
||||
#endif
|
||||
|
|
|
@ -11,37 +11,15 @@
|
|||
*/
|
||||
|
||||
#include <config.h>
|
||||
#import "moocobject.h"
|
||||
#import "moocobject-private.h"
|
||||
#import "mooobjc.h"
|
||||
#import "mooobjcmarshal.h"
|
||||
#import <objc/objc-api.h>
|
||||
|
||||
|
||||
static GSList *autorelease_pools;
|
||||
|
||||
|
||||
#ifndef MOO_OBJC_USE_FOUNDATION
|
||||
|
||||
@interface MooAutoreleasePool : MooCObject
|
||||
{
|
||||
@private
|
||||
MooAutoreleasePool *parent;
|
||||
MooAutoreleasePool *child;
|
||||
GSList *objects;
|
||||
}
|
||||
|
||||
+ (void) addObject: (id)anObj;
|
||||
|
||||
- (void) addObject: (id)anObj;
|
||||
- (void) emptyPool;
|
||||
@end
|
||||
|
||||
#else
|
||||
|
||||
typedef NSAutoreleasePool MooAutoreleasePool;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
moo_objc_send_msg (MooObjCObject *m_obj,
|
||||
const char *name)
|
||||
|
@ -115,7 +93,7 @@ moo_init_objc_api (void)
|
|||
void
|
||||
moo_objc_push_autorelease_pool (void)
|
||||
{
|
||||
MooAutoreleasePool *pool = [[MooAutoreleasePool alloc] init];
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
g_return_if_fail (pool != nil);
|
||||
autorelease_pools = g_slist_prepend (autorelease_pools, pool);
|
||||
}
|
||||
|
@ -123,7 +101,7 @@ moo_objc_push_autorelease_pool (void)
|
|||
void
|
||||
moo_objc_pop_autorelease_pool (void)
|
||||
{
|
||||
MooAutoreleasePool *pool;
|
||||
NSAutoreleasePool *pool;
|
||||
|
||||
g_return_if_fail (autorelease_pools != NULL);
|
||||
|
||||
|
@ -273,362 +251,136 @@ static MooAutoreleasePool *currentPool;
|
|||
|
||||
#endif // !MOO_OBJC_USE_FOUNDATION
|
||||
|
||||
#if 0
|
||||
|
||||
#ifdef MOO_OS_DARWIN
|
||||
#define class_get_class_name(klass) (klass->name)
|
||||
#define sel_get_name sel_getName
|
||||
#endif
|
||||
|
||||
#define OBJECT_HAS_TOGGLE_REF_FLAG 1
|
||||
#define OBJECT_HAS_TOGGLE_REF() ((g_datalist_get_flags (&moo_c_object_qdata) & OBJECT_HAS_TOGGLE_REF_FLAG) != 0)
|
||||
|
||||
static GQuark quark_toggle_refs = 0;
|
||||
typedef enum {
|
||||
CG_SIGNAL_RETAIN_DATA = 1 << 0,
|
||||
CG_SIGNAL_SWAP_DATA = 1 << 1,
|
||||
CG_SIGNAL_CONNECT_AFTER = 1 << 2
|
||||
} CGSignalFlags;
|
||||
|
||||
typedef struct {
|
||||
guint n_toggle_refs;
|
||||
struct {
|
||||
MooToggleNotify notify;
|
||||
gpointer data;
|
||||
} toggle_refs[1]; /* flexible array */
|
||||
} ToggleRefStack;
|
||||
GClosure closure;
|
||||
MooCObject *obj;
|
||||
SEL sel;
|
||||
MooCObject *data;
|
||||
guint has_data : 1;
|
||||
guint owns_data : 1;
|
||||
guint swap : 1;
|
||||
} CGClosureSel;
|
||||
|
||||
static void
|
||||
toggle_refs_notify (MooCObject *object,
|
||||
GData **qdata,
|
||||
gboolean is_last_ref)
|
||||
cg_closure_sel_marshal (CGClosureSel *closure,
|
||||
GValue *return_value,
|
||||
guint n_params,
|
||||
const GValue *params)
|
||||
{
|
||||
ToggleRefStack *tstack = g_datalist_id_get_data (qdata, quark_toggle_refs);
|
||||
g_assert (tstack->n_toggle_refs == 1);
|
||||
tstack->toggle_refs[0].notify (tstack->toggle_refs[0].data, object, is_last_ref);
|
||||
IMP callback;
|
||||
|
||||
/* TODO: use NSInvocation to enable forwarding */
|
||||
|
||||
callback = get_imp ([closure->obj class], closure->sel);
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
_moo_objc_marshal (G_CALLBACK (callback), closure->obj, closure->sel,
|
||||
return_value, n_params, params,
|
||||
closure->data, closure->has_data, closure->swap);
|
||||
}
|
||||
|
||||
@implementation MooCObject : Object
|
||||
|
||||
+ initialize
|
||||
static void
|
||||
cg_closure_sel_invalidate (G_GNUC_UNUSED gpointer data,
|
||||
CGClosureSel *cg)
|
||||
{
|
||||
quark_toggle_refs = g_quark_from_static_string ("moo-object-toggle-refs");
|
||||
return self;
|
||||
if (cg->owns_data)
|
||||
{
|
||||
[cg->data release];
|
||||
cg->data = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef MOO_OS_DARWIN
|
||||
- (retval_t) forward :(SEL)aSel :(arglist_t)argFrame
|
||||
static GClosure *
|
||||
_cg_closure_new_sel (MooCObject *target,
|
||||
SEL sel,
|
||||
MooCObject *data,
|
||||
CGSignalFlags sig_flags,
|
||||
gboolean use_data)
|
||||
{
|
||||
MOO_UNUSED_VAR (argFrame);
|
||||
g_critical ("no method `%s' found in <%s at %p>",
|
||||
sel_get_name (aSel), [self name], (gpointer) self);
|
||||
return NULL;
|
||||
}
|
||||
GClosure *closure;
|
||||
CGClosureSel *cg;
|
||||
|
||||
g_return_val_if_fail (target != nil, NULL);
|
||||
g_return_val_if_fail (sel != NULL, NULL);
|
||||
g_return_val_if_fail (data == nil || use_data, NULL);
|
||||
g_return_val_if_fail (data != nil || !(sig_flags & CG_SIGNAL_RETAIN_DATA), NULL);
|
||||
|
||||
if (![target respondsToSelector:sel])
|
||||
{
|
||||
#ifndef MOO_OBJC_USE_FOUNDATION
|
||||
const char *desc = "<unknown>";
|
||||
#else
|
||||
- forward: (SEL)aSel :(marg_list)args
|
||||
{
|
||||
MOO_UNUSED_VAR (args);
|
||||
g_critical ("no method `%s' found in <%s at %p>",
|
||||
sel_get_name (aSel), [self name], (gpointer) self);
|
||||
return nil;
|
||||
}
|
||||
const char *desc = [[target description] cString];
|
||||
#endif
|
||||
|
||||
- init
|
||||
{
|
||||
moo_c_object_ref_count = 1;
|
||||
moo_c_object_qdata = NULL;
|
||||
return [super init];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (moo_c_object_qdata)
|
||||
g_datalist_clear (&moo_c_object_qdata);
|
||||
[self free];
|
||||
}
|
||||
|
||||
- free
|
||||
{
|
||||
return [super free];
|
||||
}
|
||||
|
||||
- retain
|
||||
{
|
||||
g_assert (moo_c_object_ref_count > 0);
|
||||
|
||||
moo_c_object_ref_count++;
|
||||
|
||||
if (moo_c_object_ref_count == 2 && OBJECT_HAS_TOGGLE_REF ())
|
||||
toggle_refs_notify (self, &moo_c_object_qdata, FALSE);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) release
|
||||
{
|
||||
gboolean need_dealloc;
|
||||
|
||||
g_assert (moo_c_object_ref_count > 0);
|
||||
|
||||
moo_c_object_ref_count--;
|
||||
need_dealloc = !moo_c_object_ref_count;
|
||||
|
||||
if (moo_c_object_ref_count == 1 && OBJECT_HAS_TOGGLE_REF ())
|
||||
toggle_refs_notify (self, &moo_c_object_qdata, TRUE);
|
||||
|
||||
if (need_dealloc)
|
||||
[self dealloc];
|
||||
}
|
||||
|
||||
- autorelease
|
||||
{
|
||||
[MooAutoreleasePool addObject: self];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (guint) retainCount
|
||||
{
|
||||
return moo_c_object_ref_count;
|
||||
}
|
||||
|
||||
- (void) setQData :(GQuark)key
|
||||
:(gpointer)data
|
||||
{
|
||||
g_datalist_id_set_data (&moo_c_object_qdata, key, data);
|
||||
}
|
||||
|
||||
- (void) setQData :(GQuark)key :(gpointer)data withDestroy:(GDestroyNotify)destroy
|
||||
{
|
||||
g_datalist_id_set_data_full (&moo_c_object_qdata, key, data, destroy);
|
||||
}
|
||||
|
||||
- (gpointer) getQData :(GQuark)key
|
||||
{
|
||||
return g_datalist_id_get_data (&moo_c_object_qdata, key);
|
||||
}
|
||||
|
||||
- (void) setData :(CSTR)key :(gpointer)data
|
||||
{
|
||||
g_datalist_set_data (&moo_c_object_qdata, key, data);
|
||||
}
|
||||
|
||||
- (void) setData :(CSTR)key :(gpointer)data withDestroy:(GDestroyNotify)destroy
|
||||
{
|
||||
g_datalist_set_data_full (&moo_c_object_qdata, key, data, destroy);
|
||||
}
|
||||
|
||||
- (gpointer) getData: (CSTR)key
|
||||
{
|
||||
return g_datalist_get_data (&moo_c_object_qdata, key);
|
||||
}
|
||||
|
||||
- (void) addToggleRef :(MooToggleNotify)notify
|
||||
:(gpointer)data
|
||||
{
|
||||
ToggleRefStack *tstack;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (notify != NULL);
|
||||
g_return_if_fail (moo_c_object_ref_count >= 1);
|
||||
|
||||
[self retain];
|
||||
|
||||
tstack = g_datalist_id_remove_no_notify (&moo_c_object_qdata, quark_toggle_refs);
|
||||
if (tstack)
|
||||
{
|
||||
i = tstack->n_toggle_refs++;
|
||||
/* allocate i = tstate->n_toggle_refs - 1 positions beyond the 1 declared
|
||||
* in tstate->toggle_refs */
|
||||
tstack = g_realloc (tstack, sizeof (*tstack) + sizeof (tstack->toggle_refs[0]) * i);
|
||||
}
|
||||
else
|
||||
{
|
||||
tstack = g_renew (ToggleRefStack, NULL, 1);
|
||||
tstack->n_toggle_refs = 1;
|
||||
i = 0;
|
||||
g_critical ("in %s: object %s does not respond to selector '%s'",
|
||||
G_STRLOC, desc ? desc : "<NULL>", sel_get_name (sel));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set a flag for fast lookup after adding the first toggle reference */
|
||||
if (tstack->n_toggle_refs == 1)
|
||||
g_datalist_set_flags (&moo_c_object_qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
|
||||
closure = g_closure_new_simple (sizeof (CGClosureSel), NULL);
|
||||
g_closure_add_invalidate_notifier (closure, NULL,
|
||||
(GClosureNotify) cg_closure_sel_invalidate);
|
||||
g_closure_set_marshal(closure, (GClosureMarshal) cg_closure_sel_marshal);
|
||||
|
||||
tstack->toggle_refs[i].notify = notify;
|
||||
tstack->toggle_refs[i].data = data;
|
||||
g_datalist_id_set_data_full (&moo_c_object_qdata, quark_toggle_refs, tstack,
|
||||
(GDestroyNotify) g_free);
|
||||
}
|
||||
cg = (CGClosureSel*) closure;
|
||||
cg->obj = target;
|
||||
cg->sel = sel;
|
||||
cg->data = data;
|
||||
cg->has_data = use_data ? 1 : 0;
|
||||
cg->swap = (sig_flags & CG_SIGNAL_SWAP_DATA) ? 1 : 0;
|
||||
|
||||
- (void) removeToggleRef :(MooToggleNotify)notify
|
||||
:(gpointer)data
|
||||
{
|
||||
ToggleRefStack *tstack;
|
||||
gboolean found_one = FALSE;
|
||||
|
||||
g_return_if_fail (notify != NULL);
|
||||
|
||||
tstack = g_datalist_id_get_data (&moo_c_object_qdata, quark_toggle_refs);
|
||||
|
||||
if (tstack)
|
||||
if (sig_flags & CG_SIGNAL_RETAIN_DATA)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < tstack->n_toggle_refs; i++)
|
||||
if (tstack->toggle_refs[i].notify == notify &&
|
||||
tstack->toggle_refs[i].data == data)
|
||||
{
|
||||
found_one = TRUE;
|
||||
tstack->n_toggle_refs -= 1;
|
||||
|
||||
if (i != tstack->n_toggle_refs)
|
||||
tstack->toggle_refs[i] = tstack->toggle_refs[tstack->n_toggle_refs];
|
||||
|
||||
if (tstack->n_toggle_refs == 0)
|
||||
g_datalist_unset_flags (&moo_c_object_qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
|
||||
|
||||
[self release];
|
||||
|
||||
break;
|
||||
}
|
||||
[cg->data retain];
|
||||
cg->owns_data = TRUE;
|
||||
}
|
||||
|
||||
if (!found_one)
|
||||
g_warning ("%s: couldn't find toggle ref %p(%p)", G_STRFUNC, notify, data);
|
||||
return closure;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation MooAutoreleasePool : MooCObject
|
||||
|
||||
static MooAutoreleasePool *current_pool;
|
||||
|
||||
+ (void) addObject: (id)anObj
|
||||
static gulong
|
||||
_cg_signal_connect_sel (GObject *obj,
|
||||
const char *signal,
|
||||
MooCObject *target,
|
||||
SEL sel,
|
||||
CGSignalFlags flags)
|
||||
{
|
||||
g_return_if_fail (current_pool != nil);
|
||||
[current_pool addObject: anObj];
|
||||
}
|
||||
gulong cb_id = 0;
|
||||
GClosure *closure;
|
||||
|
||||
+ (id) currentPool
|
||||
{
|
||||
return current_pool;
|
||||
}
|
||||
closure = _cg_closure_new_sel (target, sel, nil, flags, FALSE);
|
||||
|
||||
- (void) addObject: (id)anObj
|
||||
{
|
||||
if (G_UNLIKELY (!objects))
|
||||
objects = g_ptr_array_new ();
|
||||
g_ptr_array_add (objects, anObj);
|
||||
}
|
||||
|
||||
- (void) emptyPool
|
||||
{
|
||||
[self retain];
|
||||
|
||||
if (child)
|
||||
[child emptyPool];
|
||||
|
||||
if (objects)
|
||||
if (closure)
|
||||
{
|
||||
id *objs;
|
||||
guint n_objs, i;
|
||||
|
||||
n_objs = objects->len;
|
||||
objs = (id*) g_ptr_array_free (objects, FALSE);
|
||||
objects = NULL;
|
||||
|
||||
for (i = 0; i < n_objs; ++i)
|
||||
[objs[i] release];
|
||||
g_free (objs);
|
||||
g_closure_sink (g_closure_ref (closure));
|
||||
cb_id = g_signal_connect_closure (obj, signal, closure,
|
||||
(flags & CG_SIGNAL_CONNECT_AFTER) ? 1 : 0);
|
||||
g_closure_unref (closure);
|
||||
}
|
||||
|
||||
[self release];
|
||||
return cb_id;
|
||||
}
|
||||
|
||||
- (id) autorelease
|
||||
gulong
|
||||
moo_objc_signal_connect (gpointer instance,
|
||||
const char *signal,
|
||||
MooCObject *target,
|
||||
SEL sel)
|
||||
{
|
||||
g_return_val_if_reached (self);
|
||||
g_return_val_if_fail (G_IS_OBJECT (instance), 0);
|
||||
g_return_val_if_fail (signal != NULL, 0);
|
||||
g_return_val_if_fail (target != nil, 0);
|
||||
g_return_val_if_fail (sel != 0, 0);
|
||||
|
||||
return _cg_signal_connect_sel (instance, signal, target, sel, 0);
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
[super init];
|
||||
|
||||
if (current_pool)
|
||||
{
|
||||
current_pool->child = self;
|
||||
parent = current_pool;
|
||||
current_pool = self;
|
||||
}
|
||||
|
||||
current_pool = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) free
|
||||
{
|
||||
current_pool = parent;
|
||||
|
||||
if (current_pool)
|
||||
current_pool->child = nil;
|
||||
|
||||
[self emptyPool];
|
||||
[super free];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static gpointer
|
||||
moo_object_retain (gpointer obj)
|
||||
{
|
||||
g_return_val_if_fail (obj != NULL, NULL);
|
||||
return [(id)obj retain];
|
||||
}
|
||||
|
||||
static gpointer
|
||||
moo_object_copy (gpointer obj)
|
||||
{
|
||||
g_return_val_if_fail (obj != NULL, NULL);
|
||||
return [(id)obj copy];
|
||||
}
|
||||
|
||||
static void
|
||||
moo_object_release (gpointer obj)
|
||||
{
|
||||
g_return_if_fail (obj != NULL);
|
||||
[(id)obj release];
|
||||
}
|
||||
|
||||
|
||||
GType
|
||||
moo_cboxed_type_new (Class klass,
|
||||
gboolean copy)
|
||||
{
|
||||
g_return_val_if_fail (klass != Nil, 0);
|
||||
|
||||
return g_boxed_type_register_static (class_get_class_name (klass),
|
||||
copy ? moo_object_copy : moo_object_retain,
|
||||
moo_object_release);
|
||||
}
|
||||
|
||||
|
||||
id
|
||||
moo_cobject_check_type_cast (id obj, Class klass)
|
||||
{
|
||||
if (!obj)
|
||||
g_warning ("invalid cast of (nil) to `%s'",
|
||||
class_get_class_name (klass));
|
||||
else if (![obj isKindOf :klass])
|
||||
g_warning ("invalid cast from `%s' to `%s'",
|
||||
[obj name], class_get_class_name (klass));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
BOOL
|
||||
moo_cobject_check_type (id obj, Class klass)
|
||||
{
|
||||
return obj != nil && [obj isKindOf :klass];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* -*- objc -*- */
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* mooobjcmarshal.h
|
||||
*
|
||||
* Copyright (C) 2007 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef MOO_OBJC_MARSHAL_H
|
||||
#define MOO_OBJC_MARSHAL_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "moocobject.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
void _moo_objc_marshal (GCallback callback,
|
||||
id add_obj,
|
||||
SEL add_sel,
|
||||
GValue *return_value,
|
||||
guint n_params,
|
||||
const GValue *params,
|
||||
id data,
|
||||
gboolean use_data,
|
||||
gboolean swap);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* MOO_OBJC_MARSHAL_H */
|
||||
/* -*- objc -*- */
|
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
* mooobjcmarshal.m
|
||||
*
|
||||
* Copyright (C) 2007 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#import <config.h>
|
||||
#import "mooobjcmarshal.h"
|
||||
#import "moocobject-private.h"
|
||||
#import <objc/objc-api.h>
|
||||
#import <ffi.h>
|
||||
|
||||
#define MAX_N_FREELIST 16
|
||||
|
||||
#if SIZEOF_BOOL == 1
|
||||
#define ffi_type_objc_bool ffi_type_uchar
|
||||
#elif SIZEOF_BOOL == 2
|
||||
#define ffi_type_objc_bool ffi_type_uint16
|
||||
#elif SIZEOF_BOOL == 4
|
||||
#define ffi_type_objc_bool ffi_type_uint32
|
||||
#else
|
||||
#error "Something is wrong with the BOOL type"
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
get_ffi_type (const GValue *cgvalue,
|
||||
ffi_type **arg_type,
|
||||
gpointer *arg_val,
|
||||
gpointer *freelist,
|
||||
guint *n_freelist)
|
||||
{
|
||||
BOOL *bval;
|
||||
GValue *gvalue = (GValue*) cgvalue;
|
||||
|
||||
switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))
|
||||
{
|
||||
case G_TYPE_BOOLEAN:
|
||||
if (*n_freelist == MAX_N_FREELIST)
|
||||
{
|
||||
g_warning ("%s: too many argumnents pushed", G_STRLOC);
|
||||
return FALSE;
|
||||
}
|
||||
bval = g_new (BOOL, 1);
|
||||
*bval = g_value_get_boolean (gvalue) ? 1 : 0;
|
||||
freelist[(*n_freelist)++] = bval;
|
||||
*arg_type = &ffi_type_sint;
|
||||
*arg_val = bval;
|
||||
break;
|
||||
|
||||
case G_TYPE_STRING:
|
||||
case G_TYPE_OBJECT:
|
||||
case G_TYPE_BOXED:
|
||||
*arg_type = &ffi_type_pointer;
|
||||
*arg_val = &gvalue->data[0].v_pointer;
|
||||
break;
|
||||
|
||||
case G_TYPE_CHAR:
|
||||
case G_TYPE_INT:
|
||||
case G_TYPE_ENUM:
|
||||
case G_TYPE_FLAGS:
|
||||
*arg_type = &ffi_type_sint;
|
||||
*arg_val = &gvalue->data[0].v_int;
|
||||
break;
|
||||
case G_TYPE_UCHAR:
|
||||
case G_TYPE_UINT:
|
||||
*arg_type = &ffi_type_uint;
|
||||
*arg_val = &gvalue->data[0].v_uint;
|
||||
break;
|
||||
case G_TYPE_LONG:
|
||||
*arg_type = &ffi_type_slong;
|
||||
*arg_val = &gvalue->data[0].v_long;
|
||||
break;
|
||||
case G_TYPE_ULONG:
|
||||
*arg_type = &ffi_type_ulong;
|
||||
*arg_val = &gvalue->data[0].v_ulong;
|
||||
break;
|
||||
case G_TYPE_INT64:
|
||||
*arg_type = &ffi_type_sint64;
|
||||
*arg_val = &gvalue->data[0].v_int64;
|
||||
break;
|
||||
case G_TYPE_UINT64:
|
||||
*arg_type = &ffi_type_uint64;
|
||||
*arg_val = &gvalue->data[0].v_uint64;
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
*arg_type = &ffi_type_float;
|
||||
*arg_val = &gvalue->data[0].v_float;
|
||||
break;
|
||||
case G_TYPE_DOUBLE:
|
||||
*arg_type = &ffi_type_double;
|
||||
*arg_val = &gvalue->data[0].v_double;
|
||||
break;
|
||||
case G_TYPE_POINTER:
|
||||
*arg_type = &ffi_type_pointer;
|
||||
*arg_val = &gvalue->data[0].v_pointer;
|
||||
break;
|
||||
|
||||
case G_TYPE_PARAM:
|
||||
default:
|
||||
g_warning ("Unsupported argument type: %s",
|
||||
g_type_name (G_VALUE_TYPE (gvalue)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_ffi_type_for_return (GValue *gvalue,
|
||||
ffi_type **ret_type,
|
||||
gpointer *ret_val,
|
||||
gpointer *freelist,
|
||||
guint *n_freelist)
|
||||
{
|
||||
BOOL *bval;
|
||||
|
||||
switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))
|
||||
{
|
||||
case G_TYPE_BOOLEAN:
|
||||
if (*n_freelist == MAX_N_FREELIST)
|
||||
{
|
||||
g_warning ("%s: too many argumnents pushed", G_STRLOC);
|
||||
return FALSE;
|
||||
}
|
||||
bval = g_new (BOOL, 1);
|
||||
*bval = 0;
|
||||
freelist[(*n_freelist)++] = bval;
|
||||
*ret_type = &ffi_type_sint;
|
||||
*ret_val = bval;
|
||||
break;
|
||||
|
||||
case G_TYPE_STRING:
|
||||
case G_TYPE_OBJECT:
|
||||
case G_TYPE_BOXED:
|
||||
*ret_type = &ffi_type_pointer;
|
||||
*ret_val = &gvalue->data[0].v_pointer;
|
||||
break;
|
||||
|
||||
case G_TYPE_CHAR:
|
||||
case G_TYPE_INT:
|
||||
case G_TYPE_ENUM:
|
||||
case G_TYPE_FLAGS:
|
||||
*ret_type = &ffi_type_sint;
|
||||
*ret_val = &gvalue->data[0].v_int;
|
||||
break;
|
||||
case G_TYPE_UCHAR:
|
||||
case G_TYPE_UINT:
|
||||
*ret_type = &ffi_type_uint;
|
||||
*ret_val = &gvalue->data[0].v_uint;
|
||||
break;
|
||||
case G_TYPE_LONG:
|
||||
*ret_type = &ffi_type_slong;
|
||||
*ret_val = &gvalue->data[0].v_long;
|
||||
break;
|
||||
case G_TYPE_ULONG:
|
||||
*ret_type = &ffi_type_ulong;
|
||||
*ret_val = &gvalue->data[0].v_ulong;
|
||||
break;
|
||||
case G_TYPE_INT64:
|
||||
*ret_type = &ffi_type_sint64;
|
||||
*ret_val = &gvalue->data[0].v_int64;
|
||||
break;
|
||||
case G_TYPE_UINT64:
|
||||
*ret_type = &ffi_type_uint64;
|
||||
*ret_val = &gvalue->data[0].v_uint64;
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
*ret_type = &ffi_type_float;
|
||||
*ret_val = &gvalue->data[0].v_float;
|
||||
break;
|
||||
case G_TYPE_DOUBLE:
|
||||
*ret_type = &ffi_type_double;
|
||||
*ret_val = &gvalue->data[0].v_double;
|
||||
break;
|
||||
case G_TYPE_POINTER:
|
||||
*ret_type = &ffi_type_pointer;
|
||||
*ret_val = &gvalue->data[0].v_pointer;
|
||||
break;
|
||||
|
||||
case G_TYPE_PARAM:
|
||||
default:
|
||||
g_warning ("Unsupported argument type: %s",
|
||||
g_type_name (G_VALUE_TYPE (gvalue)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
convert_return_value (gpointer ptr,
|
||||
GValue *gvalue)
|
||||
{
|
||||
BOOL *bval;
|
||||
|
||||
switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))
|
||||
{
|
||||
case G_TYPE_BOOLEAN:
|
||||
bval = ptr;
|
||||
g_value_set_boolean (gvalue, *bval);
|
||||
break;
|
||||
|
||||
case G_TYPE_STRING:
|
||||
case G_TYPE_OBJECT:
|
||||
case G_TYPE_BOXED:
|
||||
case G_TYPE_POINTER:
|
||||
break;
|
||||
|
||||
case G_TYPE_CHAR:
|
||||
case G_TYPE_INT:
|
||||
case G_TYPE_ENUM:
|
||||
case G_TYPE_FLAGS:
|
||||
case G_TYPE_UCHAR:
|
||||
case G_TYPE_UINT:
|
||||
case G_TYPE_LONG:
|
||||
case G_TYPE_ULONG:
|
||||
case G_TYPE_INT64:
|
||||
case G_TYPE_UINT64:
|
||||
case G_TYPE_FLOAT:
|
||||
case G_TYPE_DOUBLE:
|
||||
break;
|
||||
|
||||
case G_TYPE_PARAM:
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_marshal (GCallback callback,
|
||||
id add_obj,
|
||||
SEL add_sel,
|
||||
GValue *return_value,
|
||||
guint n_params,
|
||||
const GValue *params,
|
||||
id data,
|
||||
gboolean use_data,
|
||||
gboolean swap)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *ret_type, **arg_types;
|
||||
guint i_arg, i, n_args;
|
||||
gpointer ret_val, *arg_vals;
|
||||
gpointer freelist[MAX_N_FREELIST];
|
||||
guint n_freelist = 0;
|
||||
|
||||
/* params: object arg1 ... argN */
|
||||
|
||||
n_args = use_data ? n_params + 1 : n_params;
|
||||
|
||||
if (add_obj)
|
||||
n_args += 2;
|
||||
|
||||
arg_types = g_new (ffi_type*, n_args);
|
||||
arg_vals = g_new (gpointer, n_args);
|
||||
i_arg = 0;
|
||||
|
||||
if (data)
|
||||
[data retain];
|
||||
if (add_obj)
|
||||
[add_obj retain];
|
||||
|
||||
/*
|
||||
if (use_data)
|
||||
if (swap)
|
||||
callback (data, arg1, ..., argN, object)
|
||||
else
|
||||
callback (object, arg1, ..., argN, data)
|
||||
else
|
||||
if (swap)
|
||||
callback (arg1, ..., argN, object)
|
||||
else
|
||||
callback (object, arg1, ..., argN)
|
||||
*/
|
||||
|
||||
/* Return value */
|
||||
if (return_value)
|
||||
{
|
||||
if (!get_ffi_type_for_return (return_value, &ret_type, &ret_val,
|
||||
freelist, &n_freelist))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_type = &ffi_type_void;
|
||||
ret_val = NULL;
|
||||
}
|
||||
|
||||
if (add_obj)
|
||||
{
|
||||
arg_types[0] = &ffi_type_pointer;
|
||||
arg_vals[0] = &add_obj;
|
||||
arg_types[1] = &ffi_type_pointer;
|
||||
arg_vals[1] = &add_sel;
|
||||
i_arg = 2;
|
||||
}
|
||||
|
||||
if (use_data && swap)
|
||||
{
|
||||
arg_types[i_arg] = &ffi_type_pointer;
|
||||
arg_vals[i_arg] = &data;
|
||||
i_arg++;
|
||||
}
|
||||
else if (!swap)
|
||||
{
|
||||
if (!get_ffi_type (¶ms[0], &arg_types[i_arg], &arg_vals[i_arg],
|
||||
freelist, &n_freelist))
|
||||
goto out;
|
||||
i_arg++;
|
||||
}
|
||||
|
||||
for (i = 1; i < n_params; ++i, ++i_arg)
|
||||
{
|
||||
if (!get_ffi_type (¶ms[i], &arg_types[i_arg], &arg_vals[i_arg],
|
||||
freelist, &n_freelist))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (use_data && !swap)
|
||||
{
|
||||
arg_types[i_arg] = &ffi_type_pointer;
|
||||
arg_vals[i_arg] = &data;
|
||||
i_arg++;
|
||||
}
|
||||
else if (swap)
|
||||
{
|
||||
if (!get_ffi_type (¶ms[0], &arg_types[i_arg], &arg_vals[i_arg],
|
||||
freelist, &n_freelist))
|
||||
goto out;
|
||||
i_arg++;
|
||||
}
|
||||
|
||||
g_assert (i_arg == n_args);
|
||||
|
||||
if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, ret_type, arg_types) != FFI_OK)
|
||||
goto out;
|
||||
|
||||
ffi_call (&cif, FFI_FN (callback), ret_val, arg_vals);
|
||||
|
||||
if (return_value)
|
||||
convert_return_value (ret_val, return_value);
|
||||
|
||||
out:
|
||||
if (data)
|
||||
[data release];
|
||||
if (add_obj)
|
||||
[add_obj release];
|
||||
for (i = 0; i < n_freelist; ++i)
|
||||
g_free (freelist[i]);
|
||||
g_free (arg_types);
|
||||
g_free (arg_vals);
|
||||
}
|
||||
|
||||
void
|
||||
_moo_objc_marshal (GCallback callback,
|
||||
id add_obj,
|
||||
SEL add_sel,
|
||||
GValue *return_value,
|
||||
guint n_params,
|
||||
const GValue *params,
|
||||
id data,
|
||||
gboolean use_data,
|
||||
gboolean swap)
|
||||
{
|
||||
do_marshal (callback, add_obj, add_sel,
|
||||
return_value, n_params, params,
|
||||
data, use_data, swap);
|
||||
}
|
||||
|
||||
|
||||
/* -*- objc -*- */
|
Loading…
Reference in New Issue