DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2153
Version: 1.3-current


If any Mac FLTK-1.3 (or 1.1.9) application uses the Mac OS X print dialog,
and the user opens the extended form of this dialog (that showing many
options) and wants to change the local menu of this dialog,
the application crashes.
I attach a short program that shows this crash.
The problem lies in PMSessionPrintDialog (very) indirectly calling
function HandleMenu of file Fl_mac.cxx for an event that is not generated
by the menu bar, but by the dialog's local menu. This makes the
application crash.
I suggest this solution. Replace in function carbonDispatchHandler

      case kEventCommandProcess:
                GetEventParameter( event, kEventParamDirectObject, 
typeHICommand, NULL,
sizeof(HICommand), NULL, &cmd );
                ret = HandleMenu( &cmd );
        break;

by this code:

      case kEventCommandProcess:
                ret = GetEventParameter( event, kEventParamDirectObject, 
typeHICommand,
NULL, sizeof(HICommand), NULL, &cmd );
                if(ret == noErr && (cmd.attributes & kHICommandFromMenu) != 0) 
ret =
HandleMenu( &cmd );
                else ret = eventNotHandledErr;
        break;

With this, function HandleMenu does not get called by events not coming
from the application's menu bar (and does get called when these events
occur).


Link: http://www.fltk.org/str.php?L2153
Version: 1.3-current
#include "FL/Fl.H"
#include "FL/Fl_Window.H"
#include "FL/Fl_Button.H"
#include "FL/fl_draw.H"
#include "FL/fl_ask.H"
#include <FL/x.H>
#include <Carbon/Carbon.h>


class myPanel : public Fl_Widget {
    FL_EXPORT int handle(int);
public:
    FL_EXPORT void draw(void);
    FL_EXPORT myPanel(int x,int y,int w,int h) :
        Fl_Widget(x,y,w,h,NULL) {
                ;
        }
};

/* prototypes */
int MG_StartPrinting (void);
int MG_StartPage (void);
int MG_EndPage (void);
void MG_EndPrinting (void);
void print(Fl_Widget *wgt, void *data);


int main(int argc, char **argv)
{
        Fl_Window *w = new Fl_Window(200, 200);
        w->resizable(w);
        Fl_Button *b = new Fl_Button(3,3,60, 20, "Print");
        Fl_Window *w2 = (Fl_Window*)new Fl_Window(10, 30, 180, 150);
        w2->resizable(w2);
        w2->box(FL_FLAT_BOX);
        w2->color(FL_WHITE);
        Fl_Widget *panel = (Fl_Widget*)new myPanel(0, 0, w2->w(), w2->h());
        b->callback(print, panel);
        w2->end();
        w->end();
        w->show();
        Fl::run();
}


void myPanel::draw(void)
{
        fl_color(FL_GREEN);
        fl_rect(5,5,150,50);
        fl_color(FL_BLUE);
        fl_line(15,15,130,130);
        fl_font(FL_HELVETICA_ITALIC, 24);
        fl_color(FL_RED);
        fl_line(15,70,48,70);
        fl_draw("Something", 50, 80);
        int w = (int)fl_width("Something");
        fl_line(50,80,50+w,80);
}


void print(Fl_Widget *wgt, void *data)
{
        myPanel *g = (myPanel *)data;
        if( MG_StartPrinting() ) return;
        MG_StartPage();
        g->draw();
        MG_EndPage();
        MG_EndPrinting();
}

int myPanel::handle(int event)
{
        return 1;
}


static PMPrintSession  printSession;
static PMPageFormat    pageFormat = kPMNoPageFormat;
static PMPrintSettings printSettings = kPMNoPrintSettings;
int MG_StartPrinting (void)
//printing using a Quartz graphics context
//returns 0 iff OK
{
        OSStatus status;
        Boolean accepted;
        
        status = PMCreateSession(&printSession);
        if (status != noErr) return 1;
        status = PMCreatePageFormat(&pageFormat);
        status = PMSessionDefaultPageFormat(printSession, pageFormat);
        if (status != noErr) return 1;
        status = PMSessionPageSetupDialog(printSession, pageFormat, &accepted);
        if (status != noErr || !accepted) return 1;
        status = PMCreatePrintSettings(&printSettings);
        if (status != noErr || printSettings == kPMNoPrintSettings) return 1;
        status = PMSessionDefaultPrintSettings (printSession, printSettings);
        if (status != noErr) return 1;
        status = PMSessionPrintDialog(printSession, printSettings, pageFormat, 
&accepted);
        if (!accepted) status = kPMCancel;
        if (status != noErr) return 1;
        status = PMSessionBeginCGDocument(printSession, printSettings, 
pageFormat);
        if (status != noErr) return 1;
        return 0;
}


extern CGContextRef fl_gc;
extern void fl_quartz_restore_line_style_();
int MG_StartPage (void)
{       
        Fl_X::q_release_context();
        OSStatus status = PMSessionBeginPage(printSession, pageFormat, NULL);
        status = PMSessionGetGraphicsContext(printSession,NULL,(void **)&fl_gc);
        PMRect pmRect;
        status = PMGetAdjustedPageRect(pageFormat, &pmRect);
        double h = pmRect.bottom - pmRect.top;
        CGContextTranslateCTM(fl_gc, 20, 20 + h -0.5f);
        CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
        fl_quartz_restore_line_style_();
        CGContextSaveGState(fl_gc);
        return status == noErr;
}


int MG_EndPage (void)
{       
        OSStatus status = PMSessionEndPage(printSession);
        CGContextFlush(fl_gc);
        return status == noErr;
}

void MG_EndPrinting (void)
{
        OSStatus status;
        
        status = PMSessionError(printSession);
        if (status != noErr) {
                fl_alert ("PM Session error %d", status);
        }
        PMSessionEndDocument (printSession);
        
        if (pageFormat != kPMNoPageFormat) {
                PMRelease(pageFormat);
                pageFormat = kPMNoPageFormat;
        }
        if (printSettings != kPMNoPrintSettings) {
                PMRelease(printSettings);
                printSettings = kPMNoPrintSettings;
        }
        PMRelease(printSession);
        fl_gc = 0;
}
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs

Reply via email to