00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00054
00055 static void gdk_exit_func(void);
00056
00057 GdkFilterReturn gdk_wm_protocols_filter(GdkXEvent * xev,
00058 GdkEvent * event, gpointer data);
00059
00060
00061
00062 static int gdk_initialized = 0;
00063
00064
00065
00066 static GSList *gdk_error_traps = NULL;
00067 static GSList *gdk_error_trap_free_list = NULL;
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
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
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
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
00227 {NULL}
00228 };
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
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
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
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 void gdk_exit(gint errorcode)
00358 {
00359
00360
00361 exit(errorcode);
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 static void gdk_exit_func(void)
00382 {
00383 static gboolean in_gdk_exit_func = FALSE;
00384
00385
00386
00387
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
00395 gdk_ic_cleanup();
00396
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
00409
00410
00411
00412
00413
00414
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
00443
00444
00445
00446
00447
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
00475
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:
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
00499
00500 #if defined (GDK_Aogonek) && defined (GDK_tcedilla)
00501 case 1:
00502
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
00525
00526 #if defined (GDK_Hstroke) && defined (GDK_Cabovedot)
00527 case 2:
00528
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
00543
00544 #if defined (GDK_Rcedilla) && defined (GDK_Amacron)
00545 case 3:
00546
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
00561
00562 #if defined (GDK_Serbian_DJE) && defined (GDK_Cyrillic_yu)
00563 case 6:
00564
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
00577
00578 #if defined (GDK_Greek_ALPHAaccent) && defined (GDK_Greek_finalsmallsigma)
00579 case 7:
00580
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
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 }