~ubuntu-branches/ubuntu/utopic/gxine/utopic-proposed

« back to all changes in this revision

Viewing changes to .pc/debian-changes/src/wizards.c

  • Committer: Package Import Robot
  • Author(s): Steve Langasek
  • Date: 2014-05-07 21:34:55 UTC
  • mfrom: (2.1.17 sid)
  • Revision ID: package-import@ubuntu.com-20140507213455-qnu5diwyyj8bkaap
Tags: 0.5.907-3ubuntu1
* Merge from Debian unstable, remaining changes:
  - debian/rules, debian/control: use dh-autoreconf at build time.
  - debian/control: Add Xb-Npp-xxx, Xb-Npp-Description and Xb-Npp-File
    fields.
  - src/script_engine.c: fix a remaining memory leak issue associated with
    using JS_EncodeString(), which somehow didn't get fixed upstream
  - debian/gxineplugin.links: Add a link to xulrunner-addons/plugins
    directory.
  - mime.default: Add dvd, vcd, svcd tags.
* Dropped changes, no longer needed:
  - debian/gxine.install: no need to diverge from Debian since we no longer
    ship a wrapper
* All other changes dropped, as they have been included upstream or in
  Debian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2001-2007 the xine-project
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU General Public License as
6
 
 * published by the Free Software Foundation; either version 2 of the
7
 
 * License, or (at your option) any later version.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; if not, write to the Free Software
16
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
17
 
 * USA
18
 
 *
19
 
 * stuff to run on first startup / setup wizards
20
 
 */
21
 
 
22
 
#include "globals.h"
23
 
 
24
 
#include <sys/types.h>
25
 
#include <sys/stat.h>
26
 
#include <fcntl.h>
27
 
#include <unistd.h>
28
 
#include <errno.h>
29
 
 
30
 
#include <X11/Xlib.h>
31
 
 
32
 
#include <gtk/gtk.h>
33
 
#include <gdk/gdk.h>
34
 
#include <glib.h>
35
 
#include <stdio.h>
36
 
#include <stdlib.h>
37
 
#include <string.h>
38
 
 
39
 
#include "wizards.h"
40
 
#include "ui.h"
41
 
#include "utils.h"
42
 
#include "desktop_integration.h"
43
 
#include "preferences.h"
44
 
 
45
 
static GtkWidget *add_label (GtkBox *vbox, const char *label)
46
 
{
47
 
  GtkWidget *l = ui_label_new_with_markup (label);
48
 
  gtk_label_set_line_wrap (GTK_LABEL (l), TRUE);
49
 
  gtk_misc_set_alignment (GTK_MISC (l), 0, 0.5);
50
 
  gtk_box_pack_start (vbox, l, FALSE, FALSE, 5);
51
 
  return l;
52
 
}
53
 
 
54
 
static GtkWidget *add_heading (GtkBox *vbox, const char *label)
55
 
{
56
 
  char *markup = g_strdup_printf ("<big><b>%s</b></big>", label);
57
 
  GtkWidget *l = add_label (vbox, markup);
58
 
  free (markup);
59
 
  return l;
60
 
}
61
 
 
62
 
static gboolean do_welcome (GtkDialog *dlg, GtkBox *vbox)
63
 
{
64
 
  add_heading (vbox, _("Welcome to gxine!\n\n"));
65
 
  add_label (vbox, _("Would you like to run some setup wizards now "
66
 
                     "that will check your installation and maybe "
67
 
                     "do some adjustments for you if necessary?\n\n"
68
 
                     "If you do not want to run the wizards right now, "
69
 
                     "just click on the <i>Close</i> button and you will "
70
 
                     "not be bothered again.\n\n"
71
 
                     "You can always run the wizards (again) from the "
72
 
                     "help menu."));
73
 
  return FALSE;
74
 
};
75
 
 
76
 
 
77
 
typedef struct {
78
 
  char *msg, *explanation;
79
 
} hc_msg_t;
80
 
 
81
 
static void details_cb (GtkWidget* widget, gpointer data)
82
 
