This commit is contained in:
rhp 2001-06-01 03:00:01 +00:00
parent 85bd843b01
commit 31d6e2dca0
16 changed files with 491 additions and 42 deletions

54
src/api.c Normal file
View File

@ -0,0 +1,54 @@
/* Metacity misc. public entry points */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "api.h"
#include "display.h"
#include "colors.h"
PangoContext*
meta_get_pango_context (Screen *xscreen,
const PangoFontDescription *desc,
Window frame)
{
MetaScreen *screen;
screen = meta_screen_for_x_screen (xscreen);
g_return_val_if_fail (screen != NULL, NULL);
return meta_screen_get_pango_context (screen,
desc,
/* FIXME, from the frame window */
PANGO_DIRECTION_LTR);
}
gulong
meta_get_x_pixel (Screen *xscreen, const PangoColor *color)
{
MetaScreen *screen;
screen = meta_screen_for_x_screen (xscreen);
g_return_val_if_fail (screen != NULL, 0);
return meta_screen_get_x_pixel (screen, color);
}

37
src/api.h Normal file
View File

@ -0,0 +1,37 @@
/* Metacity misc. public entry points */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_API_H
#define META_API_H
/* don't add any internal headers here; api.h is an installed/public
* header. Only theme.h is also installed.
*/
#include <Xlib.h>
#include <pango/pangox.h>
PangoContext* meta_get_pango_context (Screen *xscreen,
const PangoFontDescription *desc,
Window frame);
gulong meta_get_x_pixel (Screen *xscreen,
const PangoColor *color);
#endif

42
src/colors.c Normal file
View File

@ -0,0 +1,42 @@
/* Metacity RGB color stuff */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "colors.h"
gulong
meta_screen_get_x_pixel (MetaScreen *screen,
const PangoColor *color)
{
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
double r, g, b;
r = color->red / (double) 0xffff;
g = color->green / (double) 0xffff;
b = color->blue / (double) 0xffff;
/* Now this is a low-bloat GdkRGB replacement! */
if (INTENSITY (r, g, b) > 0.5)
return WhitePixel (screen->display->xdisplay, screen->number);
else
return BlackPixel (screen->display->xdisplay, screen->number);
#undef INTENSITY
}

35
src/colors.h Normal file
View File

@ -0,0 +1,35 @@
/* Metacity RGB color stuff */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_COLORS_H
#define META_COLORS_H
/* This stuff will all just be XlibRGB eventually. Right now
* it has a stub implementation.
*/
#include "screen.h"
#include "util.h"
gulong meta_screen_get_x_pixel (MetaScreen *screen,
const PangoColor *color);
#endif

View File

@ -190,6 +190,26 @@ meta_display_screen_for_root (MetaDisplay *display,
return NULL; return NULL;
} }
MetaScreen*
meta_display_screen_for_x_screen (MetaDisplay *display,
Screen *xscreen)
{
GSList *tmp;
tmp = display->screens;
while (tmp != NULL)
{
MetaScreen *screen = tmp->data;
if (xscreen == screen->xscreen)
return screen;
tmp = tmp->next;
}
return NULL;
}
/* Grab/ungrab routines taken from fvwm */ /* Grab/ungrab routines taken from fvwm */
void void
meta_display_grab (MetaDisplay *display) meta_display_grab (MetaDisplay *display)

View File

