On Thu, 15 Nov 2001, Brian Rectanus wrote: > LyX, current CVS compiled with gcc 3.0.2-3 on Debian (Woody/Sid mix) > > libforms-bin 0.89-11 > libforms0.89 0.89-11 > libforms-dev 0.89-11 > > xfree86 4.1.0-9 > > Linux 2.4.12-ac3 SMP > Matrox G450 DualHead, no XINERAMA > > lyx crashes when opening a file on secondary display ':0.1'.
I can reproduce this with xforms-0.88.1, linux-2.2.19, XFree86-4.0.3. I also noticed an X-windows(?) warning message printed for every case below: BadMatch (invalid parameter attributes) I stepped through a fair bit of this and noticed that things like font requests and colour allocations work alright. I also tried commenting out the offending line and got a problem at the call to XDrawString at Painter.C:313 : #9 0x0021de07 in XDrawString () from /usr/X11R6/lib/libX11.so.6 #10 0x08071eb2 in Painter::text (this=0x82a957c, x=74, y=48, s=0x830e740 "Inventory [o\021", ls=9, f=@0xbfffeca8) at Painter.C:313 Commenting this out to see what else breaks gives: #9 0x0020328f in XCopyArea () from /usr/X11R6/lib/libX11.so.6 #10 0x080c4258 in LyXScreen::expose (this=0x83135b0, x=0, y=0, exp_width=667, exp_height=414) at screen.C:110 then commenting that out gives: #9 0x0020328f in XCopyArea () from /usr/X11R6/lib/libX11.so.6 #10 0x080c494d in LyXScreen::showManualCursor (this=0x83135d8, text=0x82ec8b0, x=74, y=48, asc=27, desc=7, shape=BAR_SHAPE) at screen.C:331 This one is interesting because XCreatePixmap is run just before it and it works but XCopyArea doesn't. This call also doesn't use owner->getPixmap(). It uses getWin() instead. So it seems that there is definitely a problem with the contents of the Display struct returned by fl_get_display(). Commenting this call out causes a crash on the next line which is a call to XDrawLine(). Everything else up to this point seems happy to use the display returned by fl_get_display(). The Painter::display variable points to the same Display struct as fl_get_display() returns for all other calls. So why some X calls work and others don't I am at a loss to explain -- except perhaps for attributes of the Display type that may only be used for the ones that break. Display type is hidden from apps but I'm thinking about recompiling with -DXLIB_ILLEGAL_ACCESS to see if gdb can help me pinpoint what data is wrong. If it's any consolation Window Maker doesn't seem to like dual head in this mode much either. Silly things like opening a copy of an app on each monitor whenever I use my accelerator keys to launch are worse IMO that getting annoyed with Xinerama-based annoyances like windows split between two screens. Besides, LyX works fine on whatever monitor you choose when using Xinerama. ## Looking through the code I noticed a small tweak that could be made to save a couple of bytes and neaten things up a little IMO. By applying the following tiny patch and then converting the private variable display stored in LyXColorHandler and Painter into a function (with appropriate changes to the code) we get the display variable stored in one place: ============= cut from here ======== diff -u -p -r1.16 GUIRunTime.C --- src/frontends/xforms/GUIRunTime.C 2001/09/02 11:39:59 1.16 +++ src/frontends/xforms/GUIRunTime.C 2001/11/16 05:24:38 @@ -124,7 +124,8 @@ LyXView * GUIRunTime::createMainView(int Display * GUIRunTime::x11Display() { - return fl_get_display(); + static Display * display = fl_get_display(); + return display; } =============== to here =========== Why do this? Well we store the display value locally in certain classes but make calls to GUIRunTime::x11Display() explicitly in other classes. By storing the value in a local static variable in x11Display() we only ever call fl_get_display() once -- caching the value at its entry to LyX source code rather than in various scattered classes. If somehow the display actually changes during the lifetime of the program we're screwed now anyway by keeping what would then be old values in Painter and LyXColorHandler. Using the modified form of x11Display if such a thing happens we have one place to fix. Alternatively, since fl_get_display() returns a pointer to the _same_ place everytime why not just call fl_get_display() everytime -- it seems to be doing some caching of its own anyway. Allan. (ARRae)