{
83
 
  hc_msg_t *msg = data;
84
 
  display_info (FROM_GXINE, _("Health Check Results"), "%s\n%s",
85
 
                msg->msg, msg->explanation);
86
 
}
87
 
 
88
 
static void hc_update_pref (const char *pref, const char *value)
89
 
{
90
 
  xine_cfg_entry_t entry;
91
 
  xine_config_lookup_entry (xine, pref, &entry);
92
 
  entry.str_value = (char *)value;
93
 
  preferences_update_entry (&entry);
94
 
}
95
 
 
96
 
static gboolean do_health_check (GtkDialog *dlg, GtkBox *vbox)
97
 
{
98
 
  GtkWidget           *l, *table, *b;
99
 
  xine_health_check_t  hc;
100
 
  xine_health_check_t *results;
101
 
  int                  check;
102
 
  hc_msg_t            *msg;
103
 
 
104
 
  table = gtk_table_new (1, 1, FALSE);
105
 
 
106
 
  add_heading (vbox, _("System configuration check"));
107
 
  add_label (vbox, _("The xine engine runs certain checks on your "
108
 
                     "system configuration. Results follow:"));
109
 
 
110
 
  /* If media.vcd.device is empty, set it to the default "/dev/cdrom" */
111
 
  hc.cdrom_dev = xine_config_register_string(xine,
112
 
      "media.vcd.device",
113
 
      "/dev/cdrom",
114
 
      _("device used for CD-ROM drive"),
115
 
      NULL, 0, NULL, NULL);
116
 
 
117
 
  /* Similarly for media.audio_cd.device */
118
 
  const char *audio_cd = xine_config_register_string(xine,
119
 
      "media.audio_cd.device",
120
 
      "/dev/cdrom",
121
 
      _("device used for CD-ROM drive"),
122
 
      NULL, 0, NULL, NULL);
123
 
 
124
 
  if (!audio_cd || !*audio_cd)
125
 
    audio_cd = hc.cdrom_dev;
126
 
  if (!audio_cd || !*audio_cd)
127
 
    audio_cd = "/dev/cdrom";
128
 
  if (!hc.cdrom_dev || !*hc.cdrom_dev)
129
 
    hc.cdrom_dev = audio_cd;
130
 
 
131
 
  /* If media.dvd.device is empty, set it to the default "/dev/dvd" */
132
 
  hc.dvd_dev = xine_config_register_string(xine,
133
 
      "media.dvd.device",
134
 
      "/dev/dvd",
135
 
      _("device used for DVD drive"),
136
 
      NULL, 0, NULL, NULL);
137
 
 
138
 
  if (!hc.dvd_dev || !*hc.dvd_dev)
139
 
    hc.dvd_dev = "/dev/dvd";
140
 
 
141
 
  hc_update_pref ("media.audio_cd.device", audio_cd);
142
 
  hc_update_pref ("media.vcd.device", hc.cdrom_dev);
143
 
  hc_update_pref ("media.dvd.device", hc.dvd_dev);
144
 
 
145
 
  /* Run tests */
146
 
  for (check = 0; ; ++check)
147
 
  {
148
 
    results = xine_health_check (&hc, check);
149
 
 
150
 
    if (results->status == XINE_HEALTH_CHECK_NO_SUCH_CHECK)
151
 
      break;
152
 
 
153
 
    gtk_table_resize (GTK_TABLE (table), 3, check+1);
154
 
 
155
 
    l = ui_label_new_with_xalign (results->title, 0);
156
 
    gtk_table_attach (GTK_TABLE (table), l, 0, 1, check, check+1, GTK_FILL,
157
 
                      GTK_SHRINK, 2, 5);
158
 
 
159
 
    switch (results->status)
160
 
    {
161
 
    case XINE_HEALTH_CHECK_UNSUPPORTED:
162
 
    case XINE_HEALTH_CHECK_OK:
163
 
      l = gtk_image_new_from_stock (GTK_STOCK_YES, GTK_ICON_SIZE_BUTTON);
164
 
      break;
165
 
    case XINE_HEALTH_CHECK_FAIL:
166
 
      msg = malloc (sizeof (hc_msg_t));
167
 
 
168
 
      msg->msg = results->msg;
169
 
      msg->explanation = results->explanation;
170
 
 
171
 
      b = gtk_button_new_with_label (_("Details"));
172
 
      g_signal_connect (G_OBJECT (b), "clicked", G_CALLBACK (details_cb), msg);
173
 
      gtk_table_attach (GTK_TABLE (table), b, 2, 3, check, check+1, GTK_FILL,
174
 
                        GTK_SHRINK, 2, 5);
175
 
 
176
 
      l = gtk_image_new_from_stock (GTK_STOCK_NO, GTK_ICON_SIZE_BUTTON);
177
 
      break;
178
 
    }
179
 
 
180
 
    gtk_table_attach (GTK_TABLE (table), l, 1, 2, check, check+1, GTK_FILL,
181
 
                      GTK_SHRINK, 2, 5);
182
 
  }
183
 
 
184
 
  gtk_box_pack_start (GTK_BOX(vbox), table, FALSE, FALSE, 5);
185
 
  return FALSE;
186
 
}
187
 
 
188
 
