Commit 31d6e2dc authored by rhp's avatar rhp
Browse files

...

parent 85bd843b
/* 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);
}
/* 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
/* 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
}
/* 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
......@@ -190,6 +190,26 @@ meta_display_screen_for_root (MetaDisplay *display,
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 */
void
meta_display_grab (MetaDisplay *display)
......
......@@ -24,6 +24,7 @@
#include <glib.h>
#include <Xlib.h>
#include <pango/pangox.h>
#include "eventqueue.h"
typedef struct _MetaDisplay MetaDisplay;
......@@ -35,7 +36,8 @@ struct _MetaDisplay
{
char *name;
Display *xdisplay;
/*< private-ish >*/
MetaEventQueue *events;
GSList *screens;
GHashTable *window_ids;
......@@ -43,12 +45,16 @@ struct _MetaDisplay
int server_grab_count;
};
gboolean meta_display_open (const char *name);
void meta_display_close (MetaDisplay *display);
MetaScreen* meta_display_screen_for_root (MetaDisplay *display,
Window xroot);
void meta_display_grab (MetaDisplay *display);
void meta_display_ungrab (MetaDisplay *display);
gboolean meta_display_open (const char *name);
void meta_display_close (MetaDisplay *display);
MetaScreen* meta_display_screen_for_root (MetaDisplay *display,
Window xroot);
MetaScreen* meta_display_screen_for_x_screen (MetaDisplay *display,
Screen *screen);
void meta_display_grab (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"
* to it, such as the frame window.
......
......@@ -22,6 +22,21 @@
#include "frame.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
meta_window_ensure_frame (MetaWindow *window)
{
......@@ -29,6 +44,8 @@ meta_window_ensure_frame (MetaWindow *window)
int child_x, child_y;
unsigned long background_pixel;
XSetWindowAttributes attrs;
MetaFrameInfo info;
MetaFrameGeometry geom;
if (window->frame)
return;
......@@ -37,14 +54,33 @@ meta_window_ensure_frame (MetaWindow *window)
frame->window = window;
/* FIXME de-hardcode */
child_x = 5;
child_y = 5;
/* Fill these in for the theme engine's benefit */
frame->xwindow = None;
frame->rect.width = window->rect.width;
frame->rect.height = window->rect.height;
meta_frame_init_info (frame, &info);
frame->rect.width = window->rect.width + 10;
frame->rect.height = window->rect.height + 10;
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);
background_pixel = BlackPixel (window->display, 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)
{
......@@ -151,11 +187,18 @@ void
meta_window_destroy_frame (MetaWindow *window)
{
MetaFrame *frame;
MetaFrameInfo info;
if (window->frame == NULL)
return;
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,
* thus the error trap.
......@@ -220,6 +263,16 @@ meta_frame_event (MetaFrame *frame,
case KeymapNotify:
break;
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;
case GraphicsExpose:
break;
......
......@@ -33,6 +33,8 @@ struct _MetaFrame
Window xwindow;
MetaRectangle rect;
gpointer theme_data;
};
void meta_window_ensure_frame (MetaWindow *window);
......
......@@ -37,6 +37,8 @@ main (int argc, char **argv)
meta_set_verbose (TRUE);
meta_set_debugging (TRUE);
meta_set_syncing (g_getenv ("METACITY_SYNC") != NULL);
g_type_init (0); /* grumble */
meta_errors_init ();
......
#! /bin/bash
Xnest :1 -scrns 2 -geometry 200x200 &
Xnest :1 -scrns 2 -geometry 270x270 &
sleep 1
DISPLAY=:1 unst $1 ./metacity
killall Xnest
......@@ -23,7 +23,11 @@
#include "util.h"
#include "errors.h"
#include "window.h"
#include "colors.h"
#include <cursorfont.h>
#include <locale.h>
#include <string.h>
MetaScreen*
meta_screen_new (MetaDisplay *display,
......@@ -81,7 +85,10 @@ meta_screen_new (MetaDisplay *display,
screen->number = number;
screen->xscreen = ScreenOfDisplay (xdisplay, number);
screen->xroot = xroot;
screen->pango_context = NULL;
screen->engine = &meta_default_engine;
meta_verbose ("Added screen %d on display '%s' root 0x%lx\n",
screen->number, screen->display->name, screen->xroot);
......@@ -91,6 +98,8 @@ meta_screen_new (MetaDisplay *display,
void
meta_screen_free (MetaScreen *screen)
{
if (screen->pango_context)
g_object_unref (G_OBJECT (screen->pango_context));
g_free (screen);
}
......@@ -130,3 +139,120 @@ meta_screen_manage_all_windows (MetaScreen *screen)
if (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);
}
......@@ -23,6 +23,7 @@
#define META_SCREEN_H
#include "display.h"
#include "theme.h"
struct _MetaScreen
{
......@@ -30,11 +31,26 @@ struct _MetaScreen
int number;
Screen *xscreen;
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,
int number);
void meta_screen_free (MetaScreen *screen);
void meta_screen_manage_all_windows (MetaScreen *screen);
MetaScreen* meta_screen_new (MetaDisplay *display,
int number);
void meta_screen_free (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
......@@ -20,26 +20,37 @@
*/
#include "theme.h"
#include <pango.h>
#include <pangox.h>
#include "api.h"
typedef struct _DefaultFrameData DefaultFrameData;
struct _DefaultFrameData
{
PangoLayout *layout;
GC text_gc;
};
static gpointer
default_acquire_frame (MetaFrameInfo *info)
{
DefaultFrameData *d;
PangoFontDescription *desc;
XGCValues vals;
PangoColor color;
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;
}
......@@ -55,15 +66,42 @@ default_release_frame (MetaFrameInfo *info,
if (d->layout)
g_object_unref (G_OBJECT (d->layout));
XFreeGC (info->display, d->text_gc);
g_free (d);
}
#define VERTICAL_TEXT_PAD 3
#define LEFT_WIDTH 2
#define RIGHT_WIDTH 2
#define BOTTOM_HEIGHT 2
void
default_fill_frame_geometry (MetaFrameInfo *info,
MetaFrameGeometry *geom,
gpointer frame_data)
{
DefaultFrameData *d;
PangoRectangle rect;
PangoColor color;