~ubuntu-branches/ubuntu/trusty/pcmanfm/trusty-proposed

« back to all changes in this revision

Viewing changes to src/desktop/fm-desktop.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Lee
  • Date: 2008-09-26 10:19:20 UTC
  • mfrom: (4.1.5 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080926101920-cfldybkmwgwrtv9u
Tags: 0.5-3
* Correct spellings,  03_correct_spelling.dpatch (Closes:498794) 
* Code in some files are taken from other projects, added these
  informations into copyright file. (Closes:499678)
* Applied 04_defaut_terminal.dpatch to support x-terminal-emulator
  alternative. (Closes:497494) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
*  fm-desktop.c: Desktop integration for PCManFM
3
 
*
4
 
*  Copyright (c) 2004 Brian Tarricone, <bjt23@cornell.edu>
5
 
*  Copyright (c) 2006 Hong Jen Yee (PCMan), <pcman.tw@gmail.com>
6
 
*
7
 
*  This program is free software; you can redistribute it and/or modify
8
 
*  it under the terms of the GNU General Public License as published by
9
 
*  the Free Software Foundation; either version 2 of the License, or
10
 
*  (at your option) any later version.
11
 
*
12
 
*  This program is distributed in the hope that it will be useful,
13
 
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
*  GNU Library General Public License for more details.
16
 
*
17
 
*  You should have received a copy of the GNU General Public License
18
 
*  along with this program; if not, write to the Free Software
19
 
*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
 
*
21
 
*  Random portions taken from or inspired by the original xfdesktop for xfce4:
22
 
*     Copyright (C) 2002-2003 Jasper Huijsmans (huysmans@users.sourceforge.net)
23
 
*     Copyright (C) 2003 Benedikt Meurer <benedikt.meurer@unix-ag.uni-siegen.de>
24
 
*  X event forwarding code:
25
 
*     Copyright (c) 2004 Nils Rennebarth
26
 
*
27
 
*  This file is modified form xfdesktop.c of XFCE 4.4
28
 
*  to be used in PCMan File Manager.
29
 
*/
30
 
 
31
 
#ifdef HAVE_CONFIG_H
32
 
#include <config.h>
33
 
#endif
34
 
 
35
 
#include <stdlib.h>
36
 
#include <string.h>
37
 
#include <signal.h>
38
 
 
39
 
#include <X11/Xlib.h>
40
 
#include <X11/Xatom.h>
41
 
 
42
 
#include <gmodule.h>
43
 
#include <gdk/gdkx.h>
44
 
#include <gdk/gdkkeysyms.h>
45
 
#include <gtk/gtk.h>
46
 
 
47
 
#include "fm-desktop.h"
48
 
#include "working-area.h"
49
 
#include "ptk-file-browser.h"
50
 
#include "ptk-icon-view.h"
51
 
#include "main-window.h"
52
 
#include "settings.h"
53
 
 
54
 
static GtkWidget **desktops;
55
 
static gint n_screens;
56
 
static guint busy_cursor = 0;
57
 
 
58
 
static void resize_desktops();
59
 
static GdkPixmap* set_bg_pixmap( GdkScreen* screen,
60
 
                           PtkIconView* view,
61
 
                           GdkRectangle* working_area );
62
 
 
63
 
static void
64
 
event_forward_to_rootwin( GdkScreen *gscreen, GdkEvent *event )
65
 
{
66
 
    XButtonEvent xev, xev2;
67
 
    Display *dpy = GDK_DISPLAY_XDISPLAY( gdk_screen_get_display( gscreen ) );
68
 
 
69
 
    if ( event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE )
70
 
    {
71
 
        if ( event->type == GDK_BUTTON_PRESS )
72
 
        {
73
 
            xev.type = ButtonPress;
74
 
            /*
75
 
             * rox has an option to disable the next
76
 
             * instruction. it is called "blackbox_hack". Does
77
 
             * anyone know why exactly it is needed?
78
 
             */
79
 
            XUngrabPointer( dpy, event->button.time );
80
 
        }
81
 
        else
82
 
            xev.type = ButtonRelease;
83
 
 
84
 
        xev.button = event->button.button;
85
 
        xev.x = event->button.x;    /* Needed for icewm */
86
 
        xev.y = event->button.y;
87
 
        xev.x_root = event->button.x_root;
88
 
        xev.y_root = event->button.y_root;
89
 
        xev.state = event->button.state;
90
 
 
91
 
        xev2.type = 0;
92
 
    }
93
 
    else if ( event->type == GDK_SCROLL )
94
 
    {
95
 
        xev.type = ButtonPress;
96
 
        xev.button = event->scroll.direction + 4;
97
 
        xev.x = event->scroll.x;    /* Needed for icewm */
98
 
        xev.y = event->scroll.y;
99
 
        xev.x_root = event->scroll.x_root;
100
 
        xev.y_root = event->scroll.y_root;
101
 
        xev.state = event->scroll.state;
102
 
 
103
 
        xev2.type = ButtonRelease;
104
 
        xev2.button = xev.button;
105
 
    }
106
 
    else
107
 
        return ;
108
 
    xev.window = GDK_WINDOW_XWINDOW( gdk_screen_get_root_window( gscreen ) );
109
 
    xev.root = xev.window;
110
 
    xev.subwindow = None;
111
 
    xev.time = event->button.time;
112
 
    xev.same_screen = True;
113
 
 
114
 
    XSendEvent( dpy, xev.window, False, ButtonPressMask | ButtonReleaseMask,
115
 
                ( XEvent * ) & xev );
116
 
    if ( xev2.type == 0 )
117
 
        return ;
118
 
 
119
 
    /* send button release for scroll event */
120
 
    xev2.window = xev.window;
121
 
    xev2.root = xev.root;
122
 
    xev2.subwindow = xev.subwindow;
123
 
    xev2.time = xev.time;
124
 
    xev2.x = xev.x;
125
 
    xev2.y = xev.y;
126
 
    xev2.x_root = xev.x_root;
127
 
    xev2.y_root = xev.y_root;
128
 
    xev2.state = xev.state;
129
 
    xev2.same_screen = xev.same_screen;
130
 
 
131
 
    XSendEvent( dpy, xev2.window, False, ButtonPressMask | ButtonReleaseMask,
132
 
                ( XEvent * ) & xev2 );
133
 
}
134
 
 
135
 
static gboolean
136
 
scroll_cb( GtkWidget *w, GdkEventScroll *evt, gpointer user_data )
137
 
{
138
 
    event_forward_to_rootwin( gtk_widget_get_screen( w ), ( GdkEvent* ) evt );
139
 
    return TRUE;
140
 
}
141
 
 
142
 
static gboolean
143
 
button_cb( GtkWidget *w, GdkEventButton *evt, gpointer user_data )
144
 
{
145
 
    GdkScreen * gscreen = gtk_widget_get_screen( w );
146
 
    gint button = evt->button;
147
 
    gint state = evt->state;
148
 
 
149
 
    if ( evt->type == GDK_BUTTON_PRESS )
150
 
    {
151
 
        if ( button == 2 || ( button == 1 && ( state & GDK_SHIFT_MASK )
152
 
                              && ( state & GDK_CONTROL_MASK ) ) )
153
 
        {
154
 
            return FALSE;
155
 
        }
156
 
        else if ( button == 3 || ( button == 1 && ( state & GDK_SHIFT_MASK ) ) )
157
 
        {
158
 
            //            popup_desktop_menu(gscreen, button, evt->time);
159
 
            return FALSE;
160
 
        }
161
 
    }
162
 
 
163
 
    return FALSE;
164
 
}
165
 
 
166
 
static gboolean
167
 
reload_idle_cb( gpointer data )
168
 
{
169
 
    return FALSE;
170
 
}
171
 
 
172
 
#if 0
173
 
gboolean
174
 
client_message_received( GtkWidget *w, GdkEventClient *evt, gpointer user_data )
175
 
{
176
 
    if ( evt->data_format == 8 )
177
 
    {
178
 
        if ( !strcmp( RELOAD_MESSAGE, evt->data.b ) )
179
 
        {
180
 
            g_idle_add ( ( GSourceFunc ) reload_idle_cb, NULL );
181
 
            return TRUE;
182
 
        }
183
 
        else if ( !strcmp( MENU_MESSAGE, evt->data.b ) )
184
 
        {
185
 
            popup_desktop_menu( gtk_widget_get_screen( w ), 0, GDK_CURRENT_TIME );
186
 
            return TRUE;
187
 
        }
188
 
        else if ( !strcmp( WINDOWLIST_MESSAGE, evt->data.b ) )
189
 
        {
190
 
            popup_windowlist( gtk_widget_get_screen( w ), 0, GDK_CURRENT_TIME );
191
 
            return TRUE;
192
 
        }
193
 
        else if ( !strcmp( QUIT_MESSAGE, evt->data.b ) )
194
 
        {
195
 
            gtk_main_quit();
196
 
            return TRUE;
197
 
        }
198
 
    }
199
 
 
200
 
    return FALSE;
201
 
}
202
 
 
203
 
#endif
204
 
 
205
 
static void
206
 
sighandler_cb( int sig )
207
 
{
208
 
    switch ( sig )
209
 
    {
210
 
    case SIGUSR1:
211
 
        g_idle_add ( ( GSourceFunc ) reload_idle_cb, NULL );
212
 
        break;
213
 
    default:
214
 
        gtk_main_quit();
215
 
        break;
216
 
    }
217
 
}
218
 
 
219
 
static
220
 
GdkFilterReturn on_rootwin_event ( GdkXEvent *xevent,
221
 
                                   GdkEvent *event,
222
 
                                   gpointer data )
223
 
{
224
 
    XPropertyEvent * evt = ( XPropertyEvent* ) xevent;
225
 
    /* If the size of working area changed */
226
 
    /* g_debug("%s\n", gdk_x11_get_xatom_name(evt->atom)); */
227
 
    if ( evt->type == PropertyNotify &&
228
 
            evt->atom == XInternAtom( evt->display,
229
 
                                      "_NET_WORKAREA", False ) )
230
 
    {
231
 
        resize_desktops();
232
 
    }
233
 
    return GDK_FILTER_TRANSLATE;
234
 
}
235
 
 
236
 
int fm_desktop_init()
237
 
{
238
 
    GdkDisplay * gdpy;
239
 
    gint i;
240
 
    Window xid;
241
 
    GtkSettings *settings;
242
 
    const gchar *message = NULL;
243
 
    gboolean already_running;
244
 
 
245
 
    gdpy = gdk_display_get_default();
246
 
 
247
 
    n_screens = gdk_display_get_n_screens( gdpy );
248
 
    desktops = g_new( GtkWidget *, n_screens );
249
 
    for ( i = 0; i < n_screens; i++ )
250
 
    {
251
 
        desktops[ i ] = fm_desktop_new( gdk_display_get_screen( gdpy, i ) );
252
 
        gtk_widget_add_events( desktops[ i ],
253
 
                               GDK_BUTTON_PRESS_MASK |
254
 
                               GDK_BUTTON_RELEASE_MASK |
255
 
                               GDK_SCROLL_MASK );
256
 
        g_signal_connect( G_OBJECT( desktops[ i ] ), "scroll-event",
257
 
                          G_CALLBACK( scroll_cb ), NULL );
258
 
        g_signal_connect_after( G_OBJECT( desktops[ i ] ),
259
 
                                "button-press-event",
260
 
                                G_CALLBACK( button_cb ), NULL );
261
 
        gtk_widget_show_all( desktops[ i ] );
262
 
        gdk_window_lower( desktops[ i ] ->window );
263
 
    }
264
 
 
265
 
    signal( SIGPIPE, SIG_IGN );
266
 
 
267
 
    signal( SIGHUP, sighandler_cb );
268
 
    signal( SIGINT, sighandler_cb );
269
 
    signal( SIGTERM, sighandler_cb );
270
 
    signal( SIGUSR1, sighandler_cb );
271
 
 
272
 
    return 0;
273
 
}
274
 
 
275
 
void fm_desktop_cleanup()
276
 
{
277
 
    int i;
278
 
    for ( i = 0; i < n_screens; i++ )
279
 
        gtk_widget_destroy( desktops[ i ] );
280
 
    g_free( desktops );
281
 
    if ( busy_cursor > 0 )
282
 
        g_source_remove( busy_cursor );
283
 
}
284
 
 
285
 
static gboolean remove_busy_cursor()
286
 
{
287
 
    int i;
288
 
    for ( i = 0; i < n_screens; i++ )
289
 
        gdk_window_set_cursor ( desktops[ i ] ->window, NULL );
290
 
    busy_cursor = 0;
291
 
    return FALSE;
292
 
}
293
 
 
294
 
static void show_busy_cursor()
295
 
{
296
 
    if ( busy_cursor > 0 )
297
 
        g_source_remove( busy_cursor );
298
 
    else
299
 
    {
300
 
        int i;
301
 
        for ( i = 0; i < n_screens; i++ )
302
 
        {
303
 
            GdkCursor* cursor;
304
 
            cursor = gdk_cursor_new( GDK_WATCH );
305
 
            gdk_window_set_cursor ( desktops[ i ] ->window, cursor );
306
 
            gdk_cursor_unref( cursor );
307
 
        }
308
 
    }
309
 
    busy_cursor = g_timeout_add( 1000,
310
 
                                 remove_busy_cursor, NULL );
311
 
}
312
 
 
313
 
static void on_open_item ( PtkFileBrowser* file_browser,
314
 
                           const char* path,
315
 
                           PtkOpenAction action,
316
 
                           gpointer user_data )
317
 
{
318
 
    FMMainWindow * main_window = NULL;
319
 
    show_busy_cursor();
320
 
    switch ( action )
321
 
    {
322
 
    case PTK_OPEN_NEW_TAB:
323
 
        main_window = fm_main_window_get_last_active();
324
 
    case PTK_OPEN_DIR:
325
 
    case PTK_OPEN_NEW_WINDOW:
326
 
        if ( !main_window )
327
 
            main_window = FM_MAIN_WINDOW(fm_main_window_new());
328
 
        gtk_window_set_default_size( GTK_WINDOW( main_window ),
329
 
                                     appSettings.width,
330
 
                                     appSettings.height );
331
 
        fm_main_window_add_new_tab( main_window, path,
332
 
                                    appSettings.showSidePane,
333
 
                                    appSettings.sidePaneMode );
334
 
        gtk_window_present ( GTK_WINDOW( main_window ) );
335
 
        break;
336
 
    case PTK_OPEN_TERMINAL:
337
 
        fm_main_window_open_terminal( GTK_WINDOW( user_data ), path );
338
 
    }
339
 
}
340
 
 
341
 
static void remove_filter( GObject* desktop, gpointer screen )
342
 
{
343
 
    gdk_window_remove_filter(
344
 
        gdk_screen_get_root_window( GDK_SCREEN( screen ) ),
345
 
        on_rootwin_event, desktop );
346
 
}
347
 
 
348
 
static gboolean on_desktop_key_press( GtkWidget* desktop,
349
 
                                      GdkEventKey* evt,
350
 
                                      gpointer user_data )
351
 
{
352
 
    if( evt->keyval == GDK_F4 )
353
 
    {
354
 
        PtkFileBrowser* browser = (PtkFileBrowser*)user_data;
355
 
        fm_main_window_open_terminal( GTK_WINDOW(desktop),
356
 
                                      ptk_file_browser_get_cwd( browser ));
357
 
        return TRUE;
358
 
    }
359
 
    return FALSE;
360
 
}
361
 
 
362
 
static gboolean on_desktop_expose( GtkWidget* desktop,
363
 
                                   GdkEventExpose* event,
364
 
                                   gpointer user_data )
365
 
{
366
 
    GtkWidget * align, *browser, *view;
367
 
    GdkPixmap* pix;
368
 
    align = gtk_bin_get_child( GTK_BIN( desktop ) );
369
 
    browser = gtk_bin_get_child( GTK_BIN( align ) );
370
 
    view = ptk_file_browser_get_folder_view( PTK_FILE_BROWSER(browser) );
371
 
    pix = ptk_icon_view_get_background( PTK_ICON_VIEW(view) );
372
 
    if ( pix )
373
 
    {
374
 
        gdk_draw_drawable( event->window,
375
 
                           desktop->style->fg_gc[ GTK_STATE_NORMAL ],
376
 
                           pix, event->area.x, event->area.y,
377
 
                           event->area.x, event->area.y,
378
 
                           event->area.width, event->area.height );
379
 
 
380
 
    }
381
 
    return TRUE;
382
 
}
383
 
 
384
 
static gboolean on_icon_view_button_press( PtkIconView* view,
385
 
                                           GdkEventButton* evt,
386
 
                                           GtkWidget* desktop )
387
 
{
388
 
    GtkTreePath * tree_path;
389
 
    GtkWidget* popup = NULL;
390
 
    tree_path = ptk_icon_view_get_path_at_pos( view, evt->x, evt->y );
391
 
    if ( tree_path )
392
 
    {
393
 
        /* TODO: Do some special processig on mounted devices. */
394
 
        gtk_tree_path_free( tree_path );
395
 
    }
396
 
    else /* pressed on desktop */
397
 
    {
398
 
        if( evt->button == 3 ) /* right button */
399
 
        {
400
 
            /* g_debug("no item, btn = %d", evt->button); */
401
 
            /*
402
 
            popup = gtk_menu_new();
403
 
            GtkWidget* tmp = gtk_menu_item_new_with_label("Test");
404
 
            gtk_menu_shell_append( popup, tmp );
405
 
            gtk_widget_show_all( popup );
406
 
            */
407
 
        }
408
 
    }
409
 
    if( popup )
410
 
    {
411
 
        g_signal_connect( popup, "selection-done",
412
 
                          G_CALLBACK(gtk_widget_destroy), NULL );
413
 
        gtk_menu_popup( GTK_MENU(popup), NULL, NULL, NULL, NULL, evt->button, evt->time );
414
 
        g_signal_stop_emission_by_name( view, "button-press-event" );
415
 
        return TRUE;
416
 
    }
417
 
    return FALSE;
418
 
}
419
 
 
420
 
GtkWidget* fm_desktop_new( GdkScreen* screen )
421
 
{
422
 
    GtkWidget * desktop;
423
 
    PtkFileBrowser *browser;
424
 
    GtkWidget *view;
425
 
    GtkScrolledWindow *scroll;
426
 
    GdkWindow *root;
427
 
    GtkWidget* alignment;
428
 
    char* desktop_dir;
429
 
    GdkRectangle area;
430
 
    int rpad, bpad;
431
 
    guint32 val;
432
 
 
433
 
    desktop = gtk_window_new( GTK_WINDOW_TOPLEVEL );
434
 
    get_working_area( screen, &area );
435
 
    gtk_window_move( GTK_WINDOW( desktop ), 0, 0 );
436
 
    gtk_widget_set_size_request( desktop,
437
 
                                 gdk_screen_get_width( screen ),
438
 
                                 gdk_screen_get_height( screen ) );
439
 
 
440
 
    alignment = gtk_alignment_new( 0.5, 0.5, 1, 1 );
441
 
    gtk_container_add( GTK_CONTAINER(desktop), alignment );
442
 
 
443
 
    browser = PTK_FILE_BROWSER(ptk_file_browser_new( alignment, FBVM_ICON_VIEW ));
444
 
 
445
 
    g_signal_connect( browser, "open-item",
446
 
                      G_CALLBACK( on_open_item ), desktop );
447
 
 
448
 
    ptk_file_browser_show_hidden_files( browser,
449
 
                                        appSettings.showHiddenFiles );
450
 
    ptk_file_browser_show_thumbnails( browser,
451
 
                                      appSettings.showThumbnail ? appSettings.maxThumbSize : 0 );
452
 
    desktop_dir = g_build_filename( g_get_home_dir(), "Desktop", NULL );
453
 
    /* FIXME: add histroy should be true because
454
 
    current working directory is stored in history list. */
455
 
    ptk_file_browser_chdir( browser, desktop_dir, TRUE );
456
 
    g_free( desktop_dir );
457
 
 
458
 
    gtk_widget_set_size_request( GTK_WIDGET(browser),
459
 
                                 area.width, area.height );
460
 
    rpad = gdk_screen_get_width( screen );
461
 
    rpad -= ( area.x + area.width );
462
 
    bpad = gdk_screen_get_height( screen );
463
 
    bpad -= ( area.y + area.height );
464
 
    gtk_alignment_set_padding( GTK_ALIGNMENT(alignment),
465
 
                               area.y, bpad, area.x, rpad );
466
 
    gtk_container_add( GTK_CONTAINER(alignment), GTK_WIDGET(browser) );
467
 
 
468
 
    gtk_widget_show_all( alignment );
469
 
    gtk_widget_realize( desktop );
470
 
    gdk_window_set_type_hint( desktop->window,
471
 
                              GDK_WINDOW_TYPE_HINT_DESKTOP );
472
 
 
473
 
    view = ptk_file_browser_get_folder_view( browser );
474
 
    g_signal_connect( view, "button-press-event",
475
 
                      G_CALLBACK( on_icon_view_button_press ), desktop );
476
 
    scroll = GTK_SCROLLED_WINDOW( gtk_widget_get_parent( view ) );
477
 
    gtk_scrolled_window_set_policy( scroll,
478
 
                                    GTK_POLICY_NEVER, GTK_POLICY_NEVER );
479
 
    gtk_scrolled_window_set_shadow_type( scroll, GTK_SHADOW_NONE );
480
 
 
481
 
    root = gdk_screen_get_root_window( screen );
482
 
    gdk_window_set_events( root, gdk_window_get_events( root )
483
 
                           | GDK_PROPERTY_CHANGE_MASK );
484
 
    gdk_window_add_filter( root, on_rootwin_event, desktop );
485
 
    g_signal_connect( desktop, "destroy", remove_filter, screen );
486
 
    g_signal_connect( desktop, "expose-event",
487
 
                      on_desktop_expose, NULL );
488
 
    g_signal_connect( desktop, "key-press-event",
489
 
                      on_desktop_key_press, browser );
490
 
 
491
 
    gtk_widget_set_double_buffered( desktop, FALSE );
492
 
    set_bg_pixmap( screen, PTK_ICON_VIEW(view), &area );
493
 
    gtk_window_set_skip_pager_hint( GTK_WINDOW(desktop), TRUE );
494
 
    gtk_window_set_skip_taskbar_hint( GTK_WINDOW(desktop), TRUE );
495
 
 
496
 
    /* This is borrowed from fbpanel */
497
 
#define WIN_HINTS_SKIP_FOCUS      (1<<0)    /* skip "alt-tab" */
498
 
    val = WIN_HINTS_SKIP_FOCUS;
499
 
    XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(desktop->window),
500
 
          XInternAtom(GDK_DISPLAY(), "_WIN_HINTS", False), XA_CARDINAL, 32,
501
 
          PropModeReplace, (unsigned char *) &val, 1);
502
 
 
503
 
    gdk_rgb_find_color( gtk_widget_get_colormap( view ),
504
 
                        &appSettings.desktopText );
505
 
    gdk_rgb_find_color( gtk_widget_get_colormap( view ),
506
 
                        &appSettings.desktopBg1 );
507
 
    gdk_rgb_find_color( gtk_widget_get_colormap( view ),
508
 
                        &appSettings.desktopBg2 );
509
 
 
510
 
    gtk_widget_modify_text( view,
511
 
                            GTK_STATE_NORMAL,
512
 
                            &appSettings.desktopText );
513
 
    gtk_widget_modify_base( view,
514
 
                            GTK_STATE_NORMAL,
515
 
                            &appSettings.desktopBg1 );
516
 
    gdk_window_set_background( root, &appSettings.desktopBg1 );
517
 
    return desktop;
518
 
}
519
 
 
520
 
