diff options
Diffstat (limited to 'app/wlib/gtklib')
| -rw-r--r-- | app/wlib/gtklib/.directory | 7 | ||||
| -rw-r--r-- | app/wlib/gtklib/CMakeLists.txt | 14 | ||||
| -rw-r--r-- | app/wlib/gtklib/FindGTKUnixPrint.cmake | 49 | ||||
| -rw-r--r-- | app/wlib/gtklib/filesel.c | 64 | ||||
| -rw-r--r-- | app/wlib/gtklib/gtkcolor.c | 2 | ||||
| -rw-r--r-- | app/wlib/gtklib/gtkdraw-cairo.c | 118 | ||||
| -rw-r--r-- | app/wlib/gtklib/gtkdraw.c | 1044 | ||||
| -rw-r--r-- | app/wlib/gtklib/gtkfont.c | 88 | ||||
| -rw-r--r-- | app/wlib/gtklib/gtkint.h | 42 | ||||
| -rw-r--r-- | app/wlib/gtklib/gtklist.c | 70 | ||||
| -rw-r--r-- | app/wlib/gtklib/gtkmenu.c | 2 | ||||
| -rw-r--r-- | app/wlib/gtklib/gtktext.c | 308 | ||||
| -rw-r--r-- | app/wlib/gtklib/gtkxpm.c | 90 | ||||
| -rw-r--r-- | app/wlib/gtklib/print.c | 858 | ||||
| -rw-r--r-- | app/wlib/gtklib/psprint.c | 1599 | ||||
| -rw-r--r-- | app/wlib/gtklib/wpref.c | 12 | 
16 files changed, 1438 insertions, 2929 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 );  | 