@ -24,6 +24,7 @@
#include <glib.h> #include <glib.h>
#include <Xlib.h> #include <Xlib.h>
#include <pango/pangox.h>
#include "eventqueue.h" #include "eventqueue.h"
typedef struct _MetaDisplay MetaDisplay; typedef struct _MetaDisplay MetaDisplay;
@ -36,6 +37,7 @@ struct _MetaDisplay
char *name; char *name;
Display *xdisplay; Display *xdisplay;
/*< private-ish >*/
MetaEventQueue *events; MetaEventQueue *events;
GSList *screens; GSList *screens;
GHashTable *window_ids; GHashTable *window_ids;
@ -47,8 +49,12 @@ gboolean meta_display_open (const char *name);
void meta_display_close (MetaDisplay *display); void meta_display_close (MetaDisplay *display);
MetaScreen* meta_display_screen_for_root (MetaDisplay *display, MetaScreen* meta_display_screen_for_root (MetaDisplay *display,
Window xroot); Window xroot);
MetaScreen* meta_display_screen_for_x_screen (MetaDisplay *display,
Screen *screen);
void meta_display_grab (MetaDisplay *display); void meta_display_grab (MetaDisplay *display);
void meta_display_ungrab (MetaDisplay *display); void meta_display_ungrab (MetaDisplay *display);
PangoContext* meta_display_get_pango_context (MetaDisplay *display);
/* A given MetaWindow may have various X windows that "belong" /* A given MetaWindow may have various X windows that "belong"
* to it, such as the frame window. * to it, such as the frame window.

View File

@ -22,6 +22,21 @@
#include "frame.h" #include "frame.h"
#include "errors.h" #include "errors.h"
static void
meta_frame_init_info (MetaFrame *frame,
MetaFrameInfo *info)
{
info->flags = 0;
info->frame = frame->xwindow;
info->display = frame->window->display->xdisplay;
info->screen = frame->window->screen->xscreen;
info->visual = frame->window->xvisual;
info->depth = frame->window->depth;
info->title = frame->window->title;
info->width = frame->rect.width;
info->height = frame->rect.height;
}
void void
meta_window_ensure_frame (MetaWindow *window) meta_window_ensure_frame (MetaWindow *window)
{ {
@ -29,6 +44,8 @@ meta_window_ensure_frame (MetaWindow *window)
int child_x, child_y; int child_x, child_y;
unsigned long background_pixel; unsigned long background_pixel;
XSetWindowAttributes attrs; XSetWindowAttributes attrs;
MetaFrameInfo info;
MetaFrameGeometry geom;
if (window->frame) if (window->frame)
return; return;
@ -37,14 +54,33 @@ meta_window_ensure_frame (MetaWindow *window)
frame->window = window; frame->window = window;
/* FIXME de-hardcode */ /* Fill these in for the theme engine's benefit */
child_x = 5; frame->xwindow = None;
child_y = 5; frame->rect.width = window->rect.width;
frame->rect.height = window->rect.height;
frame->rect.width = window->rect.width + 10; meta_frame_init_info (frame, &info);
frame->rect.height = window->rect.height + 10;
background_pixel = BlackPixel (window->display, window->screen->number); geom.left_width = 0;
geom.right_width = 0;
geom.top_height = 0;
geom.bottom_height = 0;
geom.background_pixel = BlackPixel (frame->window->display->xdisplay,
frame->window->screen->number);
geom.shape_mask = None;
frame->theme_data = window->screen->engine->acquire_frame (&info);
window->screen->engine->fill_frame_geometry (&info, &geom,
frame->theme_data);
child_x = geom.left_width;
child_y = geom.top_height;
frame->rect.width = window->rect.width + geom.left_width + geom.right_width;
frame->rect.height = window->rect.height + geom.top_height + geom.bottom_height;
background_pixel = geom.background_pixel;
switch (window->win_gravity) switch (window->win_gravity)
{ {
@ -151,12 +187,19 @@ void
meta_window_destroy_frame (MetaWindow *window) meta_window_destroy_frame (MetaWindow *window)
{ {
MetaFrame *frame; MetaFrame *frame;
MetaFrameInfo info;
if (window->frame == NULL) if (window->frame == NULL)
return; return;
frame = window->frame; frame = window->frame;
if (frame->theme_data)
{
meta_frame_init_info (frame, &info);
window->screen->engine->release_frame (&info, frame->theme_data);
}
/* Unparent the client window; it may be destroyed, /* Unparent the client window; it may be destroyed,
* thus the error trap. * thus the error trap.
*/ */
@ -220,6 +263,16 @@ meta_frame_event (MetaFrame *frame,
case KeymapNotify: case KeymapNotify:
break; break;
case Expose: case Expose:
{
MetaFrameInfo info;
meta_frame_init_info (frame, &info);
frame->window->screen->engine->expose_frame (&info,
event->xexpose.x,
event->xexpose.y,
event->xexpose.width,
event->xexpose.height,
frame->theme_data);
}
break; break;
case GraphicsExpose: case GraphicsExpose:
break; break;

View File

@ -33,6 +33,8 @@ struct _MetaFrame
Window xwindow; Window xwindow;
MetaRectangle rect; MetaRectangle rect;
gpointer theme_data;
}; };
void meta_window_ensure_frame (MetaWindow *window); void meta_window_ensure_frame (MetaWindow *window);

View File

@ -38,6 +38,8 @@ main (int argc, char **argv)
meta_set_debugging (TRUE); meta_set_debugging (TRUE);
meta_set_syncing (g_getenv ("METACITY_SYNC") != NULL); meta_set_syncing (g_getenv ("METACITY_SYNC") != NULL);
g_type_init (0); /* grumble */
meta_errors_init (); meta_errors_init ();
if (!meta_display_open (NULL)) if (!meta_display_open (NULL))

View File

@ -1,6 +1,6 @@
#! /bin/bash #! /bin/bash
Xnest :1 -scrns 2 -geometry 200x200 & Xnest :1 -scrns 2 -geometry 270x270 &
sleep 1 sleep 1
DISPLAY=:1 unst $1 ./metacity DISPLAY=:1 unst $1 ./metacity
killall Xnest killall Xnest

View File

@ -23,7 +23,11 @@
#include "util.h" #include "util.h"
#include "errors.h" #include "errors.h"
#include "window.h" #include "window.h"
#include "colors.h"
#include <cursorfont.h> #include <cursorfont.h>
#include <locale.h>
#include <string.h>
MetaScreen* MetaScreen*
meta_screen_new (MetaDisplay *display, meta_screen_new (MetaDisplay *display,
@ -81,6 +85,9 @@ meta_screen_new (MetaDisplay *display,
screen->number = number; screen->number = number;
screen->xscreen = ScreenOfDisplay (xdisplay, number); screen->xscreen = ScreenOfDisplay (xdisplay, number);
screen->xroot = xroot; screen->xroot = xroot;
screen->pango_context = NULL;
screen->engine = &meta_default_engine;
meta_verbose ("Added screen %d on display '%s' root 0x%lx\n", meta_verbose ("Added screen %d on display '%s' root 0x%lx\n",
screen->number, screen->display->name, screen->xroot); screen->number, screen->display->name, screen->xroot);
@ -91,6 +98,8 @@ meta_screen_new (MetaDisplay *display,
void void
meta_screen_free (MetaScreen *screen) meta_screen_free (MetaScreen *screen)
{ {
if (screen->pango_context)
g_object_unref (G_OBJECT (screen->pango_context));
g_free (screen); g_free (screen);
} }
@ -130,3 +139,120 @@ meta_screen_manage_all_windows (MetaScreen *screen)
if (children) if (children)
XFree (children); XFree (children);
} }
static GC
get_gc_func (PangoContext *context, PangoColor *color, GC base_gc)
{
MetaScreen *screen;
GC new_gc;
XGCValues vals;
int copy_mask = (GCFunction | GCPlaneMask | GCForeground | GCBackground |
GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle |
GCFillStyle | GCFillRule | GCTile | GCStipple | GCTileStipXOrigin |
GCTileStipYOrigin | GCFont | GCSubwindowMode |
GCGraphicsExposures | GCClipXOrigin | GCClipYOrigin |
GCDashOffset | GCArcMode);
screen = g_object_get_data (G_OBJECT (context), "meta-screen");
new_gc = XCreateGC (screen->display->xdisplay,
screen->xroot,
0,
&vals);
XCopyGC (screen->display->xdisplay, base_gc, copy_mask, new_gc);
vals.foreground = meta_screen_get_x_pixel (screen, color);
XChangeGC (screen->display->xdisplay, new_gc, GCForeground, &vals);
return new_gc;
}
static void
free_gc_func (PangoContext *context, GC gc)
{
MetaScreen *screen;
screen = g_object_get_data (G_OBJECT (context), "meta-screen");
XFreeGC (screen->display->xdisplay, gc);
}
static char*
get_default_language (void)
{
/* Copied from GTK, Copyright 2001 Red Hat Inc. */
gchar *lang;
gchar *p;
lang = g_strdup (setlocale (LC_CTYPE, NULL));
p = strchr (lang, '.');
if (p)
*p = '\0';
p = strchr (lang, '@');
if (p)
*p = '\0';
return lang;
}
PangoContext*
meta_screen_get_pango_context (MetaScreen *screen,
const PangoFontDescription *desc,
PangoDirection direction)
{
if (screen->pango_context == NULL)
{
PangoContext *ctx;
char *lang;
/* Copied from GDK, Copyright 2001 Red Hat, Inc. */
#ifdef HAVE_XFT
static int use_xft = -1;
if (use_xft == -1)
{
char *val = g_getenv ("META_USE_XFT");
use_xft = val && (atoi (val) != 0);
}
if (use_xft)
ctx = pango_xft_get_context (screen->display, screen->number);
else
#endif /* HAVE_XFT */
ctx = pango_x_get_context (screen->display->xdisplay);
g_object_set_data (G_OBJECT (ctx), "meta-screen", screen);
pango_x_context_set_funcs (ctx, get_gc_func, free_gc_func);
lang = get_default_language ();
pango_context_set_lang (ctx, lang);
g_free (lang);
/* FIXME these two lines are wrong;
* we should be storing a context for each direction/desc,
* so that the args to meta_screen_get_pango_context()
* are honored.
*/
pango_context_set_base_dir (ctx, direction);
pango_context_set_font_description (ctx, desc);
screen->pango_context = ctx;
}
return screen->pango_context;
}
MetaScreen*
meta_screen_for_x_screen (Screen *xscreen)
{
MetaDisplay *display;
display = meta_display_for_x_display (DisplayOfScreen (xscreen));
if (display == NULL)
return NULL;
return meta_display_screen_for_x_screen (display, xscreen);
}

View File

@ -23,6 +23,7 @@
#define META_SCREEN_H #define META_SCREEN_H
#include "display.h" #include "display.h"
#include "theme.h"
struct _MetaScreen struct _MetaScreen
{ {
@ -30,11 +31,26 @@ struct _MetaScreen
int number; int number;
Screen *xscreen; Screen *xscreen;
Window xroot; Window xroot;
MetaThemeEngine *engine;
/*< private >*/
/* we only need one since we only draw to a single visual (that of
* root window)
*/
PangoContext *pango_context;
}; };
MetaScreen* meta_screen_new (MetaDisplay *display, MetaScreen* meta_screen_new (MetaDisplay *display,
int number); int number);
void meta_screen_free (MetaScreen *screen); void meta_screen_free (MetaScreen *screen);
void meta_screen_manage_all_windows (MetaScreen *screen); void meta_screen_manage_all_windows (MetaScreen *screen);
PangoContext* meta_screen_get_pango_context (MetaScreen *screen,
const PangoFontDescription *desc,
PangoDirection direction);
MetaScreen* meta_screen_for_x_screen (Screen *xscreen);
#endif #endif

View File

@ -20,26 +20,37 @@
*/ */
#include "theme.h" #include "theme.h"
#include <pango.h> #include "api.h"
#include <pangox.h>
typedef struct _DefaultFrameData DefaultFrameData; typedef struct _DefaultFrameData DefaultFrameData;
struct _DefaultFrameData struct _DefaultFrameData
{ {
PangoLayout *layout; PangoLayout *layout;
GC text_gc;
}; };
static gpointer static gpointer
default_acquire_frame (MetaFrameInfo *info) default_acquire_frame (MetaFrameInfo *info)
{ {
DefaultFrameData *d; DefaultFrameData *d;
PangoFontDescription *desc;
XGCValues vals;
PangoColor color;
d = g_new (DefaultFrameData, 1); d = g_new (DefaultFrameData, 1);
d->layout = NULL; desc = pango_font_description_from_string ("Sans 16");
d->layout = pango_layout_new (meta_get_pango_context (info->screen,
desc,
info->frame));
color.red = color.green = color.blue = 0xffff;
vals.foreground = meta_get_x_pixel (info->screen, &color);
d->text_gc = XCreateGC (info->display,
RootWindowOfScreen (info->screen),
GCForeground,
&vals);
return d; return d;
} }
@ -55,15 +66,42 @@ default_release_frame (MetaFrameInfo *info,
if (d->layout) if (d->layout)
g_object_unref (G_OBJECT (d->layout)); g_object_unref (G_OBJECT (d->layout));
XFreeGC (info->display, d->text_gc);
g_free (d); g_free (d);
} }
#define VERTICAL_TEXT_PAD 3
#define LEFT_WIDTH 2
#define RIGHT_WIDTH 2
#define BOTTOM_HEIGHT 2
void void
default_fill_frame_geometry (MetaFrameInfo *info, default_fill_frame_geometry (MetaFrameInfo *info,
MetaFrameGeometry *geom,
gpointer frame_data) gpointer frame_data)
{ {
DefaultFrameData *d;
PangoRectangle rect;
PangoColor color;
d = frame_data;
if (info->title)
pango_layout_set_text (d->layout, info->title, -1);
else
pango_layout_set_text (d->layout, " ", -1);
pango_layout_get_pixel_extents (d->layout, NULL, &rect);
geom->top_height = rect.height + VERTICAL_TEXT_PAD * 2;
geom->left_width = LEFT_WIDTH;
geom->right_width = RIGHT_WIDTH;
geom->bottom_height = BOTTOM_HEIGHT;
color.red = color.blue = color.green = 0;
geom->background_pixel = meta_get_x_pixel (info->screen, &color);
} }
void void
@ -72,8 +110,16 @@ default_expose_frame (MetaFrameInfo *info,
int width, int height, int width, int height,
gpointer frame_data) gpointer frame_data)
{ {
DefaultFrameData *d;
d = frame_data;
pango_x_render_layout (info->display,
info->frame,
d->text_gc,
d->layout,
LEFT_WIDTH,
VERTICAL_TEXT_PAD);
} }
MetaFrameControl MetaFrameControl
@ -83,6 +129,7 @@ default_get_control (MetaFrameInfo *info,
{ {
return META_FRAME_CONTROL_NONE;
} }
MetaThemeEngine meta_default_engine = { MetaThemeEngine meta_default_engine = {
@ -93,5 +140,3 @@ MetaThemeEngine meta_default_engine = {
default_expose_frame, default_expose_frame,
default_get_control default_get_control
}; };
#endif

View File

@ -22,9 +22,14 @@
#ifndef META_THEME_H #ifndef META_THEME_H
#define META_THEME_H #define META_THEME_H
/* don't add any internal headers here; theme.h is an installed/public
* header.
*/
#include <Xlib.h> #include <Xlib.h>
#include <glib.h>
typedef struct _MetaFrameInfo MetaFrameInfo; typedef struct _MetaFrameInfo MetaFrameInfo;
typedef struct _MetaFrameGeometry MetaFrameGeometry;
typedef struct _MetaThemeEngine MetaThemeEngine; typedef struct _MetaThemeEngine MetaThemeEngine;
typedef enum typedef enum
@ -39,6 +44,8 @@ typedef enum
typedef enum typedef enum
{ {
META_FRAME_CONTROL_NONE,
META_FRAME_CONTROL_TITLE,
META_FRAME_CONTROL_DELETE, META_FRAME_CONTROL_DELETE,
META_FRAME_CONTROL_MENU, META_FRAME_CONTROL_MENU,
META_FRAME_CONTROL_ICONIFY, META_FRAME_CONTROL_ICONIFY,
@ -57,25 +64,23 @@ struct _MetaFrameInfo
{ {
/* These are read-only to engines */ /* These are read-only to engines */
MetaFrameFlags flags; MetaFrameFlags flags;
Window xwindow; /* == None in fill_frame_geometry */ Window frame; /* == None in fill_frame_geometry */
Display *display; Display *display;
Screen *screen;
Visual *visual; Visual *visual;
int depth; int depth;
Colormap cmap;
char *title; const char *title;
/* total frame size normally, but equal to child size in /* Equal to child size before fill_frame_geometry
* fill_frame_geometry * has been called
*/ */
int width; int width;
int height; int height;
};
/* Below here the engine can change things struct _MetaFrameGeometry
* in fill_frame_geometry, though defaults are already {
* filled in.
*/
/* border sizes (space between frame and child) */ /* border sizes (space between frame and child) */
int left_width; int left_width;
int right_width; int right_width;
@ -100,6 +105,7 @@ struct _MetaThemeEngine
gpointer frame_data); gpointer frame_data);
void (* fill_frame_geometry) (MetaFrameInfo *info, void (* fill_frame_geometry) (MetaFrameInfo *info,
MetaFrameGeometry *geom,
gpointer frame_data); gpointer frame_data);
void (* expose_frame) (MetaFrameInfo *info, void (* expose_frame) (MetaFrameInfo *info,

View File

@ -93,6 +93,8 @@ meta_window_new (MetaDisplay *display, Window xwindow)
window->depth = attrs.depth; window->depth = attrs.depth;
window->xvisual = attrs.visual; window->xvisual = attrs.visual;
window->title = g_strdup ("Foo foo foo foo");
meta_display_register_x_window (display, &window->xwindow, window); meta_display_register_x_window (display, &window->xwindow, window);
window->frame = NULL; window->frame = NULL;
@ -108,6 +110,8 @@ meta_window_free (MetaWindow *window)
meta_display_unregister_x_window (window->display, window->xwindow); meta_display_unregister_x_window (window->display, window->xwindow);
g_free (window->title);
meta_window_destroy_frame (window); meta_window_destroy_frame (window);
g_free (window); g_free (window);

View File

@ -37,6 +37,7 @@ struct _MetaWindow
int win_gravity; int win_gravity;
int depth; int depth;
Visual *xvisual; Visual *xvisual;
char *title;
}; };
MetaWindow* meta_window_new (MetaDisplay *display, MetaWindow* meta_window_new (MetaDisplay *display,