GdkPixmap* set_bg_pixmap( GdkScreen* screen,
521
 
                    PtkIconView* view,
522
 
                    GdkRectangle* working_area )
523
 
{
524
 
    GdkWindow * root;
525
 
    GdkPixmap* pix = NULL;
526
 
    GdkPixbuf* img;
527
 
 
528
 
    root = gdk_screen_get_root_window( screen );
529
 
    if ( appSettings.showWallpaper )
530
 
    {
531
 
        int screenw, screenh;
532
 
        int imgw, imgh, x = 0, y = 0;
533
 
        screenw = gdk_screen_get_width( screen );
534
 
        screenh = gdk_screen_get_height( screen );
535
 
        img = gdk_pixbuf_new_from_file_at_scale(
536
 
                  appSettings.wallpaper,
537
 
                  screenw, screenh,
538
 
                  TRUE, NULL );
539
 
        if ( img )
540
 
        {
541
 
            GdkGC * gc;
542
 
            pix = gdk_pixmap_new( root, screenw, screenh, -1 );
543
 
            imgw = gdk_pixbuf_get_width( img );
544
 
            imgh = gdk_pixbuf_get_height( img );
545
 
            if ( imgw == screenw )
546
 
            {
547
 
                /* center vertically */
548
 
                y = ( screenh - imgh ) / 2;
549
 
            }
550
 
            else
551
 
            {
552
 
                /* center horizontally */
553
 
                x = ( screenw - imgw ) / 2;
554
 
            }
555
 
            /* FIXME: fill the blank area with bg color.*/
556
 
            gc = gdk_gc_new( pix );
557
 
            gdk_gc_set_rgb_fg_color( gc, &appSettings.desktopBg1 );
558
 
            gdk_gc_set_fill( gc, GDK_SOLID );
559
 
            /* fill the whole pixmap is not efficient at all!!! */
560
 
            gdk_draw_rectangle( pix, gc, TRUE,
561
 
                                0, 0, screenw, screenh );
562
 
            g_object_unref( G_OBJECT( gc ) );
563
 
            gdk_draw_pixbuf( pix, NULL, img, 0, 0, x, y,
564
 
                             imgw, imgh,
565
 
                             GDK_RGB_DITHER_NONE, 0, 0 );
566
 
            gdk_pixbuf_unref( img );
567
 
        }
568
 
    }
569
 
 
570
 
    ptk_icon_view_set_background( PTK_ICON_VIEW( view ), pix,
571
 
                                  working_area->x, working_area->y );
572
 
    gdk_window_set_back_pixmap( root, pix, FALSE );
573
 
    if ( pix )
574
 
        g_object_unref( G_OBJECT( pix ) );
575
 
 
576
 
    gdk_window_clear( root );
577
 
    return pix;
578
 
}
579
 
 
580
 