#ifdef USE_INTEGRATION_WIZARD
189
 
static struct {
190
 
  GtkToggleButton *moz, *gnome, *kde, *mailcap;
191
 
} cb;
192
 
 
193
 
static void integrate_cb (GtkButton *button, gpointer data)
194
 
{
195
 
  gboolean state = !!data;
196
 
  if (GTK_WIDGET_SENSITIVE (cb.mailcap))
197
 
    gtk_toggle_button_set_active (cb.mailcap, state);
198
 
  if (GTK_WIDGET_SENSITIVE (cb.moz))
199
 
    gtk_toggle_button_set_active (cb.moz, state);
200
 
  if (GTK_WIDGET_SENSITIVE (cb.gnome))
201
 
    gtk_toggle_button_set_active (cb.gnome, state);
202
 
  if (GTK_WIDGET_SENSITIVE (cb.kde))
203
 
    gtk_toggle_button_set_active (cb.kde, state);
204
 
}
205
 
 
206
 
static GtkToggleButton *
207
 
new_toggle (GtkBox *box, const char *label, gboolean active)
208
 
{
209
 
  GtkWidget *w = gtk_check_button_new_with_mnemonic (label);
210
 
  gtk_widget_set_sensitive (w, active);
211
 
  gtk_box_pack_start (box, w, FALSE, FALSE, 5);
212
 
  GtkToggleButton *b = GTK_TOGGLE_BUTTON (w);
213
 
  gtk_toggle_button_set_active (b, active);
214
 
  return b;
215
 
}
216
 
 
217
 
static gboolean ask_integration_wizard (GtkDialog *w, GtkBox *vbox)
218
 
{
219
 
  struct stat st;
220
 
  gchar *sname;
221
 
  GtkWidget *b, *hbox;
222
 
  GtkBox *vb = GTK_BOX (vbox);
223
 
 
224
 
  add_heading (vbox, _("Registration"));
225
 
  add_label (vbox, _("Register gxine with the following applications "
226
 
                     "as a media handler/helper:"));
227
 
 
228
 
  cb.mailcap = new_toggle (vb, "~_/.mailcap", TRUE);
229
 
 
230
 
  sname = g_build_filename (plugindir, "gxineplugin.so", NULL);
231
 
  cb.moz = new_toggle (vb, _("_Mozilla & Mozilla Firefox (plugin)"), !stat (sname, &st));
232
 
  g_free (sname);
233
 
 
234
 
  cb.gnome = new_toggle (vb, _("_GNOME, Nautilus"), gxine_vfs_init ());
235
 
 
236
 
  cb.kde = new_toggle (vb, _("_KDE, Konqueror"), TRUE);
237
 
 
238
 
  hbox = gtk_hbox_new (FALSE, 2);
239
 
  gtk_box_pack_start (vb, hbox, FALSE, FALSE, 2);
240
 
 
241
 
  b = ui_button_new_stock_mnemonic (GTK_STOCK_ADD, _("_All"));
242
 
  gtk_box_pack_start (GTK_BOX (hbox), b, FALSE, FALSE, 2);
243
 
  g_signal_connect (G_OBJECT (b), "clicked",
244
 
                    (GCallback) integrate_cb, integrate_cb);
245
 
 
246
 
  b = ui_button_new_stock_mnemonic (GTK_STOCK_REMOVE, _("_None"));
247
 
  gtk_box_pack_start (GTK_BOX (hbox), b, FALSE, FALSE, 2);
248
 
  g_signal_connect (G_OBJECT (b), "clicked",
249
 
                    (GCallback) integrate_cb, NULL);
250
 
 
251
 
  return FALSE;
252
 
}
253
 
 
254
 
