~muktupavels/metacity/adwaita-icon-theme-lp-1414613

« back to all changes in this revision

Viewing changes to src/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-10-03 22:44:28 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20051003224428-ft31gkmz12qpzohj
Tags: 1:2.12.1-0ubuntu1
* New upstream release:
  - Thanks to Ray Strode, Havoc Pennington, and Elijah Newren for
    improvements in this release.
  - Truncate ridiculously long titles to avoid crashing or letting the
    pager crash (Ray, Havoc, Elijah) [#315070] (Ubuntu: #15995)
  - Get the tabbing window outline to work with gtk+ 2.8.4 again
    (Elijah) [#317528] (Ubuntu: #16589)
  - Translations: Mahay Alam Khan (bn), Francisco Javier F. Serrador (es), 
    Ivar Smolin (et), I\uffffaki Larra\uffffaga Murgoitio (eu), Luca 
    Ferretti (it), Christian Rose (sv), Clytie Siddall (vi), Funda 
    Wang (zh_CN)
* debian/control.in:
  - Bumped Standards-Version.
* debian/patches/003_bordersdrawingfix.patch:
  - dropped, fixed upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Metacity main() */
 
2
 
 
3
/* 
 
4
 * Copyright (C) 2001 Havoc Pennington
 
5
 * 
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License as
 
8
 * published by the Free Software Foundation; either version 2 of the
 
9
 * License, or (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * General Public License for more details.
 
15
 * 
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
19
 * 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include <config.h>
 
23
#include "main.h"
 
24
#include "util.h"
 
25
#include "display.h"
 
26
#include "errors.h"
 
27
#include "ui.h"
 
28
#include "session.h"
 
29
#include "prefs.h"
 
30
 
 
31
#include <glib-object.h>
 
32
#include <gmodule.h>
 
33
#ifdef HAVE_GCONF
 
34
#include <gconf/gconf-client.h>
 
35
#endif
 
36
 
 
37
 
 
38
#include <stdlib.h>
 
39
#include <sys/types.h>
 
40
#include <stdio.h>
 
41
#include <string.h>
 
42
#include <signal.h>
 
43
#include <unistd.h>
 
44
#include <errno.h>
 
45
#include <fcntl.h>
 
46
#include <locale.h>
 
47
#include <time.h>
 
48
 
 
49
static MetaExitCode meta_exit_code = META_EXIT_SUCCESS;
 
50
static GMainLoop *meta_main_loop = NULL;
 
51
static gboolean meta_restart_after_quit = FALSE;
 
52
 
 
53
static void prefs_changed_callback (MetaPreference pref,
 
54
                                    gpointer       data);
 
55
 
 
56
static void
 
57
log_handler (const gchar   *log_domain,
 
58
             GLogLevelFlags log_level,
 
59
             const gchar   *message,
 
60
             gpointer       user_data)
 
61
{
 
62
  meta_warning ("Log level %d: %s\n", log_level, message);
 
63
  meta_print_backtrace ();
 
64
}
 
65
 
 
66
static void
 
67
version (void)
 
68
{
 
69
  g_print (_("metacity %s\n"
 
70
             "Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n"
 
71
             "This is free software; see the source for copying conditions.\n"
 
72
             "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
 
73
           VERSION);
 
74
  exit (0);
 
75
}
 
76
 
 
77
#define GNOME_ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility"
 
78
 
 
79
static char *
 
80
find_accessibility_module (const char *libname)
 
81
{
 
82
  char *path;
 
83
  char *fname;
 
84
  char *retval;
 
85
 
 
86
  retval = NULL;
 
87
  
 
88
  fname = g_strconcat (libname, "." G_MODULE_SUFFIX, NULL);
 
89
  path = g_strconcat (METACITY_LIBDIR"/gtk-2.0/modules", G_DIR_SEPARATOR_S, fname, NULL);
 
90
 
 
91
  if (g_file_test (path, G_FILE_TEST_EXISTS))
 
92
    retval = path;
 
93
 
 
94
  if (path)
 
95
    retval = path;
 
96
  else
 
97
    g_free (path);
 
98
 
 
99
  g_free (fname);
 
100
 
 
101
  return retval;
 
102
}
 
103
 
 
104
static gboolean
 
105
accessibility_invoke_module (const char   *libname,
 
106
                             gboolean      init)
 
107
{
 
108
  GModule    *handle;
 
109
  void      (*invoke_fn) (void);
 
110
  const char *method;
 
111
  gboolean    retval = FALSE;
 
112
  char       *module_name;
 
113
 
 
114
  if (init)
 
115
    method = "gnome_accessibility_module_init";
 
116
  else
 
117
    method = "gnome_accessibility_module_shutdown";
 
118
 
 
119
  module_name = find_accessibility_module (libname);
 
120
 
 
121
  if (!module_name)
 
122
    {
 
123
      g_warning ("Accessibility: failed to find module '%s' which "
 
124
                 "is needed to make this application accessible",
 
125
                 libname);
 
126
 
 
127
    }
 
128
  else if (!(handle = g_module_open (module_name, G_MODULE_BIND_LAZY)))
 
129
    {
 
130
      g_warning ("Accessibility: failed to load module '%s': '%s'",
 
131
                 libname, g_module_error ());
 
132
 
 
133
    }
 
134
  else if (!g_module_symbol (handle, method, (gpointer *)&invoke_fn))
 
135
    {
 
136
      g_warning ("Accessibility: error library '%s' does not include "
 
137
                 "method '%s' required for accessibility support",
 
138
                 libname, method);
 
139
      g_module_close (handle);
 
140
 
 
141
    }
 
142
  else
 
143
    {
 
144
      retval = TRUE;
 
145
      invoke_fn ();
 
146
    }
 
147
 
 
148
  g_free (module_name);
 
149
 
 
150
  return retval;
 
151
}
 
152
 
 
153
static gboolean
 
154
accessibility_invoke (gboolean init)
 
155
{
 
156
  accessibility_invoke_module ("libgail", init);
 
157
  accessibility_invoke_module ("libatk-bridge", init);
 
158
  return TRUE;
 
159
}
 
160
 
 
161
static void
 
162
meta_print_compilation_info (void)
 
163
{
 
164
#ifdef HAVE_SHAPE
 
165
  meta_verbose ("Compiled with shape extension\n");
 
166
#else
 
167
  meta_verbose ("Compiled without shape extension\n");
 
168
#endif
 
169
#ifdef HAVE_XINERAMA
 
170
  meta_topic (META_DEBUG_XINERAMA, "Compiled with Xinerama extension\n");
 
171
#else
 
172
  meta_topic (META_DEBUG_XINERAMA, "Compiled without Xinerama extension\n");
 
173
#endif
 
174
#ifdef HAVE_XFREE_XINERAMA
 
175
  meta_topic (META_DEBUG_XINERAMA, " (using XFree86 Xinerama)\n");
 
176
#else
 
177
  meta_topic (META_DEBUG_XINERAMA, " (not using XFree86 Xinerama)\n");
 
178
#endif
 
179
#ifdef HAVE_SOLARIS_XINERAMA
 
180
  meta_topic (META_DEBUG_XINERAMA, " (using Solaris Xinerama)\n");
 
181
#else
 
182
  meta_topic (META_DEBUG_XINERAMA, " (not using Solaris Xinerama)\n");
 
183
#endif
 
184
#ifdef HAVE_XSYNC
 
185
  meta_verbose ("Compiled with sync extension\n");
 
186
#else
 
187
  meta_verbose ("Compiled without sync extension\n");
 
188
#endif
 
189
#ifdef HAVE_RANDR
 
190
  meta_verbose ("Compiled with randr extension\n");
 
191
#else
 
192
  meta_verbose ("Compiled without randr extension\n");
 
193
#endif
 
194
#ifdef HAVE_STARTUP_NOTIFICATION
 
195
  meta_verbose ("Compiled with startup notification\n");
 
196
#else
 
197
  meta_verbose ("Compiled without startup notification\n");
 
198
#endif
 
199
#ifdef HAVE_COMPOSITE_EXTENSIONS
 
200
  meta_verbose ("Compiled with composite extensions\n");
 
201
#else
 
202
  meta_verbose ("Compiled without composite extensions\n");
 
203
#endif
 
204
}
 
205
 
 
206
static void
 
207
meta_print_self_identity (void)
 
208
{
 
209
  char buf[256];
 
210
  GDate d;
 
211
  const char *charset;
 
212
 
 
213
  /* Version and current date. */
 
214
  g_date_clear (&d, 1);
 
215
  g_date_set_time (&d, time (NULL));
 
216
  g_date_strftime (buf, sizeof (buf), "%x", &d);
 
217
  meta_verbose ("Metacity version %s running on %s\n",
 
218
    VERSION, buf);
 
219
  
 
220
  /* Locale and encoding. */
 
221
  g_get_charset (&charset);
 
222
  meta_verbose ("Running in locale \"%s\" with encoding \"%s\"\n",
 
223
    setlocale (LC_ALL, NULL), charset);
 
224
 
 
225
  /* Compilation settings. */
 
226
  meta_print_compilation_info ();
 
227
}
 
228
 
 
229
typedef struct
 
230
{
 
231
  gchar *save_file;
 
232
  gchar *display_name;
 
233
  gchar *client_id;
 
234
  gboolean replace_wm;
 
235
  gboolean disable_sm;
 
236
  gboolean print_version;
 
237
} MetaArguments;
 
238
 
 
239
/**
 
240
 * meta_parse_options() parses argc and argv and returns the
 
241
 * arguments that Metacity understands in struct
 
242
 * MetaArguments. In meta_args.
 
243
 *
 
244
 * The strange call signature has to be written like it is so
 
245
 * that g_option_context_parse() gets a chance to modify argc and
 
246
 * argv.
 
247
 **/
 
248
static void
 
249
meta_parse_options (int *argc, char ***argv,
 
250
                    MetaArguments *meta_args)
 
251
{
 
252
  MetaArguments my_args = {NULL, NULL, NULL, FALSE, FALSE, FALSE};
 
253
  GOptionEntry options[] = {
 
254
    {
 
255
      "sm-disable", 0, 0, G_OPTION_ARG_NONE,
 
256
      &my_args.disable_sm,
 
257
      N_("Disable connection to session manager"),
 
258
      NULL
 
259
    },
 
260
    {
 
261
      "replace", 0, 0, G_OPTION_ARG_NONE,
 
262
      &my_args.replace_wm,
 
263
      N_("Replace the running window manager with Metacity"),
 
264
      NULL
 
265
    },
 
266
    {
 
267
      "sm-client-id", 0, 0, G_OPTION_ARG_STRING,
 
268
      &my_args.client_id,
 
269
      N_("Specify session management ID"),
 
270
      "ID"
 
271
    },
 
272
    {
 
273
      "display", 0, 0, G_OPTION_ARG_STRING,
 
274
      &my_args.display_name, N_("X Display to use"),
 
275
      "DISPLAY"
 
276
    },
 
277
    {
 
278
      "sm-save-file", 0, 0, G_OPTION_ARG_FILENAME,
 
279
      &my_args.save_file,
 
280
      N_("Initialize session from savefile"),
 
281
      "FILE"
 
282
    },
 
283
    {
 
284
      "version", 0, 0, G_OPTION_ARG_NONE,
 
285
      &my_args.print_version,
 
286
      N_("Print version"),
 
287
      NULL
 
288
    },
 
289
    {NULL}
 
290
  };
 
291
  GOptionContext *ctx;
 
292
  GError *error = NULL;
 
293
 
 
294
  ctx = g_option_context_new (NULL);
 
295
  g_option_context_add_main_entries (ctx, options, "metacity");
 
296
  if (!g_option_context_parse (ctx, argc, argv, &error))
 
297
    {
 
298
      g_print ("metacity: %s\n", error->message);
 
299
      exit(1);
 
300
    }
 
301
  g_option_context_free (ctx);
 
302
  /* Return the parsed options through the meta_args param. */
 
303
  *meta_args = my_args;
 
304
}
 
305
 
 
306
/**
 
307
 * meta_select_display() is a helper function that selects
 
308
 * which display Metacity should use. It first tries to use
 
309
 * display_name as the display. If display_name is NULL then
 
310
 * try to use the environment variable METACITY_DISPLAY. If that
 
311
 * also is NULL, use the default - :0.0
 
312
 */
 
313
static
 
314
void meta_select_display (gchar *display_name)
 
315
{
 
316
  gchar *envVar = "";
 
317
  if (display_name)
 
318
    envVar = g_strconcat ("DISPLAY=", display_name, NULL);
 
319
  else if (g_getenv ("METACITY_DISPLAY"))
 
320
    envVar = g_strconcat ("DISPLAY=",
 
321
      g_getenv ("METACITY_DISPLAY"), NULL);
 
322
  /* DO NOT FREE envVar, putenv() sucks */
 
323
  putenv (envVar);
 
324
}
 
325
    
 
326
int
 
327
main (int argc, char **argv)
 
328
{
 
329
  struct sigaction act;
 
330
  sigset_t empty_mask;
 
331
  MetaArguments meta_args;
 
332
 
 
333
  g_set_prgname (argv[0]);
 
334
  
 
335
  if (setlocale (LC_ALL, "") == NULL)
 
336
    meta_warning ("Locale not understood by C library, internationalization will not work\n");
 
337
  
 
338
  sigemptyset (&empty_mask);
 
339
  act.sa_handler = SIG_IGN;
 
340
  act.sa_mask    = empty_mask;
 
341
  act.sa_flags   = 0;
 
342
  if (sigaction (SIGPIPE,  &act, NULL) < 0)
 
343
    g_printerr ("Failed to register SIGPIPE handler: %s\n",
 
344
                g_strerror (errno));
 
345
#ifdef SIGXFSZ
 
346
  if (sigaction (SIGXFSZ,  &act, NULL) < 0)
 
347
    g_printerr ("Failed to register SIGXFSZ handler: %s\n",
 
348
                g_strerror (errno));
 
349
#endif
 
350
 
 
351
  if (g_getenv ("METACITY_VERBOSE"))
 
352
    meta_set_verbose (TRUE);
 
353
  if (g_getenv ("METACITY_DEBUG"))
 
354
    meta_set_debugging (TRUE);
 
355
  meta_set_syncing (g_getenv ("METACITY_SYNC") != NULL);
 
356
 
 
357
  if (g_get_home_dir ())
 
358
    chdir (g_get_home_dir ());
 
359
 
 
360
  meta_print_self_identity ();
 
361
  
 
362
  bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
 
363
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
364
  textdomain (GETTEXT_PACKAGE);
 
365
 
 
366
  /* Parse command line arguments.*/
 
367
  meta_parse_options (&argc, &argv, &meta_args);
 
368
 
 
369
  if (meta_args.print_version)
 
370
    version ();
 
371
 
 
372
  meta_select_display (meta_args.display_name);
 
373
  
 
374
  if (meta_args.replace_wm)
 
375
    meta_set_replace_current_wm (TRUE);
 
376
 
 
377
  if (meta_args.save_file && meta_args.client_id)
 
378
    meta_fatal ("Can't specify both SM save file and SM client id\n");
 
379
  
 
380
  meta_main_loop = g_main_loop_new (NULL, FALSE);
 
381
  
 
382
  g_type_init ();
 
383
 
 
384
  /* Load prefs */
 
385
  meta_prefs_init ();
 
386
  meta_prefs_add_listener (prefs_changed_callback, NULL);
 
387
 
 
388
  meta_ui_init (&argc, &argv);  
 
389
 
 
390
  /* must be after UI init so we can override GDK handlers */
 
391
  meta_errors_init ();
 
392
 
 
393
#if 1
 
394
  g_log_set_handler (NULL,
 
395
                     G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
 
396
                     log_handler, NULL);
 
397
  g_log_set_handler (G_LOG_DOMAIN,
 
398
                     G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
 
399
                     log_handler, NULL);
 
400
  g_log_set_handler ("Gtk",
 
401
                     G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
 
402
                     log_handler, NULL);
 
403
  g_log_set_handler ("Gdk",
 
404
                     G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
 
405
                     log_handler, NULL);
 
406
  g_log_set_handler ("GLib",
 
407
                     G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
 
408
                     log_handler, NULL);
 
409
  g_log_set_handler ("Pango",
 
410
                     G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
 
411
                     log_handler, NULL);
 
412
  g_log_set_handler ("GLib-GObject",
 
413
                     G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
 
414
                     log_handler, NULL);
 
415
  g_log_set_handler ("GThread",
 
416
                     G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
 
417
                     log_handler, NULL);
 
418
#endif
 
419
 
 
420
  if (g_getenv ("METACITY_G_FATAL_WARNINGS") != NULL)
 
421
    g_log_set_always_fatal (G_LOG_LEVEL_MASK);
 
422
  
 
423
  meta_ui_set_current_theme (meta_prefs_get_theme (), FALSE);
 
424
 
 
425
  /* Try to find some theme that'll work if the theme preference
 
426
   * doesn't exist.  First try Simple (the default theme) then just
 
427
   * try anything in the themes directory.
 
428
   */
 
429
  if (!meta_ui_have_a_theme ())
 
430
    meta_ui_set_current_theme ("Simple", FALSE);
 
431
  
 
432
  if (!meta_ui_have_a_theme ())
 
433
    {
 
434
      const char *dir_entry = NULL;
 
435
      GError *err = NULL;
 
436
      GDir   *themes_dir = NULL;
 
437
      
 
438
      if (!(themes_dir = g_dir_open (METACITY_DATADIR"/themes", 0, &err)))
 
439
        {
 
440
          meta_fatal (_("Failed to scan themes directory: %s\n"), err->message);
 
441
          g_error_free (err);
 
442
        } 
 
443
      else 
 
444
        {
 
445
          while (((dir_entry = g_dir_read_name (themes_dir)) != NULL) && 
 
446
                 (!meta_ui_have_a_theme ()))
 
447
            {
 
448
              meta_ui_set_current_theme (dir_entry, FALSE);
 
449
            }
 
450
          
 
451
          g_dir_close (themes_dir);
 
452
        }
 
453
    }
 
454
  
 
455
  if (!meta_ui_have_a_theme ())
 
456
    meta_fatal (_("Could not find a theme! Be sure %s exists and contains the usual themes."),
 
457
                METACITY_DATADIR"/themes");
 
458
  
 
459
  /* Connect to SM as late as possible - but before managing display,
 
460
   * or we might try to manage a window before we have the session
 
461
   * info
 
462
   */
 
463
  if (!meta_args.disable_sm)
 
464
    meta_session_init (meta_args.client_id, meta_args.save_file);
 
465
  
 
466
  if (!meta_display_open (NULL))
 
467
    meta_exit (META_EXIT_ERROR);
 
468
  
 
469
  {
 
470
    gboolean do_init_a11y;
 
471
    do_init_a11y = FALSE;
 
472
 
 
473
#ifdef HAVE_GCONF
 
474
    do_init_a11y = gconf_client_get_bool (
 
475
                        gconf_client_get_default (),
 
476
                        GNOME_ACCESSIBILITY_KEY, NULL);
 
477
#endif
 
478
 
 
479
    if (do_init_a11y)
 
480
      accessibility_invoke (TRUE);
 
481
  }
 
482
 
 
483
  g_main_run (meta_main_loop);
 
484
 
 
485
  {
 
486
    GSList *displays;
 
487
    GSList *tmp;
 
488
 
 
489
    /* we need a copy since closing the display removes it
 
490
     * from the list
 
491
     */
 
492
    displays = g_slist_copy (meta_displays_list ());
 
493
    tmp = displays;
 
494
    while (tmp != NULL)
 
495
      {
 
496
        meta_display_close (tmp->data);
 
497
        tmp = tmp->next;
 
498
      }
 
499
    g_slist_free (displays);
 
500
  }
 
501
 
 
502
  meta_session_shutdown ();
 
503
  
 
504
  if (meta_restart_after_quit)
 
505
    {
 
506
      GError *err;
 
507
 
 
508
      err = NULL;
 
509
      if (!g_spawn_async (NULL,
 
510
                          argv,
 
511
                          NULL,
 
512
                          G_SPAWN_SEARCH_PATH,
 
513
                          NULL,
 
514
                          NULL,
 
515
                          NULL,
 
516
                          &err))
 
517
        {
 
518
          meta_fatal (_("Failed to restart: %s\n"),
 
519
                      err->message);
 
520
          g_error_free (err); /* not reached anyhow */
 
521
          meta_exit_code = META_EXIT_ERROR;
 
522
        }
 
523
    }
 
524
  
 
525
  return meta_exit_code;
 
526
}
 
527
 
 
528
GMainLoop*
 
529
meta_get_main_loop (void)
 
530
{
 
531
  return meta_main_loop;
 
532
}
 
533
 
 
534
void
 
535
meta_quit (MetaExitCode code)
 
536
{
 
537
  meta_exit_code = code;
 
538
 
 
539
  if (g_main_is_running (meta_main_loop))
 
540
    g_main_quit (meta_main_loop);
 
541
}
 
542
 
 
543
void
 
544
meta_restart (void)
 
545
{
 
546
  meta_restart_after_quit = TRUE;
 
547
  meta_quit (META_EXIT_SUCCESS);
 
548
}
 
549
 
 
550
static void
 
551
prefs_changed_callback (MetaPreference pref,
 
552
                        gpointer       data)
 
553
{
 
554
  switch (pref)
 
555
    {
 
556
    case META_PREF_THEME:
 
557
      meta_ui_set_current_theme (meta_prefs_get_theme (), FALSE);
 
558
      meta_display_retheme_all ();
 
559
      break;
 
560
 
 
561
    case META_PREF_CURSOR_THEME:
 
562
    case META_PREF_CURSOR_SIZE:
 
563
      meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (),
 
564
                                     meta_prefs_get_cursor_size ());
 
565
      break;
 
566
    default:
 
567
      /* handled elsewhere or otherwise */
 
568
      break;
 
569
    }
 
570
}