void resize_desktops()
581
 
{
582
 
    int i;
583
 
    GdkRectangle area;
584
 
    GdkDisplay* display = gdk_display_get_default();
585
 
    GdkScreen* screen;
586
 
 
587
 
    for ( i = 0; i < n_screens; ++i )
588
 
    {
589
 
        GtkWidget *view, *alignment, *browser;
590
 
        GdkPixmap* pix;
591
 
        int bpad, rpad;
592
 
 
593
 
        screen = gdk_display_get_screen( display, i );
594
 
        get_working_area( screen, &area );
595
 
        gtk_window_move( GTK_WINDOW( desktops[ i ] ), 0, 0 );
596
 
        gtk_widget_set_size_request( desktops[ i ],
597
 
                                     gdk_screen_get_width( screen ),
598
 
                                     gdk_screen_get_height( screen ) );
599
 
        alignment = gtk_bin_get_child( GTK_BIN( desktops[ i ] ) );
600
 
        browser = gtk_bin_get_child( GTK_BIN( alignment ) );
601
 
        view = ptk_file_browser_get_folder_view( PTK_FILE_BROWSER( browser ) );
602
 
        gtk_widget_set_size_request( browser,
603
 
                                     area.width, area.height );
604
 
        rpad = gdk_screen_get_width( screen );
605
 
        rpad -= ( area.x + area.width );
606
 
        bpad = gdk_screen_get_height( screen );
607
 
        bpad -= ( area.y + area.height );
608
 
        gtk_alignment_set_padding( GTK_ALIGNMENT(alignment),
609
 
                                   area.y, bpad, area.x, rpad );
610
 
 
611
 
        set_bg_pixmap( screen, PTK_ICON_VIEW(view), &area );
612
 
    }
613
 
}
614
 
 
615
 