static void desktop_integration (void)
255
 
{
256
 
  di_registration_flush ();
257
 
  if (gtk_toggle_button_get_active (cb.mailcap))
258
 
    di_register_mailcap();
259
 
  if (gtk_toggle_button_get_active (cb.gnome))
260
 
    di_register_gnome();
261
 
  if (gtk_toggle_button_get_active (cb.kde))
262
 
    di_register_kde();
263
 
  if (gtk_toggle_button_get_active (cb.moz))
264
 
    di_register_mozilla();
265
 
}
266
 
 
267
 
static gboolean report_integration_wizard (GtkDialog *w, GtkBox *vbox)
268
 
{
269
 
  const char *report = di_registration_report ();
270
 
  if (!report)
271
 
    return TRUE;
272
 
 
273
 
  add_heading (vbox, _("Registration report"));
274
 
  add_label (vbox, _("There were some problems during registration."));
275
 
  add_label (vbox, report);
276
 
  di_registration_flush ();
277
 
 
278
 
  return FALSE;
279
 
}
280
 
#endif
281
 
 
282
 
#define RESPONSE_CLOSE 0
283
 
#define RESPONSE_NEXT  1
284
 
 
285
 
static gboolean close_cb (GtkWidget* widget, gpointer data)
286
 
{
287
 
  int *b = data;
288
 
  *b = RESPONSE_CLOSE;
289
 
  gtk_main_quit();
290
 
 
291
 
  return TRUE;
292
 
}
293
 
 
294
 
static void response_cb (GtkDialog *dbox, int response, gpointer data)
295
 
{
296
 
  int *b = data;
297
 
  switch (response)
298
 
  {
299
 
  case GTK_RESPONSE_ACCEPT:
300
 
    *b = RESPONSE_NEXT;
301
 
    break;
302
 
  default:
303
 
    *b = RESPONSE_CLOSE;
304
 
  }
305
 
  gtk_main_quit();
306
 
}
307
 
 
308
 
#define WIZARDS_LEVEL 6
309
 
 
310
 
void run_wizards (gboolean requested)
311
 
