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