1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef UI_BASE_GLIB_GLIB_SIGNAL_H_ 6 #define UI_BASE_GLIB_GLIB_SIGNAL_H_ 7 8 typedef void* gpointer; 9 10 // At the time of writing this, there were two common ways of binding our C++ 11 // code to the gobject C system. We either defined a whole bunch of "static 12 // MethodThunk()" which just called nonstatic Method()s on a class (which hurt 13 // readability of the headers and signal connection code) OR we declared 14 // "static Method()" and passed in the current object as the gpointer (and hurt 15 // readability in the implementation by having "context->" before every 16 // variable). 17 18 // The hopeful result of using these macros is that the code will be more 19 // readable and regular. There shouldn't be a bunch of static Thunks visible in 20 // the headers and the implementations shouldn't be filled with "context->" 21 // de-references. 22 23 #define CHROMEG_CALLBACK_0(CLASS, RETURN, METHOD, SENDER) \ 24 static RETURN METHOD ## Thunk(SENDER sender, gpointer userdata) { \ 25 return reinterpret_cast<CLASS*>(userdata)->METHOD(sender); \ 26 } \ 27 \ 28 RETURN METHOD(SENDER); 29 30 #define CHROMEG_CALLBACK_1(CLASS, RETURN, METHOD, SENDER, ARG1) \ 31 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, \ 32 gpointer userdata) { \ 33 return reinterpret_cast<CLASS*>(userdata)->METHOD(sender, one); \ 34 } \ 35 \ 36 RETURN METHOD(SENDER, ARG1); 37 38 #define CHROMEG_CALLBACK_2(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2) \ 39 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 40 gpointer userdata) { \ 41 return reinterpret_cast<CLASS*>(userdata)->METHOD(sender, one, two); \ 42 } \ 43 \ 44 RETURN METHOD(SENDER, ARG1, ARG2); 45 46 #define CHROMEG_CALLBACK_3(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2, ARG3) \ 47 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 48 ARG3 three, gpointer userdata) { \ 49 return reinterpret_cast<CLASS*>(userdata)-> \ 50 METHOD(sender, one, two, three); \ 51 } \ 52 \ 53 RETURN METHOD(SENDER, ARG1, ARG2, ARG3); 54 55 #define CHROMEG_CALLBACK_4(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2, ARG3, \ 56 ARG4) \ 57 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 58 ARG3 three, ARG4 four, \ 59 gpointer userdata) { \ 60 return reinterpret_cast<CLASS*>(userdata)-> \ 61 METHOD(sender, one, two, three, four); \ 62 } \ 63 \ 64 RETURN METHOD(SENDER, ARG1, ARG2, ARG3, ARG4); 65 66 #define CHROMEG_CALLBACK_5(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2, ARG3, \ 67 ARG4, ARG5) \ 68 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 69 ARG3 three, ARG4 four, ARG5 five, \ 70 gpointer userdata) { \ 71 return reinterpret_cast<CLASS*>(userdata)-> \ 72 METHOD(sender, one, two, three, four, five); \ 73 } \ 74 \ 75 RETURN METHOD(SENDER, ARG1, ARG2, ARG3, ARG4, ARG5); 76 77 #define CHROMEG_CALLBACK_6(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2, ARG3, \ 78 ARG4, ARG5, ARG6) \ 79 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 80 ARG3 three, ARG4 four, ARG5 five, \ 81 ARG6 six, gpointer userdata) { \ 82 return reinterpret_cast<CLASS*>(userdata)-> \ 83 METHOD(sender, one, two, three, four, five, six); \ 84 } \ 85 \ 86 RETURN METHOD(SENDER, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); 87 88 #define CHROMEG_VIRTUAL_CALLBACK_0(CLASS, RETURN, METHOD, SENDER) \ 89 static RETURN METHOD ## Thunk(SENDER sender, gpointer userdata) { \ 90 return reinterpret_cast<CLASS*>(userdata)->METHOD(sender); \ 91 } \ 92 \ 93 virtual RETURN METHOD(SENDER); 94 95 #define CHROMEG_VIRTUAL_CALLBACK_1(CLASS, RETURN, METHOD, SENDER, ARG1) \ 96 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, \ 97 gpointer userdata) { \ 98 return reinterpret_cast<CLASS*>(userdata)->METHOD(sender, one); \ 99 } \ 100 \ 101 virtual RETURN METHOD(SENDER, ARG1); 102 103 #define CHROMEG_VIRTUAL_CALLBACK_2(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2) \ 104 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 105 gpointer userdata) { \ 106 return reinterpret_cast<CLASS*>(userdata)->METHOD(sender, one, two); \ 107 } \ 108 \ 109 virtual RETURN METHOD(SENDER, ARG1, ARG2); 110 111 #define CHROMEG_VIRTUAL_CALLBACK_3(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2, \ 112 ARG3) \ 113 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 114 ARG3 three, gpointer userdata) { \ 115 return reinterpret_cast<CLASS*>(userdata)-> \ 116 METHOD(sender, one, two, three); \ 117 } \ 118 \ 119 virtual RETURN METHOD(SENDER, ARG1, ARG2, ARG3); 120 121 #define CHROMEG_VIRTUAL_CALLBACK_4(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2, \ 122 ARG3, ARG4) \ 123 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 124 ARG3 three, ARG4 four, \ 125 gpointer userdata) { \ 126 return reinterpret_cast<CLASS*>(userdata)-> \ 127 METHOD(sender, one, two, three, four); \ 128 } \ 129 \ 130 virtual RETURN METHOD(SENDER, ARG1, ARG2, ARG3, ARG4); 131 132 #define CHROMEG_VIRTUAL_CALLBACK_5(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2, \ 133 ARG3, ARG4, ARG5) \ 134 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 135 ARG3 three, ARG4 four, ARG5 five, \ 136 gpointer userdata) { \ 137 return reinterpret_cast<CLASS*>(userdata)-> \ 138 METHOD(sender, one, two, three, four, five); \ 139 } \ 140 \ 141 virtual RETURN METHOD(SENDER, ARG1, ARG2, ARG3, ARG4, ARG5); 142 143 #define CHROMEG_VIRTUAL_CALLBACK_6(CLASS, RETURN, METHOD, SENDER, ARG1, ARG2, \ 144 ARG3, ARG4, ARG5, ARG6) \ 145 static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, ARG2 two, \ 146 ARG3 three, ARG4 four, ARG5 five, \ 147 ARG6 six, gpointer userdata) { \ 148 return reinterpret_cast<CLASS*>(userdata)-> \ 149 METHOD(sender, one, two, three, four, five, six); \ 150 } \ 151 \ 152 virtual RETURN METHOD(SENDER, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); 153 154 #endif 155