{
312
 
  static GtkDialog *dlg = NULL;
313
 
 
314
 
  if (dlg)
315
 
  {
316
 
    gtk_window_set_modal (GTK_WINDOW (dlg), FALSE);
317
 
    gtk_window_present (GTK_WINDOW(dlg));
318
 
    return;
319
 
  }
320
 
 
321
 
  if (requested
322
 
      || (xine_config_register_num (xine, "misc.wizards_shown", 0,
323
 
                                    _("Keep track of whether user has seen wizards yet"),
324
 
                                    NULL, 32767, NULL, NULL) < WIZARDS_LEVEL))
325
 
  {
326
 
    xine_cfg_entry_t  entry;
327
 
    int b, state;
328
 
 
329
 
    static const struct {
330
 
      GtkWidget *(*create) (GtkDialog *, GtkBox *);
331
 
      gboolean (*action) (void); /* TRUE to skip a stage */
332
 
    } wizards[] = {
333
 
      { do_welcome, NULL },
334
 
      { do_health_check, NULL },
335
 
#ifdef USE_INTEGRATION_WIZARD
336
 
      { ask_integration_wizard, desktop_integration },
337
 
      { report_integration_wizard, NULL },
338
 
#endif
339
 
      { NULL }
340
 
    };
341
 
 
342
 
    if (xine_config_lookup_entry (xine, "misc.wizards_shown", &entry))
343
 
    {
344
 
      entry.num_value = WIZARDS_LEVEL;
345
 
      preferences_update_entry (&entry);
346
 
    }
347
 
 
348
 
    /* set up dialog which all wizards will use */
349
 
 
350
 
    dlg = GTK_DIALOG (gtk_dialog_new_with_buttons (_("gxine setup wizards"), NULL, 0,
351
 
                                       GTK_STOCK_GO_FORWARD, GTK_RESPONSE_ACCEPT,
352
 
                                       GTK_STOCK_CLOSE, GTK_RESPONSE_DELETE_EVENT,
353
 
                                       NULL));
354
 
    gtk_dialog_set_default_response (dlg, GTK_RESPONSE_ACCEPT);
355
 
    gtk_window_set_default_size (GTK_WINDOW (dlg), -1, 400);
356
 
    gtk_window_set_modal (GTK_WINDOW (dlg), !requested);
357
 
    g_object_connect (G_OBJECT (dlg),
358
 
        "signal::delete-event", G_CALLBACK (close_cb), &b,
359
 
        "signal::response", G_CALLBACK (response_cb), &b,
360
 
        NULL);
361
 
 
362
 
    /*
363
 
     * contents: headline, separator, wizard-specific part
364
 
     */
365
 
 
366
 
    /* headline */
367
 
    {
368
 
      GtkWidget *w, *b = gtk_hbox_new (0, 0);
369
 
      gtk_box_pack_start (GTK_BOX (dlg->vbox), b, FALSE, FALSE, 2);
370
 
      gtk_box_pack_start (GTK_BOX (b),
371
 
                          gtk_image_new_from_stock (GXINE_LOGO, icon_size_logo),
372
 
                          FALSE, FALSE, 2);
373
 
      w = ui_label_new_with_markup (_("<span face='serif' size='xx-large' weight='bold'>Welcome!</span>"));
374
 
      gtk_box_pack_start (GTK_BOX (b), w, FALSE, FALSE, 2);
375
 
    }
376
 
 
377
 
    gtk_box_pack_start (GTK_BOX (dlg->vbox),
378
 
                        gtk_hseparator_new (), FALSE, FALSE, 5);
379
 
 
380
 
    window_show ((GtkWidget *)dlg, NULL);
381
 
 
382
 
    state = -1;
383
 
    while (1)
384
 
    {
385
 
      GtkWidget *content = gtk_vbox_new (0, 0);
386
 
      gtk_box_pack_start_defaults (GTK_BOX (dlg->vbox), content);
387
 
 
388
 
      if (wizards[++state].create)
389
 
      {
390
 
        if (wizards[state].create (dlg, GTK_BOX (content)))
391
 
          goto next;
392
 
      }
393
 
      else
394
 
      {
395
 
        gtk_dialog_set_response_sensitive (dlg, GTK_RESPONSE_ACCEPT, FALSE);
396
 
        add_heading (GTK_BOX (content), _("Setup completed."));
397
 
      }
398
 
 
399
 
      gtk_widget_show_all (content);
400
 
      gtk_main ();
401
 
 
402
 
      if (b == RESPONSE_CLOSE)
403
 
        break;
404
 
 
405
 
      if (wizards[state].action)
406
 
        wizards[state].action ();
407
 
 
408
 
      next:
409
 
      gtk_container_remove (GTK_CONTAINER (dlg->vbox), content);
410
 
    }
411
 
 
412
 
    gtk_widget_destroy (GTK_WIDGET (dlg));
413
 
    dlg = NULL;
414
 
  }
415
 
}
416
 
 
417
 
static JSBool js_run_wizards (JSContext *cx, JSObject *obj, uintN argc,
418
 
                              jsval *argv, jsval *rval)
419
 
{
420
 
  /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
421
 
  se_log_fncall_checkinit ("run_wizards");
422
 
  run_wizards (TRUE);
423
 
  return JS_TRUE;
424
 
}
425
 
 
426
 
void wizards_init (void)
427
 
{
428
 
  se_defun (gse, NULL, "run_wizards", js_run_wizards, 0, 0,
429
 
            SE_GROUP_HIDDEN, NULL, NULL);
430
 
}