diff options
author | tailor <tailor@blob.baaderstrasse.com> | 2005-07-02 08:14:26 +0000 |
---|---|---|
committer | tailor <tailor@blob.baaderstrasse.com> | 2005-07-02 08:14:26 +0000 |
commit | 66a6fc5089dce6ddd55e9384c38685aa338a9912 (patch) | |
tree | 40b72f244df0db178e18c54aa1eca6d6a10b4289 /src |
Tailorization of flpsed
Import of the upstream sources from
Repository: /home/cvs
Module: flpsed
Revision: 2004-06-25 18:14:05 by hofmann
Diffstat (limited to 'src')
-rw-r--r-- | src/GsWidget.H | 77 | ||||
-rw-r--r-- | src/GsWidget.cxx | 215 | ||||
-rw-r--r-- | src/PSEditWidget.H | 93 | ||||
-rw-r--r-- | src/PSEditWidget.cxx | 427 | ||||
-rw-r--r-- | src/flpsed.cxx | 259 |
5 files changed, 1071 insertions, 0 deletions
diff --git a/src/GsWidget.H b/src/GsWidget.H new file mode 100644 index 0000000..77a4e88 --- /dev/null +++ b/src/GsWidget.H @@ -0,0 +1,77 @@ +// +// "$Id: GsWidget.H,v 1.1.1.1 2004/06/21 18:05:58 hofmann Exp $" +// +// X11 header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 2004 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#ifndef GsWidget_H +#define GsWidget_H + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <stdlib.h> + +#include <FL/Fl.H> +#include <FL/Fl_Window.H> +#include <FL/x.H> + + +class GsWidget : public Fl_Widget { + int gs_win; + Atom atoms[5]; + pid_t gs_pid; + int display_x, display_y; + int in_fd; + +protected: + int page; + Fl_Offscreen offscreen; + float xdpi, ydpi; + int paper_x, paper_y; + + void draw(); + +public: + GsWidget(int X,int Y,int W, int H); + + ~GsWidget(); + + int load(char *f); + + int load(int fd); + + int reload(); + + int next(); + + int handleX11(int ev); + + int get_page(); + +private: + void setProps(); + + void kill_gs(); + + bool gs_active(); +}; +#endif diff --git a/src/GsWidget.cxx b/src/GsWidget.cxx new file mode 100644 index 0000000..c781ea2 --- /dev/null +++ b/src/GsWidget.cxx @@ -0,0 +1,215 @@ +// +// "$Id: GsWidget.cxx,v 1.4 2004/06/25 18:14:05 hofmann Exp $" +// +// GsWidget routines. +// +// Copyright 2004 by Johannes Hofmann. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <errno.h> +#include <sys/wait.h> +#include <fcntl.h> + +#include <FL/fl_draw.H> + +#include "GsWidget.H" + + +void GsWidget::draw() { + if (!offscreen) { + offscreen = fl_create_offscreen(w(), h()); + fl_begin_offscreen(offscreen); + fl_color(FL_WHITE); + fl_rectf(0, 0, w(), h()); + fl_end_offscreen(); + } + fl_push_clip(x(), y(), w(), h()); + fl_copy_offscreen(x(), y(), w(), h(), offscreen, 0, 0); + fl_pop_clip(); +} + +void GsWidget::setProps() { + char data[512]; + int gs_win; + + if (!offscreen) { + offscreen = fl_create_offscreen(w(), h()); + } + + atoms[0] = XInternAtom(fl_display,"GHOSTVIEW" , false); + atoms[1] = XInternAtom(fl_display,"GHOSTVIEW_COLORS" , false); + atoms[2] = XInternAtom(fl_display,"NEXT" , false); + atoms[3] = XInternAtom(fl_display,"PAGE" , false); + atoms[4] = XInternAtom(fl_display,"DONE" , false); + + snprintf(data, 512, "%lu %d %d %d %d %d %g %g", + 0, 0, 0, 0, paper_x, paper_y, + xdpi, ydpi,0,0,0,0 ); + + int xid = fl_xid(window()); + + XChangeProperty(fl_display, xid, atoms[0], + XA_STRING, 8, PropModeReplace, + (unsigned char*) data, strlen(data)); + + snprintf(data, 512, "%s %d %d", "Color", 0, 65535); + + XChangeProperty(fl_display, xid, atoms[1], + XA_STRING, 8, PropModeReplace, + (unsigned char*) data, strlen(data)); +} + +void GsWidget::kill_gs() { + int status; + + if (gs_pid > 0) { + kill(gs_pid, SIGTERM); + waitpid(gs_pid, &status, 0); + gs_pid = 0; + } +} + +bool GsWidget::gs_active() { + return gs_pid > 0 && gs_win; +} + +GsWidget::GsWidget(int X,int Y,int W, int H) : Fl_Widget(X, Y, W, H) { + int w, h; + offscreen = 0; + gs_pid = 0; + page = 0; + xdpi = 75.0; + ydpi = 75.0; + paper_x = 594; // DIN A4 + paper_y = 841; // + in_fd = -1; +} + +GsWidget::~GsWidget() { + kill_gs(); + if (offscreen) { + fl_delete_offscreen(offscreen); + } +} + +int GsWidget::load(char *f) { + int fd = open(f, O_RDONLY); + if (fd == -1) { + fprintf(stderr, "Could not open file %s (errno %d).\n", f, errno); + return 1; + } + return load(fd); +} + +int GsWidget::load(int fd) { + if (in_fd >= 0 && fd != in_fd) { + close (in_fd); + } + + in_fd = fd; + + fl_cursor(FL_CURSOR_WAIT); + kill_gs(); + setProps(); + + pid_t pid = fork(); + if (pid == (pid_t) 0) { + char *argv[16]; + char gvenv[256]; + int d_null = open("/dev/null", O_WRONLY); + + dup2(d_null, STDOUT_FILENO); + close(d_null); + dup2(in_fd, STDIN_FILENO); + snprintf(gvenv, 256, "%d %d", fl_xid(window()), offscreen); + + setenv("GHOSTVIEW", gvenv, 1); + argv[0] = "gs"; + argv[1] = "-dSAFER"; + argv[2] = "-dQUIET"; + argv[3] = "-sDEVICE=x11alpha"; + argv[4] = "-sPAPERSIZE=a4"; + argv[5] = "-dNOPLATFONTS"; + argv[6] = "-"; + argv[7] = NULL; + execvp(argv[0], argv); + } else { + gs_pid = pid; + page = 0; + } +} + +int GsWidget::reload() { + int ret; + + if (in_fd >= 0) { + ret = lseek(in_fd, 0L, SEEK_SET); + if (ret == -1) { + fprintf(stderr, "lseek failed (errno %d)\n", errno); + return 1; + } + load(in_fd); + return 0; + } else { + return 1; + } +} + +int GsWidget::next() { + if (!gs_active()) { + return 1; + } else { + fl_cursor(FL_CURSOR_WAIT); + + XEvent e; + e.xclient.type = ClientMessage; + e.xclient.display = fl_display; + e.xclient.window = gs_win; + e.xclient.message_type = atoms[2]; + e.xclient.format = 32; + + XSendEvent(fl_display, gs_win, false, 0, &e); + XFlush(fl_display); + } +} + +int GsWidget::handleX11(int ev) { + if (fl_xevent->type == ClientMessage) { + gs_win = fl_xevent->xclient.data.l[0]; + + if(fl_xevent->xclient.message_type == atoms[3]) { + page++; // PAGE revceived + damage(FL_DAMAGE_ALL); + fl_cursor(FL_CURSOR_DEFAULT); + } else if(fl_xevent->xclient.message_type == atoms[4] ) { + kill_gs(); // DONE received + fl_cursor(FL_CURSOR_DEFAULT); + } + return 1; + } + return 0; +} + +int GsWidget::get_page() { + return page; +} diff --git a/src/PSEditWidget.H b/src/PSEditWidget.H new file mode 100644 index 0000000..bf2592c --- /dev/null +++ b/src/PSEditWidget.H @@ -0,0 +1,93 @@ +// +// "$Id: PSEditWidget.H,v 1.5 2004/06/25 17:25:17 hofmann Exp $" +// +// X11 header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 2004 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#ifndef PSEditWidget_H +#define PSEditWidget_H + +#include "GsWidget.H" + +class PSText; + +class PSEditWidget : public GsWidget { +private: + int mark_x, mark_y; + PSText **text; + int max_pages; + int tmp_fd; + int cur_size; + int mod, loaded; + +protected: + void clear_text(); + void draw(); + +public: + PSText *cur_text; + + PSEditWidget(int X,int Y,int W, int H); + int next(); + void new_text(int x1, int y1, const char *s, int p); + void new_text(int x1, int y1, const char *s); + int set_cur_text(int x1, int y1); + void append_text(const char *s); + void move(int x1, int y1); + void rm_char(); + int ps_to_display_x(int x1); + int ps_to_display_y(int y1); + int ps_x(int x1); + int ps_y(int y1); + int load(char *f); + int reload(); + void to_ps(FILE *f, int p); + int save(const char* savefile); + void set_cur_size(int s); + void set_size(int s); + int get_size(); + int modified(); + int file_loaded(); +}; + + +class PSText { + int x, y; + char *s; + PSText *next; + PSEditWidget *gsew; + +public: + Fl_Color c; + int size; + + PSText(PSEditWidget *g, int x1, int y1, const char *s1, int size1); + ~PSText(); + void append_text(const char*s1); + void rm_char(); + void move(int x1, int y1); + void append(PSText *g); + PSText *get_match(int x1, int y1); + void draw(int off_x,int off_y); + void string_to_ps(FILE *f, char *s); + void to_ps(FILE *f); +}; + +#endif diff --git a/src/PSEditWidget.cxx b/src/PSEditWidget.cxx new file mode 100644 index 0000000..55373f5 --- /dev/null +++ b/src/PSEditWidget.cxx @@ -0,0 +1,427 @@ +// +// "$Id: PSEditWidget.cxx,v 1.8 2004/06/25 18:14:05 hofmann Exp $" +// +// PSEditWidget routines. +// +// Copyright 2004 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <errno.h> + +#include <FL/Fl.H> +#include <FL/fl_draw.H> +#include <FL/x.H> + +#include "PSEditWidget.H" + +#define PS_POS_FORMAT "newpath %d %d moveto %% PSEditWidget\n" +#define PS_TEXT_FORMAT "(%s) show %% PSEditWidget\n" +#define PS_FONT_SIZE_FORMAT "/HelveticaNeue-Roman findfont %d scalefont setfont %% PSEditWidget\n" +#define PS_GLYPH_FORMAT "/%s glyphshow %% PSEditWidget\n" + +static struct { + const char *glyph; + const char *c; +} glyph_char[] = { + {"adieresis", "ä"}, + {"Adieresis", "Ä"}, + {"odieresis", "ö"}, + {"Odieresis", "Ö"}, + {"udieresis", "ü"}, + {"Udieresis", "Ü"}, + {"germandbls", "ß"}, + {"parenleft", "("}, + {"parenright", ")"}, + {NULL, NULL}}; + +static const char * glyph_to_char(char *glyph) { + int i=0; + + while(glyph_char[i].glyph != NULL) { + if (strcmp(glyph_char[i].glyph, glyph) == 0) { + return glyph_char[i].c; + } + i++; + } + + return NULL; +} + +static const char * char_to_glyph(char *c) { + int i=0; + + while(glyph_char[i].glyph != NULL) { + if (strncmp(glyph_char[i].c, c, 1) == 0) { + return glyph_char[i].glyph; + } + i++; + } + + return NULL; +} + +void PSEditWidget::clear_text() { + cur_text = NULL; + for (int i = 0; i < max_pages; i++) { + if (text[i]) { + delete(text[i]); + text[i] = NULL; + } + } +} + +void PSEditWidget::draw() { + GsWidget::draw(); + if (text[page]) { + text[page]->draw(x() ,y()); + } +} + +PSEditWidget::PSEditWidget(int X,int Y,int W, int H) : GsWidget(X, Y, W, H) { + max_pages = 32; + text = (PSText**) malloc(sizeof(PSText*) * max_pages); + for (int i = 0; i < max_pages; i++) { + text[i] = NULL; + } + cur_text = NULL; + cur_size = 12; + mod = 0; + loaded = 0; +} + +int PSEditWidget::next() { + if (page >= max_pages) { + max_pages = max_pages * 2; + text = (PSText**) realloc(text, sizeof(PSText*) * max_pages); + for (int i = max_pages / 2; i < max_pages; i++) { + text[i] = NULL; + } + } + cur_text = NULL; + GsWidget::next(); +} + +void PSEditWidget::new_text(int x1, int y1, const char *s, int p) { + cur_text = new PSText(this, x1, y1, s, cur_size); + if (text[p]) { + text[p]->append(cur_text); + } else { + text[p] = cur_text; + } + redraw(); + mod = 1; +} + +void PSEditWidget::new_text(int x1, int y1, const char *s) { + new_text(x1, y1, s, page); +} + +int PSEditWidget::set_cur_text(int x1, int y1) { + if (text[page]) { + cur_text = text[page]->get_match(x1, y1); + if (cur_text) { + redraw(); + return 0; + } + } + return 1; +} + +void PSEditWidget::append_text(const char *s) { + if (cur_text && s) { + cur_text->append_text(s); + mod = 1; + redraw(); + } +} + +void PSEditWidget::move(int x1, int y1) { + if (cur_text) { + cur_text->move(x1, y1); + mod = 1; + redraw(); + } +} + +void PSEditWidget::rm_char() { + if (cur_text) { + cur_text->rm_char(); + mod = 1; + redraw(); + } +} + +int PSEditWidget::ps_to_display_x(int x1) { + return (int) ((float) x1 * xdpi / 72.0); +} + +int PSEditWidget::ps_to_display_y(int y1) { + return (int) ((float) (paper_y - y1) * xdpi / 72.0); +} + +int PSEditWidget::ps_x(int x1) { + return (int) ((float) x1 * 72.0 / xdpi); +} + +int PSEditWidget::ps_y(int y1) { + return paper_y - (int)((float) y1 * 72.0 / ydpi); +} + +int PSEditWidget::reload() { + cur_text = NULL; + return GsWidget::reload(); +} + +int PSEditWidget::load(char *f) { + FILE *fp = fopen(f, "r"); + char tmpname[256]; + char linebuf[1024]; + int p = 1; + int x1, y1; + char *s, *e, glyph[1024]; + int size, ret; + + strncpy(tmpname, "/tmp/PSEditWidgetXXXXXX.ps", 256); + tmp_fd = mkstemps(tmpname, 3); + if (tmp_fd < 0) { + fprintf(stderr, "Could not create temporary file (errno %d).\n", errno); + return 1; + } + unlink(tmpname); + + clear_text(); + + while (fgets(linebuf, 1024, fp) != NULL) { + + if (strcmp(linebuf, "showpage\n") == 0) { + p++; + } + + if (strstr(linebuf, "% PSEditWidget")) { + if (sscanf(linebuf, PS_FONT_SIZE_FORMAT, &size) == 1) { + set_cur_size(size); + } else if (sscanf(linebuf, PS_POS_FORMAT, &x1, &y1) == 2) { + new_text(ps_to_display_x(x1), ps_to_display_y(y1), "", p); + } else if (sscanf(linebuf, PS_GLYPH_FORMAT, glyph) == 1) { + fprintf(stderr, "GLYPH %s\n", glyph); + append_text(glyph_to_char(glyph)); + } else if ((s = strchr(linebuf, '(')) && + (e = strrchr(linebuf, ')'))) { + *e = '\0'; + s++; + append_text(s); + } + } else { + ret = write(tmp_fd, linebuf, strlen(linebuf)); + if (ret != strlen(linebuf)) { + fprintf(stderr, "Error while writing to temporary file\n"); + } + } + } + fclose(fp); + lseek(tmp_fd, 0L, SEEK_SET); + + mod = 0; + loaded = 1; + return GsWidget::load(tmp_fd); +} + +void PSEditWidget::to_ps(FILE *f, int p) { + if (!text[p]) { + return; + } + + text[p]->to_ps(f); +} + +int PSEditWidget::save(const char* savefile) { + if (!file_loaded()) { + return 1; + } + FILE *fp = fdopen(tmp_fd, "r"); + rewind(fp); + FILE *sfp = fopen(savefile, "w"); + char linebuf[1024]; + int p = 1; + + while (fgets(linebuf, 1024, fp) != NULL) { + if (strcmp(linebuf, "showpage\n") == 0) { + to_ps(sfp, p); + p++; + } + fprintf(sfp, "%s", linebuf); + } + + fclose(sfp); + mod = 0; + return 0; +} + +int PSEditWidget::modified() { + return mod; +} + +int PSEditWidget::file_loaded() { + return loaded; +} + +void PSEditWidget::set_cur_size(int s) { + cur_size = s; +} + +void PSEditWidget::set_size(int s) { + set_cur_size(s); + if (cur_text) { + cur_text->size = s; + redraw(); + } +} + +int PSEditWidget::get_size() { + if (cur_text) { + return cur_text->size; + } else { + return cur_size; + } +} + + + + +PSText::PSText(PSEditWidget *g, int x1, int y1, const char *s1, int size1) { + x = x1; + y = y1; + s = strdup(s1); + c = FL_BLACK; + size = size1; + next = NULL; + gsew = g; +} + +PSText::~PSText() { + if (next) { + delete(next); + } + if (s) { + free(s); + } +} + +void PSText::append_text(const char*s1) { + int len = (s?strlen(s):0) + strlen(s1) + 1; + char *tmp = (char*) malloc(len); + + strncpy(tmp, s?s:"", len); + strncat(tmp, s1, len - strlen(tmp)); + + if (s) { + free(s); + } + + s = tmp; +} + +void PSText::rm_char() { + if (s && strlen(s) > 0) { + s[strlen(s) - 1] = '\0'; + } +} + +void PSText::move(int x1, int y1) { + x = x1; + y = y1; +} + +void PSText::append(PSText *g) { + PSText *p = this; + while (p->next) { + p = p->next; + } + p->next = g; +} + +PSText *PSText::get_match(int x1, int y1) { + if (abs(x - x1) < 10 && abs(y - y1) < 10) { + return this; + } else if (next) { + return next->get_match(x1, y1); + } else { + return NULL; + } +} + +void PSText::draw(int off_x,int off_y) { + PSText *p = this; + fl_color(c); + fl_font(FL_HELVETICA, size); + fl_draw(s, x + off_x, y + off_y); + if (gsew->cur_text == this) { + fl_draw_box(FL_BORDER_FRAME, x+off_x-1, y+off_y-fl_height()+fl_descent(), fl_width(s)+2, fl_height(), FL_BLACK); + } + if (p->next) { + p->next->draw(off_x, off_y); + } +} + +void PSText::string_to_ps(FILE *f, char *s) { + const char *glyph; + + if (strlen(s) == 0) { + return; + } else if ((glyph = char_to_glyph(s)) != NULL) { + fprintf(f, PS_GLYPH_FORMAT, glyph); + string_to_ps(f, &(s[1])); + return; + } else { + for(int i=0; i<strlen(s); i++) { + if ((glyph = char_to_glyph(&(s[i]))) != NULL) { + char *s1 = strdup(s); + s1[i] = '\0'; + fprintf(f, PS_TEXT_FORMAT, s1); + free(s1); + string_to_ps(f, &(s[i])); + return; + } + } + fprintf(f, PS_TEXT_FORMAT, s); + } + return; +} + +void PSText::to_ps(FILE *f) { + if (strcmp(s, "") != 0) { + fprintf(f, PS_FONT_SIZE_FORMAT, size); + fprintf(f, PS_POS_FORMAT, gsew->ps_x(x), gsew->ps_y(y)); + string_to_ps(f, s); + } + + if (next) { + next->to_ps(f); + } +} + + + diff --git a/src/flpsed.cxx b/src/flpsed.cxx new file mode 100644 index 0000000..a045b90 --- /dev/null +++ b/src/flpsed.cxx @@ -0,0 +1,259 @@ +// +// "$Id: flpsed.cxx,v 1.9 2004/06/25 18:14:05 hofmann Exp $" +// +// flpsed program. +// +// Copyright 2004 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <errno.h> + +#include <FL/Fl.H> +#include <FL/Fl_Window.H> +#include <FL/Fl_Scroll.H> +#include <FL/Fl_File_Chooser.H> +#include <FL/Fl_Input.H> +#include <FL/Fl_Int_Input.H> +#include <FL/Fl_Menu_Bar.H> +#include <FL/Fl_Menu_Item.H> + +#include "PSEditWidget.H" + +class PSEditor : public PSEditWidget { + int mark_x, mark_y; + + int handle(int event) { + switch(event) { + case FL_PUSH: + if (!file_loaded()) { + fl_beep(); + return 0; + } + + mark_x = Fl::event_x()-x(); + mark_y = Fl::event_y()-y(); + + if (!set_cur_text(mark_x, mark_y) == 0) { + new_text(mark_x, mark_y, ""); + } + + Fl::focus(this); + return 1; + case FL_DRAG: + move(Fl::event_x()-x(), Fl::event_y()-y()); + return 1; + case FL_KEYBOARD: + { + int del; + int key = Fl::event_key(); + if (key == FL_BackSpace) { + rm_char(); + } else if (Fl::compose(del)) { + if (del > 0) { + for (int i=0; i<del; i++) rm_char(); + } + if (Fl::event_length()) { + append_text(Fl::event_text()); + } + } else { + return 0; + } + + return 1; + } + case FL_FOCUS: + return 1; + case FL_UNFOCUS: + return 0; + } + return 0; + } + +public: + PSEditor(int X,int Y,int W, int H) : PSEditWidget(X, Y, W, H) {} +}; + + +// +// Main Program +// + +PSEditor *gsw_p; + +int xev_handler(int ev) { + if (gsw_p) { + return gsw_p->handleX11(ev); + } else { + return 0; + } +} + +void save_cb(); + +int check_save(void) { + if (!gsw_p->modified()) return 1; + + int r = fl_choice("The current file has not been saved.\n" + "Would you like to save it now?", + "Cancel", "Save", "Discard"); + + if (r == 1) { + save_cb(); // Save the file... + return !gsw_p->modified(); + } + + return (r == 2) ? 1 : 0; +} + + +char filename[256] = ""; + +void open_cb() { + if (!check_save()) return; + char *file = fl_file_chooser("Open File?", "*.ps", filename); + if(file != NULL) { + gsw_p->load(file); + } +} + +void first_cb() { + gsw_p->reload(); +} + +void next_cb() { + gsw_p->next(); +} + +void quit_cb() { + if (!check_save()) return; + delete gsw_p; + exit(0); +} + +void save_cb() { + char *file = fl_file_chooser("Open File?", "*.ps", filename); + if (file != NULL) { + gsw_p->save(file); + } +} + +void print_cb() { + char tmpname[256]; + char buf[256]; + int tmp_fd; + + int r = fl_ask("Print file?"); + if (r != 1) { + return; + } + + strncpy(tmpname, "/tmp/PSEditWidgetXXXXXX.ps", 256); + tmp_fd = mkstemps(tmpname, 3); + + if (tmp_fd >= 0) { + close(tmp_fd); + if (gsw_p->save(tmpname) != 0) { + fprintf(stderr, "Failed to print file\n"); + } else { + snprintf(buf, 256, "lpr %s", tmpname); + system(buf); + } + unlink(tmpname); + } +} + +void about_cb() { + fl_message("flpsed -- a pseudo PostScript editor\n" + "(c) Johannes Hofmann 2004\n\n" + "PostScript is a registered trademark of Adobe Systems"); +} + + +void size_cb(Fl_Widget *w, void *) { + Fl_Menu_* mw = (Fl_Menu_*)w; + const Fl_Menu_Item* m = mw->mvalue(); + if (m) { + gsw_p->set_size(atoi(m->label())); + } +} + + + +Fl_Menu_Item menuitems[] = { + { "&File", 0, 0, 0, FL_SUBMENU }, + { "&Open File...", FL_CTRL + 'o', (Fl_Callback *)open_cb }, + { "&Save File as...", FL_CTRL + 's', (Fl_Callback *)save_cb }, + { "&Print...", FL_CTRL + 'p', (Fl_Callback *)print_cb, 0, FL_MENU_DIVIDER }, + { "&Quit", FL_CTRL + 'q', (Fl_Callback *)quit_cb, 0 }, + { 0 }, + + { "&Page", 0, 0, 0, FL_SUBMENU }, + { "F&irst", FL_CTRL + 'i', (Fl_Callback *)first_cb }, + { "&Next", FL_CTRL + 'n', (Fl_Callback *)next_cb }, + { 0 }, + + { "&Size", 0, 0, 0, FL_SUBMENU }, + { "8", 0, (Fl_Callback *)size_cb }, + { "10", 0, (Fl_Callback *)size_cb }, + { "12", 0, (Fl_Callback *)size_cb }, + { "14", 0, (Fl_Callback *)size_cb }, + { "18", 0, (Fl_Callback *)size_cb }, + { "24", 0, (Fl_Callback *)size_cb }, + { 0 }, + + { "&Help", 0, 0, 0, FL_SUBMENU }, + { "About", 0, (Fl_Callback *)about_cb }, + { 0 }, + + { 0 } +}; + +int main(int argc, char** argv) { + Fl_Window window(600,700); + Fl_Menu_Bar* m = new Fl_Menu_Bar(0, 0, 600, 30); + m->menu(menuitems); + + Fl_Scroll scroll(0, 30, window.w(), window.h()-30); + gsw_p = new PSEditor(0, 0, 700, 900); + scroll.end(); + fl_open_display(); + Fl::add_handler(xev_handler); + + window.resizable(scroll); + + window.end(); + window.callback((Fl_Callback *)quit_cb); + window.show(1, argv); + + + // for (int i=0; i<100; i++) Fl::check(); + // if (argc >= 2) { + // gsw_p->load(argv[1]); + // } + + return Fl::run(); +} + |