1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- 2 3 eel-gtk-macros.h: Macros to reduce boilerplate when using GTK. 4 5 Copyright (C) 1999, 2000, 2001 Eazel, Inc. 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Library General Public License as 9 published by the Free Software Foundation; either version 2 of the 10 License, or (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Library General Public License for more details. 16 17 You should have received a copy of the GNU Library General Public 18 License along with this program; if not, write to the 19 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 20 Boston, MA 02110-1301, USA. 21 22 Authors: Darin Adler <darin@bentspoon.com> 23 Ramiro Estrugo <ramiro@eazel.com> 24 */ 25 26 #ifndef EEL_GTK_MACROS_H 27 #define EEL_GTK_MACROS_H 28 29 #ifndef EEL_DISABLE_DEPRECATED 30 31 /* Define a parent_class global and a get_type function for a GTK class. 32 Since this is boilerplate, it's better not to repeat it over and over again. 33 Called like this: 34 35 EEL_CLASS_BOILERPLATE (EelBookmark, eel_bookmark, GTK_TYPE_OBJECT) 36 37 The parent_class_type parameter is guaranteed to be evaluated only once 38 so it can be an expression, even an expression that contains a function call. 39 */ 40 41 #define EEL_CLASS_BOILERPLATE(class_name, prefix, parent_class_type) \ 42 EEL_BOILERPLATE (class_name, class_name, prefix, parent_class_type, \ 43 EEL_REGISTER_TYPE) 44 #define EEL_REGISTER_TYPE(class_name, corba_name) \ 45 g_type_register_static (parent_type, #class_name, &info, 0) 46 47 #define EEL_BOILERPLATE(class_name, corba_name, prefix, parent_class_type, \ 48 register_type) \ 49 \ 50 static gpointer parent_class; \ 51 \ 52 GType \ 53 prefix##_get_type (void) \ 54 { \ 55 GType parent_type; \ 56 static GType type; \ 57 \ 58 if (type == 0) { \ 59 static GTypeInfo info = { \ 60 sizeof (class_name##Class), \ 61 NULL, NULL, \ 62 (GClassInitFunc) prefix##_class_init, \ 63 NULL, NULL, \ 64 sizeof (class_name), 0, \ 65 (GInstanceInitFunc) prefix##_init, \ 66 NULL \ 67 }; \ 68 \ 69 parent_type = (parent_class_type); \ 70 type = register_type (class_name, corba_name); \ 71 parent_class = g_type_class_ref (parent_type); \ 72 } \ 73 \ 74 return type; \ 75 } 76 77 /* Call a parent class version of a virtual function (or default 78 * signal handler since that's the same thing). Nice because it 79 * documents what it's doing and there is less chance for a 80 * typo. Depends on the parent class pointer having the conventional 81 * name "parent_class" as the boilerplate macro above does it. 82 */ 83 #define EEL_CALL_PARENT(parent_class_cast_macro, signal, parameters) \ 84 \ 85 G_STMT_START { \ 86 if (parent_class_cast_macro (parent_class)->signal != NULL) { \ 87 (* parent_class_cast_macro (parent_class)->signal) parameters;\ 88 } \ 89 } G_STMT_END 90 91 /* Same thing, for functions with a return value. */ 92 #define EEL_CALL_PARENT_WITH_RETURN_VALUE(parent_class_cast_macro, signal, \ 93 parameters) \ 94 \ 95 (parent_class_cast_macro (parent_class)->signal == NULL) \ 96 ? 0 \ 97 : ((* parent_class_cast_macro (parent_class)->signal) parameters) 98 99 #endif /* EEL_DISABLE_DEPRECATED */ 100 101 /* Call a virtual function. Useful when the virtual function is not a 102 * signal, otherwise you want to gtk_signal emit. Nice because it 103 * documents what it's doing and there is less chance for a typo. 104 */ 105 #define EEL_CALL_METHOD(class_cast_macro, object, signal, parameters) \ 106 \ 107 G_STMT_START { \ 108 if (class_cast_macro (G_OBJECT_GET_CLASS (object))->signal != NULL) { \ 109 (* class_cast_macro (G_OBJECT_GET_CLASS (object))->signal) \ 110 parameters; \ 111 } \ 112 } G_STMT_END 113 114 /* Same thing, for functions with a return value. */ 115 #define EEL_CALL_METHOD_WITH_RETURN_VALUE(class_cast_macro, object, signal, \ 116 parameters) \ 117 \ 118 (class_cast_macro (G_OBJECT_GET_CLASS (object))->signal == NULL) \ 119 ? 0 \ 120 : ((* class_cast_macro (G_OBJECT_GET_CLASS (object))->signal) \ 121 parameters) \ 122 123 #ifndef G_DISABLE_ASSERT 124 125 /* Define a signal that is not implemented by this class but must be 126 * implemented by subclasses. This macro should be used inside the 127 * class initialization function. The companion macro EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL 128 * must be used earlier in the file. Called like this: 129 * 130 * EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, 131 * fm_directory_view, 132 * clear); 133 */ 134 #define EEL_ASSIGN_MUST_OVERRIDE_SIGNAL(class_pointer, prefix, signal) \ 135 \ 136 * (void (**)(void)) & (class_pointer)->signal = prefix##_unimplemented_##signal 137 138 /* Provide a debug-only implementation of a signal that must be implemented 139 * by subclasses. The debug-only implementation fires a warning if it is called. 140 * This macro should be placed as if it were a function, earlier in the file 141 * than the class initialization function. Called like this: 142 * 143 * EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, clear); 144 */ 145 #define EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL(prefix, signal) \ 146 \ 147 static void \ 148 prefix##_unimplemented_##signal (void) \ 149 { \ 150 g_warning ("failed to override signal " #prefix "->" #signal); \ 151 } 152 153 #else /* G_DISABLE_ASSERT */ 154 155 #define EEL_DEFINE_MUST_OVERRIDE_SIGNAL(class_cast_macro, class_pointer, prefix, signal) 156 #define EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL(prefix, signal) 157 #define EEL_ASSIGN_MUST_OVERRIDE_SIGNAL(class_pointer, prefix, signal) 158 159 #endif /* G_DISABLE_ASSERT */ 160 161 /* Access a method. */ 162 #define EEL_ACCESS_METHOD(class_cast_macro, object, method) \ 163 (class_cast_macro (G_OBJECT_GET_CLASS (object))->method) 164 165 /* Invoke a method for a given object. */ 166 #define EEL_INVOKE_METHOD(class_cast_macro, object, method, parameters) \ 167 ((* EEL_ACCESS_METHOD (class_cast_macro, object, method)) parameters) 168 169 /* Assert the non-nullness of a method for a given object. */ 170 #define EEL_ASSERT_METHOD(class_cast_macro, object, method) \ 171 g_assert (EEL_ACCESS_METHOD (class_cast_macro, object, method) != NULL) 172 173 /* Invoke a method if it ain't null. */ 174 #define EEL_INVOKE_METHOD_IF(class_cast_macro, object, method, parameters) \ 175 (EEL_ACCESS_METHOD (class_cast_macro, object, method) ? 0 : \ 176 EEL_INVOKE_METHOD (class_cast_macro, object, method, parameters)) 177 178 #endif /* EEL_GTK_MACROS_H */ 179