void fm_desktop_update_wallpaper()
616
 
{
617
 
    resize_desktops();
618
 
}
619
 
 
620
 
void fm_desktop_update_colors()
621
 
{
622
 
    int i;
623
 
    for ( i = 0; i < n_screens; ++i )
624
 
    {
625
 
        GdkScreen* screen;
626
 
        GtkWidget *view, *alignment, *browser;
627
 
        screen = gdk_display_get_screen( gdk_display_get_default(), i );
628
 
        alignment = gtk_bin_get_child( GTK_BIN( desktops[ i ] ) );
629
 
        browser = gtk_bin_get_child( GTK_BIN( alignment ) );
630
 
        view = ptk_file_browser_get_folder_view( PTK_FILE_BROWSER( browser ) );
631
 
        gdk_rgb_find_color( gtk_widget_get_colormap( view ),
632
 
                            &appSettings.desktopText );
633
 
        gdk_rgb_find_color( gtk_widget_get_colormap( view ),
634
 
                            &appSettings.desktopBg1 );
635
 
        gdk_rgb_find_color( gtk_widget_get_colormap( view ),
636
 
                            &appSettings.desktopBg2 );
637
 
        gdk_window_set_background(
638
 
            gdk_screen_get_root_window( screen ),
639
 
            &appSettings.desktopBg1 );
640
 
        gtk_widget_modify_text( view,
641
 
                                GTK_STATE_NORMAL,
642
 
                                &appSettings.desktopText );
643
 
        gtk_widget_modify_base( view,
644
 
                                GTK_STATE_NORMAL,
645
 
                                &appSettings.desktopBg1 );
646
 
    }
647
 
    if ( appSettings.showWallpaper )
648
 
        fm_desktop_update_wallpaper();
649
 
}
650
 
 
651
 
static PtkFileBrowser* fm_desktop_get_browser( GtkWidget* desktop )
652
 
{
653
 
    GtkWidget * align;
654
 
    align = gtk_bin_get_child( ( GtkBin* ) desktop );
655
 
    return ( PtkFileBrowser* ) gtk_bin_get_child( ( GtkBin* ) align );
656
 
}
657
 
 
658
 
void fm_desktop_update_thumbnails()
659
 
{
660
 
    int i;
661
 
    PtkFileBrowser* browser;
662
 
    for ( i = 0; i < n_screens; ++i )
663
 
    {
664
 
        browser = fm_desktop_get_browser( desktops[ i ] );
665
 
        ptk_file_browser_show_thumbnails( browser,
666
 
                                          appSettings.showThumbnail ? appSettings.maxThumbSize : 0 );
667
 
    }
668
 
}
669
 
 
670
 
void fm_desktop_update_view()
671
 
{
672
 
    int i;
673
 
    PtkFileBrowser* browser;
674
 
    for ( i = 0; i < n_screens; ++i )
675
 
    {
676
 
        browser = fm_desktop_get_browser( desktops[ i ] );
677
 
        ptk_file_browser_update_display( browser );
678
 
    }
679
 
}