gdk.c

Go to the documentation of this file.
00001 /* GDK - The GIMP Drawing Kit
00002  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 /*
00021  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
00022  * file for a list of people on the GTK+ Team.  See the ChangeLog
00023  * files for a list of changes.  These files are distributed with
00024  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
00025  */
00026 
00027 #include "config.h"
00028 
00029 #include <string.h>
00030 #include <stdlib.h>
00031 
00032 #include "gdk.h"
00033 #include "gdkprivate.h"
00034 
00035 #ifndef HAVE_XCONVERTCASE
00036 #include "gdkkeysyms.h"
00037 #endif
00038 
00039 typedef struct _GdkPredicate GdkPredicate;
00040 typedef struct _GdkErrorTrap GdkErrorTrap;
00041 
00042 struct _GdkPredicate {
00043    GdkEventFunc func;
00044    gpointer data;
00045 };
00046 
00047 struct _GdkErrorTrap {
00048    gint error_warnings;
00049    gint error_code;
00050 };
00051 
00052 /* 
00053  * Private function declarations
00054  */
00055 static void gdk_exit_func(void);
00056 
00057 GdkFilterReturn gdk_wm_protocols_filter(GdkXEvent * xev,
00058                                         GdkEvent * event, gpointer data);
00059 
00060 /* Private variable declarations
00061  */
00062 static int gdk_initialized = 0; /* 1 if the library is initialized,
00063                                  * 0 otherwise.
00064                                  */
00065 
00066 static GSList *gdk_error_traps = NULL;  /* List of error traps */
00067 static GSList *gdk_error_trap_free_list = NULL; /* Free list */
00068 
00069 #ifdef G_ENABLE_DEBUG
00070 static const GDebugKey gdk_debug_keys[] = {
00071    {"events", GDK_DEBUG_EVENTS},
00072    {"misc", GDK_DEBUG_MISC},
00073    {"dnd", GDK_DEBUG_DND},
00074    {"color-context", GDK_DEBUG_COLOR_CONTEXT},
00075    {"xim", GDK_DEBUG_XIM}
00076 };
00077 
00078 static const int gdk_ndebug_keys =
00079     sizeof(gdk_debug_keys) / sizeof(GDebugKey);
00080 
00081 #endif                          /* G_ENABLE_DEBUG */
00082 
00083 GdkArgContext *gdk_arg_context_new(gpointer cb_data)
00084 {
00085    GdkArgContext *result = g_new(GdkArgContext, 1);
00086    result->tables = g_ptr_array_new();
00087    result->cb_data = cb_data;
00088 
00089    return result;
00090 }
00091 
00092 void gdk_arg_context_destroy(GdkArgContext * context)
00093 {
00094    g_ptr_array_free(context->tables, TRUE);
00095    g_free(context);
00096 }
00097 
00098 void gdk_arg_context_add_table(GdkArgContext * context, GdkArgDesc * table)
00099 {
00100    g_ptr_array_add(context->tables, table);
00101 }
00102 
00103 void
00104 gdk_arg_context_parse(GdkArgContext * context, gint * argc, gchar *** argv)
00105 {
00106    int i, j, k;
00107 
00108    /* Save a copy of the original argc and argv */
00109    if (argc && argv) {
00110       for (i = 1; i < *argc; i++) {
00111          char *arg;
00112 
00113          if (!(*argv)[i][0] == '-' && (*argv)[i][1] == '-')
00114             continue;
00115 
00116          arg = (*argv)[i] + 2;
00117 
00118          /* '--' terminates list of arguments */
00119          if (arg == 0) {
00120             (*argv)[i] = NULL;
00121             break;
00122          }
00123 
00124          for (j = 0; j < (int)context->tables->len; j++) {
00125             GdkArgDesc *table = context->tables->pdata[j];
00126             for (k = 0; table[k].name; k++) {
00127                switch (table[k].type) {
00128                case GDK_ARG_STRING:
00129                case GDK_ARG_CALLBACK:
00130                case GDK_ARG_INT:
00131                   {
00132                      int len = strlen(table[k].name);
00133 
00134                      if (strncmp(arg, table[k].name, len) == 0 &&
00135                          (arg[len] == '=' || argc[len] == 0)) {
00136                         char *value = NULL;
00137 
00138                         (*argv)[i] = NULL;
00139 
00140                         if (arg[len] == '=')
00141                            value = arg + len + 1;
00142                         else if (i < *argc - 1) {
00143                            value = (*argv)[i + 1];
00144                            (*argv)[i + 1] = NULL;
00145                            i++;
00146                         } else
00147                            value = "";
00148 
00149                         switch (table[k].type) {
00150                         case GDK_ARG_STRING:
00151                            *(gchar **) table[k].location = g_strdup(value);
00152                            break;
00153                         case GDK_ARG_INT:
00154                            *(gint *) table[k].location = atoi(value);
00155                            break;
00156                         case GDK_ARG_CALLBACK:
00157                            (*table[k].callback) (table[k].name, value,
00158                                                  context->cb_data);
00159                            break;
00160                         default:
00161                            ;
00162                         }
00163 
00164                         goto next_arg;
00165                      }
00166                      break;
00167                   }
00168                case GDK_ARG_BOOL:
00169                case GDK_ARG_NOBOOL:
00170                   if (strcmp(arg, table[k].name) == 0) {
00171                      (*argv)[i] = NULL;
00172 
00173                      *(gboolean *) table[k].location =
00174                          (table[k].type == GDK_ARG_BOOL) ? TRUE : FALSE;
00175                      goto next_arg;
00176                   }
00177                }
00178             }
00179          }
00180        next_arg:
00181          ;
00182       }
00183 
00184       for (i = 1; i < *argc; i++) {
00185          for (k = i; k < *argc; k++)
00186             if ((*argv)[k] != NULL)
00187                break;
00188 
00189          if (k > i) {
00190             k -= i;
00191             for (j = i + k; j < *argc; j++)
00192                (*argv)[j - k] = (*argv)[j];
00193             *argc -= k;
00194          }
00195       }
00196    }
00197 }
00198 
00199 static void
00200 gdk_arg_debug_cb(const char *key, const char *value, gpointer user_data)
00201 {
00202    gdk_debug_flags |= g_parse_debug_string(value,
00203                                            (GDebugKey *) gdk_debug_keys,
00204                                            gdk_ndebug_keys);
00205 }
00206 
00207 static void
00208 gdk_arg_no_debug_cb(const char *key, const char *value, gpointer user_data)
00209 {
00210    gdk_debug_flags &= ~g_parse_debug_string(value,
00211                                             (GDebugKey *) gdk_debug_keys,
00212                                             gdk_ndebug_keys);
00213 }
00214 
00215 static void
00216 gdk_arg_name_cb(const char *key, const char *value, gpointer user_data)
00217 {
00218    g_set_prgname(value);
00219 }
00220 
00221 static GdkArgDesc gdk_args[] = {
00222    {"name", GDK_ARG_STRING, NULL, gdk_arg_name_cb},
00223 #ifdef G_ENABLE_DEBUG
00224    {"gdk-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_debug_cb},
00225    {"gdk-no-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_no_debug_cb},
00226 #endif                          /* G_ENABLE_DEBUG */
00227    {NULL}
00228 };
00229 
00230 /*
00231  *--------------------------------------------------------------
00232  * gdk_init_check
00233  *
00234  *   Initialize the library for use.
00235  *
00236  * Arguments:
00237  *   "argc" is the number of arguments.
00238  *   "argv" is an array of strings.
00239  *
00240  * Results:
00241  *   "argc" and "argv" are modified to reflect any arguments
00242  *   which were not handled. (Such arguments should either
00243  *   be handled by the application or dismissed). If initialization
00244  *   fails, returns FALSE, otherwise TRUE.
00245  *
00246  * Side effects:
00247  *   The library is initialized.
00248  *
00249  *--------------------------------------------------------------
00250  */
00251 
00252 gboolean gdk_init_check(int *argc, char ***argv)
00253 {
00254    gchar **argv_orig = NULL;
00255    gint argc_orig = 0;
00256    GdkArgContext *arg_context;
00257    gboolean result;
00258    int i;
00259 
00260    if (gdk_initialized)
00261       return TRUE;
00262 
00263    if (g_thread_supported())
00264       gdk_threads_mutex = g_mutex_new();
00265 
00266    if (argc && argv) {
00267       argc_orig = *argc;
00268 
00269       argv_orig = g_malloc((argc_orig + 1) * sizeof(char *));
00270       for (i = 0; i < argc_orig; i++)
00271          argv_orig[i] = g_strdup((*argv)[i]);
00272       argv_orig[argc_orig] = NULL;
00273 
00274       if (*argc > 0) {
00275          gchar *d;
00276 
00277          d = strrchr((*argv)[0], '/');
00278          if (d != NULL)
00279             g_set_prgname(d + 1);
00280          else
00281             g_set_prgname((*argv)[0]);
00282       }
00283    }
00284 
00285 #ifdef G_ENABLE_DEBUG
00286    {
00287       gchar *debug_string = getenv("GDK_DEBUG");
00288       if (debug_string != NULL)
00289          gdk_debug_flags = g_parse_debug_string(debug_string,
00290                                 (GDebugKey *) gdk_debug_keys, 
00291                                 gdk_ndebug_keys);
00292    }
00293 #endif                          /* G_ENABLE_DEBUG */
00294 
00295    arg_context = gdk_arg_context_new(NULL);
00296    gdk_arg_context_add_table(arg_context, gdk_args);
00297    gdk_arg_context_add_table(arg_context, _gdk_windowing_args);
00298    gdk_arg_context_parse(arg_context, argc, argv);
00299    gdk_arg_context_destroy(arg_context);
00300 
00301    GDK_NOTE(MISC, g_message("progname: \"%s\"", g_get_prgname()));
00302 
00303    result = _gdk_windowing_init_check(argc_orig, argv_orig);
00304 
00305    for (i = 0; i < argc_orig; i++)
00306       g_free(argv_orig[i]);
00307    g_free(argv_orig);
00308 
00309    if (!result)
00310       return FALSE;
00311 
00312    g_atexit(gdk_exit_func);
00313 
00314    gdk_events_init();
00315    gdk_visual_init();
00316    gdk_window_init();
00317    gdk_image_init();
00318    gdk_input_init();
00319    gdk_dnd_init();
00320 
00321 #ifdef USE_XIM
00322    gdk_im_open();
00323 #endif
00324 
00325    gdk_initialized = 1;
00326 
00327    return TRUE;
00328 }
00329 
00330 void gdk_init(int *argc, char ***argv)
00331 {
00332    if (!gdk_init_check(argc, argv)) {
00333       g_warning("cannot open display: %s", gdk_get_display());
00334       exit(1);
00335    }
00336 }
00337 
00338 /*
00339  *--------------------------------------------------------------
00340  * gdk_exit
00341  *
00342  *   Restores the library to an un-itialized state and exits
00343  *   the program using the "exit" system call.
00344  *
00345  * Arguments:
00346  *   "errorcode" is the error value to pass to "exit".
00347  *
00348  * Results:
00349  *   Allocated structures are freed and the program exits
00350  *   cleanly.
00351  *
00352  * Side effects:
00353  *
00354  *--------------------------------------------------------------
00355  */
00356 
00357 void gdk_exit(gint errorcode)
00358 {
00359    /* de-initialisation is done by the gdk_exit_funct(),
00360       no need to do this here (Alex J.) */
00361    exit(errorcode);
00362 }
00363 
00364 /*
00365  *--------------------------------------------------------------
00366  * gdk_exit_func
00367  *
00368  *   This is the "atexit" function that makes sure the
00369  *   library gets a chance to cleanup.
00370  *
00371  * Arguments:
00372  *
00373  * Results:
00374  *
00375  * Side effects:
00376  *   The library is un-initialized and the program exits.
00377  *
00378  *--------------------------------------------------------------
00379  */
00380 
00381 static void gdk_exit_func(void)
00382 {
00383    static gboolean in_gdk_exit_func = FALSE;
00384 
00385    /* This is to avoid an infinite loop if a program segfaults in
00386       an atexit() handler (and yes, it does happen, especially if a program
00387       has trounced over memory too badly for even g_message to work) */
00388    if (in_gdk_exit_func == TRUE)
00389       return;
00390    in_gdk_exit_func = TRUE;
00391 
00392    if (gdk_initialized) {
00393 #ifdef USE_XIM
00394       /* cleanup IC */
00395       gdk_ic_cleanup();
00396       /* close IM */
00397       gdk_im_close();
00398 #endif
00399       gdk_image_exit();
00400       gdk_input_exit();
00401       gdk_key_repeat_restore();
00402 
00403       gdk_initialized = 0;
00404    }
00405 }
00406 
00407 /*************************************************************
00408  * gdk_error_trap_push:
00409  *     Push an error trap. X errors will be trapped until
00410  *     the corresponding gdk_error_pop(), which will return
00411  *     the error code, if any.
00412  *   arguments:
00413  *     
00414  *   results:
00415  *************************************************************/
00416 
00417 void gdk_error_trap_push(void)
00418 {
00419    GSList *node;
00420    GdkErrorTrap *trap;
00421 
00422    if (gdk_error_trap_free_list) {
00423       node = gdk_error_trap_free_list;
00424       gdk_error_trap_free_list = gdk_error_trap_free_list->next;
00425    } else {
00426       node = g_slist_alloc();
00427       node->data = g_new(GdkErrorTrap, 1);
00428    }
00429 
00430    node->next = gdk_error_traps;
00431    gdk_error_traps = node;
00432 
00433    trap = node->data;
00434    trap->error_code = gdk_error_code;
00435    trap->error_warnings = gdk_error_warnings;
00436 
00437    gdk_error_code = 0;
00438    gdk_error_warnings = 0;
00439 }
00440 
00441 /*************************************************************
00442  * gdk_error_trap_pop:
00443  *     Pop an error trap added with gdk_error_push()
00444  *   arguments:
00445  *     
00446  *   results:
00447  *     0, if no error occured, otherwise the error code.
00448  *************************************************************/
00449 
00450 gint gdk_error_trap_pop(void)
00451 {
00452    GSList *node;
00453    GdkErrorTrap *trap;
00454    gint result;
00455 
00456    g_return_val_if_fail(gdk_error_traps != NULL, 0);
00457 
00458    node = gdk_error_traps;
00459    gdk_error_traps = gdk_error_traps->next;
00460 
00461    node->next = gdk_error_trap_free_list;
00462    gdk_error_trap_free_list = node;
00463 
00464    result = gdk_error_code;
00465 
00466    trap = node->data;
00467    gdk_error_code = trap->error_code;
00468    gdk_error_warnings = trap->error_warnings;
00469 
00470    return result;
00471 }
00472 
00473 #ifndef HAVE_XCONVERTCASE
00474 /* compatibility function from X11R6.3, since XConvertCase is not
00475  * supplied by X11R5.
00476  */
00477 void gdk_keyval_convert_case(guint symbol, guint * lower, guint * upper)
00478 {
00479    guint xlower = symbol;
00480    guint xupper = symbol;
00481 
00482    switch (symbol >> 8) {
00483 #if     defined (GDK_A) && defined (GDK_Ooblique)
00484    case 0:                     /* Latin 1 */
00485       if ((symbol >= GDK_A) && (symbol <= GDK_Z))
00486          xlower += (GDK_a - GDK_A);
00487       else if ((symbol >= GDK_a) && (symbol <= GDK_z))
00488          xupper -= (GDK_a - GDK_A);
00489       else if ((symbol >= GDK_Agrave) && (symbol <= GDK_Odiaeresis))
00490          xlower += (GDK_agrave - GDK_Agrave);
00491       else if ((symbol >= GDK_agrave) && (symbol <= GDK_odiaeresis))
00492          xupper -= (GDK_agrave - GDK_Agrave);
00493       else if ((symbol >= GDK_Ooblique) && (symbol <= GDK_Thorn))
00494          xlower += (GDK_oslash - GDK_Ooblique);
00495       else if ((symbol >= GDK_oslash) && (symbol <= GDK_thorn))
00496          xupper -= (GDK_oslash - GDK_Ooblique);
00497       break;
00498 #endif                          /* LATIN1 */
00499 
00500 #if     defined (GDK_Aogonek) && defined (GDK_tcedilla)
00501    case 1:                     /* Latin 2 */
00502       /* Assume the KeySym is a legal value (ignore discontinuities) */
00503       if (symbol == GDK_Aogonek)
00504          xlower = GDK_aogonek;
00505       else if (symbol >= GDK_Lstroke && symbol <= GDK_Sacute)
00506          xlower += (GDK_lstroke - GDK_Lstroke);
00507       else if (symbol >= GDK_Scaron && symbol <= GDK_Zacute)
00508          xlower += (GDK_scaron - GDK_Scaron);
00509       else if (symbol >= GDK_Zcaron && symbol <= GDK_Zabovedot)
00510          xlower += (GDK_zcaron - GDK_Zcaron);
00511       else if (symbol == GDK_aogonek)
00512          xupper = GDK_Aogonek;
00513       else if (symbol >= GDK_lstroke && symbol <= GDK_sacute)
00514          xupper -= (GDK_lstroke - GDK_Lstroke);
00515       else if (symbol >= GDK_scaron && symbol <= GDK_zacute)
00516          xupper -= (GDK_scaron - GDK_Scaron);
00517       else if (symbol >= GDK_zcaron && symbol <= GDK_zabovedot)
00518          xupper -= (GDK_zcaron - GDK_Zcaron);
00519       else if (symbol >= GDK_Racute && symbol <= GDK_Tcedilla)
00520          xlower += (GDK_racute - GDK_Racute);
00521       else if (symbol >= GDK_racute && symbol <= GDK_tcedilla)
00522          xupper -= (GDK_racute - GDK_Racute);
00523       break;
00524 #endif                          /* LATIN2 */
00525 
00526 #if     defined (GDK_Hstroke) && defined (GDK_Cabovedot)
00527    case 2:                     /* Latin 3 */
00528       /* Assume the KeySym is a legal value (ignore discontinuities) */
00529       if (symbol >= GDK_Hstroke && symbol <= GDK_Hcircumflex)
00530          xlower += (GDK_hstroke - GDK_Hstroke);
00531       else if (symbol >= GDK_Gbreve && symbol <= GDK_Jcircumflex)
00532          xlower += (GDK_gbreve - GDK_Gbreve);
00533       else if (symbol >= GDK_hstroke && symbol <= GDK_hcircumflex)
00534          xupper -= (GDK_hstroke - GDK_Hstroke);
00535       else if (symbol >= GDK_gbreve && symbol <= GDK_jcircumflex)
00536          xupper -= (GDK_gbreve - GDK_Gbreve);
00537       else if (symbol >= GDK_Cabovedot && symbol <= GDK_Scircumflex)
00538          xlower += (GDK_cabovedot - GDK_Cabovedot);
00539       else if (symbol >= GDK_cabovedot && symbol <= GDK_scircumflex)
00540          xupper -= (GDK_cabovedot - GDK_Cabovedot);
00541       break;
00542 #endif                          /* LATIN3 */
00543 
00544 #if     defined (GDK_Rcedilla) && defined (GDK_Amacron)
00545    case 3:                     /* Latin 4 */
00546       /* Assume the KeySym is a legal value (ignore discontinuities) */
00547       if (symbol >= GDK_Rcedilla && symbol <= GDK_Tslash)
00548          xlower += (GDK_rcedilla - GDK_Rcedilla);
00549       else if (symbol >= GDK_rcedilla && symbol <= GDK_tslash)
00550          xupper -= (GDK_rcedilla - GDK_Rcedilla);
00551       else if (symbol == GDK_ENG)
00552          xlower = GDK_eng;
00553       else if (symbol == GDK_eng)
00554          xupper = GDK_ENG;
00555       else if (symbol >= GDK_Amacron && symbol <= GDK_Umacron)
00556          xlower += (GDK_amacron - GDK_Amacron);
00557       else if (symbol >= GDK_amacron && symbol <= GDK_umacron)
00558          xupper -= (GDK_amacron - GDK_Amacron);
00559       break;
00560 #endif                          /* LATIN4 */
00561 
00562 #if     defined (GDK_Serbian_DJE) && defined (GDK_Cyrillic_yu)
00563    case 6:                     /* Cyrillic */
00564       /* Assume the KeySym is a legal value (ignore discontinuities) */
00565       if (symbol >= GDK_Serbian_DJE && symbol <= GDK_Serbian_DZE)
00566          xlower -= (GDK_Serbian_DJE - GDK_Serbian_dje);
00567       else if (symbol >= GDK_Serbian_dje && symbol <= GDK_Serbian_dze)
00568          xupper += (GDK_Serbian_DJE - GDK_Serbian_dje);
00569       else if (symbol >= GDK_Cyrillic_YU
00570                && symbol <= GDK_Cyrillic_HARDSIGN)
00571          xlower -= (GDK_Cyrillic_YU - GDK_Cyrillic_yu);
00572       else if (symbol >= GDK_Cyrillic_yu
00573                && symbol <= GDK_Cyrillic_hardsign)
00574          xupper += (GDK_Cyrillic_YU - GDK_Cyrillic_yu);
00575       break;
00576 #endif                          /* CYRILLIC */
00577 
00578 #if     defined (GDK_Greek_ALPHAaccent) && defined (GDK_Greek_finalsmallsigma)
00579    case 7:                     /* Greek */
00580       /* Assume the KeySym is a legal value (ignore discontinuities) */
00581       if (symbol >= GDK_Greek_ALPHAaccent
00582           && symbol <= GDK_Greek_OMEGAaccent)
00583          xlower += (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent);
00584       else if (symbol >= GDK_Greek_alphaaccent
00585                && symbol <= GDK_Greek_omegaaccent
00586                && symbol != GDK_Greek_iotaaccentdieresis
00587                && symbol != GDK_Greek_upsilonaccentdieresis)
00588          xupper -= (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent);
00589       else if (symbol >= GDK_Greek_ALPHA && symbol <= GDK_Greek_OMEGA)
00590          xlower += (GDK_Greek_alpha - GDK_Greek_ALPHA);
00591       else if (symbol >= GDK_Greek_alpha && symbol <= GDK_Greek_omega &&
00592                symbol != GDK_Greek_finalsmallsigma)
00593          xupper -= (GDK_Greek_alpha - GDK_Greek_ALPHA);
00594       break;
00595 #endif                          /* GREEK */
00596    }
00597 
00598    if (lower)
00599       *lower = xlower;
00600    if (upper)
00601       *upper = xupper;
00602 }
00603 #endif
00604 
00605 guint gdk_keyval_to_upper(guint keyval)
00606 {
00607    guint result;
00608 
00609    gdk_keyval_convert_case(keyval, NULL, &result);
00610 
00611    return result;
00612 }
00613 
00614 guint gdk_keyval_to_lower(guint keyval)
00615 {
00616    guint result;
00617 
00618    gdk_keyval_convert_case(keyval, &result, NULL);
00619 
00620    return result;
00621 }
00622 
00623 gboolean gdk_keyval_is_upper(guint keyval)
00624 {
00625    if (keyval) {
00626       guint upper_val = 0;
00627 
00628       gdk_keyval_convert_case(keyval, NULL, &upper_val);
00629       return upper_val == keyval;
00630    }
00631    return FALSE;
00632 }
00633 
00634 gboolean gdk_keyval_is_lower(guint keyval)
00635 {
00636    if (keyval) {
00637       guint lower_val = 0;
00638 
00639       gdk_keyval_convert_case(keyval, &lower_val, NULL);
00640       return lower_val == keyval;
00641    }
00642    return FALSE;
00643 }
00644 
00645 void gdk_threads_enter()
00646 {
00647    GDK_THREADS_ENTER();
00648 }
00649 
00650 void gdk_threads_leave()
00651 {
00652    GDK_THREADS_LEAVE();
00653 }

Generated on Tue Jul 5 14:14:36 2011 for ROOT_528-00b_version by  doxygen 1.5.1