summaryrefslogtreecommitdiff
path: root/app/wlib
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2016-12-28 20:24:50 +0100
committerJörg Frings-Fürst <debian@jff-webhosting.net>2016-12-28 20:24:50 +0100
commit09795a01ef859f072920de9df974d1b03b9ab9a4 (patch)
tree4d05907fc37f1bd781e506f5e196f7435aeec0ab /app/wlib
parent5b4163d8c76b03f0d31b09866aa4bd06b4d8d804 (diff)
New upstream version 4.2.4aupstream/4.2.4a
Diffstat (limited to 'app/wlib')
-rw-r--r--app/wlib/gtklib/.directory7
-rw-r--r--app/wlib/gtklib/CMakeLists.txt14
-rw-r--r--app/wlib/gtklib/FindGTKUnixPrint.cmake49
-rw-r--r--app/wlib/gtklib/filesel.c64
-rw-r--r--app/wlib/gtklib/gtkcolor.c2
-rw-r--r--app/wlib/gtklib/gtkdraw-cairo.c118
-rw-r--r--app/wlib/gtklib/gtkdraw.c1044
-rw-r--r--app/wlib/gtklib/gtkfont.c88
-rw-r--r--app/wlib/gtklib/gtkint.h42
-rw-r--r--app/wlib/gtklib/gtklist.c70
-rw-r--r--app/wlib/gtklib/gtkmenu.c2
-rw-r--r--app/wlib/gtklib/gtktext.c308
-rw-r--r--app/wlib/gtklib/gtkxpm.c90
-rw-r--r--app/wlib/gtklib/print.c858
-rw-r--r--app/wlib/gtklib/psprint.c1599
-rw-r--r--app/wlib/gtklib/wpref.c12
-rw-r--r--app/wlib/include/wlib.h16
-rw-r--r--app/wlib/mswlib/mswbutt.c14
-rw-r--r--app/wlib/mswlib/mswlist.c35
-rw-r--r--app/wlib/mswlib/mswmenu.c71
-rw-r--r--app/wlib/mswlib/mswmisc.c62
-rw-r--r--app/wlib/mswlib/simple-gettext.c7
22 files changed, 1616 insertions, 2956 deletions
diff --git a/app/wlib/gtklib/.directory b/app/wlib/gtklib/.directory
deleted file mode 100644
index 2482e35..0000000
--- a/app/wlib/gtklib/.directory
+++ /dev/null
@@ -1,7 +0,0 @@
-[Dolphin]
-HeaderColumnWidths=500,64,124
-SortOrder=1
-SortRole=date
-Timestamp=2015,10,6,20,51,0
-Version=3
-ViewMode=1
diff --git a/app/wlib/gtklib/CMakeLists.txt b/app/wlib/gtklib/CMakeLists.txt
index fabc5d8..cce9866 100644
--- a/app/wlib/gtklib/CMakeLists.txt
+++ b/app/wlib/gtklib/CMakeLists.txt
@@ -1,9 +1,13 @@
+
FILE(GLOB HEADERS *.h)
+INCLUDE (FindGTKUnixPrint.cmake)
+
SET(SOURCES
gtkbitmap.c
gtkbutton.c
gtkcolor.c
+ gtkdraw-cairo.c
filesel.c
gtkfont.c
gtkhelp.c
@@ -16,22 +20,18 @@ SET(SOURCES
gtktext.c
gtkwindow.c
gtkxpm.c
- psprint.c
+ print.c
wpref.c
)
-IF(XTRKCAD_USE_GTK_CAIRO)
- SET(SOURCES ${SOURCES} gtkdraw-cairo.c)
-ELSE(XTRKCAD_USE_GTK_CAIRO)
- SET(SOURCES ${SOURCES} gtkdraw.c)
-ENDIF(XTRKCAD_USE_GTK_CAIRO)
-
SET_SOURCE_FILES_PROPERTIES(wpref.c PROPERTIES COMPILE_FLAGS -DEXPORT=)
INCLUDE_DIRECTORIES(${XTrkCAD_BINARY_DIR})
INCLUDE_DIRECTORIES(${GTK_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(${GTK_UNIX_PRINT_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${GTK_WEBKIT_INCLUDE_DIRS})
ADD_LIBRARY(xtrkcad-wlib ${HEADERS} ${SOURCES})
TARGET_LINK_LIBRARIES(xtrkcad-wlib ${GTK_LIBRARIES})
+TARGET_LINK_LIBRARIES(xtrkcad-wlib ${GTK_UNIX_PRINT_LIBRARIES})
TARGET_LINK_LIBRARIES(xtrkcad-wlib ${GTK_WEBKIT_LIBRARIES})
diff --git a/app/wlib/gtklib/FindGTKUnixPrint.cmake b/app/wlib/gtklib/FindGTKUnixPrint.cmake
new file mode 100644
index 0000000..06bc548
--- /dev/null
+++ b/app/wlib/gtklib/FindGTKUnixPrint.cmake
@@ -0,0 +1,49 @@
+# - Try to find gtk-unix-print
+# Once done, this will define
+#
+# GTK_UNIX_PRINT_FOUND - system has gtk-unix-print
+# GTK_UNIX_PRINT_INCLUDE_DIRS - the gtk-unix-print include directories
+# GTK_UNIX_PRINT_LIBRARIES - link these to use gtk-unix-print
+#
+# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.org>
+# Copyright (C) 2014 Igalia S.L.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
+# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+find_package(PkgConfig)
+pkg_check_modules(GTK_UNIX_PRINT gtk+-unix-print-2.0)
+set(VERSION_OK TRUE)
+
+if (GTK_UNIX_PRINT_VERSION)
+ if (GTK_UNIX_PRINT_FIND_VERSION_EXACT)
+ if (NOT("${GTK_UNIX_PRINT_FIND_VERSION}" VERSION_EQUAL "${GTK_UNIX_PRINT_VERSION}"))
+ set(VERSION_OK FALSE)
+ endif ()
+ else ()
+ if ("${GTK_UNIX_PRINT_VERSION}" VERSION_LESS "${GTK_UNIX_PRINT_FIND_VERSION}")
+ set(VERSION_OK FALSE)
+ endif ()
+ endif ()
+endif ()
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK_UNIX_PRINT DEFAULT_MSG GTK_UNIX_PRINT_INCLUDE_DIRS GTK_UNIX_PRINT_LIBRARIES VERSION_OK)
diff --git a/app/wlib/gtklib/filesel.c b/app/wlib/gtklib/filesel.c
index 4c737ae..4b92389 100644
--- a/app/wlib/gtklib/filesel.c
+++ b/app/wlib/gtklib/filesel.c
@@ -31,16 +31,19 @@
#include "gtkint.h"
#include "i18n.h"
+#define MAX_ALLOWEDFILTERS 10
+
struct wFilSel_t {
GtkWidget * window;
wFilSelCallBack_p action;
void * data;
int pattCount;
- GtkFileFilter *filter[ 10 ];
+ GtkFileFilter *filter[ MAX_ALLOWEDFILTERS ];
wFilSelMode_e mode;
int opt;
const char * title;
wWin_p parent;
+ char *defaultExtension;
};
@@ -90,11 +93,15 @@ struct wFilSel_t * wFilSelCreate(
count = 0;
// names and patterns are separated by |
cp = strtok( cp, "|" );
- while ( cp && count < 9 ) {
+ while ( cp && count < (MAX_ALLOWEDFILTERS - 1)) {
fs->filter[ count ] = gtk_file_filter_new ();
gtk_file_filter_set_name ( fs->filter[ count ], cp );
cp = strtok( NULL, "|" );
gtk_file_filter_add_pattern (fs->filter[ count ], cp );
+ // the first pattern is considered to match the default extension
+ if( count == 0 ) {
+ fs->defaultExtension = strdup( cp );
+ }
cp = strtok( NULL, "|" );
count++;
}
@@ -121,9 +128,15 @@ struct wFilSel_t * wFilSelCreate(
int wFilSelect( struct wFilSel_t * fs, const char * dirName )
{
char name[1024];
- char *fileName;
- const char *base;
+ char *host;
+ char *file;
+ char *namePart;
int i;
+ GSList *fileNameList;
+ GError *err = NULL;
+ GtkFileFilter *activeFilter;
+
+ char **fileNames;
char * cp;
if (fs->window == NULL) {
@@ -137,6 +150,10 @@ int wFilSelect( struct wFilSel_t * fs, const char * dirName )
// get confirmation before overwritting an existing file
gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER(fs->window), TRUE );
+ // allow selecting multiple files
+ if( fs->opt & FS_MULTIPLEFILES ) {
+ gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER(fs->window), TRUE);
+ }
// add the file filters to the dialog box
if( fs->pattCount ) {
for( i = 0; i <= fs->pattCount; i++ ) {
@@ -156,17 +173,38 @@ int wFilSelect( struct wFilSel_t * fs, const char * dirName )
gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER(fs->window), name );
if( gtk_dialog_run( GTK_DIALOG( fs->window )) == GTK_RESPONSE_ACCEPT ) {
- fileName = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(fs->window) );
- if (fs->data)
- strcpy( fs->data, fileName );
+
+ fileNameList = gtk_file_chooser_get_uris( GTK_FILE_CHOOSER(fs->window) );
+ fileNames = calloc( sizeof(char *), g_slist_length (fileNameList) );
+
+ for (i=0; i < g_slist_length (fileNameList); i++ ) {
+ file = g_filename_from_uri( g_slist_nth_data( fileNameList, i ), &host, &err );
+
+ // check for presence of file extension
+ // jump behind tha last directory delimiter
+ namePart = strrchr( file, '/' ) + 1;
+ // is there a dot in the last part, yes->extension present
+ if( !strchr( namePart, '.' ) ){
+ // make room for the extension
+ file = g_realloc( file, strlen(file)+strlen(fs->defaultExtension));
+ strcat( file, fs->defaultExtension + 1 );
+ }
+ fileNames[ i ] = file;
+ g_free( g_slist_nth_data ( fileNameList, i));
+ }
+
+ if (fs->data)
+ strcpy( fs->data, fileNames[ 0 ] );
+
if (fs->action) {
- base = strrchr( fileName, '/' );
- if (base==0) {
- fprintf(stderr,"no / in %s\n", fileName );
- return 1;
- }
- fs->action( fileName, base+1, fs->data );
+ fs->action( g_slist_length(fileNameList), fileNames, fs->data );
+ }
+
+ for(i=0; i < g_slist_length(fileNameList); i++) {
+ g_free( fileNames[ i ]);
}
+ free( fileNames );
+ g_slist_free (fileNameList);
}
gtk_widget_hide( GTK_WIDGET( fs->window ));
diff --git a/app/wlib/gtklib/gtkcolor.c b/app/wlib/gtklib/gtkcolor.c
index 3856f2a..cf17199 100644
--- a/app/wlib/gtklib/gtkcolor.c
+++ b/app/wlib/gtklib/gtkcolor.c
@@ -37,7 +37,7 @@
EXPORT wDrawColor wDrawColorWhite;
EXPORT wDrawColor wDrawColorBlack;
-#define RGB(R,G,B) ( ((long)(255&0xFF))<<24 | (((long)((R)&0xFF))<<16) | (((long)((G)&0xFF))<<8) | ((long)((B)&0xFF)) )
+#define RGB(R,G,B) ( ((long)((R)&0xFF)<<16) | ((long)((G)&0xFF)<<8) | ((long)((B)&0xFF)) )
#define MAX_COLOR_DISTANCE (3)
diff --git a/app/wlib/gtklib/gtkdraw-cairo.c b/app/wlib/gtklib/gtkdraw-cairo.c
index e9b6447..9fc7eab 100644
--- a/app/wlib/gtklib/gtkdraw-cairo.c
+++ b/app/wlib/gtklib/gtkdraw-cairo.c
@@ -47,31 +47,31 @@ struct wDrawBitMap_t {
GdkBitmap * mask;
};
-struct wDraw_t {
- WOBJ_COMMON
- void * context;
- wDrawActionCallBack_p action;
- wDrawRedrawCallBack_p redraw;
+//struct wDraw_t {
+ //WOBJ_COMMON
+ //void * context;
+ //wDrawActionCallBack_p action;
+ //wDrawRedrawCallBack_p redraw;
- GdkPixmap * pixmap;
- GdkPixmap * pixmapBackup;
+ //GdkPixmap * pixmap;
+ //GdkPixmap * pixmapBackup;
- double dpi;
+ //double dpi;
- GdkGC * gc;
- wDrawWidth lineWidth;
- wDrawOpts opts;
- wPos_t maxW;
- wPos_t maxH;
- unsigned long lastColor;
- wBool_t lastColorInverted;
- const char * helpStr;
+ //GdkGC * gc;
+ //wDrawWidth lineWidth;
+ //wDrawOpts opts;
+ //wPos_t maxW;
+ //wPos_t maxH;
+ //unsigned long lastColor;
+ //wBool_t lastColorInverted;
+ //const char * helpStr;
- wPos_t lastX;
- wPos_t lastY;
+ //wPos_t lastX;
+ //wPos_t lastY;
- wBool_t delayUpdate;
- };
+ //wBool_t delayUpdate;
+ //};
struct wDraw_t psPrint_d;
@@ -98,7 +98,7 @@ struct wDraw_t psPrint_d;
*
*******************************************************************************/
-
+
static GdkGC * selectGC(
wDraw_p bd,
@@ -301,10 +301,10 @@ EXPORT void wDrawArc(
y = INMAPY(bd,y0+r);
w = 2*r;
h = 2*r;
-
+
// remove the old arc
gdk_draw_arc( bd->pixmap, gc, FALSE, x, y, w, h, (int)((-angle0 + 90)*64.0), (int)(-angle1*64.0) );
-
+
// and its center point
if (drawCenter) {
x = INMAPX(bd,x0);
@@ -312,7 +312,7 @@ EXPORT void wDrawArc(
gdk_draw_line( bd->pixmap, gc, x - ( CENTERMARK_LENGTH/2), y, x + ( CENTERMARK_LENGTH/2), y );
gdk_draw_line( bd->pixmap, gc, x, y - ( CENTERMARK_LENGTH/2), x, y + ( CENTERMARK_LENGTH/2));
}
-
+
// now create the new arc
cairo_t* cairo = gtkDrawCreateCairoContext(bd, width, lineType, color, opts);
cairo_new_path(cairo);
@@ -331,7 +331,7 @@ EXPORT void wDrawArc(
// draw the curve itself
cairo_arc_negative(cairo, INMAPX(bd, x0), INMAPY(bd, y0), r, (angle0 - 90 + angle1) * (M_PI / 180.0), (angle0 - 90) * (M_PI / 180.0));
cairo_stroke(cairo);
-
+
gtkDrawDestroyCairoContext(cairo);
if ( bd->delayUpdate || bd->widget == NULL) return;
@@ -341,7 +341,7 @@ EXPORT void wDrawArc(
update_rect.width = w+2+width+width;
update_rect.height = h+2+width+width;
gtk_widget_draw( bd->widget, &update_rect );
-
+
}
EXPORT void wDrawPoint(
@@ -397,18 +397,18 @@ EXPORT void wDrawString(
gint ascent;
gint descent;
double angle = -M_PI * a / 180.0;
-
+
if ( bd == &psPrint_d ) {
psPrintString( x, y, a, (char *) s, fp, fs, color, opts );
return;
}
-
+
x = INMAPX(bd,x);
y = INMAPY(bd,y);
-
+
/* draw text */
cairo_t* cairo = gtkDrawCreateCairoContext(bd, 0, wDrawLineSolid, color, opts);
-
+
cairo_save( cairo );
cairo_translate( cairo, x, y );
cairo_rotate( cairo, angle );
@@ -423,18 +423,18 @@ EXPORT void wDrawString(
cairo_set_source_rgb(cairo, gcolor->red / 65535.0, gcolor->green / 65535.0, gcolor->blue / 65535.0);
cairo_move_to( cairo, 0, -ascent );
-
+
pango_cairo_show_layout(cairo, layout);
gtkFontDestroyPangoLayout(layout);
cairo_restore( cairo );
gtkDrawDestroyCairoContext(cairo);
-
+
if (bd->delayUpdate || bd->widget == NULL) return;
-
- /* recalculate the area to be updated
+
+ /* recalculate the area to be updated
* for simplicity sake I added plain text height ascent and descent,
- * mathematically correct would be to use the trigonometrical functions as well
- */
+ * mathematically correct would be to use the trigonometrical functions as well
+ */
update_rect.x = (gint) x - ascent - descent - 1;
update_rect.y = (gint) y - (gint) ascent - 1;
update_rect.width = (gint) (w * cos( angle ) + 2 + ascent + descent);
@@ -455,19 +455,19 @@ EXPORT void wDrawGetTextSize(
int textHeight;
int ascent;
int descent;
-
+
*w = 0;
*h = 0;
-
+
gtkFontDestroyPangoLayout(
gtkFontCreatePangoLayout(bd->widget, NULL, fp, fs, s,
&textWidth, (int *) &textHeight,
(int *) &ascent, (int *) &descent));
-
+
*w = (wPos_t) textWidth;
*h = (wPos_t) ascent;
*d = (wPos_t) descent;
-
+
if (debugWindow >= 3)
fprintf(stderr, "text metrics: w=%d, h=%d, d=%d\n", *w, *h, *d);
}
@@ -670,7 +670,7 @@ EXPORT wDrawBitMap_p wDrawBitMapCreate(
const char * fbits )
{
wDrawBitMap_p bm;
-
+
bm = (wDrawBitMap_p)malloc( sizeof *bm );
bm->w = w;
bm->h = h;
@@ -738,7 +738,7 @@ EXPORT void wDrawBitMap(
}
}
#ifdef LATER
- gdk_draw_pixmap(bd->pixmap, gc,
+ gdk_draw_pixmap(bd->pixmap, gc,
bm->pixmap,
0, 0,
x, y,
@@ -752,7 +752,7 @@ EXPORT void wDrawBitMap(
update_rect.height = bm->h;
gtk_widget_draw( bd->widget, &update_rect );
}
-
+
/*******************************************************************************
*
@@ -760,7 +760,7 @@ EXPORT void wDrawBitMap(
*
*******************************************************************************/
-
+
EXPORT void wDrawSaveImage(
wDraw_p bd )
@@ -795,7 +795,7 @@ EXPORT void wDrawRestoreImage(
0, 0,
0, 0,
bd->w, bd->h );
-
+
if ( bd->delayUpdate || bd->widget == NULL ) return;
update_rect.x = 0;
update_rect.y = 0;
@@ -849,13 +849,19 @@ EXPORT void wDrawGetSize(
*h = bd->h-2;
}
+/**
+ * Return the resolution of a device in dpi
+ *
+ * \param d IN the device
+ * \return the resolution in dpi
+ */
EXPORT double wDrawGetDPI(
wDraw_p d )
{
- if (d == &psPrint_d)
- return 1440.0;
- else
+ //if (d == &psPrint_d)
+ //return 1440.0;
+ //else
return d->dpi;
}
@@ -927,20 +933,20 @@ static gint draw_scroll_event(
case GDK_SCROLL_UP:
action = wActionWheelUp;
break;
- case GDK_SCROLL_DOWN:
+ case GDK_SCROLL_DOWN:
action = wActionWheelDown;
- break;
+ break;
default:
action = 0;
break;
- }
+ }
if (action != 0) {
if (drawVerbose >= 2)
printf( "%s[%dx%d]\n", actionNames[action], bd->lastX, bd->lastY );
bd->action( bd, bd->context, action, bd->lastX, bd->lastY );
}
-
+
return TRUE;
}
@@ -979,7 +985,7 @@ static gint draw_button_event(
case 3: /* right mouse button */
action = event->type==GDK_BUTTON_PRESS?wActionRDown:wActionRUp;
/*bd->action( bd, bd->context, event->type==GDK_BUTTON_PRESS?wActionRDown:wActionRUp, bd->lastX, bd->lastY );*/
- break;
+ break;
}
if (action != 0) {
if (drawVerbose >= 2)
@@ -1009,7 +1015,7 @@ static gint draw_motion_event(
y = event->y;
state = event->state;
}
-
+
if (state & GDK_BUTTON1_MASK) {
action = wActionLDrag;
} else if (state & GDK_BUTTON3_MASK) {
@@ -1062,9 +1068,9 @@ static gint draw_char_event(
case GDK_F10: extKey = wAccelKey_F10; break;
case GDK_F11: extKey = wAccelKey_F11; break;
case GDK_F12: extKey = wAccelKey_F12; break;
- default: ;
+ default: ;
}
-
+
if (extKey != wAccelKey_None) {
if ( gtkFindAccelKey( event ) == NULL ) {
bd->action( bd, bd->context, wActionExtKey + ((int)extKey<<8), bd->lastX, bd->lastY );
diff --git a/app/wlib/gtklib/gtkdraw.c b/app/wlib/gtklib/gtkdraw.c
deleted file mode 100644
index b8f07ef..0000000
--- a/app/wlib/gtklib/gtkdraw.c
+++ /dev/null
@@ -1,1044 +0,0 @@
-/*
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/gtkdraw.c,v 1.9 2009-09-25 05:38:15 dspagnol Exp $
- */
-
-/* XTrkCad - Model Railroad CAD
- * Copyright (C) 2005 Dave Bullis
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#include <unistd.h>
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-
-#include "gtkint.h"
-#include "gdk/gdkkeysyms.h"
-
-static long drawVerbose = 0;
-
-struct wDrawBitMap_t {
- int w;
- int h;
- int x;
- int y;
- const char * bits;
- GdkPixmap * pixmap;
- GdkBitmap * mask;
- };
-
-struct wDraw_t {
- WOBJ_COMMON
- void * context;
- wDrawActionCallBack_p action;
- wDrawRedrawCallBack_p redraw;
-
- GdkPixmap * pixmap;
- GdkPixmap * pixmapBackup;
-
- double dpi;
-
- GdkGC * gc;
- wDrawWidth lineWidth;
- wDrawOpts opts;
- wPos_t maxW;
- wPos_t maxH;
- unsigned long lastColor;
- wBool_t lastColorInverted;
- const char * helpStr;
-
- wPos_t lastX;
- wPos_t lastY;
-
- wBool_t delayUpdate;
- };
-
-struct wDraw_t psPrint_d;
-
-/*****************************************************************************
- *
- * MACROS
- *
- */
-
-#define LBORDER (22)
-#define RBORDER (6)
-#define TBORDER (6)
-#define BBORDER (20)
-
-#define INMAPX(D,X) (X)
-#define INMAPY(D,Y) (((D)->h-1) - (Y))
-#define OUTMAPX(D,X) (X)
-#define OUTMAPY(D,Y) (((D)->h-1) - (Y))
-
-
-/*******************************************************************************
- *
- * Basic Drawing Functions
- *
-*******************************************************************************/
-
-
-
-static GdkGC * selectGC(
- wDraw_p bd,
- wDrawWidth width,
- wDrawLineType_e lineType,
- wDrawColor color,
- wDrawOpts opts )
-{
- if (width < 0.0) {
- width = - width;
- }
-/*
- if ( color != bd->lastColor ) {
- unsigned long pixColor;
- unsigned long black, white;
- white = WhitePixel(bd->display,DefaultScreen(bd->display));
- black = BlackPixel(bd->display,DefaultScreen(bd->display));
- pixColor = bd->colors[color] ^ white;
- XSetForeground( bd->display, bd->normGc, pixColor );
- bd->lastColor = color;
- }
-*/
- if (opts&wDrawOptTemp) {
- if (bd->lastColor != color || !bd->lastColorInverted) {
- gdk_gc_set_foreground( bd->gc, gtkGetColor(color,FALSE) );
- bd->lastColor = color;
- bd->lastColorInverted = TRUE;
- }
- gdk_gc_set_function( bd->gc, GDK_XOR );
- gdk_gc_set_line_attributes( bd->gc, width,
- GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER );
- } else {
- if (bd->lastColor != color || bd->lastColorInverted) {
- gdk_gc_set_foreground( bd->gc, gtkGetColor(color,TRUE) );
- bd->lastColor = color;
- bd->lastColorInverted = FALSE;
- }
- gdk_gc_set_function( bd->gc, GDK_COPY );
- if (lineType==wDrawLineDash) {
- gdk_gc_set_line_attributes( bd->gc, width,
- GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER );
- /*XSetDashes( bd->display, bd->normGc, 0, "\003\003", 2 );*/
- } else {
- gdk_gc_set_line_attributes( bd->gc, width,
- GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER );
- }
- }
- return bd->gc;
-}
-
-
-EXPORT void wDrawDelayUpdate(
- wDraw_p bd,
- wBool_t delay )
-{
- GdkRectangle update_rect;
-
- if ( (!delay) && bd->delayUpdate ) {
- update_rect.x = 0;
- update_rect.y = 0;
- update_rect.width = bd->w;
- update_rect.height = bd->h;
- gtk_widget_draw( bd->widget, &update_rect );
- }
- bd->delayUpdate = delay;
-}
-
-
-EXPORT void wDrawLine(
- wDraw_p bd,
- wPos_t x0, wPos_t y0,
- wPos_t x1, wPos_t y1,
- wDrawWidth width,
- wDrawLineType_e lineType,
- wDrawColor color,
- wDrawOpts opts )
-{
- GdkGC * gc;
- GdkRectangle update_rect;
-
- if ( bd == &psPrint_d ) {
- psPrintLine( x0, y0, x1, y1, width, lineType, color, opts );
- return;
- }
- gc = selectGC( bd, width, lineType, color, opts );
- x0 = INMAPX(bd,x0);
- y0 = INMAPY(bd,y0);
- x1 = INMAPX(bd,x1);
- y1 = INMAPY(bd,y1);
- gdk_draw_line( bd->pixmap, gc, x0, y0, x1, y1 );
- if ( bd->delayUpdate || bd->widget == NULL ) return;
- width /= 2;
- if (x0 < x1) {
- update_rect.x = x0-1-width;
- update_rect.width = x1-x0+2+width+width;
- } else {
- update_rect.x = x1-1-width;
- update_rect.width = x0-x1+2+width+width;
- }
- if (y0 < y1) {
- update_rect.y = y0-1-width;
- update_rect.height = y1-y0+2+width+width;
- } else {
- update_rect.y = y1-1-width;
- update_rect.height = y0-y1+2+width+width;
- }
- gtk_widget_draw( bd->widget, &update_rect );
-}
-
-EXPORT void wDrawArc(
- wDraw_p bd,
- wPos_t x0, wPos_t y0,
- wPos_t r,
- wAngle_t angle0,
- wAngle_t angle1,
- int drawCenter,
- wDrawWidth width,
- wDrawLineType_e lineType,
- wDrawColor color,
- wDrawOpts opts )
-{
- int x, y, w, h;
- GdkGC * gc;
- GdkRectangle update_rect;
-
- if ( bd == &psPrint_d ) {
- psPrintArc( x0, y0, r, angle0, angle1, drawCenter, width, lineType, color, opts );
- return;
- }
- gc = selectGC( bd, width, lineType, color, opts );
- if (r < 6.0/75.0) return;
- x = INMAPX(bd,x0-r);
- y = INMAPY(bd,y0+r);
- w = 2*r;
- h = 2*r;
- if (drawCenter)
- gdk_draw_point( bd->pixmap, gc,
- INMAPX(bd, x0 ), INMAPY(bd, y0 ) );
- angle1 = -angle1;
- angle0 = (-angle0) + 90.0;
- gdk_draw_arc( bd->pixmap, gc, FALSE, x, y, w, h,
- (int)(angle0*64.0), (int)(angle1*64.0) );
- if ( bd->delayUpdate || bd->widget == NULL) return;
- width /= 2;
- update_rect.x = x-1-width;
- update_rect.y = y-1-width;
- update_rect.width = w+2+width+width;
- update_rect.height = h+2+width+width;
- gtk_widget_draw( bd->widget, &update_rect );
-
-}
-
-EXPORT void wDrawPoint(
- wDraw_p bd,
- wPos_t x0, wPos_t y0,
- wDrawColor color,
- wDrawOpts opts )
-{
- GdkGC * gc;
- GdkRectangle update_rect;
-
- if ( bd == &psPrint_d ) {
- /*psPrintArc( x0, y0, r, angle0, angle1, drawCenter, width, lineType, color, opts );*/
- return;
- }
- gc = selectGC( bd, 0, wDrawLineSolid, color, opts );
- gdk_draw_point( bd->pixmap, gc,
- INMAPX(bd, x0 ), INMAPY(bd, y0 ) );
- if ( bd->delayUpdate || bd->widget == NULL) return;
- update_rect.x = INMAPX(bd, x0 )-1;
- update_rect.y = INMAPY(bd, y0 )-1;
- update_rect.width = 2;
- update_rect.height = 2;
- gtk_widget_draw( bd->widget, &update_rect );
-}
-
-/*******************************************************************************
- *
- * Strings
- *
- ******************************************************************************/
-
-EXPORT void wDrawString(
- wDraw_p bd,
- wPos_t x, wPos_t y,
- wAngle_t a,
- const char * s,
- wFont_p fp,
- wFontSize_t fs,
- wDrawColor color,
- wDrawOpts opts )
-{
- GdkGC * gc;
- PangoLayout *layout;
- GdkRectangle update_rect;
- int w;
- int h;
- gint ascent;
- gint descent;
-
- if ( bd == &psPrint_d ) {
- psPrintString( x, y, a, (char *)s, fp, fs, color, opts );
- return;
- }
-
- x = INMAPX(bd,x);
- y = INMAPY(bd,y);
-
- gc = selectGC( bd, 0, wDrawLineSolid, color, opts );
-
- layout = gtkFontCreatePangoLayout(bd->widget, NULL, fp, fs, s,
- (int *) &w, (int *) &h,
- (int *) &ascent, (int *) &descent);
-
- gdk_draw_layout(bd->pixmap, gc, x, y - ascent, layout);
- gtkFontDestroyPangoLayout(layout);
-
- if (bd->delayUpdate || bd->widget == NULL) return;
- update_rect.x = (gint) x - 1;
- update_rect.y = (gint) y - ascent - 1;
- update_rect.width = (gint) w + 2;
- update_rect.height = (gint) ascent + (gint) descent + 2;
- gtk_widget_draw(bd->widget, &update_rect);
-}
-
-EXPORT void wDrawGetTextSize(
- wPos_t *w,
- wPos_t *h,
- wPos_t *d,
- wDraw_p bd,
- const char * s,
- wFont_p fp,
- wFontSize_t fs )
-{
- int textWidth;
- int textHeight;
- int ascent;
- int descent;
-
- *w = 0;
- *h = 0;
-
- gtkFontDestroyPangoLayout(
- gtkFontCreatePangoLayout(bd->widget, NULL, fp, fs, s,
- &textWidth, (int *) &textHeight,
- (int *) &ascent, (int *) &descent));
-
- *w = (wPos_t) textWidth;
- *h = (wPos_t) ascent;
- *d = (wPos_t) descent;
-
- if (debugWindow >= 3)
- fprintf(stderr, "text metrics: w=%d, h=%d, d=%d\n", *w, *h, *d);
-}
-
-
-/*******************************************************************************
- *
- * Basic Drawing Functions
- *
-*******************************************************************************/
-
-EXPORT void wDrawFilledRectangle(
- wDraw_p bd,
- wPos_t x,
- wPos_t y,
- wPos_t w,
- wPos_t h,
- wDrawColor color,
- wDrawOpts opt )
-{
- GdkGC * gc;
- GdkRectangle update_rect;
-
- if ( bd == &psPrint_d ) {
- psPrintFillRectangle( x, y, w, h, color, opt );
- return;
- }
-
- gc = selectGC( bd, 0, wDrawLineSolid, color, opt );
- x = INMAPX(bd,x);
- y = INMAPY(bd,y)-h;
- gdk_draw_rectangle( bd->pixmap, gc, TRUE, x, y, w, h );
- if ( bd->delayUpdate || bd->widget == NULL) return;
- update_rect.x = x-1;
- update_rect.y = y-1;
- update_rect.width = w+2;
- update_rect.height = h+2;
- gtk_widget_draw( bd->widget, &update_rect );
-}
-
-EXPORT void wDrawFilledPolygon(
- wDraw_p bd,
- wPos_t p[][2],
- int cnt,
- wDrawColor color,
- wDrawOpts opt )
-{
- GdkGC * gc;
- static int maxCnt = 0;
- static GdkPoint *points;
- int i;
- GdkRectangle update_rect;
-
- if ( bd == &psPrint_d ) {
- psPrintFillPolygon( p, cnt, color, opt );
- return;
- }
-
- if (cnt > maxCnt) {
- if (points == NULL)
- points = (GdkPoint*)malloc( cnt*sizeof *points );
- else
- points = (GdkPoint*)realloc( points, cnt*sizeof *points );
- if (points == NULL)
- abort();
- maxCnt = cnt;
- }
-
- update_rect.x = bd->w;
- update_rect.y = bd->h;
- update_rect.width = 0;
- update_rect.height = 0;
- for (i=0; i<cnt; i++) {
- points[i].x = INMAPX(bd,p[i][0]);
- points[i].y = INMAPY(bd,p[i][1]);
- if (update_rect.x > points[i].x)
- update_rect.x = points[i].x;
- if (update_rect.width < points[i].x)
- update_rect.width = points[i].x;
- if (update_rect.y > points[i].y)
- update_rect.y = points[i].y;
- if (update_rect.height < points[i].y)
- update_rect.height = points[i].y;
- }
- update_rect.x -= 1;
- update_rect.y -= 1;
- update_rect.width -= update_rect.x-2;
- update_rect.height -= update_rect.y-2;
- gc = selectGC( bd, 0, wDrawLineSolid, color, opt );
- gdk_draw_polygon( bd->pixmap, gc, TRUE,
- points, cnt );
- if ( bd->delayUpdate || bd->widget == NULL) return;
- gtk_widget_draw( bd->widget, &update_rect );
-}
-
-EXPORT void wDrawFilledCircle(
- wDraw_p bd,
- wPos_t x0,
- wPos_t y0,
- wPos_t r,
- wDrawColor color,
- wDrawOpts opt )
-{
- GdkGC * gc;
- int x, y, w, h;
- GdkRectangle update_rect;
-
- if ( bd == &psPrint_d ) {
- psPrintFillCircle( x0, y0, r, color, opt );
- return;
- }
-
- gc = selectGC( bd, 0, wDrawLineSolid, color, opt );
- x = INMAPX(bd,x0-r);
- y = INMAPY(bd,y0+r);
- w = 2*r;
- h = 2*r;
- gdk_draw_arc( bd->pixmap, gc, TRUE, x, y, w, h, 0, 360*64 );
- if ( bd->delayUpdate || bd->widget == NULL) return;
- update_rect.x = x-1;
- update_rect.y = y-1;
- update_rect.width = w+2;
- update_rect.height = h+2;
- gtk_widget_draw( bd->widget, &update_rect );
-
-}
-
-
-EXPORT void wDrawClear(
- wDraw_p bd )
-{
- GdkGC * gc;
- GdkRectangle update_rect;
-
- gc = selectGC( bd, 0, wDrawLineSolid, wDrawColorWhite, 0 );
- gdk_draw_rectangle(bd->pixmap, gc, TRUE, 0, 0,
- bd->w, bd->h);
- if ( bd->delayUpdate || bd->widget == NULL) return;
- update_rect.x = 0;
- update_rect.y = 0;
- update_rect.width = bd->w;
- update_rect.height = bd->h;
- gtk_widget_draw( bd->widget, &update_rect );
-}
-
-EXPORT void * wDrawGetContext(
- wDraw_p bd )
-{
- return bd->context;
-}
-
-/*******************************************************************************
- *
- * Bit Maps
- *
-*******************************************************************************/
-
-
-EXPORT wDrawBitMap_p wDrawBitMapCreate(
- wDraw_p bd,
- int w,
- int h,
- int x,
- int y,
- const char * fbits )
-{
- wDrawBitMap_p bm;
-
- bm = (wDrawBitMap_p)malloc( sizeof *bm );
- bm->w = w;
- bm->h = h;
- /*bm->pixmap = gtkMakeIcon( NULL, fbits, w, h, wDrawColorBlack, &bm->mask );*/
- bm->bits = fbits;
- bm->x = x;
- bm->y = y;
- return bm;
-}
-
-
-EXPORT void wDrawBitMap(
- wDraw_p bd,
- wDrawBitMap_p bm,
- wPos_t x, wPos_t y,
- wDrawColor color,
- wDrawOpts opts )
-{
- GdkGC * gc;
- GdkRectangle update_rect;
- int i, j, wb;
- wPos_t xx, yy;
- wControl_p b;
- GdkDrawable * gdk_window;
-
- x = INMAPX( bd, x-bm->x );
- y = INMAPY( bd, y-bm->y )-bm->h;
- wb = (bm->w+7)/8;
- gc = selectGC( bd, 0, wDrawLineSolid, color, opts );
- for ( i=0; i<bm->w; i++ )
- for ( j=0; j<bm->h; j++ )
- if ( bm->bits[ j*wb+(i>>3) ] & (1<<(i&07)) ) {
- xx = x+i;
- yy = y+j;
- if ( 0 <= xx && xx < bd->w &&
- 0 <= yy && yy < bd->h ) {
- gdk_window = bd->pixmap;
- b = (wControl_p)bd;
- } else if ( (opts&wDrawOptNoClip) != 0 ) {
- xx += bd->realX;
- yy += bd->realY;
- b = gtkGetControlFromPos( bd->parent, xx, yy );
- if ( b ) {
- if ( b->type == B_DRAW )
- gdk_window = ((wDraw_p)b)->pixmap;
- else
- gdk_window = b->widget->window;
- xx -= b->realX;
- yy -= b->realY;
- } else {
- gdk_window = bd->parent->widget->window;
- }
- } else {
- continue;
- }
-/*printf( "gdk_draw_point( %ld, gc, %d, %d )\n", (long)gdk_window, xx, yy );*/
- gdk_draw_point( gdk_window, gc, xx, yy );
- if ( b && b->type == B_DRAW ) {
- update_rect.x = xx-1;
- update_rect.y = yy-1;
- update_rect.width = 3;
- update_rect.height = 3;
- gtk_widget_draw( b->widget, &update_rect );
- }
- }
-#ifdef LATER
- gdk_draw_pixmap(bd->pixmap, gc,
- bm->pixmap,
- 0, 0,
- x, y,
- bm->w, bm->h );
-#endif
- if ( bd->delayUpdate || bd->widget == NULL) return;
-
- update_rect.x = x;
- update_rect.y = y;
- update_rect.width = bm->w;
- update_rect.height = bm->h;
- gtk_widget_draw( bd->widget, &update_rect );
-}
-
-
-/*******************************************************************************
- *
- * Event Handlers
- *
-*******************************************************************************/
-
-
-
-EXPORT void wDrawSaveImage(
- wDraw_p bd )
-{
- if ( bd->pixmapBackup ) {
- gdk_pixmap_unref( bd->pixmapBackup );
- }
- bd->pixmapBackup = gdk_pixmap_new( bd->widget->window, bd->w, bd->h, -1 );
- selectGC( bd, 0, wDrawLineSolid, bd->lastColor, 0 );
- gdk_draw_pixmap( bd->pixmapBackup, bd->gc,
- bd->pixmap,
- 0, 0,
- 0, 0,
- bd->w, bd->h );
-}
-
-
-EXPORT void wDrawRestoreImage(
- wDraw_p bd )
-{
- GdkRectangle update_rect;
- if ( bd->pixmapBackup ) {
- selectGC( bd, 0, wDrawLineSolid, bd->lastColor, 0 );
- gdk_draw_pixmap( bd->pixmap, bd->gc,
- bd->pixmapBackup,
- 0, 0,
- 0, 0,
- bd->w, bd->h );
- if ( bd->delayUpdate || bd->widget == NULL ) return;
- update_rect.x = 0;
- update_rect.y = 0;
- update_rect.width = bd->w;
- update_rect.height = bd->h;
- gtk_widget_draw( bd->widget, &update_rect );
- }
-}
-
-
-EXPORT void wDrawSetSize(
- wDraw_p bd,
- wPos_t w,
- wPos_t h )
-{
- wBool_t repaint;
- if (bd == NULL) {
- fprintf(stderr,"resizeDraw: no client data\n");
- return;
- }
-
- /* Negative values crashes the program */
- if (w < 0 || h < 0)
- return;
-
- repaint = (w != bd->w || h != bd->h);
- bd->w = w;
- bd->h = h;
- gtk_widget_set_size_request( bd->widget, w, h );
- if (repaint) {
- if (bd->pixmap)
- gdk_pixmap_unref( bd->pixmap );
- bd->pixmap = gdk_pixmap_new( bd->widget->window, w, h, -1 );
- wDrawClear( bd );
- /*bd->redraw( bd, bd->context, w, h );*/
- }
- /*wRedraw( bd );*/
-}
-
-
-EXPORT void wDrawGetSize(
- wDraw_p bd,
- wPos_t *w,
- wPos_t *h )
-{
- if (bd->widget)
- gtkControlGetSize( (wControl_p)bd );
- *w = bd->w-2;
- *h = bd->h-2;
-}
-
-
-EXPORT double wDrawGetDPI(
- wDraw_p d )
-{
- if (d == &psPrint_d)
- return 1440.0;
- else
- return d->dpi;
-}
-
-
-EXPORT double wDrawGetMaxRadius(
- wDraw_p d )
-{
- if (d == &psPrint_d)
- return 10e9;
- else
- return 32767.0;
-}
-
-
-EXPORT void wDrawClip(
- wDraw_p d,
- wPos_t x,
- wPos_t y,
- wPos_t w,
- wPos_t h )
-{
- GdkRectangle rect;
- rect.width = w;
- rect.height = h;
- rect.x = INMAPX( d, x );
- rect.y = INMAPY( d, y ) - rect.height;
- gdk_gc_set_clip_rectangle( d->gc, &rect );
-
-}
-
-
-static gint draw_expose_event(
- GtkWidget *widget,
- GdkEventExpose *event,
- wDraw_p bd)
-{
- gdk_draw_pixmap(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- bd->pixmap,
- event->area.x, event->area.y,
- event->area.x, event->area.y,
- event->area.width, event->area.height);
- return FALSE;
-}
-
-
-static gint draw_configure_event(
- GtkWidget *widget,
- GdkEventConfigure *event,
- wDraw_p bd)
-{
- return FALSE;
-}
-
-static const char * actionNames[] = { "None", "Move", "LDown", "LDrag", "LUp", "RDown", "RDrag", "RUp", "Text", "ExtKey", "WUp", "WDown" };
-
-/**
- * Handler for scroll events, ie mouse wheel activity
- */
-
-static gint draw_scroll_event(
- GtkWidget *widget,
- GdkEventScroll *event,
- wDraw_p bd)
-{
- wAction_t action;
-
- switch( event->direction ) {
- case GDK_SCROLL_UP:
- action = wActionWheelUp;
- break;
- case GDK_SCROLL_DOWN:
- action = wActionWheelDown;
- break;
- default:
- action = 0;
- break;
- }
-
- if (action != 0) {
- if (drawVerbose >= 2)
- printf( "%s[%dx%d]\n", actionNames[action], bd->lastX, bd->lastY );
- bd->action( bd, bd->context, action, bd->lastX, bd->lastY );
- }
-
- return TRUE;
-}
-
-
-
-static gint draw_leave_event(
- GtkWidget *widget,
- GdkEvent * event )
-{
- gtkHelpHideBalloon();
- return FALSE;
-}
-
-
-/**
- * Handler for mouse button clicks.
- */
-
-static gint draw_button_event(
- GtkWidget *widget,
- GdkEventButton *event,
- wDraw_p bd )
-{
- wAction_t action = 0;
- if (bd->action == NULL)
- return TRUE;
-
- bd->lastX = OUTMAPX(bd, event->x);
- bd->lastY = OUTMAPY(bd, event->y);
-
- switch ( event->button ) {
- case 1: /* left mouse button */
- action = event->type==GDK_BUTTON_PRESS?wActionLDown:wActionLUp;
- /*bd->action( bd, bd->context, event->type==GDK_BUTTON_PRESS?wActionLDown:wActionLUp, bd->lastX, bd->lastY );*/
- break;
- case 3: /* right mouse button */
- action = event->type==GDK_BUTTON_PRESS?wActionRDown:wActionRUp;
- /*bd->action( bd, bd->context, event->type==GDK_BUTTON_PRESS?wActionRDown:wActionRUp, bd->lastX, bd->lastY );*/
- break;
- }
- if (action != 0) {
- if (drawVerbose >= 2)
- printf( "%s[%dx%d]\n", actionNames[action], bd->lastX, bd->lastY );
- bd->action( bd, bd->context, action, bd->lastX, bd->lastY );
- }
- gtk_widget_grab_focus( bd->widget );
- return TRUE;
-}
-
-static gint draw_motion_event(
- GtkWidget *widget,
- GdkEventMotion *event,
- wDraw_p bd )
-{
- int x, y;
- GdkModifierType state;
- wAction_t action;
-
- if (bd->action == NULL)
- return TRUE;
-
- if (event->is_hint) {
- gdk_window_get_pointer (event->window, &x, &y, &state);
- } else {
- x = event->x;
- y = event->y;
- state = event->state;
- }
-
- if (state & GDK_BUTTON1_MASK) {
- action = wActionLDrag;
- } else if (state & GDK_BUTTON3_MASK) {
- action = wActionRDrag;
- } else {
- action = wActionMove;
- }
- bd->lastX = OUTMAPX(bd, x);
- bd->lastY = OUTMAPY(bd, y);
- if (drawVerbose >= 2)
- printf( "%lx: %s[%dx%d] %s\n", (long)bd, actionNames[action], bd->lastX, bd->lastY, event->is_hint?"<Hint>":"<>" );
- bd->action( bd, bd->context, action, bd->lastX, bd->lastY );
- gtk_widget_grab_focus( bd->widget );
- return TRUE;
-}
-
-
-static gint draw_char_event(
- GtkWidget * widget,
- GdkEventKey *event,
- wDraw_p bd )
-{
- guint key = event->keyval;
- wAccelKey_e extKey = wAccelKey_None;
- switch (key) {
- case GDK_Escape: key = 0x1B; break;
- case GDK_Return: key = 0x0D; break;
- case GDK_Linefeed: key = 0x0A; break;
- case GDK_Tab: key = 0x09; break;
- case GDK_BackSpace: key = 0x08; break;
- case GDK_Delete: extKey = wAccelKey_Del; break;
- case GDK_Insert: extKey = wAccelKey_Ins; break;
- case GDK_Home: extKey = wAccelKey_Home; break;
- case GDK_End: extKey = wAccelKey_End; break;
- case GDK_Page_Up: extKey = wAccelKey_Pgup; break;
- case GDK_Page_Down: extKey = wAccelKey_Pgdn; break;
- case GDK_Up: extKey = wAccelKey_Up; break;
- case GDK_Down: extKey = wAccelKey_Down; break;
- case GDK_Right: extKey = wAccelKey_Right; break;
- case GDK_Left: extKey = wAccelKey_Left; break;
- case GDK_F1: extKey = wAccelKey_F1; break;
- case GDK_F2: extKey = wAccelKey_F2; break;
- case GDK_F3: extKey = wAccelKey_F3; break;
- case GDK_F4: extKey = wAccelKey_F4; break;
- case GDK_F5: extKey = wAccelKey_F5; break;
- case GDK_F6: extKey = wAccelKey_F6; break;
- case GDK_F7: extKey = wAccelKey_F7; break;
- case GDK_F8: extKey = wAccelKey_F8; break;
- case GDK_F9: extKey = wAccelKey_F9; break;
- case GDK_F10: extKey = wAccelKey_F10; break;
- case GDK_F11: extKey = wAccelKey_F11; break;
- case GDK_F12: extKey = wAccelKey_F12; break;
- default: ;
- }
-
- if (extKey != wAccelKey_None) {
- if ( gtkFindAccelKey( event ) == NULL ) {
- bd->action( bd, bd->context, wActionExtKey + ((int)extKey<<8), bd->lastX, bd->lastY );
- }
- return TRUE;
- } else if (key <= 0xFF && (event->state&(GDK_CONTROL_MASK|GDK_MOD1_MASK)) == 0 && bd->action) {
- bd->action( bd, bd->context, wActionText+(key<<8), bd->lastX, bd->lastY );
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-
-/*******************************************************************************
- *
- * Create
- *
-*******************************************************************************/
-
-
-
-int XW = 0;
-int XH = 0;
-int xw, xh, cw, ch;
-
-EXPORT wDraw_p wDrawCreate(
- wWin_p parent,
- wPos_t x,
- wPos_t y,
- const char * helpStr,
- long option,
- wPos_t width,
- wPos_t height,
- void * context,
- wDrawRedrawCallBack_p redraw,
- wDrawActionCallBack_p action )
-{
- wDraw_p bd;
-
- bd = (wDraw_p)gtkAlloc( parent, B_DRAW, x, y, NULL, sizeof *bd, NULL );
- bd->option = option;
- bd->context = context;
- bd->redraw = redraw;
- bd->action = action;
- gtkComputePos( (wControl_p)bd );
-
- bd->widget = gtk_drawing_area_new();
- gtk_drawing_area_size( GTK_DRAWING_AREA(bd->widget), width, height );
- gtk_widget_set_size_request( GTK_WIDGET(bd->widget), width, height );
- gtk_signal_connect (GTK_OBJECT (bd->widget), "expose_event",
- (GtkSignalFunc) draw_expose_event, bd);
- gtk_signal_connect (GTK_OBJECT(bd->widget),"configure_event",
- (GtkSignalFunc) draw_configure_event, bd);
- gtk_signal_connect (GTK_OBJECT (bd->widget), "motion_notify_event",
- (GtkSignalFunc) draw_motion_event, bd);
- gtk_signal_connect (GTK_OBJECT (bd->widget), "button_press_event",
- (GtkSignalFunc) draw_button_event, bd);
- gtk_signal_connect (GTK_OBJECT (bd->widget), "button_release_event",
- (GtkSignalFunc) draw_button_event, bd);
- gtk_signal_connect (GTK_OBJECT (bd->widget), "scroll_event",
- (GtkSignalFunc) draw_scroll_event, bd);
- gtk_signal_connect_after (GTK_OBJECT (bd->widget), "key_press_event",
- (GtkSignalFunc) draw_char_event, bd);
- gtk_signal_connect (GTK_OBJECT (bd->widget), "leave_notify_event",
- (GtkSignalFunc) draw_leave_event, bd);
- GTK_WIDGET_SET_FLAGS(GTK_WIDGET(bd->widget), GTK_CAN_FOCUS);
- gtk_widget_set_events (bd->widget, GDK_EXPOSURE_MASK
- | GDK_LEAVE_NOTIFY_MASK
- | GDK_BUTTON_PRESS_MASK
- | GDK_BUTTON_RELEASE_MASK
-/* | GDK_SCROLL_MASK */
- | GDK_POINTER_MOTION_MASK
- | GDK_POINTER_MOTION_HINT_MASK
- | GDK_KEY_PRESS_MASK
- | GDK_KEY_RELEASE_MASK );
- bd->lastColor = -1;
- bd->dpi = 75;
- bd->maxW = bd->w = width;
- bd->maxH = bd->h = height;
-
- gtk_fixed_put( GTK_FIXED(parent->widget), bd->widget, bd->realX, bd->realY );
- gtkControlGetSize( (wControl_p)bd );
- gtk_widget_realize( bd->widget );
- bd->pixmap = gdk_pixmap_new( bd->widget->window, width, height, -1 );
- bd->gc = gdk_gc_new( parent->gtkwin->window );
- gdk_gc_copy( bd->gc, parent->gtkwin->style->base_gc[GTK_STATE_NORMAL] );
-{
- GdkCursor * cursor;
- cursor = gdk_cursor_new ( GDK_TCROSS );
- gdk_window_set_cursor ( bd->widget->window, cursor);
- gdk_cursor_destroy (cursor);
-}
-#ifdef LATER
- if (labelStr)
- bd->labelW = gtkAddLabel( (wControl_p)bd, labelStr );
-#endif
- gtk_widget_show( bd->widget );
- gtkAddButton( (wControl_p)bd );
- gtkAddHelpString( bd->widget, helpStr );
- return bd;
-}
-
-/*******************************************************************************
- *
- * BitMaps
- *
-*******************************************************************************/
-
-wDraw_p wBitMapCreate( wPos_t w, wPos_t h, int arg )
-{
- wDraw_p bd;
-
- bd = (wDraw_p)gtkAlloc( gtkMainW, B_DRAW, 0, 0, NULL, sizeof *bd, NULL );
-
- bd->lastColor = -1;
- bd->dpi = 75;
- bd->maxW = bd->w = w;
- bd->maxH = bd->h = h;
-
- bd->pixmap = gdk_pixmap_new( gtkMainW->widget->window, w, h, -1 );
- if ( bd->pixmap == NULL ) {
- wNoticeEx( NT_ERROR, "CreateBitMap: pixmap_new failed", "Ok", NULL );
- return FALSE;
- }
- bd->gc = gdk_gc_new( gtkMainW->gtkwin->window );
- if ( bd->gc == NULL ) {
- wNoticeEx( NT_ERROR, "CreateBitMap: gc_new failed", "Ok", NULL );
- return FALSE;
- }
- gdk_gc_copy( bd->gc, gtkMainW->gtkwin->style->base_gc[GTK_STATE_NORMAL] );
- wDrawClear( bd );
- return bd;
-}
-
-
-wBool_t wBitMapDelete( wDraw_p d )
-{
- gdk_pixmap_unref( d->pixmap );
- d->pixmap = NULL;
- return TRUE;
-}
diff --git a/app/wlib/gtklib/gtkfont.c b/app/wlib/gtklib/gtkfont.c
index 1a707f8..89937d7 100644
--- a/app/wlib/gtklib/gtkfont.c
+++ b/app/wlib/gtklib/gtkfont.c
@@ -1,7 +1,5 @@
/** \file gtkfont.c
* Font selection and loading.
- *
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/gtkfont.c,v 1.12 2009-12-07 19:31:31 m_fischer Exp $
*/
/* XTrkCad - Model Railroad CAD
@@ -81,7 +79,7 @@ static wFont_p curFont = NULL;
static void fontSelectionDialogCallback(GtkFontSelectionDialog *fontSelectionDialog, gint response, gpointer data)
{
gchar *fontName;
-
+
switch (response)
{
case GTK_RESPONSE_APPLY: /* once the apply button is hidden, this should not be used */
@@ -120,10 +118,10 @@ static wBool_t fontInit()
"helvetica bold 18",
"helvetica bold oblique 18",
};
-
+
int s = 0;
int i, j, k;
-
+
for (i = F_TIMES; i <= F_HELV; ++i) {
for (j = FW_MEDIUM; j <= FW_BOLD; ++j) {
for (k = FS_REGULAR; k <= FS_ITALIC; ++k) {
@@ -134,7 +132,7 @@ static wBool_t fontInit()
}
}
}
-
+
if (curFont == NULL) {
curFont = (wFont_p) malloc(sizeof(struct wFont_t));
if (curFont == NULL)
@@ -143,7 +141,7 @@ static wBool_t fontInit()
curFont->fontDescription = pango_font_description_from_string(fontName ? fontName : "helvetica 18");
absoluteFontSize = (int) PANGO_PIXELS(pango_font_description_get_size(curFont->fontDescription));
}
-
+
fontInitted = TRUE;
return TRUE;
}
@@ -153,6 +151,21 @@ static double fontFactor = 1.0;
#define FONTSIZE_TO_PANGOSIZE(fs) ((gint) ((fs) * (fontFactor) + .5))
+/**
+ * Create a Pango layout with a specified font and font size
+ *
+ * \param widget IN
+ * \param cairo IN cairo context
+ * \param fp IN font
+ * \param fs IN size
+ * \param s IN ???
+ * \param width_p OUT width of layout
+ * \param height_p OUT height of layout
+ * \param ascent_p OUT ascent of layout
+ * \param descent_p OUT descent of layout
+ * \return the created Pango layout
+ */
+
PangoLayout *gtkFontCreatePangoLayout(GtkWidget *widget,
void *cairo,
wFont_p fp,
@@ -165,9 +178,9 @@ PangoLayout *gtkFontCreatePangoLayout(GtkWidget *widget,
{
if (!fontInitted)
fontInit();
-
+
PangoLayout *layout = NULL;
-
+
gchar *utf8 = gtkConvertInput(s);
/* RPH -- pango_cairo_create_layout() is missing in CentOS 4.8.
@@ -175,7 +188,7 @@ PangoLayout *gtkFontCreatePangoLayout(GtkWidget *widget,
libpangocairo at all.
pango_cairo_create_layout() was introduced with Pango 1.10. */
-#if PANGO_VERSION_MAJOR >= 1 && PANGO_VERSION_MINOR >= 10
+#if PANGO_VERSION_MAJOR >= 1 && PANGO_VERSION_MINOR >= 10
if (cairo != NULL) {
layout = pango_cairo_create_layout((cairo_t *) cairo);
pango_layout_set_text(layout, utf8, -1);
@@ -183,17 +196,17 @@ PangoLayout *gtkFontCreatePangoLayout(GtkWidget *widget,
else
#endif
layout = gtk_widget_create_pango_layout(widget, utf8);
-
+
PangoFontDescription *fontDescription = (fp ? fp : curFont)->fontDescription;
-
+
PangoContext *context;
PangoFontMetrics *metrics;
-
+
/* set attributes */
pango_font_description_set_size(fontDescription,
FONTSIZE_TO_PANGOSIZE(fs) * PANGO_SCALE);
pango_layout_set_font_description(layout, fontDescription);
-
+
/* get layout measures */
pango_layout_get_pixel_size(layout, width_p, height_p);
context = gtk_widget_get_pango_context(widget);
@@ -202,7 +215,7 @@ PangoLayout *gtkFontCreatePangoLayout(GtkWidget *widget,
*ascent_p = PANGO_PIXELS(pango_font_metrics_get_ascent(metrics));
*descent_p = PANGO_PIXELS(pango_font_metrics_get_descent(metrics));
pango_font_metrics_unref(metrics);
-
+
#if WLIB_FONT_DEBUG >= 3
fprintf(stderr, "font layout created:\n");
fprintf(stderr, " widget: %p\n", widget);
@@ -214,7 +227,7 @@ PangoLayout *gtkFontCreatePangoLayout(GtkWidget *widget,
fprintf(stderr, " layout ascent: %d (pixels)\n", *ascent_p);
fprintf(stderr, " layout descent: %d (pixels)\n", *descent_p);
#endif
-
+
return layout;
}
@@ -234,7 +247,7 @@ void wSelectFont(
{
if (!fontInitted)
fontInit();
-
+
if (fontSelectionDialog == NULL) {
fontSelectionDialog = gtk_font_selection_dialog_new(_("Font Select"));
gtk_window_set_position(GTK_WINDOW(fontSelectionDialog), GTK_WIN_POS_MOUSE);
@@ -244,17 +257,17 @@ void wSelectFont(
gtk_signal_connect(GTK_OBJECT(fontSelectionDialog), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &fontSelectionDialog);
}
gtk_window_set_title(GTK_WINDOW(fontSelectionDialog), title);
-
+
if (curFont != NULL) {
- /* the curFont description contains the latest font info
+ /* the curFont description contains the latest font info
* which is depended on the current scale
- * overwrite it with the absoluteFontSize */
+ * overwrite it with the absoluteFontSize */
pango_font_description_set_size(curFont->fontDescription,FONTSIZE_TO_PANGOSIZE(absoluteFontSize) * PANGO_SCALE);
gchar *fontName = pango_font_description_to_string(curFont->fontDescription);
gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(fontSelectionDialog), fontName);
g_free(fontName);
}
-
+
gtk_widget_show(fontSelectionDialog);
}
@@ -262,7 +275,7 @@ static wFont_p gtkSelectedFont( void )
{
if (!fontInitted)
fontInit();
-
+
return curFont;
}
@@ -270,12 +283,12 @@ wFontSize_t wSelectedFontSize( void )
{
if (!fontInitted)
fontInit();
-
+
#if WLIB_FONT_DEBUG >= 3
fprintf(stderr, "the font size of current font description is: %d\n",pango_font_description_get_size(curFont->fontDescription)/PANGO_SCALE);
- fprintf(stderr, "the font size of absoluteFontSize is: %d\n",absoluteFontSize);
+ fprintf(stderr, "the font size of absoluteFontSize is: %d\n",absoluteFontSize);
#endif
-
+
//return (wFontSize_t) PANGO_PIXELS(pango_font_description_get_size(curFont->fontDescription));
return absoluteFontSize;
}
@@ -283,26 +296,35 @@ wFontSize_t wSelectedFontSize( void )
void wSetSelectedFontSize(int size){
absoluteFontSize = (wFontSize_t)size;
}
-
+
+/**
+ * get the Pango font description as a string from a font definition.
+ * If the font definition is NULL, a default font is return. This is
+ * the current font if one is set. If not the first font from the font
+ * list is returned.
+ *
+ * \param fp IN the font definition
+ * \return the font description
+ */
const char *gtkFontTranslate( wFont_p fp )
{
static gchar *fontName = NULL;
-
+
if (fontName != NULL)
g_free(fontName);
-
+
if (!fontInitted)
fontInit();
-
+
if (fp == NULL)
fp = gtkSelectedFont();
-
+
if (fp == NULL)
fp = standardFonts[0][FW_MEDIUM][FS_REGULAR];
-
+
fontName = pango_font_description_to_string(fp->fontDescription);
-
+
#if WLIB_FONT_DEBUG >= 2
fprintf(stderr, "font translation: ");
fprintf(stderr, " \"%s\"\n", fontName);
@@ -315,6 +337,6 @@ wFont_p wStandardFont( int face, wBool_t bold, wBool_t italic )
{
if (!fontInitted)
fontInit();
-
+
return standardFonts[face-F_TIMES][bold][italic];
}
diff --git a/app/wlib/gtklib/gtkint.h b/app/wlib/gtklib/gtkint.h
index 4cbeace..c27c70b 100644
--- a/app/wlib/gtklib/gtkint.h
+++ b/app/wlib/gtklib/gtkint.h
@@ -68,7 +68,7 @@ typedef void (*setTriggerCallback_p)( wControl_p b );
struct wWin_t {
WOBJ_COMMON
- GtkWidget *gtkwin; /**< GTK window */
+ GtkWidget *gtkwin; /**< GTK window */
wPos_t lastX, lastY;
wControl_p first, last;
wWinCallBack_p winProc; /**< window procedure */
@@ -157,15 +157,10 @@ void gtkPrintColorMap( FILE *, int, int );
int gtkMapPixel( long );
/* psprint.c */
-typedef struct {
- wIndex_t cmdOrFile;
- FILE * f;
- } wPrinterStream_t;
-typedef wPrinterStream_t * wPrinterStream_p;
-
-wPrinterStream_p wPrinterOpen( void );
-void wPrinterWrite( wPrinterStream_p p, char * buff, int siz );
-void wPrinterClose( wPrinterStream_p );
+
+void WlibApplySettings( GtkPrintOperation *op );
+void WlibSaveSettings( GtkPrintOperation *op );
+
void psPrintLine( wPos_t, wPos_t, wPos_t, wPos_t,
wDrawWidth, wDrawLineType_e, wDrawColor, wDrawOpts );
void psPrintArc( wPos_t, wPos_t, wPos_t, double, double, int,
@@ -177,4 +172,31 @@ void psPrintFillRectangle( wPos_t, wPos_t, wPos_t, wPos_t, wDrawColor, wDrawOpts
void psPrintFillPolygon( wPos_t [][2], int, wDrawColor, wDrawOpts );
void psPrintFillCircle( wPos_t, wPos_t, wPos_t, wDrawColor, wDrawOpts );
+struct wDraw_t {
+ WOBJ_COMMON
+ void * context;
+ wDrawActionCallBack_p action;
+ wDrawRedrawCallBack_p redraw;
+
+ GdkPixmap * pixmap;
+ GdkPixmap * pixmapBackup;
+
+ double dpi;
+
+ GdkGC * gc;
+ wDrawWidth lineWidth;
+ wDrawOpts opts;
+ wPos_t maxW;
+ wPos_t maxH;
+ unsigned long lastColor;
+ wBool_t lastColorInverted;
+ const char * helpStr;
+
+ wPos_t lastX;
+ wPos_t lastY;
+
+ wBool_t delayUpdate;
+ cairo_t *printContext;
+ cairo_surface_t *curPrintSurface;
+ };
#endif
diff --git a/app/wlib/gtklib/gtklist.c b/app/wlib/gtklib/gtklist.c
index b2c9799..fb8afaa 100644
--- a/app/wlib/gtklib/gtklist.c
+++ b/app/wlib/gtklib/gtklist.c
@@ -1,7 +1,6 @@
-/*
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/gtklist.c,v 1.4 2009-05-30 11:11:26 m_fischer Exp $
+/** \file gtklist.c
+ * Listboxes, dropdown boxes, combo boxes
*/
-
/* XTrkCad - Model Railroad CAD
* Copyright (C) 2005 Dave Bullis
*
@@ -42,7 +41,7 @@ static char ListItemDataKey[] = "ListItemDataKey";
*/
typedef struct wListItem_t * wListItem_p;
-
+
struct wList_t {
WOBJ_COMMON
GtkWidget *list;
@@ -73,7 +72,7 @@ struct wListItem_t {
static wListItem_p getListItem(
wList_p b,
- wIndex_t inx,
+ wIndex_t inx,
GList ** childR )
{
GList * child;
@@ -86,7 +85,7 @@ static wListItem_p getListItem(
return NULL;
if ( b->type == B_LIST )
return (wListItem_p)gtk_clist_get_row_data( GTK_CLIST(b->list), inx );
-
+
for ( child=GTK_LIST(b->list)->children; inx>0&&child; child=child->next,inx-- );
if (child==NULL) {
fprintf( stderr, "wListGetValues - End Of List\n" );
@@ -195,7 +194,7 @@ static void parseLabelStr(
textBuffer = (char**)realloc( textBuffer, count * sizeof *textBuffer );
textBufferCount = count;
}
-
+
strcpy( labelBuffer, labelStr );
cp = labelBuffer;
for ( col=0; cp && col<count; col++ ) {
@@ -354,6 +353,29 @@ EXPORT wIndex_t wListGetSelectedCount(
return selcnt;
}
+/**
+ * Select all items in list.
+ *
+ * \param bl IN list handle
+ * \return
+ */
+
+void wListSelectAll( wList_p bl )
+{
+ wIndex_t inx;
+ wListItem_p ldp;
+
+ // mark all items selected
+ gtk_clist_select_all(GTK_CLIST(bl->list));
+
+ // and synchronize the internal data structures
+ wListGetCount(bl);
+ for ( inx=0; inx<bl->count; inx++ ) {
+ ldp = getListItem( bl, inx, NULL );
+
+ ldp->selected = TRUE;
+ }
+}
EXPORT wBool_t wListSetValues(
wList_p b,
@@ -494,21 +516,21 @@ If list is created with 'BL_
} else {
parseLabelStr( labelStr, b->colCnt, &texts );
gtk_clist_append( GTK_CLIST(b->list), texts );
-
- /*
- * this has taken forever to find out: the adjustment has to be notified
+
+ /*
+ * this has taken forever to find out: the adjustment has to be notified
* about the list change by the program. So we need to get the current alignment.
* increment the upper value and then inform the scrolled window about the update.
* The upper value is increased only if the current value is smaller than the size
- * of the list box.
+ * of the list box.
*/
-
+
adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(b->widget));
-
+
if( adj->upper < adj->step_increment * (b->count+1)) {
adj->upper += adj->step_increment;
gtk_adjustment_changed( adj );
- }
+ }
if ( bm ) {
pixmap = gtkMakeIcon( b->widget, bm, &bitmap );
gtk_clist_set_pixtext( GTK_CLIST(b->list), b->count, 0, texts[0], 5, pixmap, bitmap );
@@ -609,7 +631,7 @@ static int selectCList(
bl->action( row, id_p->label, 1, bl->data, id_p->itemData );
return 1;
}
-
+
static int unselectCList(
GtkWidget * clist,
@@ -753,7 +775,7 @@ static int DropListSelectionChanged(
return 1;
#endif
}
-
+
#endif
@@ -817,7 +839,7 @@ EXPORT wList_p wListCreate(
void *data ) /* Context */
/*
*/
-{
+{
wList_p b;
b = (wList_p)gtkAlloc( parent, B_LIST, x, y, labelStr, sizeof *b, data );
@@ -873,17 +895,17 @@ EXPORT wList_p wListCreate(
/** Create a drop down list. The drop down is created and intialized with the supplied values.
*
- * \param IN parent Parent window
+ * \param IN parent Parent window
* \param IN x, X-position
* \param IN y Y-position
- * \param IN helpStr Help string
+ * \param IN helpStr Help string
* \param IN labelStr Label
- * \param IN option Options
+ * \param IN option Options
* \param IN number Number of displayed entries
- * \param IN width Width
+ * \param IN width Width
* \param IN valueP Selected index
* \param IN action Callback
- * \param IN data Context
+ * \param IN data Context
*/
EXPORT wList_p wDropListCreate(
@@ -1032,7 +1054,7 @@ EXPORT wList_p wListCreate(
void *data ) /* Context */
/*
*/
-{
+{
wList_p bl;
long col;
static wPos_t zeroPos = 0;
@@ -1069,7 +1091,7 @@ EXPORT wList_p wListCreate(
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (bl->widget),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
/* gtk_container_add( GTK_CONTAINER(bl->widget), bl->list ); */
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(bl->widget), bl->list );
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(bl->widget), bl->list );
if (width == 0)
width = 100;
for ( col=0; col<colCnt; col++ ) {
diff --git a/app/wlib/gtklib/gtkmenu.c b/app/wlib/gtklib/gtkmenu.c
index 0782f02..d3258c4 100644
--- a/app/wlib/gtklib/gtkmenu.c
+++ b/app/wlib/gtklib/gtkmenu.c
@@ -546,7 +546,7 @@ void wMenuListDelete(
GtkWidget * label;
char * labelStrConverted;
- if (ml->count <= 0) abort();
+ if (ml->count < 0) abort();
origin = getMlistOrigin(ml->parentMenu, ml);
children = gtk_container_children( GTK_CONTAINER(ml->parentMenu->menu) );
if (children == NULL) abort();
diff --git a/app/wlib/gtklib/gtktext.c b/app/wlib/gtklib/gtktext.c
index 8da31d3..e067f43 100644
--- a/app/wlib/gtklib/gtktext.c
+++ b/app/wlib/gtklib/gtktext.c
@@ -1,5 +1,5 @@
/** \file gtktext.c
- * Multi line text entry
+ * Multi-line Text Boxes
*/
/* XTrkCad - Model Railroad CAD
@@ -24,7 +24,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
+#include <math.h>
+#include "i18n.h"
#include "gtkint.h"
/*
@@ -32,13 +33,18 @@
*/
#define USE_TEXTVIEW
-/*
- *****************************************************************************
- *
- * Multi-line Text Boxes
- *
- *****************************************************************************
- */
+
+struct PrintData {
+ wText_p tb;
+ gint lines_per_page;
+ gdouble font_size;
+ gchar **lines;
+ gint total_lines;
+ gint total_pages;
+};
+
+#define HEADER_HEIGHT 20.0
+#define HEADER_GAP 8.5
struct wText_t {
WOBJ_COMMON
@@ -69,16 +75,6 @@ EXPORT void wTextClear(
bt->changed = FALSE;
}
-/**
- * Add text to a multiline text field. Font is selected as requested.
- * Bold is supported if the flags BT_BOLD is set as flags for the entry
- * field. For bold, pango text markup is used
- *
- *
- * \param bt IN the text field
- * \param text IN text to add
- */
-
EXPORT void wTextAppend(
wText_p bt,
const char * text )
@@ -86,7 +82,6 @@ EXPORT void wTextAppend(
#ifdef USE_TEXTVIEW
GtkTextBuffer * tb;
GtkTextIter ti1, ti2;
-// PangoFontDescription *pfd;
#else
static GdkFont * fixedRegularFont = NULL;
static GdkFont * fixedBoldFont = NULL;
@@ -102,14 +97,6 @@ EXPORT void wTextAppend(
if (bt->text == 0) abort();
#ifdef USE_TEXTVIEW
tb = gtk_text_view_get_buffer( GTK_TEXT_VIEW(bt->text) );
- //if ((bt->option&BT_FIXEDFONT)) {
- ///* creating PangoFontDescription from string, specified in entry */
- //pfd = pango_font_description_from_string("Monospace");
- ///* setting label's font */
- //gtk_widget_modify_font(GTK_WIDGET(tb), pfd);
- ///* freeing PangoFontDescription, cause it has been copied by prev. call */
- //pango_font_description_free(pfd);
- //}
#else
if ((bt->option&BT_FIXEDFONT)) {
if (fixedRegularFont==NULL)
@@ -251,42 +238,224 @@ EXPORT wBool_t wTextSave(
fclose(f);
return TRUE;
}
+/**
+ * Begin the printing by retrieving the contents of the text box and
+ * count the lines of text.
+ *
+ * \param operation IN the GTK print operation
+ * \param context IN print context
+ * \param pd IN data structure for user data
+ *
+ */
+
+static void
+begin_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ struct PrintData *pd)
+{
+ gchar *contents;
+ gdouble height;
+
+ contents = gtkGetText( pd->tb );
+ pd->lines = g_strsplit (contents, "\n", 0);
+
+ /* Count the total number of lines in the file. */
+ /* ignore the header lines */
+ pd->total_lines = 6;
+ while (pd->lines[pd->total_lines] != NULL)
+ pd->total_lines++;
+
+ /* Based on the height of the page and font size, calculate how many lines can be
+ * rendered on a single page. A padding of 3 is placed between lines as well.
+ * Space for page header, table header and footer lines is subtracted from the total size
+ */
+ height = gtk_print_context_get_height (context) - (pd->font_size + 3) - 2 * ( HEADER_HEIGHT + HEADER_GAP );
+ pd->lines_per_page = floor (height / (pd->font_size + 3));
+ pd->total_pages = (pd->total_lines - 1) / pd->lines_per_page + 1;
+ gtk_print_operation_set_n_pages (operation, pd->total_pages);
+
+ free( contents );
+}
+/**
+ * Draw the page, which includes a header with the file name and page number along
+ * with one page of text with a font of "Monospace 10".
+ *
+ * \param operation IN the GTK print operation
+ * \param context IN print context
+ * \param page_nr IN page to print
+ * \param pd IN data structure for user data
+ *
+ *
+ */
+
+static void
+draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ struct PrintData *pd )
+{
+ cairo_t *cr;
+ PangoLayout *layout;
+ gdouble width, text_height, height;
+ gint line, i, text_width, layout_height;
+ PangoFontDescription *desc;
+ gchar *page_str;
+
+ cr = gtk_print_context_get_cairo_context (context);
+ width = gtk_print_context_get_width (context);
+
+ layout = gtk_print_context_create_pango_layout (context);
+ desc = pango_font_description_from_string ("Monospace");
+ pango_font_description_set_size (desc, pd->font_size * PANGO_SCALE);
+
+ /*
+ * render the header line with document type parts list on left and
+ * first line of layout title on right
+ */
+
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, pd->lines[ 0 ], -1); // document type
+ pango_layout_set_width (layout, -1);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
+ pango_layout_get_size (layout, NULL, &layout_height);
+ text_height = (gdouble) layout_height / PANGO_SCALE;
+
+ cairo_move_to (cr, 0, (HEADER_HEIGHT - text_height) / 2);
+ pango_cairo_show_layout (cr, layout);
+
+ pango_layout_set_text (layout, pd->lines[ 2 ], -1); // layout title
+ pango_layout_get_size (layout, &text_width, NULL);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
+
+ cairo_move_to (cr, width - (text_width / PANGO_SCALE),
+ (HEADER_HEIGHT - text_height) / 2);
+ pango_cairo_show_layout (cr, layout);
+
+ /* Render the column header */
+ cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP + pd->font_size + 3 );
+ pango_layout_set_text (layout, pd->lines[ 6 ], -1);
+ pango_cairo_show_layout (cr, layout);
+ cairo_rel_move_to (cr, 0, pd->font_size + 3 );
+ pango_layout_set_text (layout, pd->lines[ 7 ], -1);
+ pango_cairo_show_layout (cr, layout);
+
+ /* Render the page text with the specified font and size. */
+ cairo_rel_move_to (cr, 0, pd->font_size + 3 );
+ line = page_nr * pd->lines_per_page + 8;
+ for (i = 0; i < pd->lines_per_page && line < pd->total_lines; i++)
+ {
+ pango_layout_set_text (layout, pd->lines[line], -1);
+ pango_cairo_show_layout (cr, layout);
+ cairo_rel_move_to (cr, 0, pd->font_size + 3);
+ line++;
+ }
+
+ /*
+ * Render the footer line with date on the left and page number
+ * on the right
+ */
+ pango_layout_set_text (layout, pd->lines[ 5 ], -1); // date
+ pango_layout_set_width (layout, -1);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
+ pango_layout_get_size (layout, NULL, &layout_height);
+ text_height = (gdouble) layout_height / PANGO_SCALE;
+
+ height = gtk_print_context_get_height (context);
+ cairo_move_to (cr, 0, height - ((HEADER_HEIGHT - text_height) / 2));
+ pango_cairo_show_layout (cr, layout);
+
+ page_str = g_strdup_printf (_("%d of %d"), page_nr + 1, pd->total_pages); // page number
+ pango_layout_set_text( layout, page_str, -1 );
+ pango_layout_get_size (layout, &text_width, NULL);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
+
+ cairo_move_to (cr, width - (text_width / PANGO_SCALE),
+ height - ((HEADER_HEIGHT - text_height) / 2));
+ pango_cairo_show_layout (cr, layout);
+
+ g_free (page_str);
+ g_object_unref (layout);
+ pango_font_description_free (desc);
+}
+
+/**
+ * Clean up after the printing operation since it is done.
+ *
+ * \param operation IN the GTK print operation
+ * \param context IN print context
+ * \param pd IN data structure for user data
+ *
+ *
+ */
+static void
+end_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ struct PrintData *pd)
+{
+ g_strfreev (pd->lines);
+ free( pd );
+}
+
+/**
+ * Print the content of a multi line text box. This function is only used
+ * for printing the parts list. So it makes some assumptions on the structure
+ * and the content. Change if the multi line entry is changed.
+ * The deprecated gtk_text is not supported by this function.
+ *
+ * Thanks to Andrew Krause's book for a good starting point.
+ *
+ * \param bt IN the text field
+ * \return TRUE on success, FALSE on error
+ */
EXPORT wBool_t wTextPrint(
wText_p bt )
{
- wPrinterStream_p f;
-#ifndef USE_TEXTVIEW
- int siz, pos, cnt;
-#endif
- char * cp;
-
- f = wPrinterOpen();
- if (f==NULL) {
- return FALSE;
+ GtkPrintOperation *operation;
+ GtkWidget *dialog;
+ GError *error = NULL;
+ gint res;
+ struct PrintData *data;
+
+ /* Create a new print operation, applying saved print settings if they exist. */
+ operation = gtk_print_operation_new ();
+ WlibApplySettings( operation );
+
+ data = malloc(sizeof( struct PrintData));
+ data->font_size = 10.0;
+ data->tb = bt;
+
+ g_signal_connect (G_OBJECT (operation), "begin_print",
+ G_CALLBACK (begin_print), (gpointer) data);
+ g_signal_connect (G_OBJECT (operation), "draw_page",
+ G_CALLBACK (draw_page), (gpointer) data);
+ g_signal_connect (G_OBJECT (operation), "end_print",
+ G_CALLBACK (end_print), (gpointer) data);
+
+ /* Run the default print operation that will print the selected file. */
+ res = gtk_print_operation_run (operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+ GTK_WINDOW(gtkMainW->gtkwin), &error);
+
+ /* If the print operation was accepted, save the new print settings. */
+ if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
+ {
+ WlibSaveSettings( operation );
}
-#ifdef USE_TEXTVIEW
- cp = gtkGetText( bt );
- wPrinterWrite( f, cp, strlen(cp) );
- free(cp);
-
-#else
- siz = gtk_text_get_length( GTK_TEXT(bt->text) );
- pos = 0;
- cnt = BUFSIZ;
- while (pos<siz) {
- if (pos+cnt>siz)
- cnt = siz-pos;
- cp = gtk_editable_get_chars( GTK_EDITABLE(bt->text), pos, pos+cnt );
- if (cp == NULL)
- break;
- wPrinterWrite( f, cp, cnt );
- free(cp);
- pos += cnt;
+ /* Otherwise, report that the print operation has failed. */
+ else if (error)
+ {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtkMainW->gtkwin),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ error->message);
+
+ g_error_free (error);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
}
-#endif
- wPrinterClose(f);
+ g_object_unref (operation);
+
return TRUE;
}
@@ -402,21 +571,7 @@ static void textChanged(
bt->changed = TRUE;
}
-/**
- * Create a multi line text entry widget. The created widget is
- * configured as requested by the BT_* flags. This includes Monospaced
- * font for BT_FIXEDFONT, readonly for BT_READONLY and a markup for
- * bold when setup via BT_BOLD.
- *
- * \param parent IN parent window
- * \param x,y IN position
- * \param helpstr IN label for linking into help system
- * \param labelStr IN label
- * \param option IN widget options
- * \param width, height IN size of widget
- * \return handle for new widget
- */
-
+
EXPORT wText_p wTextCreate(
wWin_p parent,
wPos_t x,
@@ -430,7 +585,6 @@ EXPORT wText_p wTextCreate(
wText_p bt;
#ifdef USE_TEXTVIEW
GtkTextBuffer * tb;
- PangoFontDescription *pfd;
#else
GtkRequisition requisition;
#endif
@@ -453,14 +607,6 @@ EXPORT wText_p wTextCreate(
gtk_text_buffer_create_tag( tb, "bold", "weight", PANGO_WEIGHT_BOLD, NULL);
/* gtk_text_buffer_create_tag( tb, "italic", "style", PANGO_STYLE_ITALIC, NULL); */
/* gtk_text_buffer_create_tag( tb, "bolditalic", "weight", PANGO_WEIGHT_BOLD, "style", PANGO_STYLE_ITALIC, NULL); */
- if ((bt->option & BT_FIXEDFONT)) {
- /* creating PangoFontDescription from string, specified in entry */
- pfd = pango_font_description_from_string("Monospace");
- /* setting label's font */
- gtk_widget_modify_font(GTK_WIDGET(bt->text), pfd);
- /* freeing PangoFontDescription, cause it has been copied by prev. call */
- pango_font_description_free(pfd);
- }
bt->vscroll = gtk_vscrollbar_new( GTK_TEXT_VIEW(bt->text)->vadjustment );
if (bt->vscroll == 0) abort();
#else
diff --git a/app/wlib/gtklib/gtkxpm.c b/app/wlib/gtklib/gtkxpm.c
index 022c973..54ce5a6 100644
--- a/app/wlib/gtklib/gtkxpm.c
+++ b/app/wlib/gtklib/gtkxpm.c
@@ -19,7 +19,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-
+
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_MALLOC_H
@@ -34,7 +34,7 @@
struct xpmColTable {
int color; /* color value (rgb) */
- char name[ 5 ]; /* corresponding character representation */
+ char name[ 5 ]; /* corresponding character representation */
UT_hash_handle hh; /* makes this structure hashable */
};
@@ -42,34 +42,30 @@ static struct xpmColTable *colTable = NULL;
// must be 64 chars long
static char colVal[] = ".*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-
-struct wDraw_t {
- WOBJ_COMMON
- void * context;
- wDrawActionCallBack_p action;
- wDrawRedrawCallBack_p redraw;
-
- GdkPixmap * pixmap;
- GdkPixmap * pixmapBackup;
-
- double dpi;
-
- GdkGC * gc;
- wDrawWidth lineWidth;
- wDrawOpts opts;
- wPos_t maxW;
- wPos_t maxH;
- unsigned long lastColor;
- wBool_t lastColorInverted;
- const char * helpStr;
-
- wPos_t lastX;
- wPos_t lastY;
-
- wBool_t delayUpdate;
- };
-
+
+//struct wDraw_t {
+ //WOBJ_COMMON
+ //void * context;
+ //wDrawActionCallBack_p action;
+ //wDrawRedrawCallBack_p redraw;
+
+ //double dpi;
+
+ //GdkGC * gc;
+ //wDrawWidth lineWidth;
+ //wDrawOpts opts;
+ //wPos_t maxW;
+ //wPos_t maxH;
+ //unsigned long lastColor;
+ //wBool_t lastColorInverted;
+ //const char * helpStr;
+
+ //wPos_t lastX;
+ //wPos_t lastY;
+
+ //wBool_t delayUpdate;
+ //};
+
/**
* Export as XPM bitmap file. During creation of the color table, a 4 byte color
* encoding is assumed and a table created accordingly. Once the whole picture has been scanned
@@ -78,7 +74,7 @@ struct wDraw_t {
* This routine was heavily inspired by on implementation for TK written by Jan Nijtmans.
*
* \param d IN the drawing area ?
- * \param fileName IN fully qualified filename for the bitmap file.
+ * \param fileName IN fully qualified filename for the bitmap file.
* \return TRUE on success, FALSE on error
*/
@@ -88,7 +84,7 @@ wBool_t wBitMapWriteFile( wDraw_p d, const char * fileName )
gint x, y;
guint32 pixel;
FILE * f;
- int cc = 0;
+ int cc = 0;
struct xpmColTable *ct, *tmp;
int numChars;
@@ -106,11 +102,11 @@ wBool_t wBitMapWriteFile( wDraw_p d, const char * fileName )
fprintf( f, "/* XPM */\n" );
fprintf( f, "static char * xtrkcad_bitmap[] = {\n" );
fprintf( f, "/* width height num_colors chars_per_pixel */\n" );
-
+
// count colors used and create the color table in the same pass
for( y = 0; y < d->h;y ++ ) {
for (x = 0; x < d->w; x++ ) {
-
+
pixel = gdk_image_get_pixel( image, x, y );
//check whether color is new
@@ -119,18 +115,18 @@ wBool_t wBitMapWriteFile( wDraw_p d, const char * fileName )
// not found previously, so add a new color table entry
int i;
int c;
-
+
ct = malloc( sizeof( struct xpmColTable ) );
ct->name[ 4 ] = '\0';
for( i = 3, c = cc; i >= 0; i--, c>>=6 ) {
(ct->name)[ i ] = colVal[ c & 0x3F ];
- }
+ }
ct->color = pixel;
-
+
HASH_ADD(hh, colTable, color, sizeof( guint32 ), ct);
cc++;
- }
- }
+ }
+ }
}
// calculate how many characters are needed for the color table
@@ -143,15 +139,15 @@ wBool_t wBitMapWriteFile( wDraw_p d, const char * fileName )
} else {
if( cc > 0x3f ) {
numChars = 2;
- }
+ }
}
- }
- // print color table
+ }
+ // print color table
fprintf( f, "\"%d %d %d %d\"\n", d->w, d->h, cc, numChars );
fprintf( f, "/* colors */\n" );
for( ct = colTable; ct != NULL; ct = ct->hh.next )
fprintf( f, "\"%s c #%6.6x\",\n", (ct->name) + (4 - numChars ), ct->color );
-
+
// print the pixels
fprintf( f, "/* pixels */\n" );
for ( y=0; y<d->h; y++ ) {
@@ -159,17 +155,17 @@ wBool_t wBitMapWriteFile( wDraw_p d, const char * fileName )
for ( x=0; x<d->w; x++ ) {
pixel = gdk_image_get_pixel( image, x, y );
HASH_FIND( hh, colTable, &pixel, sizeof(guint32), ct );
- fputs( (ct->name) + (4 - numChars ), f );
+ fputs( (ct->name) + (4 - numChars ), f );
}
fprintf( f, "\"%s\n", (y<d->h-1)?",":"" );
}
// delete the hash and free the content
HASH_ITER(hh, colTable, ct, tmp) {
- HASH_DEL(colTable,ct);
- free(ct);
+ HASH_DEL(colTable,ct);
+ free(ct);
}
-
+
gdk_image_destroy( image );
fprintf( f, "};\n" );
fclose( f );
diff --git a/app/wlib/gtklib/print.c b/app/wlib/gtklib/print.c
new file mode 100644
index 0000000..9f4a4a8
--- /dev/null
+++ b/app/wlib/gtklib/print.c
@@ -0,0 +1,858 @@
+/** \file print.c
+ * Printing functions using GTK's print API
+ */
+
+/* XTrkCad - Model Railroad CAD
+ * Copyright (C) 2015 Martin Fischer
+ *
+ * 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 <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <pwd.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#include <math.h>
+#include <locale.h>
+
+#include <stdint.h>
+
+#include "gtkint.h"
+#include <gtk/gtkprintunixdialog.h>
+#include <gtk/gtkprintjob.h>
+
+#include "wlib.h"
+#include "i18n.h"
+
+extern wDrawColor wDrawColorWhite;
+extern wDrawColor wDrawColorBlack;
+
+/*****************************************************************************
+ *
+ * MACROS
+ *
+ */
+
+#define PRINT_PORTRAIT (0)
+#define PRINT_LANDSCAPE (1)
+
+#define PPI (72.0)
+#define P2I( P ) ((P)/PPI)
+
+#define CENTERMARK_LENGTH (60) /**< size of cross marking center of circles */
+#define DASH_LENGTH (8.0) /**< length of single dash */
+
+#define PAGESETTINGS "xtrkcad.page" /**< filename for page settings */
+#define PRINTSETTINGS "xtrkcad.printer" /**< filename for printer settings */
+
+/*****************************************************************************
+ *
+ * VARIABLES
+ *
+ */
+
+static GtkPrintSettings *settings; /**< current printer settings */
+static GtkPageSetup *page_setup; /**< current paper settings */
+static GtkPrinter *selPrinter; /**< printer selected by user */
+static GtkPrintJob *curPrintJob; /**< currently active print job */
+extern struct wDraw_t psPrint_d;
+
+static wBool_t printContinue; /**< control print job, FALSE for cancelling */
+
+static wIndex_t pageCount; /**< unused, could be used for progress indicator */
+static wIndex_t totalPageCount; /**< unused, could be used for progress indicator */
+
+static double paperWidth; /**< physical paper width */
+static double paperHeight; /**< physical paper height */
+static double tBorder; /**< top margin */
+static double rBorder; /**< right margin */
+static double lBorder; /**< left margin */
+static double bBorder; /**< bottom margin */
+
+static long printFormat = PRINT_LANDSCAPE;
+
+/*****************************************************************************
+ *
+ * FUNCTIONS
+ *
+ */
+
+static void WlibGetPaperSize( void );
+
+/**
+ * Initialize printer und paper selection using the saved settings
+ *
+ * \param op IN print operation to initialize. If NULL only the global
+ * settings are loaded.
+ */
+
+void
+WlibApplySettings( GtkPrintOperation *op )
+{
+ gchar *filename;
+ GError *err = NULL;
+ GtkWidget *dialog;
+
+ filename = g_build_filename( wGetAppWorkDir(), PRINTSETTINGS, NULL );
+
+ if( !(settings = gtk_print_settings_new_from_file( filename, &err ))) {
+ if( err->code != G_FILE_ERROR_NOENT ) {
+ // ignore file not found error as defaults will be used
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtkMainW->gtkwin),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ err->message);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ } else {
+ // create default print settings
+ settings = gtk_print_settings_new();
+ }
+ g_error_free (err);
+ }
+ g_free( filename );
+
+ if (settings && op )
+ gtk_print_operation_set_print_settings (op, settings);
+
+ err = NULL;
+ filename = g_build_filename( wGetAppWorkDir(), PAGESETTINGS, NULL );
+ if( !(page_setup = gtk_page_setup_new_from_file( filename, &err ))) {
+ // ignore file not found error as defaults will be used
+ if( err->code != G_FILE_ERROR_NOENT ) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtkMainW->gtkwin),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ err->message);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ } else {
+ page_setup = gtk_page_setup_new();
+ }
+ g_error_free (err);
+ } else {
+ // on success get the paper dimensions
+ WlibGetPaperSize();
+ }
+ g_free( filename );
+
+ if( page_setup && op )
+ gtk_print_operation_set_default_page_setup (op, page_setup);
+
+}
+
+/**
+ * Save the printer settings. If op is not NULL the settings are retrieved
+ * from the print operation. Otherwise the state of the globals is saved.
+ *
+ * \param op IN printer operation. If NULL the glabal variables are used
+ */
+
+void
+WlibSaveSettings( GtkPrintOperation *op )
+{
+ GError *err = NULL;
+ gchar *filename;
+ GtkWidget *dialog;
+
+ if( op ) {
+ if (settings != NULL)
+ g_object_unref (settings);
+ settings = g_object_ref (gtk_print_operation_get_print_settings (op));
+ }
+ filename = g_build_filename( wGetAppWorkDir(), PRINTSETTINGS, NULL );
+ if( !gtk_print_settings_to_file( settings, filename, &err )) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtkMainW->gtkwin),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ err->message);
+
+ g_error_free (err);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+ g_free( filename );
+
+ if( op ) {
+ if (page_setup != NULL)
+ g_object_unref (page_setup);
+ page_setup = g_object_ref (gtk_print_operation_get_default_page_setup (op));
+ }
+ filename = g_build_filename( wGetAppWorkDir(), PAGESETTINGS, NULL );
+ if( !gtk_page_setup_to_file( page_setup, filename, &err )) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtkMainW->gtkwin),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ err->message);
+
+ g_error_free (err);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+ g_free( filename );
+
+}
+
+/**
+ * Page setup function. Previous settings are loaded and the setup
+ * dialog is shown. The settings are saved after the dialog ends.
+ *
+ * \param callback IN unused
+ */
+
+void wPrintSetup( wPrintSetupCallBack_p callback )
+{
+ GtkPageSetup *new_page_setup;
+ gchar *filename;
+ GError *err;
+ GtkWidget *dialog;
+
+ WlibApplySettings( NULL );
+
+ new_page_setup = gtk_print_run_page_setup_dialog (GTK_WINDOW (gtkMainW->gtkwin),
+ page_setup, settings);
+ if (page_setup)
+ g_object_unref (page_setup);
+
+ page_setup = new_page_setup;
+
+ WlibGetPaperSize();
+ WlibSaveSettings( NULL );
+}
+
+/*****************************************************************************
+ *
+ * BASIC PRINTING
+ *
+ */
+
+
+/**
+ * set the current line type for printing operations
+ *
+ * \param lineWidth IN new line width
+ * \param lineType IN flag for line type (dashed or full)
+ * \param opts IN unused
+ * \return
+ */
+
+
+static void setLineType(
+ double lineWidth,
+ wDrawLineType_e lineType,
+ wDrawOpts opts )
+{
+ cairo_t *cr = psPrint_d.printContext;
+ double dashLength = DASH_LENGTH;
+
+ if (lineWidth < 0.0) {
+ lineWidth = P2I(-lineWidth)*2.0;
+ }
+
+ // make sure that there is a minimum line width used
+ if ( lineWidth == 0.0 )
+ lineWidth = 0.1;
+
+ cairo_set_line_width( cr, lineWidth );
+
+ if (lineType == wDrawLineDash)
+ cairo_set_dash( cr, &dashLength, 1, 0.0 );
+ else
+ cairo_set_dash( cr, NULL, 0, 0.0 );
+}
+
+/**
+ * set the color for the following print operations
+ *
+ * \param color IN the new color
+ * \return
+ */
+
+static void psSetColor(
+ wDrawColor color )
+{
+ cairo_t *cr = psPrint_d.printContext;
+ GdkColor* const gcolor = gtkGetColor(color, TRUE);
+
+ cairo_set_source_rgb(cr, gcolor->red / 65535.0,
+ gcolor->green / 65535.0,
+ gcolor->blue / 65535.0);
+}
+
+/**
+ * Print a straight line
+ *
+ * \param x0, y0 IN starting point in pixels
+ * \param x1, y1 IN ending point in pixels
+ * \param width line width
+ * \param lineType
+ * \param color color
+ * \param opts ?
+ */
+
+void psPrintLine(
+ wPos_t x0, wPos_t y0,
+ wPos_t x1, wPos_t y1,
+ wDrawWidth width,
+ wDrawLineType_e lineType,
+ wDrawColor color,
+ wDrawOpts opts )
+{
+ if (color == wDrawColorWhite)
+ return;
+ if (opts&wDrawOptTemp)
+ return;
+
+ psSetColor(color);
+ setLineType( width, lineType, opts );
+
+ cairo_move_to( psPrint_d.printContext,
+ x0, y0 );
+ cairo_line_to( psPrint_d.printContext,
+ x1, y1 );
+ cairo_stroke( psPrint_d.printContext );
+}
+
+/**
+ * Print an arc around a specified center
+ *
+ * \param x0, y0 IN center of arc
+ * \param r IN radius
+ * \param angle0, angle1 IN start and end angle
+ * \param drawCenter draw marking for center
+ * \param width line width
+ * \param lineType
+ * \param color color
+ * \param opts ?
+ */
+
+void psPrintArc(
+ wPos_t x0, wPos_t y0,
+ wPos_t r,
+ double angle0,
+ double angle1,
+ wBool_t drawCenter,
+ wDrawWidth width,
+ wDrawLineType_e lineType,
+ wDrawColor color,
+ wDrawOpts opts )
+{
+ cairo_t *cr = psPrint_d.printContext;
+
+ if (color == wDrawColorWhite)
+ return;
+ if (opts&wDrawOptTemp)
+ return;
+
+ psSetColor(color);
+ setLineType(width, lineType, opts);
+
+ if (angle1 >= 360.0)
+ angle1 = 359.999;
+ angle1 = 90.0-(angle0+angle1);
+ while (angle1 < 0.0) angle1 += 360.0;
+ while (angle1 >= 360.0) angle1 -= 360.0;
+ angle0 = 90.0-angle0;
+ while (angle0 < 0.0) angle0 += 360.0;
+ while (angle0 >= 360.0) angle0 -= 360.0;
+
+ // draw the curve
+ cairo_arc( cr, x0, y0, r, angle1 * M_PI / 180.0, angle0 * M_PI / 180.0 );
+
+ if( drawCenter ) {
+ // draw crosshair for center of curve
+ cairo_move_to( cr, x0 - CENTERMARK_LENGTH / 2, y0 );
+ cairo_line_to( cr, x0 + CENTERMARK_LENGTH / 2, y0 );
+ cairo_move_to( cr, x0, y0 - CENTERMARK_LENGTH / 2 );
+ cairo_line_to( cr, x0, y0 + CENTERMARK_LENGTH / 2 );
+ }
+ cairo_stroke( psPrint_d.printContext );
+}
+
+/**
+ * Print a filled rectangle
+ *
+ * \param x0, y0 IN top left corner
+ * \param x1, y1 IN bottom right corner
+ * \param color IN fill color
+ * \param opts IN options
+ * \return
+ */
+
+void psPrintFillRectangle(
+ wPos_t x0, wPos_t y0,
+ wPos_t x1, wPos_t y1,
+ wDrawColor color,
+ wDrawOpts opts )
+{
+ cairo_t *cr = psPrint_d.printContext;
+ double width = x0 - x1;
+ double height = y0 - y1;
+
+ if (color == wDrawColorWhite)
+ return;
+ if (opts&wDrawOptTemp)
+ return;
+ psSetColor(color);
+
+ cairo_rectangle( cr, x0, y0, width, height );
+
+ cairo_fill( cr );
+}
+
+/**
+ * Print a filled polygon
+ *
+ * \param p IN a list of x and y coordinates
+ * \param cnt IN the number of points
+ * \param color IN fill color
+ * \param opts IN options
+ * \return
+ */
+
+void psPrintFillPolygon(
+ wPos_t p[][2],
+ int cnt,
+ wDrawColor color,
+ wDrawOpts opts )
+{
+ int inx;
+ cairo_t *cr = psPrint_d.printContext;
+
+ if (color == wDrawColorWhite)
+ return;
+ if (opts&wDrawOptTemp)
+ return;
+
+ psSetColor(color);
+
+ cairo_move_to( cr, p[ 0 ][ 0 ], p[ 0 ][ 1 ] );
+ for (inx=0; inx<cnt; inx++)
+ cairo_line_to( cr, p[ inx ][ 0 ], p[ inx ][ 1 ] );
+ cairo_fill( cr );
+}
+
+/**
+ * Print a filled circle
+ *
+ * \param x0, y0 IN coordinates of center (in pixels )
+ * \param r IN radius
+ * \param color IN fill color
+ * \param opts IN options
+ * \return
+ */
+
+void psPrintFillCircle(
+ wPos_t x0, wPos_t y0,
+ wPos_t r,
+ wDrawColor color,
+ wDrawOpts opts )
+{
+ if (color == wDrawColorWhite)
+ return;
+ if (opts&wDrawOptTemp)
+ return;
+ psSetColor(color);
+
+ cairo_arc( psPrint_d.printContext,
+ x0, y0, r, 0.0, 2 * M_PI );
+
+ cairo_fill( psPrint_d.printContext );
+}
+
+
+/**
+ * Print a string at the given position using specified font and text size.
+ * The orientatoion of the y-axis in XTrackCAD is wrong for cairo. So for
+ * all other print primitives a flip operation is done. As this would
+ * also affect the string orientation, printing a string has to be
+ * treated differently. The starting point is transformed, then the
+ * string is rotated and scaled as needed. Finally the string position
+ * translated to the starting point calculated previously. The same
+ * solution would have to be applied to a bitmap should printing
+ * bitmaps ever be implemented.
+ *
+ * \param x IN x position in pixels
+ * \param y IN y position in pixels
+ * \param a IN angle of baseline in degrees. Positive is clockwise, 0 is direction of positive x axis
+ * \param s IN string to print
+ * \param fp IN font
+ * \param fs IN font size
+ * \param color IN text color
+ * \param opts IN ???
+ * \return
+ */
+
+void psPrintString(
+ wPos_t x, wPos_t y,
+ double a,
+ char * s,
+ wFont_p fp,
+ double fs,
+ wDrawColor color,
+ wDrawOpts opts )
+{
+ char * cp;
+ double x0 = (double)x, y0 = (double)y;
+ double text_height;
+
+ cairo_t *cr;
+ cairo_matrix_t matrix;
+
+ PangoLayout *layout;
+ PangoFontDescription *desc;
+ PangoFontMetrics *metrics;
+ PangoContext *pcontext;
+
+ if (color == wDrawColorWhite)
+ return;
+
+ cr = psPrint_d.printContext;
+
+ // get the current transformation matrix and transform the starting
+ // point of the string
+ cairo_get_matrix( cr, &matrix );
+ cairo_matrix_transform_point( &matrix, &x0, &y0 );
+
+ cairo_save( cr );
+
+ layout = pango_cairo_create_layout( cr );
+
+ // set the correct font and size
+ /** \todo use a getter function instead of double conversion */
+ desc = pango_font_description_from_string (gtkFontTranslate( fp ));
+
+ //don't know why the size has to be reduced to 75% :-(
+ pango_font_description_set_size(desc, fs * PANGO_SCALE *0.75 );
+
+ // render the string to a Pango layout
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, s, -1);
+ pango_layout_set_width (layout, -1);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
+
+ // get the height of the string
+ pcontext = pango_cairo_create_context( cr );
+ metrics = pango_context_get_metrics(pcontext, desc, pango_context_get_language(pcontext));
+ text_height = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE;
+
+ // transform the string to the correct position
+ cairo_identity_matrix( cr );
+
+ cairo_translate( cr, x0 + text_height * sin ( -a * M_PI / 180.0) , y0 - text_height * cos ( a * M_PI / 180.0) );
+ cairo_rotate( cr, -a * M_PI / 180.0 );
+
+ // set the color
+ psSetColor( color );
+
+ // and show the string
+ pango_cairo_show_layout (cr, layout);
+
+ // free unused objects
+ g_object_unref( layout );
+ g_object_unref( pcontext );
+
+ cairo_restore( cr );
+}
+
+/**
+ * Create clipping retangle.
+ *
+ * \param x, y IN starting position
+ * \param w, h IN width and height of rectangle
+ * \return
+ */
+
+void wPrintClip( wPos_t x, wPos_t y, wPos_t w, wPos_t h )
+{
+ cairo_move_to( psPrint_d.printContext, x, y );
+ cairo_rel_line_to( psPrint_d.printContext, w, 0 );
+ cairo_rel_line_to( psPrint_d.printContext, 0, h );
+ cairo_rel_line_to( psPrint_d.printContext, -w, 0 );
+ cairo_close_path( psPrint_d.printContext );
+ cairo_clip( psPrint_d.printContext );
+}
+
+/*****************************************************************************
+ *
+ * PAGE FUNCTIONS
+ *
+ */
+
+/**
+ * Get the paper dimensions and margins and setup the internal variables
+ * \return
+ */
+
+static void
+WlibGetPaperSize( void )
+{
+ double temp;
+
+ bBorder = gtk_page_setup_get_bottom_margin( page_setup, GTK_UNIT_INCH );
+ tBorder = gtk_page_setup_get_top_margin( page_setup, GTK_UNIT_INCH );
+ lBorder = gtk_page_setup_get_left_margin( page_setup, GTK_UNIT_INCH );
+ rBorder = gtk_page_setup_get_right_margin( page_setup, GTK_UNIT_INCH );
+ paperHeight = gtk_page_setup_get_paper_height( page_setup, GTK_UNIT_INCH );
+ paperWidth = gtk_page_setup_get_paper_width( page_setup, GTK_UNIT_INCH );
+
+ // XTrackCAD does page orientation itself. Basic assumption is that the
+ // paper is always oriented in portrait mode. Ignore settings by user
+ if( paperHeight < paperWidth ) {
+ temp = paperHeight;
+ paperHeight = paperWidth;
+ paperWidth = temp;
+ }
+}
+
+/**
+ * Get the paper size. The size returned is the printable area of the
+ * currently selected paper, ie. the physical size minus the margins.
+ * \param w OUT printable width of the paper in inches
+ * \param h OUT printable height of the paper in inches
+ * \return
+ */
+
+void wPrintGetPageSize(
+ double * w,
+ double * h )
+{
+ // if necessary load the settings
+ if( !settings )
+ WlibApplySettings( NULL );
+
+ WlibGetPaperSize();
+
+ *w = paperWidth -lBorder - rBorder;
+ *h = paperHeight - tBorder - bBorder;
+}
+
+/**
+ * Get the paper size. The size returned is the physical size of the
+ * currently selected paper.
+ * \param w OUT physical width of the paper in inches
+ * \param h OUT physical height of the paper in inches
+ * \return
+ */
+
+void wPrintGetPhysSize(
+ double * w,
+ double * h )
+{
+ // if necessary load the settings
+ if( !settings )
+ WlibApplySettings( NULL );
+
+ WlibGetPaperSize();
+
+ *w = paperWidth;
+ *h = paperHeight;
+}
+
+/**
+ * Cancel the current print job. This function is preserved here for
+ * reference in case the function should be implemented again.
+ * \param context IN unused
+ * \return
+ */
+static void printAbort( void * context )
+{
+ printContinue = FALSE;
+// wWinShow( printAbortW, FALSE );
+}
+
+/**
+ * Initialize new page.
+ * The cairo_save() / cairo_restore() cycle was added to solve problems
+ * with a multi page print operation. This might actually be a bug in
+ * cairo but I didn't examine that any further.
+ *
+ * \return print context for the print operation
+ */
+wDraw_p wPrintPageStart( void )
+{
+ pageCount++;
+
+ cairo_save( psPrint_d.printContext );
+
+ return &psPrint_d;
+}
+
+/**
+ * End of page. This function returns the contents of printContinue. The
+ * caller continues printing as long as TRUE is returned. Setting
+ * printContinue to FALSE in an asynchronous handler therefore cleanly
+ * terminates a print job at the end of the page.
+ *
+ * \param p IN ignored
+ * \return always printContinue
+ */
+
+
+wBool_t wPrintPageEnd( wDraw_p p )
+{
+ cairo_show_page( psPrint_d.printContext );
+
+ cairo_restore( psPrint_d.printContext );
+
+ return printContinue;
+}
+
+/*****************************************************************************
+ *
+ * PRINT START/END
+ *
+ */
+
+
+/**
+ * Start a new document
+ *
+ * \param title IN title of document ( name of layout )
+ * \param fTotalPageCount IN number of pages to print (unused)
+ * \param copiesP OUT ???
+ * \return TRUE if successful, FALSE if cancelled by user
+ */
+
+wBool_t wPrintDocStart( const char * title, int fTotalPageCount, int * copiesP )
+{
+ GtkWidget *printDialog;
+ gint res;
+ cairo_surface_type_t surface_type;
+ cairo_matrix_t matrix;
+
+ printDialog = gtk_print_unix_dialog_new( title, GTK_WINDOW(gtkMainW->gtkwin));
+
+ // load the settings
+ WlibApplySettings( NULL );
+
+ // and apply them to the printer dialog
+ gtk_print_unix_dialog_set_settings( (GtkPrintUnixDialog *)printDialog, settings );
+ gtk_print_unix_dialog_set_page_setup( (GtkPrintUnixDialog *)printDialog, page_setup );
+
+ res = gtk_dialog_run( (GtkDialog *)printDialog );
+ if( res == GTK_RESPONSE_OK ) {
+ selPrinter = gtk_print_unix_dialog_get_selected_printer( (GtkPrintUnixDialog *)printDialog );
+
+ if( settings )
+ g_object_unref (settings);
+ settings = gtk_print_unix_dialog_get_settings( (GtkPrintUnixDialog *)printDialog );
+
+ if( page_setup )
+ g_object_unref( page_setup );
+ page_setup = gtk_print_unix_dialog_get_page_setup( (GtkPrintUnixDialog *)printDialog );
+
+ curPrintJob = gtk_print_job_new( title,
+ selPrinter,
+ settings,
+ page_setup );
+
+ psPrint_d.curPrintSurface = gtk_print_job_get_surface( curPrintJob,
+ NULL );
+ psPrint_d.printContext = cairo_create( psPrint_d.curPrintSurface );
+
+ //update the paper dimensions
+ WlibGetPaperSize();
+
+ /* for the file based surfaces the resolution is 72 dpi (see documentation) */
+ surface_type = cairo_surface_get_type( psPrint_d.curPrintSurface );
+ if( surface_type == CAIRO_SURFACE_TYPE_PDF ||
+ surface_type == CAIRO_SURFACE_TYPE_PS ||
+ surface_type == CAIRO_SURFACE_TYPE_SVG )
+ psPrint_d.dpi = 72;
+ else
+ psPrint_d.dpi = (double)gtk_print_settings_get_resolution( settings );
+
+ // in XTrackCAD 0,0 is top left, in cairo bottom left. This is
+ // corrected via the following transformations.
+ // also the translate makes sure that the drawing is rendered
+ // within the paper margins
+
+ cairo_scale( psPrint_d.printContext, 1.0, -1.0 );
+ cairo_translate( psPrint_d.printContext, lBorder * psPrint_d.dpi, -(paperHeight-bBorder) *psPrint_d.dpi );
+
+ WlibSaveSettings( NULL );
+ }
+ gtk_widget_destroy (printDialog);
+
+ if (copiesP)
+ *copiesP = 1;
+
+ printContinue = TRUE;
+
+ if( res != GTK_RESPONSE_OK )
+ return FALSE;
+ else
+ return TRUE;
+}
+
+/**
+ * Callback for job finished event. Destroys the cairo context.
+ *
+ * \param job IN unused
+ * \param data IN unused
+ * \param err IN if != NULL, an error dialog ist displayed
+ * \return
+ */
+
+void
+doPrintJobFinished( GtkPrintJob *job, void *data, GError *err )
+{
+ GtkWidget *dialog;
+
+ cairo_destroy( psPrint_d.printContext );
+ if( err ) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtkMainW->gtkwin),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ err->message);
+ }
+}
+
+/**
+ * Finish the print operation
+ * \return
+ */
+
+void wPrintDocEnd( void )
+{
+ cairo_surface_finish( psPrint_d.curPrintSurface );
+
+ gtk_print_job_send( curPrintJob,
+ doPrintJobFinished,
+ NULL,
+ NULL );
+
+// wWinShow( printAbortW, FALSE );
+}
+
+
+wBool_t wPrintQuit( void )
+{
+ return FALSE;
+}
+
+
+wBool_t wPrintInit( void )
+{
+ return TRUE;
+}
diff --git a/app/wlib/gtklib/psprint.c b/app/wlib/gtklib/psprint.c
deleted file mode 100644
index 8e7cbe6..0000000
--- a/app/wlib/gtklib/psprint.c
+++ /dev/null
@@ -1,1599 +0,0 @@
-/*
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/psprint.c,v 1.5 2009-05-15 18:54:20 m_fischer Exp $
- */
-
-/* XTrkCad - Model Railroad CAD
- * Copyright (C) 2005 Dave Bullis
- *
- * 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 <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <pwd.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#include <math.h>
-#include <locale.h>
-
-#include <stdint.h>
-
-#include <gtk/gtk.h>
-
-#include "gtkint.h"
-#include "wlib.h"
-/* #include "dynarr.h" */
-#include "i18n.h"
-
-#ifndef TRUE
-#define TRUE (1)
-#define FALSE (0)
-#endif
-
-#define MM(m) ((m)/25.4)
-
-/* char * gtkFontTranslate( wFont_p ); */
-extern wDrawColor wDrawColorWhite;
-extern wDrawColor wDrawColorBlack;
-
-/*****************************************************************************
- *
- * MACROS
- *
- */
-
-#define PRINT_COMMAND (0)
-#define PRINT_FILE (1)
-
-#define PRINT_PORTRAIT (0)
-#define PRINT_LANDSCAPE (1)
-
-/* #define MAXIMUM(a,b) ((a)>(b) ? (a) : (b)) */
-#define min(a,b) ((a)<(b) ? (a) : (b))
-#define PPI (72.0)
-#define P2I( P ) ((P)/PPI)
-
-#define DPI (1440.0)
-#define D2I( D ) (((double)(D))/DPI)
-
-#define CENTERMARK_LENGTH 60
-
-#define WFONT "WFONT"
-#define WPRINTER "WPRINTER"
-#define WMARGIN "WMARGIN"
-#define WMARGINMAP "WMARGINMAP"
-#define WPRINTFONT "WPRINTFONT"
-
-/*****************************************************************************
- *
- * VARIABLES
- *
- */
-
-extern struct wDraw_t psPrint_d;
-
-/*
-typedef struct {
- wIndex_t cmdOrFile;
- FILE * f;
- } wPrinterStream_t;
-typedef wPrinterStream_t * wPrinterStream_p;
-*/
-static wBool_t printContinue;
-static wWin_p printAbortW;
-static wMessage_p printAbortT;
-static wMessage_p printAbortM;
-
-static wWin_p printFileW;
-static wWin_p newFontAliasW;
-static wWin_p printSetupW;
-static wList_p optPrinterB;
-static wList_p optPaperSizeB;
-static wMessage_p newFontAliasXFntB;
-static wList_p optMarginB;
-static wButton_p optMarginDelB;
-static wFloat_p optTopMargin;
-static wFloat_p optBottomMargin;
-static wFloat_p optRightMargin;
-static wFloat_p optLeftMargin;
-static wChoice_p optFormat;
-static wList_p optXFontL;
-static wString_p optPSFontS;
-static wFloat_p optFontSizeFactor;
-static long optXFontX;
-static const char * optXFont;
-static char optPSFont[200];
-
-#ifdef LATER
-static char addPrinterName[80];
-static char addPrinterCommand[80];
-static wWin_p addPrinterW;
-static wString_p addPrinterN;
-static wString_p addPrinterC;
-static char addMarginName[80];
-static wWin_p addMarginW;
-static wString_p addMarginN;
-#endif
-
-static FILE * psFile;
-static wPrinterStream_p psFileStream;
-static wIndex_t pageCount;
-static wIndex_t totalPageCount;
-
-static long newPPrinter;
-static long newPPaper;
-static wPrintSetupCallBack_p printSetupCallBack;
-
-static double tBorder;
-static double rBorder;
-static double lBorder;
-static double bBorder;
-
-static long printFormat = PRINT_LANDSCAPE;
-static double currLineWidth = 0;
-
-static long curPrinter = 0;
-static char *sPrintFileName;
-static long curMargin = 0;
-
-static const char * prefName;
-static const char * prefPaper;
-static const char * prefMargin;
-static const char * prefFormat;
-
-static char newMarginName[256];
-
-typedef enum { PS_LT_SOLID, PS_LT_DASH } PS_LT_E;
-static PS_LT_E currentLT = PS_LT_SOLID;
-
-static double fontSizeFactor = 1.0;
-
-static struct {
- const char * name;
- double w, h;
- } papers[] = {
- { "Letter", 8.5, 11.0 },
- { "Legal", 8.5, 14.0 },
- { "Tabloid", 11.0, 17.0 },
- { "Ledger", 17.0, 11.0 },
- { "Fan Fold", 13.2, 11.0 },
- { "Statement", 5.5, 8.5 },
- { "Executive", 7.5, 10.0 },
- { "Folio", 8.27, 13 },
- { "A0", MM(841), MM(1189) },
- { "A1", MM(594), MM(841) },
- { "A2", MM(420), MM(594) },
- { "A3", MM(297), MM(420) },
- { "A4", MM(210), MM(297) },
- { "A5", MM(148), MM(210) },
- { "A6", MM(105), MM(148) },
- { "A7", MM(74), MM(105) },
- { "A8", MM(52), MM(74) },
- { "A9", MM(37), MM(52) },
- { "A10", MM(26), MM(37) },
- { "B0", MM(1000), MM(1414) },
- { "B1", MM(707), MM(1000) },
- { "B2", MM(500), MM(707) },
- { "B3", MM(353), MM(500) },
- { "B4", MM(250), MM(353) },
- { "B5", MM(176), MM(250) },
- { "B6", MM(125), MM(176) },
- { "B7", MM(88), MM(125) },
- { "B8", MM(62), MM(88) },
- { "B9", MM(44), MM(62) },
- { "B10", MM(31), MM(44) },
- { "C0", MM(917), MM(1297) },
- { "C1", MM(648), MM(917) },
- { "C2", MM(458), MM(648) },
- { "C3", MM(324), MM(458) },
- { "C4", MM(229), MM(324) },
- { "C5", MM(162), MM(229) },
- { "C6", MM(114), MM(162) },
- { "C7", MM(81), MM(114) },
- { "DL", MM(110), MM(220) },
- { NULL } };
-wIndex_t curPaper = 0;
-
-typedef struct {
- const char * name;
- const char * cmd;
- wIndex_t class;
- } printers_t;
-dynArr_t printers_da;
-#define printers(N) DYNARR_N(printers_t,printers_da,N)
-
-typedef struct {
- const char * name;
- double t, b, r, l;
- } margins_t;
-dynArr_t margins_da;
-#define margins(N) DYNARR_N(margins_t,margins_da,N)
-
-static void printFileNameSel( void * junk );
-static void printInit( void );
-
-/*
- * Stuff related to determining the list of fonts used in the
- * Postscript file. A simple linked-list is used to implement a
- * stack. Everything is specialized to this application.
- */
-
-/**
- * Nodes of the \a fontsUsed list.
- */
-struct list_node {
- struct list_node *next;
- char *data;
-} ;
-
-/**
- * Pointer to the \a fontsUsed list.
- */
-static struct list_node *fontsUsed = NULL;
-
-
-/**
- * Pushes its argument on to the \a fontsUsed list.
- * \param item - IN pointer to a string to put on the list
- * \return nothing
- */
-void fontsUsedPush( const char *item) {
- struct list_node *newitem;
- newitem = malloc(sizeof(struct list_node));
- if (newitem == NULL) exit (2);
- newitem->next=fontsUsed;
- newitem->data = strdup(item);
- if (newitem->data == NULL) exit(3);
- fontsUsed=newitem;
-}
-
-/**
- * Pops the top node from the \a fontsUsed list.
- * Note that a pointer to the complete node is returned. The
- * caller is responsible for freeing both the data and the list
- * node when it is finished using them.
- * \return pointer to the list node.
- */
-struct list_node * fontsUsedPop() {
- struct list_node *item;
- if (fontsUsed == NULL) return NULL;
- item = fontsUsed;
- fontsUsed = item->next;
- return item ;
-}
-
-/**
- * \a fontsUsed list (re-)initializer.
- */
-void fontsUsedInit() {
- struct list_node *p;
- while ((p=fontsUsedPop()) != NULL) {
- free(p->data);
- free(p);
- }
- fontsUsed=NULL;
-}
-
-/**
- * Checks if \a s is already in \a fontsUsed list.
- * \param s - IN string to be checked.
- * \return TRUE if found, FALSE if not.
- */
-int fontsUsedContains( const char *s ) {
- struct list_node *ptr;
- ptr = fontsUsed;
- while ( ptr != NULL ) {
- if ( strcmp(s, ptr->data) == 0 ) return TRUE;
- ptr= ptr->next;
- }
- return FALSE ;
-}
-
-/**
- * Adds the \a fontName to the list of fonts being used.
- * Only if it is not already in the list.
- *
- * This function should be called anywhere the string "findfont"
- * is being emitted to the Postscript file.
- * \param \a fontName IN - string contaning the name to add.
- */
-void addFontName( const char * fontName){
- if (fontsUsedContains(fontName)) return;
- fontsUsedPush(fontName);
-}
-
-/* ***************************************** */
-
-/**
- * This function does a normal printf but uses the default C
- * locale as decimal separator.
- *
- * \param template IN printf-like format string
- * ... IN parameters according to format string
- * \return describe the return value
- */
-
-static void
-psPrintf (FILE *ps, const char *template, ...)
-{
- va_list ap;
-
- setlocale( LC_NUMERIC, "C" );
-
- va_start( ap, template );
- vfprintf( ps, template, ap );
- va_end( ap );
-
- setlocale( LC_NUMERIC, "" );
-}
-
-void wPrintSetup( wPrintSetupCallBack_p callback )
-{
- printInit();
- newPPrinter = curPrinter;
- newPPaper = curPaper;
- printSetupCallBack = callback;
- wListSetIndex( optPrinterB, newPPrinter );
- wListSetIndex( optPaperSizeB, newPPaper );
- wWinShow( printSetupW, TRUE );
-}
-
-static void pSetupOk( void )
-{
- curPrinter = newPPrinter;
- curPaper = newPPaper;
- wWinShow( printSetupW, FALSE );
- wPrefSetString( "printer", "name", printers(curPrinter).name );
- wPrefSetString( "printer", "paper", papers[curPaper].name );
- if ( curMargin < margins_da.cnt )
- wPrefSetString( "printer", "margin", margins(curMargin).name );
- wPrefSetString( "printer", "format", (printFormat==PRINT_LANDSCAPE?"landscape":"portrait") );
- if (printSetupCallBack)
- printSetupCallBack( TRUE );
- wPrefSetFloat( WPRINTFONT, "factor", fontSizeFactor );
-}
-
-static void pSetupCancel( void )
-{
- wWinShow( printSetupW, FALSE );
- if (printSetupCallBack)
- printSetupCallBack( FALSE );
-}
-
-
-/*****************************************************************************
- *
- * PRINTER LIST MANAGEMENT
- *
- */
-
-
-static wBool_t wPrintNewPrinter(
- const char * name )
-{
- char * cp;
- const char *cpEqual;
-
- printInit();
- DYNARR_APPEND( printers_t, printers_da, 10 );
- cpEqual = strchr( name, '=' );
- if (cpEqual == NULL) {
- printers(printers_da.cnt-1).cmd = strdup( "lpr -P%s" );
- printers(printers_da.cnt-1).name = name;
- } else {
- cp = strdup( name );
- cp[cpEqual-name] = 0;
- printers(printers_da.cnt-1).name = cp;
- printers(printers_da.cnt-1).cmd = cp+(cpEqual-name+1);
- name = cp;
- }
- if (optPrinterB) {
- wListAddValue( optPrinterB, printers(printers_da.cnt-1).name, NULL, (void*)(intptr_t)(printers_da.cnt-1) );
- if ( prefName && strcasecmp( prefName, name ) == 0 ) {
- curPrinter = printers_da.cnt-1;
- wListSetIndex( optPrinterB, curPrinter );
- }
- }
- return TRUE;
-}
-
-
-static void doMarginSel(
- wIndex_t inx,
- const char * name,
- wIndex_t op,
- void * listData,
- void * itemData )
-{
- margins_t * p;
- static margins_t dummy = { "", 0, 0, 0, 0 };
- if ( inx < 0 ) {
- for ( inx=0,p=&margins(0); inx<margins_da.cnt; inx++,p++ ) {
- if ( strcasecmp( name, margins(inx).name ) == 0 )
- break;
- }
- if ( inx >= margins_da.cnt ) {
- strncpy( newMarginName, name, sizeof newMarginName );
- p = &dummy;
- }
- } else {
- p = &margins(inx);
- }
- curMargin = inx;
- tBorder = p->t;
- bBorder = p->b;
- rBorder = p->r;
- lBorder = p->l;
- wFloatSetValue( optTopMargin, tBorder );
- wFloatSetValue( optBottomMargin, bBorder );
- wFloatSetValue( optRightMargin, rBorder );
- wFloatSetValue( optLeftMargin, lBorder );
-}
-
-static wIndex_t wPrintNewMargin(
- const char * name,
- const char * value )
-{
- margins_t * m;
- int rc;
- DYNARR_APPEND( margins_t, margins_da, 10 );
- m = &margins(margins_da.cnt-1);
-
- setlocale( LC_NUMERIC, "C" );
- if ((rc=sscanf( value, "%lf %lf %lf %lf", &m->t, &m->b, &m->r, &m->l ))!=4) {
- margins_da.cnt--;
- setlocale( LC_NUMERIC, "" );
- return FALSE;
- }
- setlocale( LC_NUMERIC, "" );
-
- m->name = strdup( name );
- if (optMarginB)
- wListAddValue( optMarginB, name, NULL, NULL );
- if ( prefMargin && strcasecmp( prefMargin, name ) == 0 ) {
- curMargin = margins_da.cnt-1;
- wListSetIndex( optMarginB, curMargin );
- tBorder = m->t;
- bBorder = m->b;
- rBorder = m->r;
- lBorder = m->l;
- wFloatSetValue( optTopMargin, tBorder );
- wFloatSetValue( optBottomMargin, bBorder );
- wFloatSetValue( optRightMargin, rBorder );
- wFloatSetValue( optLeftMargin, lBorder );
- }
- return TRUE;
-}
-
-
-static void doChangeMargin( void )
-{
- static char marginValue[256];
- margins_t * m;
- sprintf( marginValue, "%0.3f %0.3f %0.3f %0.3f", tBorder, bBorder, rBorder, lBorder );
- if ( curMargin >= margins_da.cnt ) {
- DYNARR_APPEND( margins_t, margins_da, 10 );
- curMargin = margins_da.cnt-1;
- margins(curMargin).name = strdup( newMarginName );
- wListAddValue( optMarginB, margins(curMargin).name, NULL, NULL );
- wListSetIndex( optMarginB, curMargin );
- }
- m = &margins(curMargin);
- m->t = tBorder;
- m->b = bBorder;
- m->r = rBorder;
- m->l = lBorder;
- wPrefSetString( WMARGIN, m->name, marginValue );
-}
-
-
-static void doMarginDelete( void )
-{
- int inx;
- if ( curMargin >= margins_da.cnt || margins_da.cnt <= 1 || curMargin == 0 )
- return;
- wPrefSetString( WMARGIN, margins(curMargin).name, "" );
- free( (char*)margins(curMargin).name );
- for ( inx=curMargin+1; inx<margins_da.cnt; inx++ )
- margins(inx-1) = margins(inx);
- margins_da.cnt--;
- wListDelete( optMarginB, curMargin );
- if ( curMargin >= margins_da.cnt )
- curMargin--;
- doMarginSel( curMargin, margins(curMargin).name, 0, NULL, NULL );
-}
-
-
-static const char * curPsFont = NULL;
-static const char * curXFont = NULL;
-
-
-static void newFontAliasSel( const char * alias, void * data )
-{
- wPrefSetString( WFONT, curXFont, alias );
- curPsFont = wPrefGetString( WFONT, curXFont );
- wWinShow( newFontAliasW, FALSE );
- wListAddValue( optXFontL, curXFont, NULL, NULL );
-}
-
-
-static const char * findPSFont( wFont_p fp )
-{
- const char *f;
- static const char * oldXFont = NULL;
-
- curXFont = gtkFontTranslate(fp);
- if (curXFont != NULL &&
- oldXFont != NULL &&
- strcasecmp(oldXFont, curXFont) == 0 &&
- curPsFont != NULL )
- return curPsFont;
- if (curXFont == NULL)
- return "Times-Roman";
- oldXFont = curXFont;
- printInit();
- f = wPrefGetString( WFONT, curXFont );
- if (f)
- return curPsFont = f;
- wMessageSetValue( newFontAliasXFntB, curXFont );
- wWinShow( newFontAliasW, TRUE );
- return curPsFont;
-}
-
-/*****************************************************************************
- *
- * BASIC PRINTING
- *
- */
-
-static void setLineType(
- double lineWidth,
- wDrawLineType_e lineType,
- wDrawOpts opts )
-{
- PS_LT_E want;
-
- if (lineWidth < 0.0) {
- lineWidth = P2I(-lineWidth)*2.0;
- }
-
- if (lineWidth != currLineWidth) {
- currLineWidth = lineWidth;
- psPrintf( psFile, "%0.3f setlinewidth\n", currLineWidth / (PPI*10) );
- }
-
- if (lineType == wDrawLineDash)
- want = PS_LT_DASH;
- else
- want = PS_LT_SOLID;
- if (want != currentLT) {
- currentLT = want;
- switch (want) {
- case PS_LT_DASH:
- psPrintf( psFile, "[%0.3f %0.3f] 0 setdash\n", P2I(2), P2I(2) );
- break;
- case PS_LT_SOLID:
- psPrintf( psFile, "[] 0 setdash\n" );
- break;
- }
- }
-}
-
-
-void psSetColor(
- wDrawColor color )
-{
- static long currColor = 0;
- long newColor;
-
- newColor = wDrawGetRGB( color );
- if (newColor != currColor) {
- psPrintf( psFile, "%0.3f %0.3f %0.3f setrgbcolor\n",
- (float)((newColor>>16)&0xFF)/256.0,
- (float)((newColor>>8)&0xFF)/256.0,
- (float)((newColor)&0xFF)/256.0 );
- currColor = newColor;
- }
-}
-
-
-void psPrintLine(
- wPos_t x0, wPos_t y0,
- wPos_t x1, wPos_t y1,
- wDrawWidth width,
- wDrawLineType_e lineType,
- wDrawColor color,
- wDrawOpts opts )
-{
- if (color == wDrawColorWhite)
- return;
- if (opts&wDrawOptTemp)
- return;
- psSetColor(color);
- setLineType( width, lineType, opts );
- psPrintf(psFile,
- "%0.3f %0.3f moveto %0.3f %0.3f lineto closepath stroke\n",
- D2I(x0), D2I(y0), D2I(x1), D2I(y1) );
-}
-
-/**
- * Print an arc around a specified center
- *
- * \param x0, y0 IN center of arc
- * \param r IN radius
- * \param angle0, angle1 IN start and end angle
- * \param drawCenter draw marking for center
- * \param width line width
- * \param lineType
- * \param color color
- * \param opts ?
- */
-
-void psPrintArc(
- wPos_t x0, wPos_t y0,
- wPos_t r,
- double angle0,
- double angle1,
- wBool_t drawCenter,
- wDrawWidth width,
- wDrawLineType_e lineType,
- wDrawColor color,
- wDrawOpts opts )
-{
- if (color == wDrawColorWhite)
- return;
- if (opts&wDrawOptTemp)
- return;
- psSetColor(color);
- setLineType(width, lineType, opts);
- if (angle1 >= 360.0)
- angle1 = 359.999;
- angle1 = 90.0-(angle0+angle1);
- while (angle1 < 0.0) angle1 += 360.0;
- while (angle1 >= 360.0) angle1 -= 360.0;
- angle0 = 90.0-angle0;
- while (angle0 < 0.0) angle0 += 360.0;
- while (angle0 >= 360.0) angle0 -= 360.0;
- psPrintf(psFile,
- "newpath %0.3f %0.3f %0.3f %0.3f %0.3f arc stroke\n",
- D2I(x0), D2I(y0), D2I(r), angle1, angle0 );
-
- if( drawCenter ) {
- psPrintf(psFile,
- "%0.3f %0.3f moveto %0.3f %0.3f lineto closepath stroke\n",
- D2I(x0 - CENTERMARK_LENGTH / 2), D2I(y0), D2I(x0 + CENTERMARK_LENGTH / 2), D2I(y0) );
- psPrintf(psFile,
- "%0.3f %0.3f moveto %0.3f %0.3f lineto closepath stroke\n",
- D2I(x0), D2I(y0 - CENTERMARK_LENGTH / 2), D2I(x0), D2I(y0 + CENTERMARK_LENGTH / 2) );
-
- }
-}
-
-
-void psPrintFillRectangle(
- wPos_t x0, wPos_t y0,
- wPos_t x1, wPos_t y1,
- wDrawColor color,
- wDrawOpts opts )
-{
- if (color == wDrawColorWhite)
- return;
- if (opts&wDrawOptTemp)
- return;
- psSetColor(color);
- psPrintf(psFile,
- "%0.3f %0.3f moveto %0.3f %0.3f lineto closepath fill\n",
- D2I(x0), D2I(y0), D2I(x1), D2I(y1) );
-}
-
-
-void psPrintFillPolygon(
- wPos_t p[][2],
- int cnt,
- wDrawColor color,
- wDrawOpts opts )
-{
- int inx;
- if (color == wDrawColorWhite)
- return;
- if (opts&wDrawOptTemp)
- return;
- psSetColor(color);
- psPrintf( psFile, "%0.3f %0.3f moveto ", D2I(p[0][0]), D2I(p[0][1]) );
- for (inx=0; inx<cnt; inx++)
- psPrintf( psFile, "%0.3f %0.3f lineto ", D2I(p[inx][0]), D2I(p[inx][1]) );
- psPrintf( psFile, "closepath fill\n" );
-}
-
-
-void psPrintFillCircle(
- wPos_t x0, wPos_t y0,
- wPos_t r,
- wDrawColor color,
- wDrawOpts opts )
-{
- if (color == wDrawColorWhite)
- return;
- if (opts&wDrawOptTemp)
- return;
- psSetColor(color);
- psPrintf(psFile,
- "newpath %0.3f %0.3f %0.3f 0.0 360.0 arc fill\n",
- D2I(x0), D2I(y0), D2I(r) );
-}
-
-
-void psPrintString(
- wPos_t x, wPos_t y,
- double a,
- char * s,
- wFont_p fp,
- double fs,
- wDrawColor color,
- wDrawOpts opts )
-{
- char * cp;
-
- fs = P2I(fs*fontSizeFactor);
- if (fs < 0.05*72.0/1440.0)
- return;
-#ifdef NOWHITE
- if (color == wDrawColorWhite)
- return;
-#endif
- if (opts&wDrawOptTemp)
- return;
- psSetColor( color );
- setLineType(currLineWidth, wDrawLineSolid, opts);
- psPrintf(psFile,
- "/%s findfont %0.3f scalefont setfont\n"
- "gsave\n"
- "%0.3f %0.3f translate %0.3f rotate 0 0 moveto\n(",
- findPSFont(fp), fs, D2I(x), D2I(y), a );
- addFontName(findPSFont(fp));
- for (cp=s; *cp; cp++) {
- if (*cp == '(' || *cp == ')')
- psPrintf(psFile, "\\" );
- psPrintf(psFile, "%c", *cp);
- }
- psPrintf(psFile, ") show\ngrestore\n" );
-}
-
-void wPrintClip( wPos_t x, wPos_t y, wPos_t w, wPos_t h )
-{
- psPrintf( psFile, "\
-%0.3f %0.3f moveto \n\
-%0.3f %0.3f lineto \n\
-%0.3f %0.3f lineto \n\
-%0.3f %0.3f lineto \n\
-closepath clip newpath\n",
- D2I(x), D2I(y),
- D2I(x+w), D2I(y),
- D2I(x+w), D2I(y+h),
- D2I(x), D2I(y+h) );
-}
-
-/*****************************************************************************
- *
- * PAGE FUNCTIONS
- *
- */
-
-void wPrintGetPageSize(
- double * w,
- double * h )
-{
- printInit();
- if (printFormat == PRINT_LANDSCAPE) {
- *w = papers[curPaper].h - tBorder - bBorder;
- *h = papers[curPaper].w - lBorder - rBorder;
- } else {
- *w = papers[curPaper].w - lBorder - rBorder;
- *h = papers[curPaper].h - tBorder - bBorder;
- }
-}
-
-void wPrintGetPhysSize(
- double * w,
- double * h )
-{
- printInit();
- if (printFormat == PRINT_LANDSCAPE) {
- *w = papers[curPaper].h;
- *h = papers[curPaper].w;
- } else {
- *w = papers[curPaper].w;
- *h = papers[curPaper].h;
- }
-}
-
-
-static void printAbort( void * context )
-{
- printContinue = FALSE;
- wWinShow( printAbortW, FALSE );
-}
-
-/**
- * Initialize new page.
- *
- * \return ???
- */
-wDraw_p wPrintPageStart( void )
-{
- char tmp[80];
-
- if (psFile == NULL)
- return NULL;
-
- pageCount++;
- psPrintf( psFile,
- "%%%%Page: %d %d\n" \
- "save\n" \
- "gsave\n" \
- "0 setlinewidth\n"\
- "1 setlinecap\n",
- pageCount,
- (totalPageCount>0?totalPageCount:pageCount) );
-
- if (printFormat == PRINT_LANDSCAPE) {
- psPrintf(psFile, "%0.3f %0.3f translate -90 rotate\n", lBorder*PPI, (papers[curPaper].h-tBorder)*PPI);
- } else {
- psPrintf(psFile, "%0.3f %0.3f translate 0 rotate\n", lBorder*PPI, bBorder*PPI);
- }
-
- psPrintf( psFile, "%0.1f %0.1f scale\n", PPI, PPI );
-
- psPrintf( psFile, "/Times-Bold findfont %0.3f scalefont setfont\n",
- P2I(16) );
- addFontName("Times-Bold");
- sprintf( tmp, _("Page %d"), pageCount );
- wMessageSetValue( printAbortM, tmp );
- wFlush();
-
- currLineWidth = 0;
- return &psPrint_d;
-}
-
-/**
- * End of page
- *
- * \param p IN ignored
- * \return always printContinue
- */
-
-
-wBool_t wPrintPageEnd( wDraw_p p )
-{
- psPrintf( psFile,
- "grestore\n" \
- "restore\n" \
- "showpage\n"\
- "%%%%EndPage\n");
-
- return printContinue;
-}
-
-/*****************************************************************************
- *
- * PRINT START/END
- *
- */
-
-/**
- * Allow the user to enter a new file name and location for the file.
- * Thanks to Andrew Krause's great book Foundations of GTK+ Development
- * for this code snippet.
- *
- * \param junk IN ignored
- */
-
-static void printFileNameSel( void * junk )
-{
- GtkWidget *dialog;
- gchar *filename;
- gint result;
-
- dialog = gtk_file_chooser_dialog_new (_("Print to file ..."), (GtkWindow *)printSetupW->gtkwin,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
-
- result = gtk_dialog_run (GTK_DIALOG (dialog));
- if (result == GTK_RESPONSE_ACCEPT)
- {
- filename = gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER ( dialog ));
- if( filename ) {
- sPrintFileName = malloc( strlen( filename ) + 1 );
- if( sPrintFileName ) {
- strcpy( sPrintFileName, filename );
- }
- else {
- fputs( "Insufficient memory for printing to file\n", stderr );
- abort();
- }
- g_free( filename );
- }
- }
-
- gtk_widget_destroy (dialog);
-}
-
-
-/*
- * open the printer output stream. In case print to file is selected, the filename for
- * the print out is fetched from the user and the file opened.
- *
- * \return the printer stream
- */
-
-wPrinterStream_p wPrinterOpen( void )
-{
- char * fn;
- char sPrintCmdName[80];
- char tmp[80+8];
- FILE * f;
- wIndex_t cmdOrFile;
- wPrinterStream_p p;
-
- printInit();
- pageCount = 0;
- f = NULL;
- curPsFont = NULL;
- if (curPrinter == 0 ) {
-
- printFileNameSel( NULL );
-
- // did the user cancel the file dialog? If yes, cancel operation
- if( !sPrintFileName ) {
- return( NULL );
- }
- if ( sPrintFileName[0] == '\0' ) {
- wNoticeEx( NT_ERROR, _("No file name specified"), _("Ok"), NULL );
- return NULL;
- }
- if ( access(sPrintFileName, F_OK ) == 0 ) {
- sprintf( tmp, _("%s exists"), sPrintFileName );
- if (!wNoticeEx( NT_INFORMATION, tmp, _("Overwrite"), _("Cancel") ))
- return NULL;
- }
- f = fopen( sPrintFileName, "w" );
- if (f == NULL) {
- strcat( sPrintFileName, _(": cannot open") );
- wNoticeEx( NT_ERROR, sPrintFileName, _("Ok"), NULL );
- return NULL;
- }
- fn = sPrintFileName;
- cmdOrFile = PRINT_FILE;
- } else {
- sprintf( sPrintCmdName, printers(curPrinter).cmd, printers(curPrinter).name );
- f = popen( sPrintCmdName, "w" );
- fn = sPrintCmdName;
- cmdOrFile = PRINT_COMMAND;
- }
- if (f == NULL) {
- strcat( sPrintFileName, _(": cannot open") );
- wNoticeEx( NT_ERROR, sPrintFileName, _("Ok"), NULL );
- return NULL;
- }
- p = (wPrinterStream_p)malloc( sizeof *p );
- p->f = f;
- p->cmdOrFile = cmdOrFile;
- return p;
-}
-
-
-void wPrinterWrite( wPrinterStream_p p, char * buff, int siz )
-{
- fwrite( buff, 1, siz, p->f );
-}
-
-void wPrinterClose( wPrinterStream_p p )
-{
- if (p->cmdOrFile == PRINT_FILE)
- fclose( p->f );
- else
- pclose( p->f );
-
- // free the filename again
- if( sPrintFileName ) {
- free( sPrintFileName );
- sPrintFileName = NULL;
- }
-}
-
-/**
- * Start a new Postscript document
- *
- * Opens the output file and emits the Adobe DSC Prolog comments,
- * etc. Note that the 3.0 in "PS-Adobe-3.0" refers to the
- * version of the Document Structuring Conventions Specification,
- * not to the Postscript language level.
- *
- * \param title IN title of document ( name of layout )
- * \param fTotalPageCount IN number of pages to print
- * \param copiesP OUT ???
- * \return TRUE if successful
- */
-
-wBool_t wPrintDocStart( const char * title, int fTotalPageCount, int * copiesP )
-{
- char tmp[80];
- pageCount = 0;
- totalPageCount = fTotalPageCount;
- psFile = NULL;
- psFileStream = wPrinterOpen();
- if (psFileStream == NULL)
- return FALSE;
- psFile = psFileStream->f;
-
- /* Initialize the list of fonts used */
- fontsUsedInit(); /* in case a document had been
- produced earlier */
-
- psPrintf( psFile,
- "%%!PS-Adobe-3.0\n\
-%%%%DocumentFonts: (atend)\n\
-%%%%Title: %s\n\
-%%%%Creator: XTrackCAD\n\
-%%%%Pages: (atend)\n\
-%%%%BoundingBox: %ld %ld %ld %ld\n\
-%%%%EndComments\n\n\
-%%%%Prolog\n\
-/mp_stm usertime def\n\
-/mp_pgc statusdict begin pagecount end def\n\
-statusdict begin /jobname (<stdin>) def end\n\
-%%%%EndProlog\n", \
- title,
- (long)floor(margins(curMargin).l*72),
- (long)floor(margins(curMargin).b*72),
- (long)floor((papers[curPaper].w-margins(curMargin).r)*72),
- (long)floor((papers[curPaper].h-margins(curMargin).t)*72) );
-
- printContinue = TRUE;
- sprintf( tmp, ("Now printing %s"), title );
- wMessageSetValue( printAbortT, tmp );
- wMessageSetValue( printAbortM, _("Page 1") );
- pageCount = 0;
- wWinShow( printAbortW, TRUE );
- if (copiesP)
- *copiesP = 1;
- return TRUE;
-}
-
-/**
- * Outputs the Adobe Document Structure Comments.
- * These are needed at the
- * end of a Postscript document destined for modern (2012) print
- * spoolers. E.g. CUPS
- */
-
-void wPrintDocEnd( void )
-{
- struct list_node *p;
- int i;
- if (psFile == NULL)
- return;
-
- psPrintf( psFile,
- "%%%%Trailer\n%%%%Pages: %d\n",
- pageCount );
-
- /* Postscript lines are <255 chars so print fonts list 4
- per line
- */
- psPrintf( psFile, "%%%%DocumentFonts: " );
- p = fontsUsed;
- i = 0;
- while ((p=fontsUsedPop()) != NULL) {
- if ((i % 4) == 0 ) psPrintf( psFile, "\n%%%%+ ");
- psPrintf( psFile, " %s", p->data);
- free(p->data);
- free(p);
- i++;
- }
- psPrintf( psFile, "\n");
-
- psPrintf( psFile, "%%%%EOF\n");
- /* Reset the fonts list to empty for the next document.
- */
- fontsUsedInit();
-
- wPrinterClose( psFileStream );
- wWinShow( printAbortW, FALSE );
-}
-
-
-wBool_t wPrintQuit( void )
-{
- return FALSE;
-}
-
-
-static void pLine( double x0, double y0, double x1, double y1 )
-{
- psPrintf( psFile, "%0.3f %0.3f moveto %0.3f %0.3f lineto stroke\n",
- x0, y0, x1, y1 );
-}
-
-/**
- * Generate a test page that helps setting up printer margins.
- */
-
-static void pTestPage( void )
-{
- double w, h;
- long oldPrinter;
- int i, j, k, run;
- double x0, x1, y0, y1;
- const char * psFont, * xFont;
- long curMargin0;
-
- oldPrinter = curPrinter;
- curPrinter = newPPrinter;
- curMargin0 = curMargin;
- curMargin = 0;
- wPrintDocStart( _("Printer Margin Test Page"), 1, NULL );
- wPrintPageStart();
- curMargin = curMargin0;
- w = papers[curPaper].w;
- h = papers[curPaper].h;
- if ( psFile == NULL )
- return;
-
-#define MAXIMUM (100)
-
- psPrintf( psFile, "/Times-Roman findfont 0.06 scalefont setfont\n" );
- addFontName("Times-Roman");
- for ( i=5; i<=MAXIMUM; i+=5 ) {
- x0 = ((double)i)/100;
- pLine( 0.5, x0, w-0.5, x0 );
- pLine( 0.5, h-x0, w-0.5, h-x0 );
- pLine( x0, 0.5, x0, h-0.5 );
- pLine( w-x0, 0.5, w-x0, h-0.5 );
-
- psPrintf( psFile, "%0.3f %0.3f moveto (%0.2f) show\n",
- 1.625 + x0*5 - 0.05, 0.2+MAXIMUM/100.0, x0 );
- pLine( 1.625 + x0*5, (0.2+MAXIMUM/100.0), 1.625 + x0*5, x0 );
- psPrintf( psFile, "%0.3f %0.3f moveto (%0.2f) show\n",
- 1.625 + x0*5 - 0.05, h-(0.2+MAXIMUM/100.0)-0.05, x0 );
- pLine( 1.625 + x0*5, h-(0.2+MAXIMUM/100.0), 1.625 + x0*5, h-x0 );
-
- psPrintf( psFile, "%0.3f %0.3f moveto (%0.2f) show\n",
- (0.2+MAXIMUM/100.0), 1.625 + x0*5-0.020, x0 );
- pLine( (0.2+MAXIMUM/100.0), 1.625 + x0*5, x0, 1.625 + x0*5 );
- psPrintf( psFile, "%0.3f %0.3f moveto (%0.2f) show\n",
- w-(0.2+MAXIMUM/100.0)-0.10, 1.625 + x0*5-0.020, x0 );
- pLine( w-(0.2+MAXIMUM/100.0), 1.625 + x0*5, w-x0, 1.625 + x0*5 );
- }
-
- psPrintf( psFile, "/Times-Bold findfont 0.20 scalefont setfont\n" );
- addFontName("Times-Bold");
- psPrintf( psFile, "%0.3f %0.3f moveto (%s) show\n", 2.0, h-2.0, "Printer Margin Setup" );
- psPrintf( psFile, "/Times-Roman findfont 0.12 scalefont setfont\n" );
- addFontName("Times-Roman");
- psPrintf( psFile, "%0.3f %0.3f moveto (%s) show\n", 2.0, h-2.15,
- "Enter the position of the first visible line for each margin on the Printer Setup dialog");
- if ( curMargin < margins_da.cnt )
- psPrintf( psFile, "%0.3f %0.3f moveto ("
- "Current margins for the %s printer are: Top: %0.3f, Left: %0.3f, Right: %0.3f, Bottom: %0.3f"
- ") show\n", 2.0, h-2.30,
- margins(curMargin).name, margins(curMargin).t, margins(curMargin).l, margins(curMargin).r, margins(curMargin).b );
-
-
- psPrintf( psFile, "/Times-Bold findfont 0.20 scalefont setfont\n" );
- addFontName("Times-Bold");
- psPrintf( psFile, "%0.3f %0.3f moveto (%s) show\n", 2.0, h-3.0, "Font Map" );
- for (i=j=0; 0.2*j < h-5.0 && (psFont = wPrefGetSectionItem( WFONT, &i, &xFont )) != NULL; j++ ) {
- if ( psFont[0] == '\0' ) continue;
- psPrintf( psFile, "/Times-Roman findfont 0.12 scalefont setfont\n" );
- addFontName("Times-Roman");
- psPrintf( psFile, "%0.3f %0.3f moveto (%s -> %s) show\n", 2.0, h-3.15-0.15*j, xFont, psFont );
- psPrintf( psFile, "/%s findfont 0.12 scalefont setfont\n", psFont );
- addFontName(psFont);
- psPrintf( psFile, "%0.3f %0.3f moveto (%s) show\n", 5.5, h-3.15-0.15*j, "ABCD wxyz 0123 -+$!" );
- }
- x0 = 0.5;
- run = TRUE;
- i = 0;
- while (run) {
- x1 = x0 + 0.25;
- if (x1 >= w-0.5) {
- x1 = w-0.5;
- run = FALSE;
- }
- for ( j = 1; j<5; j++ ) {
- y0 = ((double)(i+j))/100;
- for (k=0; k<MAXIMUM/25; k++) {
- pLine( x0, y0+k*0.25, x1, y0+k*0.25 );
- pLine( x0, h-y0-k*0.25, x1, h-y0-k*0.25 );
- }
- }
- x0 += 0.25;
- i += 5;
- if (i >= 25)
- i = 0;
- }
-
- y0 = 0.5;
- run = TRUE;
- i = 0;
- while (run) {
- y1 = y0 + 0.25;
- if (y1 >= h-0.5) {
- y1 = h-0.5;
- run = FALSE;
- }
- for ( j = 1; j<5; j++ ) {
- x0 = ((double)(i+j))/100;
- for (k=0; k<MAXIMUM/25; k++) {
- pLine( x0+k*0.25, y0, x0+k*0.25, y1 );
- pLine( w-x0-k*0.25, y0, w-x0-k*0.25, y1 );
- }
- }
- y0 += 0.25;
- i += 5;
- if (i >= 25)
- i = 0;
- }
-
- /* psPrintf( psFile, "showpage\n"); */
- wPrintPageEnd(NULL);
- wPrintDocEnd();
- curPrinter = oldPrinter;
-}
-
-
-#ifdef LATER
-static void newPrinter( void * context )
-{
- wStringSetValue( addPrinterN, "" );
- wStringSetValue( addPrinterC, "" );
- addPrinterName[0] = 0;
- addPrinterCommand[0] = 0;
- wWinShow( addPrinterW, TRUE );
-}
-
-
-static void addPrinterOk( const char * str, void * context )
-{
- char tmp[80];
- if (strlen(addPrinterName) == 0 || strlen(addPrinterCommand) == 0) {
- wNotice( _("Enter both printer name and command"), _("Ok"), NULL );
- return;
- }
- if (printerDefine)
- printerDefine( addPrinterName, addPrinterCommand );
- else
- wNotice( _("Can not save New Printer definition"), _("Ok"), NULL );
- sprintf( tmp, "%s=%s", addPrinterName, addPrinterCommand );
- wPrintNewPrinter( tmp );
-}
-
-
-static void newMargin( void * context )
-{
- wStringSetValue( addMarginN, "" );
- addMarginName[0] = 0;
- wWinShow( addMarginW, TRUE );
- gtkSetReadonly((wControl_p)optTopMargin,FALSE);
- gtkSetReadonly((wControl_p)optBottomMargin,FALSE);
- gtkSetReadonly((wControl_p)optLeftMargin,FALSE);
- gtkSetReadonly((wControl_p)optRightMargin,FALSE);
-}
-
-
-static void addMarginOk( const char * str, void * context )
-{
- margins_t * m;
- if (strlen(addMarginName) == 0) {
- wNotice( _("Enter printer name"), _("Ok"), NULL );
- return;
- }
- if (marginDefine)
- marginDefine( addMarginName, tBorder, bBorder, rBorder, lBorder );
- else
- wNotice( _("Can not save New Margin definition"), _("Ok"), NULL );
- DYNARR_APPEND( margins_t, margins_da, 10 );
- m = &margins(margins_da.cnt-1);
- m->name = strdup( addMarginName );
- m->t = tBorder;
- m->b = bBorder;
- m->r = rBorder;
- m->l = lBorder;
- wListAddValue( optMarginB, addMarginName, NULL, NULL );
- gtkSetReadonly((wControl_p)optTopMargin,TRUE);
- gtkSetReadonly((wControl_p)optBottomMargin,TRUE);
- gtkSetReadonly((wControl_p)optLeftMargin,TRUE);
- gtkSetReadonly((wControl_p)optRightMargin,TRUE);
-}
-#endif
-
-
-static wLines_t lines[] = {
- { 1, 25, 11, 95, 11 },
- { 1, 95, 11, 95, 111 },
- { 1, 95, 111, 25, 111 },
- { 1, 25, 111, 25, 11 }};
-#ifdef LATER
- { 1, 97, 10, 125, 10 },
- { 1, 160, 10, 177, 10 },
- { 1, 97, 10, 97, 50 },
- { 1, 97, 67, 97, 110 },
- { 1, 177, 10, 177, 50 },
- { 1, 177, 67, 177, 110 },
- { 1, 97, 110, 125, 110 },
- { 1, 160, 110, 177, 110 } };
-#endif
-
-static const char * printFmtLabels[] = { N_("Portrait"), N_("Landscape"), NULL };
-
-static struct {
- const char * xfontname, * psfontname;
- } fontmap[] = {
- { "times-medium-r", "Times-Roman" },
- { "times-medium-i", "Times-Italic" },
- { "times-bold-r", "Times-Bold" },
- { "times-bold-i", "Times-BoldItalic" },
- { "helvetica-medium-r", "Helvetica" },
- { "helvetica-medium-o", "Helvetica-Oblique" },
- { "helvetica-bold-r", "Helvetica-Bold" },
- { "helvetica-bold-o", "Helvetica-BoldOblique" },
- { "courier-medium-r", "Courier" },
- { "courier-medium-o", "Courier-Oblique" },
- { "courier-medium-i", "Courier-Oblique" },
- { "courier-bold-r", "Courier-Bold" },
- { "courier-bold-o", "Courier-BoldOblique" },
- { "courier-bold-i", "Courier-BoldOblique" },
- { "avantgarde-book-r", "AvantGarde-Book" },
- { "avantgarde-book-o", "AvantGarde-BookOblique" },
- { "avantgarde-demi-r", "AvantGarde-Demi" },
- { "avantgarde-demi-o", "AvantGarde-DemiOblique" },
- { "palatino-medium-r", "Palatino-Roman" },
- { "palatino-medium-i", "Palatino-Italic" },
- { "palatino-bold-r", "Palatino-Bold" },
- { "palatino-bold-i", "Palatino-BoldItalic" },
- { "new century schoolbook-medium-r", "NewCenturySchlbk-Roman" },
- { "new century schoolbook-medium-i", "NewCenturySchlbk-Italic" },
- { "new century schoolbook-bold-r", "NewCenturySchlbk-Bold" },
- { "new century schoolbook-bold-i", "NewCenturySchlbk-BoldItalic" },
- { "zapfchancery-medium-i", "ZapfChancery-MediumItalic" } };
-
-static struct {
- const char * name, * value;
- } pagemargins [] = {
- { "None", "0.00 0.00 0.00 0.00" },
- { "BJC-600", "0.10 0.44 0.38 0.13" },
- { "DeskJet", "0.167 0.50 0.25 0.25" },
- { "PaintJet", "0.167 0.167 0.167 0.167" },
- { "DJ505", "0.25 0.668 0.125 0.125" },
- { "DJ560C", "0.37 0.46 0.25 0.25" },
- { "LaserJet", "0.43 0.21 0.43 0.28" } };
-
-
-static void doSetOptXFont(
- wIndex_t inx,
- const char * xFont,
- wIndex_t inx2,
- void * itemData,
- void * listData )
-{
- const char * cp;
- optXFont = xFont;
- cp = wPrefGetString( WFONT, xFont );
- if ( !cp )
- cp = "";
- wStringSetValue( optPSFontS, cp );
-}
-
-
-static void doSetOptPSFont(
- const char * psFont,
- void * data )
-{
- if ( optXFont &&
- psFont[0] )
- wPrefSetString( WFONT, optXFont, psFont );
-}
-
-
-static void printInit( void )
-{
- wIndex_t i;
- wPos_t x, y;
- static wBool_t printInitted = FALSE;
- const char * cp, * cq;
- char num[10];
-
- if (printInitted)
- return;
-
- printInitted = TRUE;
- prefName = wPrefGetString( "printer", "name" );
- prefPaper = wPrefGetString( "printer", "paper" );
- prefMargin = wPrefGetString( "printer", "margin" );
- prefFormat = wPrefGetString( "printer", "format" );
- if (prefFormat && strcasecmp(prefFormat, "landscape") == 0)
- printFormat = PRINT_LANDSCAPE;
- else
- printFormat = PRINT_PORTRAIT;
- wPrefGetFloat( WPRINTFONT, "factor", &fontSizeFactor, 1.0 );
- if ( fontSizeFactor < 0.5 || fontSizeFactor > 2.0 ) {
- fontSizeFactor = 1.0;
- wPrefSetFloat( WPRINTFONT, "factor", fontSizeFactor );
- }
-
- x = wLabelWidth( _("Paper Size") )+4;
- printSetupW = wWinPopupCreate( NULL, 4, 4, "printSetupW", _("Print Setup"), "xvprintsetup", F_AUTOSIZE|F_RECALLPOS, NULL, NULL );
- optPrinterB = wDropListCreate( printSetupW, x, -4, "printSetupPrinter", _("Printer"), 0, 4, 100, &newPPrinter, NULL, NULL );
-#ifdef LATER
- wButtonCreate( printSetupW, -10, 2, "printSetupPrinter", _("New"), 0, 0, newPrinter, NULL );
-#endif
- optPaperSizeB = wDropListCreate( printSetupW, x, -4, "printSetupPaper", _("Paper Size"), 0, 4, 100, &newPPaper, NULL, NULL );
- y = wControlGetPosY( (wControl_p)optPaperSizeB ) + wControlGetHeight( (wControl_p)optPaperSizeB ) + 10;
- for ( i=0; i<sizeof lines / sizeof lines[0]; i++ ) {
- lines[i].x0 += x;
- lines[i].x1 += x;
- lines[i].y0 += y;
- lines[i].y1 += y;
- }
- wLineCreate( printSetupW, NULL, sizeof lines / sizeof lines[0], lines );
- optTopMargin = wFloatCreate( printSetupW, x+35, y, "printSetupMargin", NULL, 0, 50, 0.0, 1.0, &tBorder, (wFloatCallBack_p)doChangeMargin, NULL );
- optLeftMargin = wFloatCreate( printSetupW, x, y+50, "printSetupMargin", _("Margin"), 0, 50, 0.0, 1.0, &lBorder, (wFloatCallBack_p)doChangeMargin, NULL );
- optRightMargin = wFloatCreate( printSetupW, x+70, y+50, "printSetupMargin", NULL, 0, 50, 0.0, 1.0, &rBorder, (wFloatCallBack_p)doChangeMargin, NULL );
- optBottomMargin = wFloatCreate( printSetupW, x+35, y+100, "printSetupMargin", NULL, 0, 50, 0.0, 1.0, &bBorder, (wFloatCallBack_p)doChangeMargin, NULL );
- optMarginB = wDropListCreate( printSetupW, x, -5, "printSetupMargin", NULL, BL_EDITABLE, 4, 100, NULL, doMarginSel, NULL );
- optMarginDelB = wButtonCreate( printSetupW, wControlGetPosX((wControl_p)optMarginB)+wControlGetWidth((wControl_p)optMarginB)+5, wControlGetPosY((wControl_p)optMarginB), "printSetupMarginDelete", "Delete", 0, 0, (wButtonCallBack_p)doMarginDelete, NULL );
-#ifdef LATER
- wButtonCreate( printSetupW, -10, wControlGetPosY((wControl_p)optMarginB), "printSetupMargin", _("New"), 0, 0, newMargin, NULL );
-#endif
- optFormat = wRadioCreate( printSetupW, x, -5, "printSetupFormat", _("Format"), BC_HORZ,
- printFmtLabels, &printFormat, NULL, NULL );
- optXFontL = wDropListCreate( printSetupW, x, -6, "printSetupXFont", _("X Font"), 0, 4, 200, &optXFontX, doSetOptXFont, NULL );
- optPSFontS = wStringCreate( printSetupW, x, -4, "printSetupPSFont", _("PS Font"), 0, 200, optPSFont, 0, doSetOptPSFont, NULL );
- optFontSizeFactor = wFloatCreate( printSetupW, x, -4, "printSetupFontSizeFactor", _("Factor"), 0, 50, 0.5, 2.0, &fontSizeFactor, (wFloatCallBack_p)NULL, NULL );
- y = wControlGetPosY( (wControl_p)optFontSizeFactor ) + wControlGetHeight( (wControl_p)optFontSizeFactor ) + 10;
- x = wControlGetPosX( (wControl_p)optPrinterB ) + wControlGetWidth( (wControl_p)optPrinterB ) + 10;
- wButtonCreate( printSetupW, x, 4, "printSetupOk", _("Ok"), 0, 0, (wButtonCallBack_p)pSetupOk, NULL );
- wButtonCreate( printSetupW, x, -4, "printSetupCancel", _("Cancel"), 0, 0, (wButtonCallBack_p)pSetupCancel, NULL );
- wButtonCreate( printSetupW, x, -14, "printSetupTest", _("Print Test Page"), 0, 0, (wButtonCallBack_p)pTestPage, NULL );
-
-#ifdef LATER
- addPrinterW = wWinPopupCreate( printSetupW, 2, 2, "printSetupPrinter", _("Add Printer"), "xvaddprinter", F_AUTOSIZE|F_RECALLPOS, NULL, NULL );
- addPrinterN = wStringCreate( addPrinterW, 100, -3, "printSetupPrinter",
- _("Name: "), 0, 150, addPrinterName, sizeof addPrinterName,
- addPrinterOk, NULL );
- addPrinterC = wStringCreate( addPrinterW, 100, -3, "printSetupPrinter",
- _("Command: "), 0, 150, addPrinterCommand, sizeof addPrinterCommand,
- addPrinterOk, NULL );
-
- addMarginW = wWinPopupCreate( printSetupW, 2, 2, "printSetupMargin", _("Add Margin"), "xvaddmargin", F_AUTOSIZE|F_RECALLPOS, NULL, NULL );
- addMarginN = wStringCreate( addMarginW, 100, -3, "printSetupMargin",
- _("Name: "), 0, 150, addMarginName, sizeof addMarginName,
- addMarginOk, NULL );
-#endif
-
- printFileW = wWinPopupCreate( printSetupW, 2, 2, "printFileNameW", _("Print To File"), "xvprinttofile", F_BLOCK|F_AUTOSIZE|F_RECALLPOS, NULL, NULL );
- wStringCreate( printFileW, 100, 3, "printFileName",
- _("File Name? "), 0, 150, sPrintFileName, sizeof sPrintFileName,
- NULL, NULL );
- wButtonCreate( printFileW, -4, 3, "printFileNameOk", _("Ok"), BB_DEFAULT, 0, printFileNameSel, NULL );
-
- newFontAliasW = wWinPopupCreate( printSetupW, 2, 2, "printFontAliasW", _("Font Alias"), "xvfontalias", F_BLOCK|F_AUTOSIZE|F_RECALLPOS, NULL, NULL );
- wMessageCreate( newFontAliasW, 0, 0, NULL, 200, _("Enter a post-script font name for:") );
- newFontAliasXFntB = wMessageCreate( newFontAliasW, 0, -3, NULL, 200, "" );
- wStringCreate( newFontAliasW, 0, -3, "printFontAlias", NULL, 0, 200, NULL, 0, newFontAliasSel, NULL );
-
- for (i=0; papers[i].name; i++ ) {
- wListAddValue( optPaperSizeB, papers[i].name, NULL, (void*)(intptr_t)i );
- if ( prefPaper && strcasecmp( prefPaper, papers[i].name ) == 0 ) {
- curPaper = i;
- wListSetIndex( optPaperSizeB, i );
- }
- }
-
- printAbortW = wWinPopupCreate( printSetupW, 2, 2, "printAbortW", _("Printing"), "xvprintabort", F_AUTOSIZE|F_RECALLPOS, NULL, NULL );
- printAbortT = wMessageCreate( printAbortW, 0, 0, "printAbortW", 200, _("Now printing") );
- printAbortM = wMessageCreate( printAbortW, 0, -4, "printAbortW", 200, NULL );
- wButtonCreate( printAbortW, 0, 80, "printAbortW", _("Abort Print"), 0, 0, printAbort, NULL );
-
- for (i=0;i<sizeof fontmap/sizeof fontmap[0]; i++) {
- cp = wPrefGetString( WFONT, fontmap[i].xfontname );
- if (!cp)
- wPrefSetString( WFONT, fontmap[i].xfontname, fontmap[i].psfontname );
- }
-
- cp = wPrefGetString( WPRINTER, "1" );
- if (!cp)
- wPrefSetString( WPRINTER, "1", "lp=lpr -P%s" );
- wPrintNewPrinter( "FILE" );
- for (i=1; ;i++) {
- sprintf( num, "%d", i );
- cp = wPrefGetString( WPRINTER, num );
- if (!cp)
- break;
- wPrintNewPrinter(cp);
- }
-
- for (i=0;i<sizeof pagemargins/sizeof pagemargins[0]; i++) {
- cp = wPrefGetString( WMARGIN, pagemargins[i].name );
- if (!cp)
- wPrefSetString( WMARGIN, pagemargins[i].name, pagemargins[i].value );
- sprintf( num, "%d", i );
- wPrefSetString( WMARGINMAP, num, pagemargins[i].name );
- }
- for (i=0; (cq = wPrefGetSectionItem( WMARGIN, &i, &cp )); ) {
- wPrintNewMargin(cp, cq);
- }
-
- for ( i=0, optXFont=NULL; wPrefGetSectionItem( WFONT, &i, &cp ); ) {
- if ( optXFont == NULL )
- optXFont = cp;
- wListAddValue( optXFontL, cp, NULL, NULL );
- }
- wListSetIndex( optXFontL, 0 );
- if ( optXFont ) {
- cp = wPrefGetString( WFONT, optXFont );
- wStringSetValue( optPSFontS, cp );
- }
-
-}
-
-
-wBool_t wPrintInit( void )
-{
- return TRUE;
-}
-
-/*****************************************************************************
- *
- * TEST
- *
- */
-
-#ifdef TEST
-
-void main ( INT_T argc, char * argv[] )
-{
- if (argc != 7) {
- fprintf( stderr, "%s <L|P> <origX> <origY> <roomSizeX> <roomSizeY>\n", argv[0] );
- exit(1);
- }
- argv++;
- printFormat = (*(*argv++)=='L')?PRINT_LANDSCAPE:PRINT_PORTRAIT;
- printDraw_d.orig.x = atof(*argv++);
- printDraw_d.orig.y = atof(*argv++);
- printRoomSize.x = atof(*argv++);
- printRoomSize.y = atof(*argv++);
- fprintf( stderr, "Fmt=%c, orig=(%0.3f %0.3f) RS=(%0.3f %0.3f)\n",
- (printFormat==PRINT_LANDSCAPE)?'L':'P',
- printDraw_d.orig.x, printDraw_d.orig.y,
- printRoomSize.x, printRoomSize.y );
- wPrintGetPageSize(PRINT_GAUDY, printFormat);
- fprintf( stderr, "PageSize= (%0.3f %0.3f)\n", printDraw_d.size.x, printDraw_d.size.y );
-
- wPrintDocStart( PRINT_GAUDY );
- wPrintPage( PRINT_GAUDY, 0, 0 );
- wPrintDocEnd( );
-}
-
-#endif
diff --git a/app/wlib/gtklib/wpref.c b/app/wlib/gtklib/wpref.c
index b79c8d2..4df3de9 100644
--- a/app/wlib/gtklib/wpref.c
+++ b/app/wlib/gtklib/wpref.c
@@ -66,8 +66,8 @@ EXPORT const char * wGetAppLibDir( void )
* The search order is:
* 1. Directory specified by the XTRKCADLIB environment variable
* 2. Directory specified by XTRKCAD_INSTALL_PREFIX/share/xtrkcad
- * 3. /usr/lib/xtrkcad
- * 4. /usr/local/lib/xtrkcad
+ * 3. /usr/share/xtrkcad
+ * 4. /usr/local/share/xtrkcad
*
* \return pointer to directory name
*/
@@ -102,13 +102,13 @@ EXPORT const char * wGetAppLibDir( void )
}
#endif
- strcpy( appLibDir, "/usr/lib/" );
+ strcpy( appLibDir, "/usr/share/" );
strcat( appLibDir, wAppName );
if ((stat( appLibDir, &buf) == 0 ) && S_ISDIR( buf.st_mode)) {
return appLibDir;
}
- strcpy( appLibDir, "/usr/local/lib/" );
+ strcpy( appLibDir, "/usr/local/share/" );
strcat( appLibDir, wAppName );
if ((stat( appLibDir, &buf) == 0 ) && S_ISDIR( buf.st_mode)) {
return appLibDir;
@@ -118,8 +118,8 @@ EXPORT const char * wGetAppLibDir( void )
_("The required configuration files could not be located in the expected location.\n\n"
"Usually this is an installation problem. Make sure that these files are installed in either \n"
" %s/share/xtrkcad or\n"
- " /usr/lib/%s or\n"
- " /usr/local/lib/%s\n"
+ " /usr/share/%s or\n"
+ " /usr/local/share/%s\n"
"If this is not possible, the environment variable %s must contain "
"the name of the correct directory."),
XTRKCAD_INSTALL_PREFIX, wAppName, wAppName, envvar );
diff --git a/app/wlib/include/wlib.h b/app/wlib/include/wlib.h
index 4582231..cf8f337 100644
--- a/app/wlib/include/wlib.h
+++ b/app/wlib/include/wlib.h
@@ -1,20 +1,21 @@
/** \file wlib.h
- * Commaon definitions and declarations for the wlib library
- *
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/include/wlib.h,v 1.18 2010-04-28 04:04:39 dspagnol Exp $
+ * Common definitions and declarations for the wlib library
*/
#ifndef WIN_H
#define WIN_H
#ifdef WINDOWS
#include <stdio.h>
+#define FILE_SEP_CHAR "\\"
+#else
+#define FILE_SEP_CHAR "/"
#endif
#ifdef USE_SIMPLE_GETTEXT
char *bindtextdomain( char *domainname, char *dirname );
char *bind_textdomain_codeset(char *domainname, char *codeset );
char *textdomain( char *domainname );
-char *gettext( char *msgid );
+char *gettext( const char *msgid );
char *g_win32_getlocale (void);
#endif
@@ -331,6 +332,7 @@ void wListSetEditable( wList_p, wBool_t );
wIndex_t wListAddValue( wList_p, const char *, wIcon_p, void * );
void wListDelete( wList_p, wIndex_t );
wIndex_t wListGetValues( wList_p, char *, int, void * *, void * * );
+void wListSelectAll( wList_p bl );
wIndex_t wListGetCount( wList_p );
void * wListGetItemContext( wList_p, wIndex_t );
wBool_t wListGetItemSelected( wList_p, wIndex_t );
@@ -638,16 +640,18 @@ void wAttachAccelKey( wAccelKey_e, int, wAccelKeyCallBack_p, void * );
* File Selection
*/
+#define FS_MULTIPLEFILES 1
+
struct wFilSel_t;
typedef enum {
FS_SAVE,
FS_LOAD,
FS_UPDATE }
wFilSelMode_e;
-typedef int (*wFilSelCallBack_p)( const char * pathName, const char * fileName, void * );
+typedef int (*wFilSelCallBack_p)( int files, char ** fileName, void * );
struct wFilSel_t * wFilSelCreate(wWin_p, wFilSelMode_e, int, const char *, const char *,
wFilSelCallBack_p, void * );
-int wFilSelect( struct wFilSel_t *, const char * );
+int wFilSelect( struct wFilSel_t *, const char * );
/*------------------------------------------------------------------------------
diff --git a/app/wlib/mswlib/mswbutt.c b/app/wlib/mswlib/mswbutt.c
index b5d7b49..24e669f 100644
--- a/app/wlib/mswlib/mswbutt.c
+++ b/app/wlib/mswlib/mswbutt.c
@@ -257,7 +257,7 @@ static void buttDone(
free(b);
}
-long FAR PASCAL _export pushButt(
+LRESULT CALLBACK pushButt(
HWND hWnd,
UINT message,
UINT wParam,
@@ -301,9 +301,10 @@ long FAR PASCAL _export pushButt(
InvalidateRect( b->hWnd, NULL, TRUE );
return 0L;
break;
- case WM_ERASEBKGND:
- if (kludge12)
- return 1L;
+ case WM_LBUTTONUP:
+ /* don't know why but this solves a problem with color selection */
+ Sleep( 0 );
+ break;
}
return CallWindowProc( oldButtProc, hWnd, message, wParam, lParam );
}
@@ -372,9 +373,8 @@ wButton_p wButtonCreate(
b->action = action;
mswCallBacks[B_BUTTON] = &buttonCallBacks;
mswChainFocus( (wControl_p)b );
- newButtProc = MakeProcInstance( (XWNDPROC)pushButt, mswHInst );
- oldButtProc = (XWNDPROC)GetWindowLong( b->hWnd, GWL_WNDPROC );
- SetWindowLong( b->hWnd, GWL_WNDPROC, (LONG)newButtProc );
+
+ oldButtProc = (WNDPROC) SetWindowLongPtr(b->hWnd, GWL_WNDPROC, (LONG_PTR)&pushButt);
if (mswPalette) {
hDc = GetDC( b->hWnd );
SelectPalette( hDc, mswPalette, 0 );
diff --git a/app/wlib/mswlib/mswlist.c b/app/wlib/mswlib/mswlist.c
index 968624a..18fa92d 100644
--- a/app/wlib/mswlib/mswlist.c
+++ b/app/wlib/mswlib/mswlist.c
@@ -285,6 +285,39 @@ void wListDelete(
}
+/**
+ * Select all items in list.
+ *
+ * \param bl IN list handle
+ * \return
+ */
+
+void wListSelectAll( wList_p bl )
+{
+ wIndex_t inx;
+ listData *ldp;
+
+ // mark all items selected
+ SendMessage( bl->hWnd,
+ LB_SETSEL,
+ (WPARAM)TRUE,
+ (DWORD)-1L );
+
+ // and synchronize the internal data structures
+ wListGetCount(bl);
+ for ( inx=0; inx<bl->count; inx++ ) {
+ ldp = (listData*)SendMessage( bl->hWnd,
+ (bl->type==B_LIST?LB_GETITEMDATA:CB_GETITEMDATA),
+ inx, 0L );
+ ldp->selected = TRUE;
+ SendMessage( bl->hWnd,
+ (UINT)bl->type==B_LIST?LB_SETITEMDATA:CB_SETITEMDATA,
+ (WPARAM)inx,
+ (DWORD)ldp );
+ }
+}
+
+
wIndex_t wListGetCount(
wList_p bl )
{
@@ -333,6 +366,8 @@ wIndex_t wListGetSelectedCount(
}
+
+
wIndex_t wListAddValue(
wList_p b,
const char * value,
diff --git a/app/wlib/mswlib/mswmenu.c b/app/wlib/mswlib/mswmenu.c
index 15053a2..de49742 100644
--- a/app/wlib/mswlib/mswmenu.c
+++ b/app/wlib/mswlib/mswmenu.c
@@ -1,3 +1,26 @@
+/** \file mswmenu.c
+ * Pulldown menu creation and handling
+ * \todo Code for accelerator keys was copied and pasted, replace with utility function
+ */
+
+/* XTrkCad - Model Railroad CAD
+ * Copyright (C) (C) 2005 Dave Bullis
+ *
+ * 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.
+ */
+
#define OEMRESOURCE
#include <windows.h>
@@ -9,6 +32,7 @@
#include <ctype.h>
#include <assert.h>
#include "mswint.h"
+#include "i18n.h"
/*
*****************************************************************************
@@ -834,6 +858,11 @@ wMenuToggle_p wMenuToggleCreate(
{
wMenuToggle_p mt;
int rc;
+ char label[80];
+ char *cp;
+ char ac;
+ UINT vk;
+ long modifier;
mt = (wMenuToggle_p)createMenuItem( m, M_TOGGLE, helpStr, labelStr, sizeof *mt );
/*setAcclKey( m->parent, m->menu, mt->menu_item, acclKey );*/
@@ -842,7 +871,47 @@ wMenuToggle_p wMenuToggleCreate(
mt->mparent = m;
mt->enabled = TRUE;
mt->parentMenu = m;
- rc = AppendMenu( m->menu, MF_STRING, mt->index, labelStr );
+ strcpy( label, mt->labelStr );
+ modifier = 0;
+
+ if ( acclKey != 0 ) {
+ DYNARR_APPEND( acclTable_t, acclTable_da, 10 );
+ cp = label + strlen( label );
+ *cp++ = '\t';
+ if (acclKey & WCTL ) {
+ strcpy( cp, _("Ctrl+") );
+// cp += 5;
+ modifier |= WKEY_CTRL;
+ }
+ if (acclKey & WALT ) {
+ strcpy( cp, _("Alt+") );
+// cp += 4;
+ modifier |= WKEY_ALT;
+ }
+ if (acclKey & WSHIFT ) {
+ strcpy( cp, _("Shift+") );
+// cp += 6;
+ modifier |= WKEY_SHIFT;
+ }
+ cp = label + strlen( label );
+ if( ((char)acclKey & 0xFF ) == ' ' ) {
+ strcat( label, _("Space") );
+ } else {
+ *cp++ = toupper( (char)(acclKey & 0xFF) );
+ *cp++ = '\0';
+ }
+ ac = (char)(acclKey & 0xFF);
+ if (isalpha(ac)) {
+ ac = tolower( ac );
+ }
+ vk = VkKeyScan( ac );
+ if ( vk & 0xFF00 )
+ modifier |= WKEY_SHIFT;
+ acclTable(acclTable_da.cnt-1).acclKey = (modifier<<8) | (vk&0x00FF);
+ acclTable(acclTable_da.cnt-1).mp = mt;
+ }
+
+ rc = AppendMenu( m->menu, MF_STRING, mt->index, label );
wMenuToggleSet( mt, set );
return mt;
}
diff --git a/app/wlib/mswlib/mswmisc.c b/app/wlib/mswlib/mswmisc.c
index fc1dbe6..85438e0 100644
--- a/app/wlib/mswlib/mswmisc.c
+++ b/app/wlib/mswlib/mswmisc.c
@@ -1,7 +1,5 @@
/** \file mswmisc.c
* Basic windows functions and main entry point for application.
- *
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/mswlib/mswmisc.c,v 1.28 2010-04-28 04:04:38 dspagnol Exp $
*/
/* XTrkCad - Model Railroad CAD
@@ -2003,13 +2001,26 @@ static char selFileName[1024];
static char selFileTitle[1024];
static char sysDirName[1024];
+/**
+ * Run the file selector. After the selector is finished an array of filenames is
+ * created. Each filename will be fully qualified. The array and the number of
+ * filenames are passed to a callback function. This is similar to the argc argv c
+ * convention in C. Once the callback returns, the allocated strings are free'd.
+ *
+ * \param fs IN the file selector dialog
+ * \param dirName IN the initial directory presented
+ * \return FALSE on error, TRUE if ok
+ */
+
int wFilSelect(
struct wFilSel_t * fs,
const char * dirName )
{
int rc;
OPENFILENAME ofn;
- char * fileName;
+ char **fileName;
+ char *nextFileName;
+ int cntFiles;
const char * ext;
char defExt[4];
int i;
@@ -2024,7 +2035,7 @@ int wFilSelect(
ofn.hwndOwner = mswHWnd;
ofn.lpstrFilter = fs->extList;
ofn.nFilterIndex = 0;
- selFileName[0] = '\0';
+ memset( selFileName, '\0', sizeof(selFileName));
ofn.lpstrFile = selFileName;
ofn.nMaxFile = sizeof selFileName;
selFileTitle[0] = '\0';
@@ -2041,7 +2052,13 @@ int wFilSelect(
defExt[0] = '\0';
}
ofn.lpstrDefExt = defExt;
- ofn.Flags |= OFN_LONGFILENAMES;
+
+ if ( fs->option & FS_MULTIPLEFILES ) {
+ ofn.Flags = OFN_ALLOWMULTISELECT | OFN_LONGFILENAMES | OFN_EXPLORER;
+ } else {
+ ofn.Flags = OFN_LONGFILENAMES;
+ }
+
if (fs->mode == FS_LOAD) {
ofn.Flags |= OFN_FILEMUSTEXIST;
rc = GetOpenFileName( &ofn );
@@ -2054,12 +2071,37 @@ int wFilSelect(
return FALSE;
if (!rc)
return FALSE;
- fileName = strrchr( selFileName, '\\' );
- if (fileName == NULL) {
- mswFail( "wFilSelect: cant extract fileName" );
- return FALSE;
+
+ nextFileName = selFileName;
+ selFileName[ofn.nFileOffset - 1] = '\0';
+ cntFiles = 0;
+
+ while (*nextFileName) {
+ cntFiles++;
+ nextFileName = nextFileName + strlen( nextFileName ) + 1;
+ }
+
+ // strings were counted including the path on its own so reduce the count
+ cntFiles--;
+
+ // build up the array of filenames
+ fileName = malloc(sizeof(nextFileName) * cntFiles);
+ nextFileName = selFileName + ofn.nFileOffset;
+ for ( i=0; i < cntFiles; i++) {
+ fileName[ i ] = malloc(strlen(selFileName) + strlen(nextFileName) + 2 );
+ strcpy(fileName[ i ], selFileName);
+ strcat(fileName[ i ], FILE_SEP_CHAR);
+ strcat(fileName[ i ], nextFileName);
+ nextFileName = nextFileName + strlen( nextFileName ) + 1;
}
- fs->action( selFileName, fileName+1, fs->data );
+
+ fs->action( cntFiles, fileName, fs->data );
+
+ for (i=0; i < cntFiles; i++) {
+ free( fileName[ i ] );
+ }
+ free( fileName );
+
return TRUE;
}
diff --git a/app/wlib/mswlib/simple-gettext.c b/app/wlib/mswlib/simple-gettext.c
index 295d515..d213fc3 100644
--- a/app/wlib/mswlib/simple-gettext.c
+++ b/app/wlib/mswlib/simple-gettext.c
@@ -1,4 +1,5 @@
-/* simple-gettext.c - a simplified version of gettext.
+/* \file simple-gettext.c
+ * a simplified version of gettext.
* Copyright (C) 1995, 1996, 1997, 1999,
* 2005 Free Software Foundation, Inc.
*
@@ -378,7 +379,7 @@ get_string( struct loaded_domain *domain, u32 idx )
*/
char *
-gettext( char *msgid )
+gettext( const char *msgid )
{
struct loaded_domain *domain;
size_t act = 0;
@@ -446,7 +447,7 @@ gettext( char *msgid )
}
not_found:
- return msgid;
+ return (char *)msgid;
}
/**