draw-workspace.c

Go to the documentation of this file.
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 
00003 /* Draw a workspace */
00004 
00005 /* This file should not be modified to depend on other files in
00006  * libwnck or metacity, since it's used in both of them
00007  */
00008 
00009 /* 
00010  * Copyright (C) 2002 Red Hat Inc.
00011  * 
00012  * This program is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU General Public License as
00014  * published by the Free Software Foundation; either version 2 of the
00015  * License, or (at your option) any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful, but
00018  * WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * General Public License for more details.
00021  * 
00022  * You should have received a copy of the GNU General Public License
00023  * along with this program; if not, write to the Free Software
00024  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00025  * 02111-1307, USA.
00026  */
00027 
00028 #include "draw-workspace.h"
00029 
00030 
00031 static void
00032 get_window_rect (const WnckWindowDisplayInfo *win,
00033                  int                    screen_width,
00034                  int                    screen_height,
00035                  const GdkRectangle    *workspace_rect,
00036                  GdkRectangle          *rect)
00037 {
00038   double width_ratio, height_ratio;
00039   int x, y, width, height;
00040   
00041   width_ratio = (double) workspace_rect->width / (double) screen_width;
00042   height_ratio = (double) workspace_rect->height / (double) screen_height;
00043   
00044   x = win->x;
00045   y = win->y;
00046   width = win->width;
00047   height = win->height;
00048   
00049   x *= width_ratio;
00050   y *= height_ratio;
00051   width *= width_ratio;
00052   height *= height_ratio;
00053   
00054   x += workspace_rect->x;
00055   y += workspace_rect->y;
00056   
00057   if (width < 3)
00058     width = 3;
00059   if (height < 3)
00060     height = 3;
00061 
00062   rect->x = x;
00063   rect->y = y;
00064   rect->width = width;
00065   rect->height = height;
00066 }
00067 
00068 static void
00069 draw_window (GtkWidget                   *widget,
00070              GdkDrawable                 *drawable,
00071              const WnckWindowDisplayInfo *win,
00072              const GdkRectangle          *winrect,
00073              GtkStateType                state)
00074 {
00075   cairo_t *cr;
00076   GdkPixbuf *icon;
00077   int icon_x, icon_y, icon_w, icon_h;
00078   gboolean is_active;
00079   GdkColor *color;
00080 
00081   is_active = win->is_active;
00082   
00083   cr = gdk_cairo_create (drawable);
00084   cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height);
00085   cairo_clip (cr);
00086 
00087   if (is_active)
00088     color = &widget->style->light[state];
00089   else
00090     color = &widget->style->bg[state];
00091   cairo_set_source_rgb (cr,
00092                         color->red / 65535.,
00093                         color->green / 65535.,
00094                         color->blue / 65535.);
00095 
00096   cairo_rectangle (cr,
00097                    winrect->x + 1, winrect->y + 1,
00098                    MAX (0, winrect->width - 2), MAX (0, winrect->height - 2));
00099   cairo_fill (cr);
00100 
00101 
00102   icon = win->icon;
00103 
00104   icon_w = icon_h = 0;
00105           
00106   if (icon)
00107     {              
00108       icon_w = gdk_pixbuf_get_width (icon);
00109       icon_h = gdk_pixbuf_get_height (icon);
00110 
00111       /* If the icon is too big, fall back to mini icon.
00112        * We don't arbitrarily scale the icon, because it's
00113        * just too slow on my Athlon 850.
00114        */
00115       if (icon_w > (winrect->width - 2) ||
00116           icon_h > (winrect->height - 2))
00117         {
00118           icon = win->mini_icon;
00119           if (icon)
00120             {
00121               icon_w = gdk_pixbuf_get_width (icon);
00122               icon_h = gdk_pixbuf_get_height (icon);
00123         
00124               /* Give up. */
00125               if (icon_w > (winrect->width - 2) ||
00126                   icon_h > (winrect->height - 2))
00127                 icon = NULL;
00128             }
00129         }
00130     }
00131 
00132   if (icon)
00133     {
00134       icon_x = winrect->x + (winrect->width - icon_w) / 2;
00135       icon_y = winrect->y + (winrect->height - icon_h) / 2;
00136       
00137       cairo_save (cr);
00138       gdk_cairo_set_source_pixbuf (cr, icon, icon_x, icon_y);
00139       cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h);
00140       cairo_clip (cr);
00141       cairo_paint (cr);
00142       cairo_restore (cr);
00143     }
00144           
00145   if (is_active)
00146     color = &widget->style->fg[state];
00147   else
00148     color = &widget->style->fg[state];
00149 
00150   cairo_set_source_rgb (cr,
00151                         color->red / 65535.,
00152                         color->green / 65535.,
00153                         color->blue / 65535.);
00154   cairo_set_line_width (cr, 1.0);
00155   cairo_rectangle (cr,
00156                    winrect->x + 0.5, winrect->y + 0.5,
00157                    MAX (0, winrect->width - 1), MAX (0, winrect->height - 1));
00158   cairo_stroke (cr);
00159   
00160   cairo_destroy (cr);
00161 }
00162 
00163 void
00164 wnck_draw_workspace (GtkWidget                   *widget,
00165                      GdkDrawable                 *drawable,
00166                      int                          x,
00167                      int                          y,
00168                      int                          width,
00169                      int                          height,
00170                      int                          screen_width,
00171                      int                          screen_height,
00172                      GdkPixbuf                   *workspace_background,
00173                      gboolean                     is_active,
00174                      const WnckWindowDisplayInfo *windows,
00175                      int                          n_windows)
00176 {
00177   int i;
00178   GdkRectangle workspace_rect;
00179   GtkStateType state;
00180 
00181   workspace_rect.x = x;
00182   workspace_rect.y = y;
00183   workspace_rect.width = width;
00184   workspace_rect.height = height;
00185 
00186   if (is_active)
00187     state = GTK_STATE_SELECTED;
00188   else if (workspace_background) 
00189     state = GTK_STATE_PRELIGHT;
00190   else
00191     state = GTK_STATE_NORMAL;
00192   
00193   if (workspace_background)
00194     {
00195       gdk_draw_pixbuf (drawable,
00196                        GTK_WIDGET (widget)->style->dark_gc[state],
00197                        workspace_background,
00198                        0, 0,
00199                        x, y,
00200                        -1, -1,
00201                        GDK_RGB_DITHER_MAX,
00202                        0, 0);
00203     }
00204   else
00205     {
00206       cairo_t *cr;
00207       
00208       cr = gdk_cairo_create (widget->window);
00209       gdk_cairo_set_source_color (cr, &widget->style->dark[state]);
00210       cairo_rectangle (cr, x, y, width, height);
00211       cairo_fill (cr);
00212       cairo_destroy (cr);
00213     }
00214   
00215   i = 0;
00216   while (i < n_windows)
00217     {
00218       const WnckWindowDisplayInfo *win = &windows[i];
00219       GdkRectangle winrect;
00220       
00221       get_window_rect (win, screen_width,
00222                        screen_height, &workspace_rect, &winrect);
00223       
00224       draw_window (widget,
00225                    drawable,
00226                    win,
00227                    &winrect,
00228                    state);
00229       
00230       ++i;
00231     }
00232 }

Generated on Sat Aug 23 22:04:18 2008 for metacity by  doxygen 1.5.5