Piles of bug fixes; piles of new toys; running to a dinner, comment later -mig
Этот коммит содержится в:
родитель
93ffc92a80
Коммит
89821ca886
@ -14,10 +14,25 @@ INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
GNOMESRCS = gkey.c gmain.c gscreen.c gwidget.c \
|
||||
gmenu.c ginfo.c ghelp.c glayout.c gtools.c gdesktop.c
|
||||
GNOMESRCS = \
|
||||
gkey.c \
|
||||
gmain.c \
|
||||
gscreen.c \
|
||||
gwidget.c \
|
||||
gmenu.c \
|
||||
ginfo.c \
|
||||
ghelp.c \
|
||||
glayout.c \
|
||||
gtools.c \
|
||||
gdesktop.c \
|
||||
gutil.c \
|
||||
gtrans.c
|
||||
|
||||
GNOMEHDRS = gmain.h gscreen.h gwidget.h gconf.h
|
||||
GNOMEHDRS = \
|
||||
gmain.h \
|
||||
gscreen.h \
|
||||
gwidget.h \
|
||||
gconf.h
|
||||
|
||||
#
|
||||
# These objects from ../src do not depend on HAVE_X / HAVE_GNOME??
|
||||
@ -37,7 +52,7 @@ OOBJS = main.o dlg.o screen.o widget.o wtools.o info.o boxes.o \
|
||||
|
||||
OBJS = $(LOBJS) $(OOBJS) \
|
||||
gkey.o gmain.o gscreen.o gwidget.o gmenu.o ghelp.o ginfo.o \
|
||||
glayout.o gtools.o gdesktop.o
|
||||
glayout.o gtools.o gdesktop.o gtrans.o gutil.o
|
||||
|
||||
#
|
||||
# Distribution variables
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define PORT_HAS_FRONTEND_RUN_DLG 1
|
||||
#define PORT_HAS_FILE_HANDLERS 1
|
||||
#define PORT_HAS_GETCH 1
|
||||
|
||||
#define PORT_HAS_MY_SYSTEM 1
|
||||
#define PORT_HAS_DIALOG_TITLE 1
|
||||
#define PORT_WANTS_CLEAN_BUTTON 1
|
||||
#define PORT_HAS_CREATE_PANELS 1
|
||||
|
@ -55,47 +55,6 @@ enum {
|
||||
/* The list of icons on the desktop */
|
||||
static GList *desktop_icons;
|
||||
|
||||
/*
|
||||
* Creates a shaped window, toplevel, non-wm managed window from a given file
|
||||
* uses the all-mighty Imlib to do all the difficult work for us
|
||||
*/
|
||||
GtkWidget *
|
||||
shaped_icon_new_from_file (char *file, int extra_events)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GdkImlibImage *im;
|
||||
GdkWindowPrivate *private;
|
||||
|
||||
if (!g_file_exists (file))
|
||||
return;
|
||||
|
||||
im = gdk_imlib_load_image (file);
|
||||
if (!im)
|
||||
return NULL;
|
||||
|
||||
gtk_widget_push_visual (gdk_imlib_get_visual ());
|
||||
gtk_widget_push_colormap (gdk_imlib_get_colormap ());
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
|
||||
gtk_widget_set_events (window, gtk_widget_get_events (window) | extra_events);
|
||||
|
||||
gtk_widget_pop_colormap ();
|
||||
gtk_widget_pop_visual ();
|
||||
|
||||
gtk_widget_set_usize (window, im->rgb_width, im->rgb_height);
|
||||
gtk_widget_realize (window);
|
||||
gdk_window_resize (window->window, im->rgb_width, im->rgb_height);
|
||||
private = (GdkWindowPrivate *) window->window;
|
||||
private->width = im->rgb_width;
|
||||
private->height = im->rgb_height;
|
||||
gdk_imlib_apply_image (im, window->window);
|
||||
|
||||
gdk_imlib_destroy_image (im);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the dentry is zero, then no information from the on-disk .desktop file is used
|
||||
* In this case, we probably will have to store the geometry for a file somewhere
|
||||
@ -125,15 +84,16 @@ desktop_icon_set_position (desktop_icon_t *di, GtkWidget *widget)
|
||||
x = current_x;
|
||||
y = current_y;
|
||||
|
||||
current_y += 64;
|
||||
gtk_widget_size_request (widget, &widget->requisition);
|
||||
current_y += widget->requisition.height + 8;
|
||||
if (current_y > gdk_screen_height ()){
|
||||
current_x += 64;
|
||||
current_x += 0;
|
||||
current_y = 0;
|
||||
}
|
||||
}
|
||||
di->x = x;
|
||||
di->y = y;
|
||||
gtk_widget_set_uposition (widget, x, y);
|
||||
gtk_widget_set_uposition (widget, 6 + x, y);
|
||||
}
|
||||
|
||||
static int operation_value;
|
||||
@ -210,8 +170,7 @@ check_window_id_in_one_panel (gpointer data, gpointer user_data)
|
||||
PanelContainer *pc = (PanelContainer *) data;
|
||||
int id = (int) user_data;
|
||||
WPanel *panel = pc->panel;
|
||||
g_panel_contents *gpc = (g_panel_contents *) panel->widget.wdata;
|
||||
GtkCList *clist = GTK_CLIST (gpc->list);
|
||||
GtkCList *clist = GTK_CLIST (panel->list);
|
||||
GdkWindowPrivate *gdk_wp;
|
||||
|
||||
gdk_wp = (GdkWindowPrivate *) clist->clist_window;
|
||||
@ -385,14 +344,16 @@ desktop_load_dentry (char *filename)
|
||||
GnomeDesktopEntry *dentry;
|
||||
desktop_icon_t *di;
|
||||
GtkWidget *window;
|
||||
|
||||
char *icon_label;
|
||||
|
||||
dentry = gnome_desktop_entry_load (filename);
|
||||
|
||||
if (!dentry)
|
||||
return;
|
||||
|
||||
icon_label = dentry->name ? dentry->name : x_basename (dentry->exec);
|
||||
if (dentry->icon)
|
||||
window = shaped_icon_new_from_file (dentry->icon, GDK_BUTTON_PRESS_MASK);
|
||||
window = create_transparent_text_window (dentry->icon, icon_label, GDK_BUTTON_PRESS_MASK);
|
||||
else {
|
||||
static char *default_icon_path;
|
||||
static char exists;
|
||||
@ -404,7 +365,7 @@ desktop_load_dentry (char *filename)
|
||||
}
|
||||
|
||||
if (exists)
|
||||
window = shaped_icon_new_from_file (default_icon_path, GDK_BUTTON_PRESS_MASK);
|
||||
window = create_transparent_text_window (default_icon_path, icon_label, GDK_BUTTON_PRESS_MASK);
|
||||
else {
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_widget_set_usize (window, 20, 20);
|
||||
@ -500,7 +461,7 @@ desktop_create_launch_entry (char *pathname, char *short_name)
|
||||
char *icon;
|
||||
|
||||
icon = get_desktop_icon (pathname);
|
||||
window = shaped_icon_new_from_file (icon, GDK_BUTTON_PRESS_MASK);
|
||||
window = create_transparent_text_window (icon, x_basename (pathname), GDK_BUTTON_PRESS_MASK);
|
||||
g_free (icon);
|
||||
di = xmalloc (sizeof (desktop_icon_t), "dcle");
|
||||
di->dentry = NULL;
|
||||
|
@ -1 +1,2 @@
|
||||
#define MC_LIB_DESKTOP "mc.desktop"
|
||||
GtkWidget *create_transparent_text_window (char *file, char *text, int extra_events);
|
||||
|
@ -88,10 +88,7 @@ set_new_current_panel (WPanel *panel)
|
||||
void
|
||||
set_hintbar (char *str)
|
||||
{
|
||||
g_panel_contents *gp;
|
||||
|
||||
gp = (g_panel_contents *) current_panel_ptr->panel->widget.wdata;
|
||||
gtk_label_set (GTK_LABEL (gp->status), str);
|
||||
gtk_label_set (GTK_LABEL (current_panel_ptr->panel->status), str);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -178,15 +178,7 @@ x_panel_container_show (widget_data wdata)
|
||||
void
|
||||
x_focus_widget (Widget_Item *p)
|
||||
{
|
||||
/* Ok, ultra hack again: the top-level containers dont have regular
|
||||
* widgets in p->widget->wdata, but a g_panel_contents in there
|
||||
*/
|
||||
if (((void *)p->widget->callback) == ((void *)panel_callback)){
|
||||
g_panel_contents *g = (g_panel_contents *) p->widget->wdata;
|
||||
|
||||
gtk_widget_grab_focus (GTK_WIDGET (g->list));
|
||||
} else
|
||||
gtk_widget_grab_focus (GTK_WIDGET (p->widget->wdata));
|
||||
gtk_widget_grab_focus (GTK_WIDGET (p->widget->wdata));
|
||||
}
|
||||
|
||||
void
|
||||
@ -224,8 +216,8 @@ x_init_dlg (Dlg_head *h)
|
||||
void
|
||||
x_destroy_dlg (Dlg_head *h)
|
||||
{
|
||||
printf ("me llaman!\n");
|
||||
gtk_grab_remove (GTK_WIDGET (GTK_BIN (h->wdata)->child));
|
||||
if (!(h->grided & DLG_NO_TED))
|
||||
gtk_grab_remove (GTK_WIDGET (GTK_BIN (h->wdata)->child));
|
||||
gtk_widget_destroy (GTK_WIDGET(h->wdata));
|
||||
}
|
||||
|
||||
@ -280,3 +272,4 @@ create_panels (void)
|
||||
set_current_panel (0);
|
||||
run_dlg (h);
|
||||
}
|
||||
|
||||
|
@ -7,3 +7,7 @@
|
||||
- Menu organization
|
||||
- Intenrationalization
|
||||
- All of the dialogs.
|
||||
|
||||
Possibly make a way to bind a toplevel widget to the Dlg_head part of the
|
||||
system so that grab_add/ungrab and the widget destruction reuse all of that
|
||||
code for NON_TED dialogs.
|
@ -82,10 +82,9 @@ panel_file_list_set_row_colors (GtkCList *cl, int row, int color_pair)
|
||||
void
|
||||
x_fill_panel (WPanel *panel)
|
||||
{
|
||||
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
|
||||
const int top = panel->count;
|
||||
const int items = panel->format->items;
|
||||
GtkCList *cl = GTK_CLIST (g->list);
|
||||
GtkCList *cl = GTK_CLIST (panel->list);
|
||||
int i, col, type_col, color;
|
||||
char **texts;
|
||||
|
||||
@ -169,8 +168,7 @@ static int will_select;
|
||||
void
|
||||
x_select_item (WPanel *panel)
|
||||
{
|
||||
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
|
||||
GtkCList *clist = GTK_CLIST (g->list);
|
||||
GtkCList *clist = GTK_CLIST (panel->list);
|
||||
|
||||
if (will_select)
|
||||
return;
|
||||
@ -184,31 +182,26 @@ x_select_item (WPanel *panel)
|
||||
void
|
||||
x_unselect_item (WPanel *panel)
|
||||
{
|
||||
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
|
||||
gtk_clist_unselect_row (GTK_CLIST (g->list), panel->selected, 0);
|
||||
gtk_clist_unselect_row (GTK_CLIST (panel->list), panel->selected, 0);
|
||||
}
|
||||
|
||||
void
|
||||
x_filter_changed (WPanel *panel)
|
||||
{
|
||||
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
|
||||
|
||||
if (panel->filter){
|
||||
char *string;
|
||||
|
||||
string = g_copy_strings ("Filter: ", panel->filter, NULL);
|
||||
gtk_label_set (GTK_LABEL (g->filter), string);
|
||||
gtk_label_set (GTK_LABEL (panel->filter), string);
|
||||
g_free (string);
|
||||
} else
|
||||
gtk_label_set (GTK_LABEL (g->filter), "No filter");
|
||||
gtk_label_set (GTK_LABEL (panel->filter), "No filter");
|
||||
}
|
||||
|
||||
void
|
||||
x_adjust_top_file (WPanel *panel)
|
||||
{
|
||||
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
|
||||
|
||||
gtk_clist_moveto (GTK_CLIST (g->list), panel->top_file, 0, 0.0, 0.0);
|
||||
gtk_clist_moveto (GTK_CLIST (panel->list), panel->top_file, 0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
#define COLUMN_INSET 3
|
||||
@ -788,56 +781,55 @@ panel_create_filter (WPanel *panel, GtkWidget **label)
|
||||
void
|
||||
x_create_panel (Dlg_head *h, widget_data parent, WPanel *panel)
|
||||
{
|
||||
g_panel_contents *g = g_new (g_panel_contents, 1);
|
||||
GtkWidget *status_line, *filter_w, *statusbar, *vbox;
|
||||
|
||||
g->table = gtk_table_new (2, 1, 0);
|
||||
gtk_widget_show (g->table);
|
||||
panel->table = gtk_table_new (2, 1, 0);
|
||||
gtk_widget_show (panel->table);
|
||||
|
||||
g->list = panel_create_file_list (panel);
|
||||
gtk_widget_show (g->list);
|
||||
panel->list = panel_create_file_list (panel);
|
||||
gtk_widget_show (panel->list);
|
||||
|
||||
g->current_dir = panel_create_cwd (panel);
|
||||
gtk_widget_show (g->current_dir);
|
||||
panel->current_dir = panel_create_cwd (panel);
|
||||
gtk_widget_show (panel->current_dir);
|
||||
|
||||
filter_w = panel_create_filter (panel, &g->filter);
|
||||
filter_w = panel_create_filter (panel, &panel->filter_w);
|
||||
gtk_widget_show (filter_w);
|
||||
|
||||
status_line = gtk_hbox_new (0, 0);
|
||||
gtk_widget_show (status_line);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (status_line), g->current_dir, 0, 0, 0);
|
||||
gtk_box_pack_start (GTK_BOX (status_line), panel->current_dir, 0, 0, 0);
|
||||
gtk_box_pack_end (GTK_BOX (status_line), filter_w, 0, 0, 0);
|
||||
|
||||
g->status = statusbar = gtk_label_new ("");
|
||||
panel->status = statusbar = gtk_label_new ("");
|
||||
gtk_widget_show (statusbar);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (g->table), g->list, 0, 1, 1, 2,
|
||||
gtk_table_attach (GTK_TABLE (panel->table), panel->list, 0, 1, 1, 2,
|
||||
GTK_EXPAND | GTK_FILL | GTK_SHRINK,
|
||||
GTK_EXPAND | GTK_FILL | GTK_SHRINK,
|
||||
0, 0);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (g->table), status_line, 0, 1, 0, 1,
|
||||
gtk_table_attach (GTK_TABLE (panel->table), status_line, 0, 1, 0, 1,
|
||||
GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (g->table), statusbar, 0, 1, 2, 3,
|
||||
gtk_table_attach (GTK_TABLE (panel->table), statusbar, 0, 1, 2, 3,
|
||||
GTK_EXPAND | GTK_FILL | GTK_SHRINK,
|
||||
0, 0, 0);
|
||||
|
||||
gtk_widget_show (g->table);
|
||||
gtk_widget_show (panel->table);
|
||||
|
||||
/* Ultra nasty hack: pull the vbox from wdata */
|
||||
vbox = GTK_WIDGET (panel->widget.wdata);
|
||||
|
||||
panel->widget.wdata = (widget_data) g;
|
||||
panel->widget.wdata = (widget_data) panel->table;
|
||||
|
||||
/* Now, insert our table in our parent */
|
||||
gtk_container_add (GTK_CONTAINER (vbox), g->table);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), panel->table);
|
||||
|
||||
if (!pixmaps_ready){
|
||||
if (!GTK_WIDGET_REALIZED (g->list))
|
||||
gtk_widget_realize (g->list);
|
||||
panel_create_pixmaps (g->list);
|
||||
if (!GTK_WIDGET_REALIZED (panel->list))
|
||||
gtk_widget_realize (panel->list);
|
||||
panel_create_pixmaps (panel->list);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,14 +9,6 @@ void x_add_sort_label (WPanel *panel, int index, char *text, char *tag, void *sr
|
||||
void x_sort_label_start (WPanel *panel);
|
||||
void x_reset_sort_labels (WPanel *panel);
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *table;
|
||||
GtkWidget *list;
|
||||
GtkWidget *current_dir;
|
||||
GtkWidget *filter;
|
||||
GtkWidget *status;
|
||||
} g_panel_contents;
|
||||
|
||||
WPanel *create_container (Dlg_head *h, char *str);
|
||||
|
||||
typedef struct {
|
||||
|
@ -1,6 +1,12 @@
|
||||
/*
|
||||
* (C) 1998 the Free Software Foundation
|
||||
*
|
||||
* Written by Miguel de Icaza
|
||||
*/
|
||||
#include "util.h"
|
||||
#include <gnome.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include "gconf.h"
|
||||
#include "myslang.h"
|
||||
#include "dlg.h"
|
||||
#undef HAVE_LIBGPM
|
||||
@ -9,6 +15,7 @@
|
||||
#include "widget.h"
|
||||
#include "wtools.h"
|
||||
#include "dialog.h"
|
||||
#include "color.h"
|
||||
|
||||
static int sel_pos;
|
||||
|
||||
@ -17,47 +24,79 @@ void query_set_sel (int new_sel)
|
||||
sel_pos = new_sel;
|
||||
}
|
||||
|
||||
static void
|
||||
pack_button (WButton *button, GtkBox *box)
|
||||
{
|
||||
if (!button)
|
||||
return;
|
||||
gtk_box_pack_start_defaults (GTK_BOX (box), GTK_WIDGET (button->widget.wdata));
|
||||
}
|
||||
|
||||
int query_dialog (char *header, char *text, int flags, int count, ...)
|
||||
{
|
||||
va_list ap;
|
||||
Dlg_head *h;
|
||||
WLabel *label;
|
||||
GtkDialog *dialog;
|
||||
GtkWidget *label, *focus_widget;
|
||||
int i;
|
||||
GList *list;
|
||||
int i, result = -1;
|
||||
|
||||
va_start (ap, count);
|
||||
h = create_dlg (0, 0, 0, 0, dialog_colors, default_dlg_callback, "[QueryBox]", "query",
|
||||
DLG_NO_TED);
|
||||
dialog = GTK_DIALOG (gtk_dialog_new ());
|
||||
label = gtk_label_new (text);
|
||||
gtk_widget_show (label);
|
||||
|
||||
|
||||
x_set_dialog_title (h, header);
|
||||
|
||||
label = label_new (0, 0, text, NULL);
|
||||
add_widget (h, label);
|
||||
|
||||
if (flags & D_ERROR)
|
||||
fprintf (stderr, "Messagebox: this should be displayed like an error\n");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (dialog->vbox), label);
|
||||
gtk_container_border_width (GTK_CONTAINER (dialog->vbox), 5);
|
||||
|
||||
va_start (ap, count);
|
||||
list = g_list_alloc ();
|
||||
for (i = 0; i < count; i++){
|
||||
GtkWidget *button;
|
||||
WButton *button;
|
||||
char *cur_name = va_arg (ap, char *);
|
||||
|
||||
button = gtk_button_new_with_label (cur_name);
|
||||
gtk_widget_show (button);
|
||||
button = button_new (0, 0, B_USER+i, NORMAL_BUTTON, cur_name, 0, 0, NULL);
|
||||
|
||||
gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dialog)->action_area), button);
|
||||
add_widget (h, button);
|
||||
list = g_list_append (list, button);
|
||||
|
||||
if (i == sel_pos){
|
||||
focus_widget = button;
|
||||
}
|
||||
if (i == sel_pos)
|
||||
h->initfocus = h->current;
|
||||
}
|
||||
if (focus_widget)
|
||||
gtk_widget_grab_focus (focus_widget);
|
||||
va_end (ap);
|
||||
|
||||
/* Init the widgets */
|
||||
init_dlg (h);
|
||||
gtk_grab_add (dialog);
|
||||
|
||||
/* Now do the GTK stuff */
|
||||
gtk_container_add (GTK_CONTAINER (dialog->vbox), GTK_WIDGET (label->widget.wdata));
|
||||
gtk_container_border_width (GTK_CONTAINER (dialog->vbox), 5);
|
||||
|
||||
g_list_foreach (list, (GFunc) pack_button, dialog->action_area);
|
||||
g_list_free (list);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (dialog));
|
||||
|
||||
gtk_grab_add (GTK_WIDGET (dialog));
|
||||
gtk_main ();
|
||||
gtk_grab_remove (GTK_WIDGET (dialog));
|
||||
frontend_run_dlg (h);
|
||||
dlg_run_done (h);
|
||||
gtk_grab_remove (dialog);
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
switch (h->ret_value){
|
||||
case B_CANCEL:
|
||||
break;
|
||||
default:
|
||||
result = h->ret_value - B_USER;
|
||||
}
|
||||
destroy_dlg (h);
|
||||
|
||||
sel_pos = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* To show nice messages to the users */
|
||||
|
276
gnome/gtrans.c
Обычный файл
276
gnome/gtrans.c
Обычный файл
@ -0,0 +1,276 @@
|
||||
/* Module for creating a shaped window with text (for desktop icons)
|
||||
*
|
||||
* Copyright (C) 1998 the Free Software Foundation
|
||||
*
|
||||
* Author: Federico Mena <federico@nuclecu.unam.mx>
|
||||
*/
|
||||
|
||||
#include <gnome.h>
|
||||
#include <string.h>
|
||||
#include "gdesktop.h"
|
||||
/* The spacing between the cute little icon and the text */
|
||||
#define SPACING 2
|
||||
|
||||
/*
|
||||
* Most of this code was yanked from the gtktooltips module in Gtk+.
|
||||
* I have tweaked it a bit for MC's purposes - Federico
|
||||
*/
|
||||
|
||||
struct text_info {
|
||||
GList *rows;
|
||||
GdkFont *font;
|
||||
int width;
|
||||
int height;
|
||||
int baseline_skip;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
free_string (gpointer data, gpointer user_data)
|
||||
{
|
||||
if (data)
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
text_info_free (struct text_info *ti)
|
||||
{
|
||||
g_list_foreach (ti->rows, free_string, NULL);
|
||||
g_list_free (ti->rows);
|
||||
g_free (ti);
|
||||
}
|
||||
|
||||
static struct text_info *
|
||||
layout_text (GtkWidget *widget, char *text)
|
||||
{
|
||||
struct text_info *ti;
|
||||
char *row_end, *row_text, *break_pos;
|
||||
int i, row_width, window_width;
|
||||
size_t len;
|
||||
|
||||
ti = g_new (struct text_info, 1);
|
||||
|
||||
ti->rows = NULL;
|
||||
ti->font = widget->style->font;
|
||||
ti->width = 0;
|
||||
ti->height = 0;
|
||||
|
||||
ti->baseline_skip = ti->font->ascent + ti->font->descent;
|
||||
|
||||
window_width = 0;
|
||||
|
||||
while (*text) {
|
||||
row_end = strchr (text, '\n');
|
||||
if (!row_end)
|
||||
row_end = strchr (text, '\0');
|
||||
|
||||
len = row_end - text + 1;
|
||||
row_text = g_new (char, len);
|
||||
memcpy (row_text, text, len - 1);
|
||||
row_text[len - 1] = '\0';
|
||||
|
||||
/* Adjust the window's width or shorten the row until
|
||||
* it fits in the window.
|
||||
*/
|
||||
|
||||
while (1) {
|
||||
row_width = gdk_string_width (ti->font, row_text);
|
||||
if (!window_width) {
|
||||
/* make an initial guess at window's width */
|
||||
|
||||
if (row_width > (gdk_screen_width () / 12))
|
||||
window_width = gdk_screen_width () / 12;
|
||||
else
|
||||
window_width = row_width;
|
||||
}
|
||||
|
||||
if (row_width <= window_width)
|
||||
break;
|
||||
|
||||
if (strchr (row_text, ' ')) {
|
||||
/* the row is currently too wide, but we have
|
||||
* blanks in the row so we can break it into
|
||||
* smaller pieces
|
||||
*/
|
||||
|
||||
int avg_width = row_width / strlen (row_text);
|
||||
|
||||
i = window_width;
|
||||
|
||||
if (avg_width != 0)
|
||||
i /= avg_width;
|
||||
|
||||
if ((size_t) i >= len)
|
||||
i = len - 1;
|
||||
|
||||
break_pos = strchr (row_text + i, ' ');
|
||||
if (!break_pos) {
|
||||
break_pos = row_text+ i;
|
||||
while (*--break_pos != ' ');
|
||||
}
|
||||
|
||||
*break_pos = '\0';
|
||||
} else {
|
||||
/* We can't break this row into any smaller
|
||||
* pieces, so we have no choice but to widen
|
||||
* the window
|
||||
*
|
||||
* For MC, we may want to modify the code above
|
||||
* so that it can also split the string on the
|
||||
* slahes of filenames.
|
||||
*/
|
||||
|
||||
window_width = row_width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (row_width > ti->width)
|
||||
ti->width = row_width;
|
||||
|
||||
ti->rows = g_list_append (ti->rows, row_text);
|
||||
ti->height += ti->baseline_skip;
|
||||
|
||||
text += strlen (row_text);
|
||||
if (!*text)
|
||||
break;
|
||||
|
||||
if (text[0] == '\n' && text[1]) {
|
||||
/* end of paragraph and there is more text to come */
|
||||
ti->rows = g_list_append (ti->rows, NULL);
|
||||
ti->height += ti->baseline_skip / 2;
|
||||
}
|
||||
|
||||
text++; /* skip blank or newline */
|
||||
}
|
||||
|
||||
return ti;
|
||||
}
|
||||
|
||||
static void
|
||||
paint_text (struct text_info *ti, GdkDrawable *drawable, GdkGC *gc, int x_ofs, int y_ofs)
|
||||
{
|
||||
int y, w;
|
||||
GList *item;
|
||||
|
||||
y = y_ofs + ti->font->ascent;
|
||||
|
||||
for (item = ti->rows; item; item = item->next) {
|
||||
if (item->data) {
|
||||
w = gdk_string_width (ti->font, item->data);
|
||||
gdk_draw_string (drawable, ti->font, gc, x_ofs + (ti->width - w) / 2, y, item->data);
|
||||
y += ti->baseline_skip;
|
||||
} else
|
||||
y += ti->baseline_skip / 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_window_text (GtkWidget *window, GdkImlibImage *im, char *text)
|
||||
{
|
||||
GdkPixmap *pixmap;
|
||||
GdkPixmap *im_pixmap;
|
||||
GdkBitmap *mask;
|
||||
GdkBitmap *im_mask;
|
||||
struct text_info *ti;
|
||||
GdkColor color;
|
||||
GdkGC *gc;
|
||||
int width, height;
|
||||
|
||||
ti = layout_text (window, text);
|
||||
|
||||
width = MAX (ti->width, im->rgb_width);
|
||||
height = im->rgb_height + SPACING + ti->height;
|
||||
|
||||
/* pixmap */
|
||||
|
||||
pixmap = gdk_pixmap_new (window->window, width, height, gdk_imlib_get_visual ()->depth);
|
||||
|
||||
gc = gdk_gc_new (pixmap);
|
||||
|
||||
gdk_color_white (gdk_imlib_get_colormap (), &color);
|
||||
gdk_gc_set_foreground (gc, &color);
|
||||
gdk_draw_rectangle (pixmap, gc, TRUE, 0, 0, width, height);
|
||||
|
||||
im_pixmap = gdk_imlib_move_image (im);
|
||||
gdk_window_copy_area (pixmap, gc,
|
||||
(width - im->rgb_width) / 2,
|
||||
0,
|
||||
im_pixmap,
|
||||
0, 0,
|
||||
im->rgb_width, im->rgb_height);
|
||||
gdk_imlib_free_pixmap (im_pixmap);
|
||||
|
||||
/* mask */
|
||||
|
||||
mask = gdk_pixmap_new (window->window, width, height, 1);
|
||||
|
||||
gc = gdk_gc_new (mask);
|
||||
|
||||
color.pixel = 0;
|
||||
gdk_gc_set_foreground (gc, &color);
|
||||
gdk_draw_rectangle (mask, gc, TRUE, 0, 0, width, height);
|
||||
|
||||
im_mask = gdk_imlib_move_mask (im);
|
||||
if (im_mask) {
|
||||
gdk_window_copy_area (mask, gc,
|
||||
(width - im->rgb_width) / 2,
|
||||
0,
|
||||
im_mask,
|
||||
0, 0,
|
||||
im->rgb_width, im->rgb_height);
|
||||
gdk_imlib_free_bitmap (im_mask);
|
||||
}
|
||||
|
||||
color.pixel = 1;
|
||||
gdk_gc_set_foreground (gc, &color);
|
||||
paint_text (ti, mask, gc,
|
||||
(width - ti->width) / 2,
|
||||
im->rgb_height + SPACING);
|
||||
|
||||
gdk_gc_destroy (gc);
|
||||
|
||||
/* set contents */
|
||||
|
||||
gtk_widget_set_usize (window, width, height);
|
||||
gdk_window_set_back_pixmap (window->window, pixmap, FALSE);
|
||||
gdk_window_shape_combine_mask (window->window, mask, 0, 0);
|
||||
|
||||
gdk_pixmap_unref (pixmap);
|
||||
gdk_pixmap_unref (mask);
|
||||
|
||||
text_info_free (ti);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
create_transparent_text_window (char *file, char *text, int extra_events)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GdkImlibImage *im;
|
||||
|
||||
if (!g_file_exists (file))
|
||||
return NULL;
|
||||
|
||||
im = gdk_imlib_load_image (file);
|
||||
if (!im)
|
||||
return NULL;
|
||||
|
||||
gtk_widget_push_visual (gdk_imlib_get_visual ());
|
||||
gtk_widget_push_colormap (gdk_imlib_get_colormap ());
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_widget_set_events (window, gtk_widget_get_events (window) | extra_events);
|
||||
|
||||
gtk_widget_pop_colormap ();
|
||||
gtk_widget_pop_visual ();
|
||||
|
||||
gtk_widget_realize (window);
|
||||
|
||||
gdk_imlib_render (im, im->rgb_width, im->rgb_height);
|
||||
|
||||
set_window_text (window, im, text);
|
||||
|
||||
gdk_imlib_destroy_image (im);
|
||||
|
||||
return window;
|
||||
}
|
87
gnome/gutil.c
Обычный файл
87
gnome/gutil.c
Обычный файл
@ -0,0 +1,87 @@
|
||||
/* Various utilities - Unix variants
|
||||
Copyright (C) 1998 the Free Software Foundation.
|
||||
|
||||
Written 1998 by:
|
||||
Miguel de Icaza
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <signal.h> /* my_system */
|
||||
#include <limits.h> /* INT_MAX */
|
||||
#include <sys/time.h> /* select: timeout */
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h> /* my_system */
|
||||
#endif
|
||||
#include <errno.h> /* my_system */
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
|
||||
int my_system (int as_shell_command, const char *shell, const char *command)
|
||||
{
|
||||
struct sigaction ignore, save_intr, save_quit, save_stop;
|
||||
pid_t pid;
|
||||
int status = 0;
|
||||
|
||||
ignore.sa_handler = SIG_IGN;
|
||||
sigemptyset (&ignore.sa_mask);
|
||||
ignore.sa_flags = 0;
|
||||
|
||||
sigaction (SIGINT, &ignore, &save_intr);
|
||||
sigaction (SIGQUIT, &ignore, &save_quit);
|
||||
|
||||
if ((pid = fork ()) < 0){
|
||||
fprintf (stderr, "\n\nfork () = -1\n");
|
||||
return -1;
|
||||
}
|
||||
if (pid == 0){
|
||||
sigaction (SIGINT, &save_intr, NULL);
|
||||
sigaction (SIGQUIT, &save_quit, NULL);
|
||||
|
||||
if (as_shell_command)
|
||||
execl (shell, shell, "-c", command, (char *) 0);
|
||||
else
|
||||
execlp (shell, shell, command, (char *) 0);
|
||||
|
||||
_exit (127); /* Exec error */
|
||||
}
|
||||
sigaction (SIGINT, &save_intr, NULL);
|
||||
sigaction (SIGQUIT, &save_quit, NULL);
|
||||
sigaction (SIGTSTP, &save_stop, NULL);
|
||||
|
||||
#ifdef SCO_FLAVOR
|
||||
waitpid(-1, NULL, WNOHANG);
|
||||
#endif /* SCO_FLAVOR */
|
||||
|
||||
return WEXITSTATUS(status);
|
||||
}
|
Загрузка…
Ссылка в новой задаче
Block a user