X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Ffiginset.C;h=e39691c7d8349d694a374407e8916a30360e3428;hb=3c8aba3b556871fb1100a2f98cd93d5d4e3f70c9;hp=b58b7dc4fcb0b5183f91dc47f42326626e9ee12d;hpb=a94cb21697336d5e81e21d0f1ec2a8b8b78dbbcc;p=lyx.git diff --git a/src/insets/figinset.C b/src/insets/figinset.C index b58b7dc4fc..e39691c7d8 100644 --- a/src/insets/figinset.C +++ b/src/insets/figinset.C @@ -2,9 +2,6 @@ * figinset.C - part of LyX project */ -extern int reverse_video; -extern long int background_pixels; - /* Rework of path-handling (Matthias 04.07.1996 ) * ------------------------------------------------ * figinsets keep an absolute path to the eps-file. @@ -31,6 +28,12 @@ extern long int background_pixels; #include +#include +#include +#include +#include +#include + #include #include #include @@ -40,7 +43,6 @@ extern long int background_pixels; #include #include -#include "form1.h" #include "figinset.h" #include "lyx.h" #include "lyx_main.h" @@ -49,55 +51,53 @@ extern long int background_pixels; #include "support/filetools.h" #include "LyXView.h" // just because of form_main #include "debug.h" -#include "lyxdraw.h" #include "LaTeXFeatures.h" #include "lyxrc.h" #include "gettext.h" #include "lyx_gui_misc.h" // CancelCloseBoxCB #include "support/FileInfo.h" +#include "support/lyxlib.h" +#include "Painter.h" +#include "font.h" +#include "bufferview_funcs.h" +#include "ColorHandler.h" + +using std::ostream; +using std::istream; +using std::ofstream; +using std::ifstream; +using std::queue; +using std::list; +using std::vector; +using std::find; +using std::flush; +using std::endl; +#ifdef HAVE_SSTREAM +using std::ostringstream; +#endif -extern BufferView *current_view; -static volatile bool alarmed; +extern BufferView * current_view; +extern FL_OBJECT * figinset_canvas; -extern FL_OBJECT *figinset_canvas; -//inline -extern "C" void waitalarm(int) -{ - alarmed = true; -} +extern char ** environ; // is this only redundtant on linux systems? Lgb. -extern char **environ; // is this only redundtant on linux systems? Lgb. -extern void UpdateInset(Inset* inset, bool mark_dirty = true); -// better for asyncron updating: -void PutInsetIntoInsetUpdateList(Inset* inset); -extern void ProhibitInput(); -extern void AllowInput(); - -#define DEG2PI 57.295779513 -#define figallocchunk 32 - -static int figinsref = 0; /* number of figures */ -static int figarrsize = 0; /* current max number of figures */ -static int bmpinsref = 0; /* number of bitmaps */ -static int bmparrsize = 0; /* current max number of bitmaps */ - -struct queue { - float rx, ry; /* resolution x and y */ - int ofsx, ofsy; /* x and y translation */ - figdata *data; /* we are doing it for this data */ - queue *next; /* next item in queue */ -}; +static float const DEG2PI = 57.295779513; -struct pidwait { - int pid; /* pid to wait for */ - pidwait *next; /* next */ +struct queue_element { + float rx, ry; // resolution x and y + int ofsx, ofsy; // x and y translation + figdata * data; // we are doing it for this data }; -#define MAXGS 3 /* maximum 3 gs's at a time */ +static int const MAXGS = 3; /* maximum 3 gs's at a time */ + +typedef vector figures_type; +typedef vector bitmaps_type; +static figures_type figures; // all figures +static bitmaps_type bitmaps; // all bitmaps + +static queue gsqueue; // queue for ghostscripting -static Figref **figures; /* all the figures */ -static figdata **bitmaps; /* all the bitmaps */ -static queue *gsqueue = 0; /* queue for ghostscripting */ static int gsrunning = 0; /* currently so many gs's are running */ static bool bitmap_waiting = false; /* bitmaps are waiting finished */ static char bittable[256]; /* bit reversion table */ @@ -111,38 +111,67 @@ static int gs_spc; // shades per color static bool gs_gray; // is grayscale? static int gs_allcolors; // number of all colors -static pidwait *pw = 0; // pid wait list +static list pidwaitlist; // pid wait list +static +GC createGC() +{ + XGCValues val; + val.foreground = BlackPixel(fl_display, + DefaultScreen(fl_display)); + + val.function=GXcopy; + val.graphics_exposures = false; + val.line_style = LineSolid; + val.line_width = 0; + return XCreateGC(fl_display, RootWindow(fl_display, 0), + GCForeground | GCFunction | GCGraphicsExposures + | GCLineWidth | GCLineStyle , &val); +} + +static +GC local_gc_copy; -extern FD_form_main *fd_form_main; -extern Colormap color_map; +static void addpidwait(int pid) { // adds pid to pid wait list - register pidwait *p = new pidwait; - - p->pid = pid; - p->next = pw; - pw = p; + pidwaitlist.push_back(pid); if (lyxerr.debugging()) { - lyxerr << "Pids to wait for: " << p->pid << endl; - while (p->next) { - p = p->next; - lyxerr << p->pid << endl; + lyxerr << "Pids to wait for: \n"; + for (list::const_iterator cit = pidwaitlist.begin(); + cit != pidwaitlist.end(); ++cit) { + lyxerr << (*cit) << '\n'; } + lyxerr << flush; } } -extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, - XEvent *ev, void *) +static +string make_tmp(int pid) { - int i; - char tmp[128]; + return system_tempdir + "/~lyxgs" + tostr(pid) + ".ps"; +} - XClientMessageEvent *e = (XClientMessageEvent*) ev; + +static +void kill_gs(int pid, int sig) +{ + if (lyxerr.debugging()) + lyxerr << "Killing gs " << pid << endl; + lyx::kill(pid, sig); + unlink(make_tmp(pid).c_str()); +} + + +extern "C" // static +int GhostscriptMsg(FL_OBJECT *, Window, int, int, + XEvent * ev, void *) +{ + XClientMessageEvent * e = reinterpret_cast(ev); if(lyxerr.debugging()) { lyxerr << "ClientMessage, win:[xx] gs:[" << e->data.l[0] @@ -150,53 +179,61 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, } // just kill gs, that way it will work for sure - for (i = 0; i < bmpinsref; ++i) - if ((long)bitmaps[i]->bitmap == (long)e->data.l[1]) { + // This loop looks like S**T so it probably is... + for (bitmaps_type::iterator it = bitmaps.begin(); + it != bitmaps.end(); ++it) + if (static_cast((*it)->bitmap) == + static_cast(e->data.l[1])) { // found the one - figdata *p = bitmaps[i]; + figdata * p = (*it); p->gsdone = true; // first update p->bitmap, if necessary - if (p->bitmap != None && p->flags > (1|8) && gs_color && p->wid) { + if (p->bitmap != None + && p->flags > (1|8) && gs_color && p->wid) { // query current colormap and re-render // the pixmap with proper colors - XColor *cmap; XWindowAttributes wa; - register XImage *im; - int i, y, wid1, spc1 = gs_spc-1, - spc2 = gs_spc*gs_spc, wid = p->wid, - forkstat; - Display *tmpdisp; - GC gc = getGC(gc_copy); - - XGetWindowAttributes(fl_display, fl_get_canvas_id( - figinset_canvas), &wa); + register XImage * im; + int i; + int y; + int wid1; + int spc1 = gs_spc - 1; + int spc2 = gs_spc * gs_spc; + int wid = p->wid; + int forkstat; + Display * tmpdisp; + GC gc = local_gc_copy; + + XGetWindowAttributes(fl_display, + fl_get_canvas_id( + figinset_canvas), + &wa); XFlush(fl_display); if (lyxerr.debugging()) { - lyxerr - << "Starting image translation " - << p->bitmap << " " - << p->flags << " " - << p->wid << "x" << p->hgh - << " " << wa.depth - << " " << XYPixmap << endl; - + lyxerr << "Starting image translation " + << p->bitmap << " " + << p->flags << " " + << p->wid << "x" << p->hgh + << " " << wa.depth + << " " << XYPixmap << endl; } // now fork rendering process forkstat = fork(); if (forkstat == -1) { - lyxerr.debug() << "Cannot fork, using slow " + lyxerr.debug() + << "Cannot fork, using slow " "method for pixmap translation." << endl; tmpdisp = fl_display; - } else if (forkstat > 0) { + } else if (forkstat > 0) { // parent // register child if (lyxerr.debugging()) { lyxerr << "Spawned child " << forkstat << endl; } addpidwait(forkstat); - break; // in parent process - } else { + break; + } else { // child tmpdisp = XOpenDisplay(XDisplayName(0)); XFlush(tmpdisp); } @@ -212,61 +249,53 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, } goto noim; } + { // query current colormap - cmap = (XColor *) malloc(gs_allcolors*sizeof(XColor)); - for (i = 0; i < gs_allcolors; ++i) cmap[i].pixel = i; - XQueryColors(tmpdisp, color_map, cmap, gs_allcolors); - XFlush(tmpdisp); - wid1 = p->wid - 1; + XColor * cmap = new XColor[gs_allcolors]; + for (i = 0; i < gs_allcolors; ++i) cmap[i].pixel = i; + XQueryColors(tmpdisp, + fl_state[fl_get_vclass()] + .colormap, cmap, + gs_allcolors); + XFlush(tmpdisp); + wid1 = p->wid - 1; // now we process all the image - for (y = 0; y < p->hgh; ++y) { - register int x; - for (x = 0; x < wid; ++x) { - register XColor* pc; - pc = cmap + XGetPixel(im, x, y); - XFlush(tmpdisp); - XPutPixel(im, x, y, gs_pixels[((pc->red+6553)* - spc1/65535)*spc2+((pc->green+6553)* - spc1/65535)*gs_spc+((pc->blue+6553)* - spc1/65535)]); - XFlush(tmpdisp); + for (y = 0; y < p->hgh; ++y) { + for (int x = 0; x < wid; ++x) { + XColor * pc = cmap + + XGetPixel(im, x, y); + XFlush(tmpdisp); + XPutPixel(im, x, y, + gs_pixels[((pc->red+6553)* + spc1/65535)*spc2+((pc->green+6553)* + spc1/65535)*gs_spc+((pc->blue+6553)* + spc1/65535)]); + XFlush(tmpdisp); + } + } + // This must be correct. + delete [] cmap; + if (lyxerr.debugging()) { + lyxerr << "Putting image back" + << endl; + } + XPutImage(tmpdisp, p->bitmap, + gc, im, 0, 0, + 0, 0, p->wid, p->hgh); + XDestroyImage(im); + if (lyxerr.debugging()) { + lyxerr << "Done translation" + << endl; } - } - if (lyxerr.debugging()) { - lyxerr << "Putting image back" << endl; - } - XPutImage(tmpdisp, p->bitmap, gc, im, 0, 0, - 0, 0, p->wid, p->hgh); - XDestroyImage(im); - if (lyxerr.debugging()) { - lyxerr << "Done translation" << endl; } noim: - if (lyxerr.debugging()) { - lyxerr << "Killing gs " - << p->gspid << endl; - } - kill(p->gspid, SIGHUP); - - sprintf(tmp, "%s/~lyxgs%d.ps", - system_tempdir.c_str(), - p->gspid); - unlink(tmp); + kill_gs(p->gspid, SIGHUP); if (forkstat == 0) { XCloseDisplay(tmpdisp); _exit(0); } } else { - if (lyxerr.debugging()) { - lyxerr << "Killing gs " - << p->gspid << endl; - } - kill(p->gspid, SIGHUP); - - sprintf(tmp, "%s/~lyxgs%d.ps", - system_tempdir.c_str(), - p->gspid); - unlink(tmp); + kill_gs(p->gspid, SIGHUP); } break; } @@ -274,12 +303,10 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, } -static void AllocColors(int num) +static +void AllocColors(int num) // allocate color cube numxnumxnum, if possible { - XColor xcol; - int i; - if (lyxerr.debugging()) { lyxerr << "Allocating color cube " << num << 'x' << num << 'x' << num << endl; @@ -291,19 +318,22 @@ static void AllocColors(int num) return; } if (num > 5) num = 5; - for (i = 0; i < num*num*num; ++i) { - xcol.red = 65535*(i/(num*num))/(num-1); - xcol.green = 65535*((i/num) % num)/(num-1); - xcol.blue = 65535*(i % num)/(num-1); + XColor xcol; + for (int i = 0; i < num * num * num; ++i) { + xcol.red = 65535 * (i / (num * num)) / (num - 1); + xcol.green = 65535 * ((i / num) % num) / (num - 1); + xcol.blue = 65535 * (i % num) / (num - 1); xcol.flags = DoRed | DoGreen | DoBlue; - if (!XAllocColor(fl_display, color_map, &xcol)) { - if (i) XFreeColors(fl_display, color_map, + if (!XAllocColor(fl_display, + fl_state[fl_get_vclass()].colormap, &xcol)) { + if (i) XFreeColors(fl_display, + fl_state[fl_get_vclass()].colormap, gs_pixels, i, 0); if(lyxerr.debugging()) { lyxerr << "Cannot allocate color cube " << num << endl;; } - AllocColors(num-1); + AllocColors(num - 1); return; } gs_pixels[i] = xcol.pixel; @@ -311,18 +341,16 @@ static void AllocColors(int num) gs_color = true; gs_gray = false; gs_spc = num; - gs_num_pixels = num*num*num; + gs_num_pixels = num * num * num; } -static void AllocGrays(int num) // allocate grayscale ramp +static +void AllocGrays(int num) { - XColor xcol; - int i; - if (lyxerr.debugging()) { - lyxerr << "Allocating grayscale ramp " + lyxerr << "Allocating grayscale colormap " << num << endl; } @@ -332,17 +360,20 @@ static void AllocGrays(int num) return; } if (num > 128) num = 128; - for (i = 0; i < num; ++i) { - xcol.red = xcol.green = xcol.blue = 65535*i/(num-1); + XColor xcol; + for (int i = 0; i < num; ++i) { + xcol.red = xcol.green = xcol.blue = 65535 * i / (num - 1); xcol.flags = DoRed | DoGreen | DoBlue; - if (!XAllocColor(fl_display, color_map, &xcol)) { - if (i) XFreeColors(fl_display, color_map, + if (!XAllocColor(fl_display, + fl_state[fl_get_vclass()].colormap, &xcol)) { + if (i) XFreeColors(fl_display, + fl_state[fl_get_vclass()].colormap, gs_pixels, i, 0); if (lyxerr.debugging()) { lyxerr << "Cannot allocate grayscale " << num << endl; } - AllocGrays(num/2); + AllocGrays(num / 2); return; } gs_pixels[i] = xcol.pixel; @@ -353,132 +384,98 @@ static void AllocGrays(int num) } +static void InitFigures() { - unsigned int i, j, k; - Visual *vi; - - bmparrsize = figarrsize = figallocchunk; - figures = (Figref**) malloc(sizeof(Figref*)*figallocchunk); - bitmaps = (figdata**) malloc(sizeof(figdata*)*figallocchunk); + // if bitmaps and figures are not empty we will leak mem + figures.clear(); + bitmaps.clear(); - for (i = 0; i < 256; ++i) { + unsigned int k; + for (unsigned int i = 0; i < 256; ++i) { k = 0; - for (j = 0; j < 8; ++j) + for (unsigned int j = 0; j < 8; ++j) if (i & (1 << (7-j))) k |= 1 << j; - bittable[i] = (char) ~k; + bittable[i] = char(~k); } - fl_add_canvas_handler(figinset_canvas, ClientMessage, - GhostscriptMsg, fd_form_main); - - // now we have to init color_map - if (!color_map) color_map = DefaultColormap(fl_display, - DefaultScreen(fl_display)); // allocate color cube on pseudo-color display // first get visual gs_color = false; + if (lyxrc.use_gui) { + fl_add_canvas_handler(figinset_canvas, ClientMessage, + GhostscriptMsg, + current_view->owner()->getMainForm()); - vi = DefaultVisual(fl_display, DefaultScreen(fl_display)); - if (lyxerr.debugging()) { - printf("Visual ID: %ld, class: %d, bprgb: %d, mapsz: %d\n", - vi->visualid, vi->c_class, - vi->bits_per_rgb, vi->map_entries); - } - color_visual = ( (vi->c_class == StaticColor) || - (vi->c_class == PseudoColor) || - (vi->c_class == TrueColor) || - (vi->c_class == DirectColor) ); - if ((vi->c_class & 1) == 0) return; - // now allocate colors - if (vi->c_class == GrayScale) { - // allocate grayscale - AllocGrays(vi->map_entries/2); - } else { - // allocate normal color - int i = 5; - while (i*i*i*2 > vi->map_entries) --i; - AllocColors(i); + local_gc_copy = createGC(); + + Visual * vi = DefaultVisual(fl_display, + DefaultScreen(fl_display)); + if (lyxerr.debugging()) { + printf("Visual ID: %ld, class: %d, bprgb: %d, mapsz: %d\n", + vi->visualid, vi->c_class, + vi->bits_per_rgb, vi->map_entries); + } + color_visual = ( (vi->c_class == StaticColor) || + (vi->c_class == PseudoColor) || + (vi->c_class == TrueColor) || + (vi->c_class == DirectColor) ); + if ((vi->c_class & 1) == 0) return; + // now allocate colors + if (vi->c_class == GrayScale) { + // allocate grayscale + AllocGrays(vi->map_entries/2); + } else { + // allocate normal color + int i = 5; + while (i * i * i * 2 > vi->map_entries) --i; + AllocColors(i); + } + gs_allcolors = vi->map_entries; } - gs_allcolors = vi->map_entries; } +static void DoneFigures() { - free(figures); - free(bitmaps); - figarrsize = 0; - bmparrsize = 0; - + // if bitmaps and figures are not empty we will leak mem + bitmaps.clear(); + figures.clear(); + lyxerr.debug() << "Unregistering figures..." << endl; fl_remove_canvas_handler(figinset_canvas, ClientMessage, GhostscriptMsg); - - if (gs_color) { - lyxerr.debug() << "Freeing up the colors..." << endl; - XFreeColors(fl_display, color_map, gs_pixels, - gs_num_pixels, 0); - /******????????????????? what's planes in this case ??????***/ - } } -int FindBmpIndex(figdata *tmpdata) +static +void freefigdata(figdata * tmpdata) { - int i = 0; - while (i < bmpinsref) { - if (bitmaps[i] == tmpdata) return i; - ++i; - } - return i; -} - - -static void chpixmap(Pixmap, int, int) -{ - Display* tempdisp = XOpenDisplay(XDisplayName(0)); - - // here read the pixmap and change all colors to those we - // have allocated - - XCloseDisplay(tempdisp); -} - - -static void freefigdata(figdata *tmpdata) -{ - int i; - tmpdata->ref--; if (tmpdata->ref) return; if (tmpdata->gspid > 0) { int pid = tmpdata->gspid; - char buf[128]; - // change Pixmap according to our allocated colormap - chpixmap(tmpdata->bitmap, tmpdata->wid, tmpdata->hgh); // kill ghostscript and unlink it's files tmpdata->gspid = -1; - kill(pid, SIGKILL); - sprintf(buf, "%s/~lyxgs%d.ps", system_tempdir.c_str(), pid); - unlink(buf); + kill_gs(pid, SIGKILL); } if (tmpdata->bitmap) XFreePixmap(fl_display, tmpdata->bitmap); + bitmaps.erase(find(bitmaps.begin(), bitmaps.end(), tmpdata)); delete tmpdata; - i = FindBmpIndex(tmpdata); - --bmpinsref; - while (i < bmpinsref) { - bitmaps[i] = bitmaps[i+1]; - ++i; - } } -static void runqueue() +static +void runqueue() { + // This _have_ to be set before the fork! + unsigned long background_pixel = + lyxColorHandler->colorPixel(LColor::background); + // run queued requests for ghostscript, if any if (!gsrunning && gs_color && !gs_xcolor) { // here alloc all colors, so that gs will use only @@ -488,13 +485,11 @@ static void runqueue() } while (gsrunning < MAXGS) { - queue *p; - int pid; - char tbuf[384], tbuf2[80]; - Atom *prop; + //char tbuf[384]; //, tbuf2[80]; + Atom * prop; int nprop, i; - if (!gsqueue) { + if (gsqueue.empty()) { if (!gsrunning && gs_xcolor) { // de-allocate rest of colors // ***** @@ -502,193 +497,243 @@ static void runqueue() } return; } - p = gsqueue; - + queue_element * p = &gsqueue.front(); if (!p->data) { - delete p; + gsqueue.pop(); continue; } - pid = fork(); + int pid = ::fork(); if (pid == -1) { if (lyxerr.debugging()) { - lyxerr << "GS start error! Cannot fork." << endl; + lyxerr << "GS start error! Cannot fork." + << endl; } p->data->broken = true; p->data->reading = false; return; } if (pid == 0) { // child - char **env, rbuf[80], gbuf[40]; + char ** env; int ne = 0; - Display* tempdisp = XOpenDisplay(XDisplayName(0)); + Display * tempdisp = XOpenDisplay(XDisplayName(0)); // create translation file - sprintf(tbuf, "%s/~lyxgs%d.ps", system_tempdir.c_str(), - int(getpid())); - - FilePtr f(tbuf, FilePtr::write); - fprintf(f, "gsave clippath pathbbox grestore\n" - "4 dict begin\n" - "/ury exch def /urx exch def /lly exch def " + ofstream ofs; + ofs.open(make_tmp(getpid()).c_str()); + ofs << "gsave clippath pathbbox grestore\n" + << "4 dict begin\n" + << "/ury exch def /urx exch def /lly exch def " "/llx exch def\n" - "%g %g translate\n" - "%g rotate\n" - "%g %g translate\n" - "%g %g scale\n" - "%d %d translate\nend\n", - p->data->wid / 2.0, p->data->hgh / 2.0, - p->data->angle, - - (p->data->raw_wid / 2.0), -(p->data->raw_hgh / 2.0), - p->rx / 72.0, p->ry / 72.0, - -p->ofsx, -p->ofsy - ); - - // DON'T EVER remove this!! - f.close(); // was this all? (Lgb) - - // gs process - set ghostview environment first - sprintf(tbuf2, "GHOSTVIEW=%ld %ld", fl_get_canvas_id( - figinset_canvas), p->data->bitmap); + << p->data->wid / 2.0 << " " + << p->data->hgh / 2.0 << " translate\n" + << p->data->angle << " rotate\n" + << -(p->data->raw_wid / 2.0) << " " + << -(p->data->raw_hgh / 2.0) << " translate\n" + << p->rx / 72.0 << " " << p->ry / 72.0 + << " scale\n" + << -p->ofsx << " " << -p->ofsy << " translate\n" + << "end" << endl; + ofs.close(); // Don't remove this. + // gs process - set ghostview environment first +#ifdef HAVE_SSTREAM + ostringstream t2; +#else + char tbuf2[80]; + ostrstream t2(tbuf2, sizeof(tbuf2)); +#endif + t2 << "GHOSTVIEW=" << fl_get_canvas_id(figinset_canvas) + << ' ' << p->data->bitmap; +#ifndef HAVE_SSTREAM + t2 << '\0'; +#endif // now set up ghostview property on a window - sprintf(tbuf, "0 0 0 0 %d %d 72 72 0 0 0 0", - p->data->wid, p->data->hgh); -//#warning BUG seems that the only bug here might be the hardcoded dpi.. Bummer! + // #warning BUG seems that the only bug here + // might be the hardcoded dpi.. Bummer! +#ifdef HAVE_SSTREAM + ostringstream t1; +#else + char tbuf[384]; + ostrstream t1(tbuf, sizeof(tbuf)); +#endif + t1 << "0 0 0 0 " << p->data->wid << ' ' + << p->data->hgh << " 72 72 0 0 0 0"; +#ifndef HAVE_SSTREAM + t1 << '\0'; +#endif if (lyxerr.debugging()) { lyxerr << "Will set GHOSTVIEW property to [" - << tbuf << "]" << endl; + << t1.str() << "]" << endl; } // wait until property is deleted if executing multiple // ghostscripts + XGrabServer(tempdisp); for (;;) { - // grab server to prevent other child interfering - // with setting GHOSTVIEW property + // grab server to prevent other child + // interfering with setting GHOSTVIEW property + // The grabbing goes on for too long, is it + // really needed? (Lgb) + // I moved most of the grabs... (Lgb) if (lyxerr.debugging()) { - lyxerr << "Grabbing the server" << endl; + lyxerr << "Grabbing the server" + << endl; } - XGrabServer(tempdisp); - prop = XListProperties(tempdisp, fl_get_canvas_id( + prop = XListProperties(tempdisp, + fl_get_canvas_id( figinset_canvas), &nprop); if (!prop) break; bool err = true; for (i = 0; i < nprop; ++i) { - char *p = XGetAtomName(tempdisp, prop[i]); + char * p = XGetAtomName(tempdisp, + prop[i]); if (strcmp(p, "GHOSTVIEW") == 0) { err = false; break; } XFree(p); } - XFree((char *)prop); /* jc: */ + XFree(reinterpret_cast(prop)); // jc: if (err) break; - // release the server - XUngrabServer(tempdisp); - XFlush(tempdisp); - // ok, property found, we must wait until ghostscript - // deletes it + // ok, property found, we must wait until + // ghostscript deletes it if (lyxerr.debugging()) { - lyxerr << "Releasing the server" << endl; - lyxerr << "[" + lyxerr << "Releasing the server\n[" << getpid() << "] GHOSTVIEW property" " found. Waiting." << endl; } -#ifdef WITH_WARNINGS -#warning What is this doing? (wouldn't a sleep(1); work too?') -#endif - alarm(1); - alarmed = false; - signal(SIGALRM, waitalarm); - while (!alarmed) pause(); + XUngrabServer(tempdisp); + XFlush(tempdisp); + ::sleep(1); + XGrabServer(tempdisp); } - +#ifdef HAVE_SSTREAM XChangeProperty(tempdisp, fl_get_canvas_id(figinset_canvas), XInternAtom(tempdisp, "GHOSTVIEW", false), XInternAtom(tempdisp, "STRING", false), 8, PropModeAppend, - reinterpret_cast(tbuf), - strlen(tbuf)); + reinterpret_cast(const_cast(t1.str().c_str())), + t1.str().size()); +#else + XChangeProperty(tempdisp, + fl_get_canvas_id(figinset_canvas), + XInternAtom(tempdisp, "GHOSTVIEW", false), + XInternAtom(tempdisp, "STRING", false), + 8, PropModeAppend, + reinterpret_cast(const_cast(t1.str())), + ::strlen(t1.str())); +#endif + XUngrabServer(tempdisp); + XFlush(tempdisp); + +#ifdef HAVE_SSTREAM + ostringstream t3; +#else + //char tbuf[384]; + ostrstream t3(tbuf, sizeof(tbuf)); +#endif switch (p->data->flags & 3) { - case 0: tbuf[0] = 'H'; break; // Hidden - case 1: tbuf[0] = 'M'; break; // Mono - case 2: tbuf[0] = 'G'; break; // Gray + case 0: t3 << 'H'; break; // Hidden + case 1: t3 << 'M'; break; // Mono + case 2: t3 << 'G'; break; // Gray case 3: if (color_visual) - tbuf[0] = 'C'; // Color + t3 << 'C'; // Color else - tbuf[0] = 'G'; // Gray + t3 << 'G'; // Gray break; } + + t3 << ' ' << BlackPixelOfScreen(DefaultScreenOfDisplay(tempdisp)) + << ' ' << background_pixel; +#ifndef HAVE_SSTREAM + t3 << '\0'; +#endif - if (reverse_video) { - sprintf(tbuf+1, " %ld %ld", WhitePixelOfScreen( - DefaultScreenOfDisplay(fl_display)), - background_pixels); - } else { - sprintf(tbuf+1, " %ld %ld", BlackPixelOfScreen( - DefaultScreenOfDisplay(fl_display)), - background_pixels); - } - + XGrabServer(tempdisp); +#ifdef HAVE_SSTREAM + XChangeProperty(tempdisp, + fl_get_canvas_id(figinset_canvas), + XInternAtom(tempdisp, + "GHOSTVIEW_COLORS", false), + XInternAtom(tempdisp, "STRING", false), + 8, PropModeReplace, + reinterpret_cast(const_cast(t3.str().c_str())), + t3.str().size()); +#else XChangeProperty(tempdisp, fl_get_canvas_id(figinset_canvas), - XInternAtom(tempdisp, "GHOSTVIEW_COLORS", false), + XInternAtom(tempdisp, + "GHOSTVIEW_COLORS", false), XInternAtom(tempdisp, "STRING", false), 8, PropModeReplace, - reinterpret_cast(tbuf), - strlen(tbuf)); + reinterpret_cast(const_cast(t3.str())), + ::strlen(t3.str())); +#endif XUngrabServer(tempdisp); XFlush(tempdisp); + if (lyxerr.debugging()) { lyxerr << "Releasing the server" << endl; } XCloseDisplay(tempdisp); // set up environment - while (environ[ne]) ++ne; - env = (char **) malloc(sizeof(char*)*(ne+2)); + while (environ[ne]) + ++ne; + typedef char * char_p; + env = new char_p[ne + 2]; +#ifdef HAVE_SSTREAM + string tmp = t2.str().c_str(); + env[0] = new char[tmp.size() + 1]; + std::copy(tmp.begin(), tmp.end(), env[0]); + env[0][tmp.size()] = '\0'; +#else env[0] = tbuf2; - memcpy(&env[1], environ, sizeof(char*)*(ne+1)); +#endif + ::memcpy(&env[1], environ, sizeof(char*) * (ne + 1)); environ = env; // now make gs command // close(0); // close(1); do NOT close. If GS writes out // errors it would hang. (Matthias 290596) - sprintf(rbuf, "-r%gx%g", p->rx, p->ry); - sprintf(gbuf, "-g%dx%d", p->data->wid, p->data->hgh); + + string rbuf = "-r" + tostr(p->rx) + "x" + tostr(p->ry); + string gbuf = "-g" + tostr(p->data->wid) + "x" + tostr(p->data->hgh); + // now chdir into dir with .eps file, to be on the safe // side - chdir(OnlyPath(p->data->fname).c_str()); + ::chdir(OnlyPath(p->data->fname).c_str()); // make temp file name - sprintf(tbuf, "%s/~lyxgs%d.ps", system_tempdir.c_str(), - int(getpid())); + string tmpf = make_tmp(getpid()); if (lyxerr.debugging()) { - printf("starting gs %s %s, pid: %d\n", tbuf, - p->data->fname.c_str(), int(getpid())); + lyxerr << "starting gs " << tmpf << " " + << p->data->fname + << ", pid: " << getpid() << endl; } - int err = execlp(lyxrc->ps_command.c_str(), - lyxrc->ps_command.c_str(), + int err = ::execlp(lyxrc.ps_command.c_str(), + lyxrc.ps_command.c_str(), "-sDEVICE=x11", "-dNOPAUSE", "-dQUIET", "-dSAFER", - rbuf, gbuf, tbuf, + rbuf.c_str(), gbuf.c_str(), tmpf.c_str(), p->data->fname.c_str(), "showpage.ps", "quit.ps", "-", 0); // if we are still there, an error occurred. lyxerr << "Error executing ghostscript. " << "Code: " << err << endl; lyxerr.debug() << "Cmd: " - << lyxrc->ps_command + << lyxrc.ps_command << " -sDEVICE=x11 " - << tbuf << ' ' + << tmpf.c_str() << ' ' << p->data->fname << endl; _exit(0); // no gs? } @@ -696,72 +741,53 @@ static void runqueue() if (lyxerr.debugging()) { lyxerr << "GS [" << pid << "] started" << endl; } - gsqueue = gsqueue->next; - gsrunning++; + p->data->gspid = pid; - delete p; + ++gsrunning; + gsqueue.pop(); } } -static void addwait(int psx, int psy, int pswid, int pshgh, figdata *data) +static +void addwait(int psx, int psy, int pswid, int pshgh, figdata * data) { // recompute the stuff and put in the queue - queue *p, *p2; - p = new queue; - p->ofsx = psx; - p->ofsy = psy; - p->rx = ((float)data->raw_wid*72)/pswid; - p->ry = ((float)data->raw_hgh*72)/pshgh; - - p->data = data; - p->next = 0; - - // now put into queue - p2 = gsqueue; - if (!gsqueue) gsqueue = p; - else { - while (p2->next) p2 = p2->next; - p2->next = p; - } + queue_element p; + p.ofsx = psx; + p.ofsy = psy; + p.rx = (float(data->raw_wid) * 72.0) / pswid; + p.ry = (float(data->raw_hgh) * 72.0) / pshgh; + + p.data = data; + + gsqueue.push(p); // if possible, run the queue runqueue(); } -static figdata *getfigdata(int wid, int hgh, string const & fname, - int psx, int psy, int pswid, int pshgh, - int raw_wid, int raw_hgh, float angle, char flags) +static +figdata * getfigdata(int wid, int hgh, string const & fname, + int psx, int psy, int pswid, int pshgh, + int raw_wid, int raw_hgh, float angle, char flags) { /* first search for an exact match with fname and width/height */ - int i = 0; - figdata *p; - XWindowAttributes wa; - if (fname.empty()) return 0; + if (fname.empty() || !IsFileReadable(fname)) + return 0; - while (i < bmpinsref) { - if (bitmaps[i]->wid == wid && bitmaps[i]->hgh == hgh && - bitmaps[i]->flags == flags && bitmaps[i]->fname==fname && - bitmaps[i]->angle == angle) { - bitmaps[i]->ref++; - return bitmaps[i]; + for (bitmaps_type::iterator it = bitmaps.begin(); + it != bitmaps.end(); ++it) { + if ((*it)->wid == wid && (*it)->hgh == hgh && + (*it)->flags == flags && (*it)->fname == fname && + (*it)->angle == angle) { + (*it)->ref++; + return (*it); } - ++i; - } - /* not found -> create new record or return 0 if no record */ - ++bmpinsref; - if (bmpinsref > bmparrsize) { - // allocate more space - bmparrsize += figallocchunk; - figdata **tmp = (figdata**) malloc(sizeof(figdata*)*bmparrsize); - memcpy(tmp, bitmaps, sizeof(figdata*)*(bmparrsize-figallocchunk)); - free(bitmaps); - bitmaps = tmp; } - p = new figdata; - bitmaps[bmpinsref-1] = p; + figdata * p = new figdata; p->wid = wid; p->hgh = hgh; p->raw_wid = raw_wid; @@ -769,6 +795,8 @@ static figdata *getfigdata(int wid, int hgh, string const & fname, p->angle = angle; p->fname = fname; p->flags = flags; + bitmaps.push_back(p); + XWindowAttributes wa; XGetWindowAttributes(fl_display, fl_get_canvas_id( figinset_canvas), &wa); @@ -800,44 +828,43 @@ static figdata *getfigdata(int wid, int hgh, string const & fname, } -static void getbitmap(figdata *p) +static +void getbitmap(figdata * p) { p->gspid = -1; } -static void makeupdatelist(figdata *p) +static +void makeupdatelist(figdata * p) { - int i; - - for (i = 0; i < figinsref; ++i) if (figures[i]->data == p) { - if (lyxerr.debugging()) { - lyxerr << "Updating inset " << figures[i]->inset - << endl; + for(figures_type::iterator it = figures.begin(); + it != figures.end(); ++it) + if ((*it)->data == p) { + if (lyxerr.debugging()) { + lyxerr << "Updating inset " + << (*it)->inset + << endl; + } + // add inset figures[i]->inset into to_update list + current_view->pushIntoUpdateList((*it)->inset); } - //UpdateInset(figures[i]->inset); - // add inset figures[i]->inset into to_update list - PutInsetIntoInsetUpdateList(figures[i]->inset); - } } -void sigchldchecker(pid_t pid, int *status) +// this func is only "called" in spellchecker.C +void sigchldchecker(pid_t pid, int * status) { - int i; - figdata *p; - - bool pid_handled = false; - lyxerr.debug() << "Got pid = " << pid << endl; - pid_handled = false; - for (i = bmpinsref - 1; i >= 0; --i) { - if (bitmaps[i]->reading && pid == bitmaps[i]->gspid) { + bool pid_handled = false; + for (bitmaps_type::iterator it = bitmaps.begin(); + it != bitmaps.end(); ++it) { + if ((*it)->reading && pid == (*it)->gspid) { lyxerr.debug() << "Found pid in bitmaps" << endl; // now read the file and remove it from disk - p = bitmaps[i]; + figdata * p = (*it); p->reading = false; - if (bitmaps[i]->gsdone) *status = 0; + if ((*it)->gsdone) *status = 0; if (*status == 0) { lyxerr.debug() << "GS [" << pid << "] exit OK." << endl; @@ -854,39 +881,27 @@ void sigchldchecker(pid_t pid, int *status) p->broken = false; } else { // remove temporary files - char tmp[128]; - sprintf(tmp, "%s/~lyxgs%d.ps", - system_tempdir.c_str(), - p->gspid); - unlink(tmp); + unlink(make_tmp(p->gspid).c_str()); p->gspid = -1; p->broken = true; } - makeupdatelist(bitmaps[i]); - gsrunning--; + makeupdatelist((*it)); + --gsrunning; runqueue(); pid_handled = true; } } if (!pid_handled) { lyxerr.debug() << "Checking pid in pidwait" << endl; - pidwait *p = pw, *prev = 0; - while (p) { - if (pid == p->pid) { - lyxerr.debug() << "Found pid in pidwait" << endl; - lyxerr.debug() << "Caught child pid of recompute routine " << pid << endl; - if (prev) - prev->next = p->next; - else - pw = p->next; - free(p); - break; - } - prev = p; - p = p->next; + list::iterator it = find(pidwaitlist.begin(), + pidwaitlist.end(), pid); + if (it != pidwaitlist.end()) { + lyxerr.debug() << "Found pid in pidwait\n" + << "Caught child pid of recompute " + "routine" << pid << endl; + pidwaitlist.erase(it); } } - if (pid == -1) { lyxerr.debug() << "waitpid error" << endl; switch (errno) { @@ -917,35 +932,26 @@ void sigchldchecker(pid_t pid, int *status) } -static void getbitmaps() +static +void getbitmaps() { - int i; bitmap_waiting = false; - for (i = 0; i < bmpinsref; ++i) - if (bitmaps[i]->gspid > 0 && !bitmaps[i]->reading) - getbitmap(bitmaps[i]); + for (bitmaps_type::iterator it = bitmaps.begin(); + it != bitmaps.end(); ++it) + if ((*it)->gspid > 0 && !(*it)->reading) + getbitmap((*it)); } -static void RegisterFigure(InsetFig *fi) +static +void RegisterFigure(InsetFig * fi) { - Figref *tmpfig; - - if (figinsref == 0) InitFigures(); + if (figures.empty()) InitFigures(); fi->form = 0; - ++figinsref; - if (figinsref > figarrsize) { - // allocate more space - figarrsize += figallocchunk; - Figref **tmp = (Figref**) malloc(sizeof(Figref*)*figarrsize); - memcpy(tmp, figures, sizeof(Figref*)*(figarrsize-figallocchunk)); - free(figures); - figures = tmp; - } - tmpfig = new Figref; + Figref * tmpfig = new Figref; tmpfig->data = 0; tmpfig->inset = fi; - figures[figinsref-1] = tmpfig; + figures.push_back(tmpfig); fi->figure = tmpfig; if (lyxerr.debugging()) { @@ -955,21 +961,10 @@ static void RegisterFigure(InsetFig *fi) } -int FindFigIndex(Figref *tmpfig) -{ - int i = 0; - while (i < figinsref) { - if (figures[i] == tmpfig) return i; - ++i; - } - return i; -} - - -static void UnregisterFigure(InsetFig *fi) +static +void UnregisterFigure(InsetFig * fi) { - Figref *tmpfig = fi->figure; - int i; + Figref * tmpfig = fi->figure; if (tmpfig->data) freefigdata(tmpfig->data); if (tmpfig->inset->form) { @@ -979,45 +974,21 @@ static void UnregisterFigure(InsetFig *fi) fl_hide_form(tmpfig->inset->form->Figure); } #if FL_REVISION == 89 -#warning Reactivate this free_form calls + // CHECK Reactivate this free_form calls #else fl_free_form(tmpfig->inset->form->Figure); - free(tmpfig->inset->form); + free(tmpfig->inset->form); // Why free? tmpfig->inset->form = 0; #endif } - i = FindFigIndex(tmpfig); - --figinsref; - while (i < figinsref) { - figures[i] = figures[i+1]; - ++i; - } + figures.erase(find(figures.begin(), figures.end(), tmpfig)); delete tmpfig; - if (figinsref == 0) DoneFigures(); + if (figures.empty()) DoneFigures(); } -static char* NextToken(FILE *myfile) -{ - char* token = 0; - char c; - int i = 0; - - if (!feof(myfile)) { - token = new char[256]; - do { - c = fgetc(myfile); - token[i++]=c; - } while (!feof(myfile) && !isspace(c)); - - token[i-1]='\0'; /* just the end of a command */ - } - return token; -} - - -InsetFig::InsetFig(int tmpx, int tmpy, Buffer *o) +InsetFig::InsetFig(int tmpx, int tmpy, Buffer * o) : owner(o) { wid = tmpx; @@ -1029,6 +1000,7 @@ InsetFig::InsetFig(int tmpx, int tmpy, Buffer *o) pflags = flags = 9; psubfigure = subfigure = false; xwid = xhgh = angle = 0; + pswid = pshgh = 0; raw_wid = raw_hgh = 0; changedfname = false; RegisterFigure(this); @@ -1044,94 +1016,98 @@ InsetFig::~InsetFig() } -int InsetFig::Ascent(LyXFont const&) const +int InsetFig::ascent(Painter &, LyXFont const &) const { return hgh + 3; } -int InsetFig::Descent(LyXFont const&) const +int InsetFig::descent(Painter &, LyXFont const &) const { return 1; } -int InsetFig::Width(LyXFont const&) const +int InsetFig::width(Painter &, LyXFont const &) const { return wid + 2; } -void InsetFig::Draw(LyXFont font, LyXScreen &scr, int baseline, float &x) +void InsetFig::draw(Painter & pain, LyXFont const & f, + int baseline, float & x) const { + LyXFont font(f); + if (bitmap_waiting) getbitmaps(); - + // I wish that I didn't have to use this // but the figinset code is so complicated so // I don't want to fiddle with it now. - unsigned long pm = scr.getForeground(); - + if (figure && figure->data && figure->data->bitmap && !figure->data->reading && !figure->data->broken) { // draw the bitmap - XCopyArea(fl_display, figure->data->bitmap, pm, getGC(gc_copy), - 0, 0, wid, hgh, int(x+1), baseline-hgh); - XFlush(fl_display); - if (flags & 4) XDrawRectangle(fl_display, pm, getGC(gc_copy), - int(x), baseline - hgh - 1, - wid+1, hgh+1); + pain.pixmap(int(x + 1), baseline - hgh, + wid, hgh, figure->data->bitmap); + + if (flags & 4) + pain.rectangle(int(x), baseline - hgh - 1, + wid + 1, hgh + 1); + } else { char * msg = 0; // draw frame - XDrawRectangle(fl_display, pm, getGC(gc_copy), - (int) x, - baseline - hgh - 1, wid+1, hgh+1); - if (figure && figure->data) { - if (figure->data->broken) msg = _("[render error]"); - else if (figure->data->reading) msg = _("[rendering ... ]"); - } else - if (fname.empty()) msg = _("[no file]"); - else if ((flags & 3) == 0) msg = _("[not displayed]"); - else if (lyxrc->ps_command.empty()) msg = _("[no ghostscript]"); + pain.rectangle(x, baseline - hgh - 1, wid + 1, hgh + 1); + if (figure && figure->data) { + if (figure->data->broken) msg = _("[render error]"); + else if (figure->data->reading) msg = _("[rendering ... ]"); + } + else if (fname.empty()) + msg = _("[no file]"); + else if (!IsFileReadable(fname)) + msg = _("[bad file name]"); + else if ((flags & 3) == 0) + msg = _("[not displayed]"); + else if (lyxrc.ps_command.empty()) + msg = _("[no ghostscript]"); + if (!msg) msg = _("[unknown error]"); - font.setFamily (LyXFont::SANS_FAMILY); - font.setSize (LyXFont::SIZE_FOOTNOTE); + font.setFamily(LyXFont::SANS_FAMILY); + font.setSize(LyXFont::SIZE_FOOTNOTE); string justname = OnlyFilename (fname); - font.drawString(justname,pm, - baseline - font.maxAscent() - 4, - (int) x + 8); - font.setSize (LyXFont::SIZE_TINY); - font.drawText (msg, strlen(msg),pm, - baseline - 4, - (int) x + 8); - + pain.text(int(x + 8), baseline - lyxfont::maxAscent(font) - 4, + justname, font); + + font.setSize(LyXFont::SIZE_TINY); + pain.text(int(x + 8), baseline - 4, msg, strlen(msg), font); } - x += Width(font); // ? + x += width(pain, font); // ? } -void InsetFig::Write(FILE *file) +void InsetFig::Write(ostream & os) const { Regenerate(); - fprintf(file, "Figure size %d %d\n", wid, hgh); + os << "Figure size " << wid << " " << hgh << "\n"; if (!fname.empty()) { - string buf1 = OnlyPath(owner->getFileName()); - string fname2 = MakeRelPath(fname, buf1); - fprintf(file, "file %s\n", fname2.c_str()); + string buf1 = OnlyPath(owner->fileName()); + string fname2 = MakeRelPath(fname, buf1); + os << "file " << fname2 << "\n"; } if (!subcaption.empty()) - fprintf(file, "subcaption %s\n", subcaption.c_str()); - if (wtype) fprintf(file, "width %d %g\n", wtype, xwid); - if (htype) fprintf(file, "height %d %g\n", htype, xhgh); - if (angle != 0) fprintf(file, "angle %g\n", angle); - fprintf(file, "flags %d\n", flags); - if (subfigure) fprintf(file, "subfigure\n"); + os << "subcaption " << subcaption << "\n"; + if (wtype) os << "width " << static_cast(wtype) << " " << xwid << "\n"; + if (htype) os << "height " << static_cast(htype) << " " << xhgh << "\n"; + if (angle != 0) os << "angle " << angle << "\n"; + os << "flags " << flags << "\n"; + if (subfigure) os << "subfigure\n"; } -void InsetFig::Read(LyXLex &lex) +void InsetFig::Read(LyXLex & lex) { string buf; bool finished = false; @@ -1149,7 +1125,7 @@ void InsetFig::Read(LyXLex &lex) } else if (token == "file") { if (lex.next()) { buf = lex.GetString(); - string buf1 = OnlyPath(owner->getFileName()); + string buf1 = OnlyPath(owner->fileName()); fname = MakeAbsPath(buf, buf1); changedfname = true; } @@ -1215,50 +1191,49 @@ void InsetFig::Read(LyXLex &lex) } -int InsetFig::Latex(FILE *file, signed char /* fragile*/ ) +int InsetFig::Latex(ostream & os, + bool /* fragile*/, bool /* fs*/) const { Regenerate(); - if (!cmd.empty()) fprintf(file, "%s ", cmd.c_str()); + if (!cmd.empty()) os << cmd << " "; return 0; } -int InsetFig::Latex(string &file, signed char /* fragile*/ ) +int InsetFig::Ascii(ostream &) const { - Regenerate(); - file += cmd + ' '; return 0; } -int InsetFig::Linuxdoc(string &/*file*/) +int InsetFig::Linuxdoc(ostream &) const { return 0; } -int InsetFig::DocBook(string &file) +int InsetFig::DocBook(ostream & os) const { - string figurename=fname; + string figurename = fname; if(suffixIs(figurename, ".eps")) - figurename.erase(fname.length() - 5); + figurename.erase(fname.length() - 4); - file += "@"; + os << "@"; return 0; } -void InsetFig::Validate(LaTeXFeatures &features) const +void InsetFig::Validate(LaTeXFeatures & features) const { features.graphics = true; if (subfigure) features.subfigure = true; } -unsigned char InsetFig::Editable() const +Inset::EDITABLE InsetFig::Editable() const { - return 1; + return IS_EDITABLE; } @@ -1268,7 +1243,13 @@ bool InsetFig::Deletable() const } -void InsetFig::Edit(int, int) +char const * InsetFig::EditMessage() const +{ + return _("Opened figure"); +} + + +void InsetFig::Edit(BufferView * bv, int, int, unsigned int) { lyxerr.debug() << "Editing InsetFig." << endl; Regenerate(); @@ -1276,15 +1257,15 @@ void InsetFig::Edit(int, int) // We should have RO-versions of the form instead. // The actual prevention of altering a readonly doc // is done in CallbackFig() - if(current_view->buffer()->isReadonly()) - WarnReadonly(); + if(bv->buffer()->isReadonly()) + WarnReadonly(bv->buffer()->fileName()); if (!form) { form = create_form_Figure(); fl_set_form_atclose(form->Figure, CancelCloseBoxCB, 0); - fl_set_object_return(form->Angle,FL_RETURN_ALWAYS); - fl_set_object_return(form->Width,FL_RETURN_ALWAYS); - fl_set_object_return(form->Height,FL_RETURN_ALWAYS); + fl_set_object_return(form->Angle, FL_RETURN_ALWAYS); + fl_set_object_return(form->Width, FL_RETURN_ALWAYS); + fl_set_object_return(form->Height, FL_RETURN_ALWAYS); } RestoreForm(); if (form->Figure->visible) { @@ -1296,9 +1277,9 @@ void InsetFig::Edit(int, int) } -Inset *InsetFig::Clone() +Inset * InsetFig::Clone() const { - InsetFig *tmp = new InsetFig(100, 100, owner); + InsetFig * tmp = new InsetFig(100, 100, owner); if (lyxerr.debugging()) { lyxerr << "Clone Figure: buffer:[" @@ -1324,8 +1305,11 @@ Inset *InsetFig::Clone() tmp->pswid = pswid; tmp->pshgh = pshgh; tmp->fname = fname; - if (!fname.empty() && (flags & 3) && !lyxrc->ps_command.empty()) { - // do not display if there is "do not display" chosen (Matthias 260696) + if (!fname.empty() && IsFileReadable(fname) + && (flags & 3) && !lyxrc.ps_command.empty() + && lyxrc.use_gui) { + // do not display if there is + // "do not display" chosen (Matthias 260696) tmp->figure->data = getfigdata(wid, hgh, fname, psx, psy, pswid, pshgh, raw_wid, raw_hgh, angle, flags & (3|8)); @@ -1344,10 +1328,34 @@ Inset::Code InsetFig::LyxCode() const } -void InsetFig::Regenerate() +static +string stringify(InsetFig::HWTYPE hw, float f, string suffix) +{ + string res; + switch (hw) { + case InsetFig::DEF: + break; + case InsetFig::CM:// \resizebox*{h-length}{v-length}{text} + res = tostr(f) + "cm"; + break; + case InsetFig::IN: + res = tostr(f) + "in"; + break; + case InsetFig::PER_PAGE: + res = tostr(f/100) + "\\text" + suffix; + break; + case InsetFig::PER_COL: + // Doesn't occur for htype... + res = tostr(f/100) + "\\column" + suffix; + break; + } + return res; +} + + +void InsetFig::Regenerate() const { string cmdbuf; - string gcmd; string resizeW, resizeH; string rotate, recmd; @@ -1355,77 +1363,15 @@ void InsetFig::Regenerate() cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}"; cmd += _("empty figure path"); cmd += '}'; - //if (form) fl_set_object_label(form->cmd, ""); return; } - string buf1 = OnlyPath(owner->getFileName()); + string buf1 = OnlyPath(owner->fileName()); string fname2 = MakeRelPath(fname, buf1); - gcmd = "\\includegraphics{" + fname2 + '}'; - - switch (wtype) { - case DEF: - break; - case CM:{// \resizebox*{h-length}{v-length}{text} - char buf[10]; - sprintf(buf, "%g", xwid); // should find better - resizeW = buf; - resizeW += "cm"; - break; - } - case IN: { - char buf[10]; - sprintf(buf, "%g", xwid); - resizeW = buf; - resizeW += "in"; - break; - } - case PER_PAGE:{ - char buf[10]; - sprintf(buf, "%g", xwid/100); - resizeW = buf; - resizeW += "\\textwidth"; - break; - } - case PER_COL:{ - char buf[10]; - sprintf(buf, "%g", xwid/100); - resizeW = buf; - resizeW += "\\columnwidth"; - break; - } - } - - switch (htype) { - case DEF: - break; - case CM: { - char buf[10]; - sprintf(buf, "%g", xhgh); - resizeH = buf; - resizeH += "cm"; - break; - } - case IN:{ - char buf[10]; - sprintf(buf, "%g", xhgh); - resizeH = buf; - resizeH += "in"; - break; - } - case PER_PAGE: { - char buf[10]; - sprintf(buf, "%g", xhgh/100); - resizeH = buf; - resizeH += "\\textheight"; - break; - } - case PER_COL: { - // Doesn't occur; case exists to suppress compiler warnings. - break; - } - } + string gcmd = "\\includegraphics{" + fname2 + '}'; + resizeW = stringify(wtype, xwid, "width"); + resizeH = stringify(htype, xhgh, "height"); if (!resizeW.empty() || !resizeH.empty()) { recmd = "\\resizebox*{"; @@ -1443,12 +1389,8 @@ void InsetFig::Regenerate() if (angle != 0) { - char buf[10]; - sprintf(buf, "%g", angle); // \rotatebox{angle}{text} - rotate = "\\rotatebox{"; - rotate += buf; - rotate += "}{"; + rotate = "\\rotatebox{" + tostr(angle) + "}{"; } cmdbuf = recmd; @@ -1459,110 +1401,41 @@ void InsetFig::Regenerate() if (subfigure) { if (!subcaption.empty()) cmdbuf = "\\subfigure[" + subcaption + - "]{" + cmdbuf + "}"; + "]{" + cmdbuf + "}"; else cmdbuf = "\\subfigure{" + cmdbuf + "}"; } cmd = cmdbuf; - - //if (form) fl_set_object_label(form->cmd, cmd.c_str()); } void InsetFig::TempRegenerate() { - string gcmd; string cmdbuf; string resizeW, resizeH; string rotate, recmd; - string tsubcap; - char const *tfname; // *textra; - float tangle, txwid, txhgh; - - tfname = fl_get_input(form->EpsFile); - tsubcap = fl_get_input(form->Subcaption); - tangle = atof(fl_get_input(form->Angle)); - txwid = atof(fl_get_input(form->Width)); - txhgh = atof(fl_get_input(form->Height)); + char const * tfname = fl_get_input(form->EpsFile); + string tsubcap = fl_get_input(form->Subcaption); + float tangle = atof(fl_get_input(form->Angle)); + float txwid = atof(fl_get_input(form->Width)); + float txhgh = atof(fl_get_input(form->Height)); if (!tfname || !*tfname) { - //fl_set_object_label(form->cmd, ""); - //fl_redraw_object(form->cmd); - cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}"; - cmd += _("empty figure path"); + cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}"; + cmd += _("empty figure path"); cmd += '}'; return; } - string buf1 = OnlyPath(owner->getFileName()); + string buf1 = OnlyPath(owner->fileName()); string fname2 = MakeRelPath(tfname, buf1); // \includegraphics*[][]{file} - gcmd = "\\includegraphics{" + fname2 + '}'; - - switch (twtype) { - case DEF: - break; - case CM: {// \resizebox*{h-length}{v-length}{text} - char buf[10]; - sprintf(buf, "%g", txwid); // should find better - resizeW = buf; - resizeW += "cm"; - break; - } - case IN: { - char buf[10]; - sprintf(buf, "%g", txwid); - resizeW = buf; - resizeW += "in"; - break; - } - case PER_PAGE: { - char buf[10]; - sprintf(buf, "%g", txwid/100); - resizeW = buf; - resizeW += "\\textwidth"; - break; - } - case PER_COL: { - char buf[10]; - sprintf(buf, "%g", txwid/100); - resizeW = buf; - resizeW += "\\columnwidth"; - break; - } - } + string gcmd = "\\includegraphics{" + fname2 + '}'; - switch (thtype) { - case DEF: - break; - case CM: { - char buf[10]; - sprintf(buf, "%g", txhgh); - resizeH = buf; - resizeH += "cm"; - break; - } - case IN: { - char buf[10]; - sprintf(buf, "%g", txhgh); - resizeH = buf; - resizeH += "in"; - break; - } - case PER_PAGE: { - char buf[10]; - sprintf(buf, "%g", txhgh/100); - resizeH = buf; - resizeH += "\\textheight"; - break; - } - case PER_COL: { - // Doesn't occur; case exists to suppress compiler warnings. - break; - } - } + resizeW = stringify(twtype, txwid, "width"); + resizeH = stringify(thtype, txhgh, "height"); // \resizebox*{h-length}{v-length}{text} if (!resizeW.empty() || !resizeH.empty()) { @@ -1580,47 +1453,36 @@ void InsetFig::TempRegenerate() } if (tangle != 0) { - char buf[10]; - sprintf(buf, "%g", tangle); // \rotatebox{angle}{text} - rotate = "\\rotatebox{"; - rotate += buf; - rotate += "}{"; + rotate = "\\rotatebox{" + tostr(tangle) + "}{"; } - cmdbuf = recmd; - cmdbuf += rotate; - cmdbuf += gcmd; + cmdbuf = recmd + rotate + gcmd; if (!rotate.empty()) cmdbuf += '}'; if (!recmd.empty()) cmdbuf += '}'; if (psubfigure && !tsubcap.empty()) { cmdbuf = string("\\subfigure{") + tsubcap - + string("}{") + cmdbuf + "}"; + + string("}{") + cmdbuf + "}"; } - - - //fl_set_object_label(form->cmd, cmdbuf.c_str()); - //fl_redraw_object(form->cmd); } void InsetFig::Recompute() { bool changed = changedfname; - int newx, newy, nraw_x, nraw_y, frame_wid, frame_hgh; - float sin_a, cos_a; + int newx, newy, nraw_x, nraw_y; if (changed) GetPSSizes(); - sin_a = sin (angle / DEG2PI); /* rotation; H. Zeller 021296 */ - cos_a = cos (angle / DEG2PI); - frame_wid = (int) ceil (fabs(cos_a * pswid) + fabs(sin_a * pshgh)); - frame_hgh= (int) ceil (fabs(cos_a * pshgh) + fabs(sin_a * pswid)); + float sin_a = sin (angle / DEG2PI); /* rotation; H. Zeller 021296 */ + float cos_a = cos (angle / DEG2PI); + int frame_wid = int(ceil(fabs(cos_a * pswid) + fabs(sin_a * pshgh))); + int frame_hgh= int(ceil(fabs(cos_a * pshgh) + fabs(sin_a * pswid))); /* now recompute wid and hgh, and if that is changed, set changed */ /* this depends on chosen size of the picture and its bbox */ // This will be redone in 0.13 ... (hen) - if (!fname.empty()) { + if (!fname.empty() && IsFileReadable(fname)) { // say, total width is 595 pts, as A4 in TeX, thats in 1/72" */ newx = frame_wid; @@ -1629,16 +1491,16 @@ void InsetFig::Recompute() case DEF: break; case CM: /* cm */ - newx = (int) (28.346*xwid); + newx = int(28.346 * xwid); break; case IN: /* in */ - newx = (int) (72*xwid); + newx = int(72 * xwid); break; case PER_PAGE: /* % of page */ - newx = (int) (5.95*xwid); + newx = int(5.95 * xwid); break; case PER_COL: /* % of col */ - newx = (int) (2.975*xwid); + newx = int(2.975 * xwid); break; } @@ -1649,20 +1511,21 @@ void InsetFig::Recompute() //lyxerr << "This should not happen!" << endl; break; case CM: /* cm */ - newy = (int) (28.346*xhgh); + newy = int(28.346 * xhgh); break; case IN: /* in */ - newy = (int) (72*xhgh); + newy = int(72 * xhgh); break; case PER_PAGE: /* % of page */ - newy = (int) (8.42*xhgh); + newy = int(8.42 * xhgh); break; case PER_COL: // Doesn't occur; case exists to suppress // compiler warnings. break; } - if (htype && !wtype && frame_hgh) newx = newy*frame_wid/frame_hgh; + if (htype && !wtype && frame_hgh) + newx = newy*frame_wid/frame_hgh; } else { newx = wid; newy = hgh; @@ -1671,12 +1534,12 @@ void InsetFig::Recompute() if (frame_wid == 0) nraw_x = 5; else - nraw_x = (int) ((1.0 * pswid * newx)/frame_wid); + nraw_x = int((1.0 * pswid * newx)/frame_wid); if (frame_hgh == 0) nraw_y = 5; else - nraw_y = (int) ((1.0 * pshgh * newy)/frame_hgh); + nraw_y = int((1.0 * pshgh * newy)/frame_hgh); // cannot be zero, actually, set it to some minimum, so its clickable if (newx < 5) newx = 5; @@ -1695,10 +1558,11 @@ void InsetFig::Recompute() subfigure = psubfigure; if (changed) { - figdata *pf = figure->data; + figdata * pf = figure->data; // get new data - if (!fname.empty() && (flags & 3) && !lyxrc->ps_command.empty()) { + if (!fname.empty() && IsFileReadable(fname) && (flags & 3) + && !lyxrc.ps_command.empty()) { // do not display if there is "do not display" // chosen (Matthias 260696) figure->data = getfigdata(wid, hgh, fname, @@ -1718,11 +1582,9 @@ void InsetFig::Recompute() void InsetFig::GetPSSizes() { /* get %%BoundingBox: from postscript file */ - int lastchar, c; - char *p = 0; /* defaults to associated size - * ..just in case the PS-file is not readable (Henner,24-Aug-97) + * ..just in case the PS-file is not readable (Henner, 24-Aug-97) */ psx = 0; psy = 0; @@ -1730,10 +1592,10 @@ void InsetFig::GetPSSizes() pshgh = hgh; if (fname.empty()) return; - - FilePtr f(fname, FilePtr::read); + string p; + ifstream ifs(fname.c_str()); - if (!f()) return; // file not found !!!! + if (!ifs) return; // file not found !!!! /* defaults to A4 page */ psx = 0; @@ -1741,44 +1603,39 @@ void InsetFig::GetPSSizes() pswid = 595; pshgh = 842; - lastchar = fgetc(f); + char lastchar = 0; ifs.get(lastchar); for (;;) { - c = fgetc(f); - if (c == EOF) { + char c = 0; ifs.get(c); + if (ifs.eof()) { lyxerr.debug() << "End of (E)PS file reached and" " no BoundingBox!" << endl; break; } if (c == '%' && lastchar == '%') { - p = NextToken(f); - if (!p) break; - if (strcmp(p, "EndComments") == 0) break; - if (strcmp(p, "BoundingBox:") == 0) { + ifs >> p; + if (p.empty()) break; + lyxerr.debug() << "Token: `" << p << "'" << endl; + if (p == "BoundingBox:") { float fpsx, fpsy, fpswid, fpshgh; - if (fscanf(f, "%f %f %f %f", &fpsx, &fpsy, - &fpswid, &fpshgh) == 4) { - psx = (int) fpsx; - psy = (int) fpsy; - pswid = (int) fpswid; - pshgh = (int) fpshgh; - } - + if (ifs >> fpsx >> fpsy >> fpswid >> fpshgh) { + psx = int(fpsx); + psy = int(fpsy); + pswid = int(fpswid); + pshgh = int(fpshgh); + } if (lyxerr.debugging()) { lyxerr << "%%%%BoundingBox:" << psx << ' ' << psy << ' ' << pswid << ' ' << pshgh << endl; - break; } + break; } c = 0; - delete[] p; - p = 0; } lastchar = c; } - if (p) delete[] p; pswid -= psx; pshgh -= psy; @@ -1788,10 +1645,10 @@ void InsetFig::GetPSSizes() void InsetFig::CallbackFig(long arg) { bool regen = false; - char const *p; + char const * p; if (lyxerr.debugging()) { - printf("Figure callback, arg %ld\n", arg); + lyxerr << "Figure callback, arg " << arg << endl; } switch (arg) { @@ -1897,8 +1754,7 @@ void InsetFig::CallbackFig(long arg) break; case 7: /* apply */ case 8: /* ok (apply and close) */ - if(!current_view->buffer()->isReadonly()) - { + if(!current_view->buffer()->isReadonly()) { wtype = twtype; htype = thtype; xwid = atof(fl_get_input(form->Width)); @@ -1906,13 +1762,13 @@ void InsetFig::CallbackFig(long arg) angle = atof(fl_get_input(form->Angle)); p = fl_get_input(form->EpsFile); if (p && *p) { - string buf1 = OnlyPath(owner->getFileName()); + string buf1 = OnlyPath(owner->fileName()); fname = MakeAbsPath(p, buf1); changedfname = true; } else { if (!fname.empty()) { changedfname = true; - fname.clear(); + fname.erase(); } } subcaption = fl_get_input(form->Subcaption); @@ -1924,15 +1780,15 @@ void InsetFig::CallbackFig(long arg) lyxerr << "Update: [" << wid << 'x' << hgh << ']' << endl; } - UpdateInset(this); + current_view->updateInset(this, true); if (arg == 8) { fl_set_focus_object(form->Figure, form->OkBtn); fl_hide_form(form->Figure); #if FL_REVISION == 89 -#warning Reactivate this free_form calls + // CHECK Reactivate this free_form calls #else fl_free_form(form->Figure); - free(form); + free(form); // Why free? form = 0; #endif } @@ -1946,10 +1802,11 @@ void InsetFig::CallbackFig(long arg) fl_set_focus_object(form->Figure, form->OkBtn); fl_hide_form(form->Figure); #if FL_REVISION == 89 -#warning Reactivate this free_form calls + // CHECK Reactivate this free_form calls + // Jug, is this still a problem? #else fl_free_form(form->Figure); - free(form); + free(form); // Why free? form = 0; #endif break; @@ -1958,7 +1815,9 @@ void InsetFig::CallbackFig(long arg) if (regen) TempRegenerate(); } -inline void DisableFigurePanel(FD_Figure * const form) + +inline +void DisableFigurePanel(FD_Figure * const form) { fl_deactivate_object(form->EpsFile); fl_deactivate_object(form->Browse); @@ -1993,7 +1852,9 @@ inline void DisableFigurePanel(FD_Figure * const form) fl_set_object_lcol (form->ApplyBtn, FL_INACTIVE); } -inline void EnableFigurePanel(FD_Figure * const form) + +inline +void EnableFigurePanel(FD_Figure * const form) { fl_activate_object(form->EpsFile); fl_activate_object(form->Browse); @@ -2028,11 +1889,9 @@ inline void EnableFigurePanel(FD_Figure * const form) fl_set_object_lcol (form->ApplyBtn, FL_BLACK); } + void InsetFig::RestoreForm() { - char buf[32]; - int pflags; - EnableFigurePanel(form); twtype = wtype; @@ -2060,7 +1919,7 @@ void InsetFig::RestoreForm() fl_activate_object(form->Height); } - pflags = flags & 3; + int pflags = flags & 3; fl_set_button(form->Wysiwyg0, (pflags == 0)); fl_set_button(form->Wysiwyg1, (pflags == 1)); fl_set_button(form->Wysiwyg2, (pflags == 2)); @@ -2070,14 +1929,11 @@ void InsetFig::RestoreForm() fl_set_button(form->Subfigure, (subfigure != 0)); pflags = flags; psubfigure = subfigure; - sprintf(buf, "%g", xwid); - fl_set_input(form->Width, buf); - sprintf(buf, "%g", xhgh); - fl_set_input(form->Height, buf); - sprintf(buf, "%g", angle); - fl_set_input(form->Angle, buf); + fl_set_input(form->Width, tostr(xwid).c_str()); + fl_set_input(form->Height, tostr(xhgh).c_str()); + fl_set_input(form->Angle, tostr(angle).c_str()); if (!fname.empty()){ - string buf1 = OnlyPath(owner->getFileName()); + string buf1 = OnlyPath(owner->fileName()); string fname2 = MakeRelPath(fname, buf1); fl_set_input(form->EpsFile, fname2.c_str()); } @@ -2090,11 +1946,9 @@ void InsetFig::RestoreForm() } -void InsetFig::Preview(char const *p) +void InsetFig::Preview(char const * p) { - int pid; - - pid = fork(); + int pid = fork(); if (pid == -1) { lyxerr << "Cannot fork process!" << endl; @@ -2105,12 +1959,12 @@ void InsetFig::Preview(char const *p) return; // parent process } - string buf1 = OnlyPath(owner->getFileName()); + string buf1 = OnlyPath(owner->fileName()); string buf2 = MakeAbsPath(p, buf1); lyxerr << "Error during rendering " - << execlp(lyxrc->view_pspic_command.c_str(), - lyxrc->view_pspic_command.c_str(), + << execlp(lyxrc.view_pspic_command.c_str(), + lyxrc.view_pspic_command.c_str(), buf2.c_str(), 0) << endl; _exit(0); @@ -2119,32 +1973,31 @@ void InsetFig::Preview(char const *p) void InsetFig::BrowseFile() { - string buf, buf2, bufclip; static string current_figure_path; static int once = 0; LyXFileDlg fileDlg; if (lyxerr.debugging()) { lyxerr << "Filename: " - << owner->getFileName() << endl; + << owner->fileName() << endl; } string p = fl_get_input(form->EpsFile); - buf = MakeAbsPath(owner->getFileName()); - buf2 = OnlyPath(buf); + string buf = MakeAbsPath(owner->fileName()); + string buf2 = OnlyPath(buf); if (!p.empty()) { buf = MakeAbsPath(p, buf2); buf = OnlyPath(buf); } else { - buf = OnlyPath(owner->getFileName().c_str()); + buf = OnlyPath(owner->fileName().c_str()); } // Does user clipart directory exist? - bufclip = AddName (user_lyxdir, "clipart"); + string bufclip = AddName (user_lyxdir, "clipart"); FileInfo fileInfo(bufclip); if (!(fileInfo.isOK() && fileInfo.isDir())) - // No - bail out to system clipart directory - bufclip = AddName (system_lyxdir, "clipart"); + // No - bail out to system clipart directory + bufclip = AddName (system_lyxdir, "clipart"); fileDlg.SetButton(0, _("Clipart"), bufclip); @@ -2152,15 +2005,16 @@ void InsetFig::BrowseFile() bool error = false; do { - ProhibitInput(); + ProhibitInput(current_view); if (once) { - p =fileDlg.Select(_("EPS Figure"), current_figure_path, + p = fileDlg.Select(_("EPS Figure"), + current_figure_path, "*ps", string()); } else { p = fileDlg.Select(_("EPS Figure"), buf, "*ps", string()); } - AllowInput(); + AllowInput(current_view); if (p.empty()) return; @@ -2169,9 +2023,10 @@ void InsetFig::BrowseFile() once = 1; if (contains(p, "#") || contains(p, "~") || contains(p, "$") - || contains(p, "%") || contains(p, " ")) - { - WriteAlert(_("Filename can't contain any of these characters:"), // xgettext:no-c-format + || contains(p, "%") || contains(p, " ")) { + WriteAlert(_("Filename can't contain any " + "of these characters:"), + // xgettext:no-c-format _("space, '#', '~', '$' or '%'.")); error = true; } @@ -2181,7 +2036,7 @@ void InsetFig::BrowseFile() } -void GraphicsCB(FL_OBJECT *obj, long arg) +void GraphicsCB(FL_OBJECT * obj, long arg) { /* obj->form contains the form */ @@ -2190,14 +2045,15 @@ void GraphicsCB(FL_OBJECT *obj, long arg) } /* find inset we were reacting to */ - for (int i = 0; i < figinsref; ++i) - if (figures[i]->inset->form && figures[i]->inset->form->Figure + for (figures_type::iterator it = figures.begin(); + it != figures.end(); ++it) + if ((*it)->inset->form && (*it)->inset->form->Figure == obj->form) { - if (lyxerr.debugging()) { - lyxerr << "Calling back figure " << i << endl; + lyxerr << "Calling back figure " + << (*it) << endl; } - figures[i]->inset->CallbackFig(arg); + (*it)->inset->CallbackFig(arg); return; } } @@ -2205,13 +2061,14 @@ void GraphicsCB(FL_OBJECT *obj, long arg) void HideFiguresPopups() { - for (int i = 0; i < figinsref; ++i) - if (figures[i]->inset->form - && figures[i]->inset->form->Figure->visible) { + for (figures_type::iterator it = figures.begin(); + it != figures.end(); ++it) + if ((*it)->inset->form + && (*it)->inset->form->Figure->visible) { if (lyxerr.debugging()) { - lyxerr << "Hiding figure " << i << endl; + lyxerr << "Hiding figure " << (*it) << endl; } // hide and free the form - figures[i]->inset->CallbackFig(9); + (*it)->inset->CallbackFig(9); } }