Author: spitzak
Date: 2007-06-07 08:36:39 -0400 (Thu, 07 Jun 2007)
New Revision: 5887
Log:
Fix for STR 1692
OSX returns correct list for Monitors::list() and Monitors::all(), including
the work area.
Added new monitors test/demo program that is actually fairly nice
Fixed bugs with drawing scaled rectangles so that the demo program works.
Added:
trunk/test/monitors.cxx
Modified:
trunk/fltk/draw.h
trunk/src/fillrect.cxx
trunk/src/osx/run.cxx
trunk/src/path.cxx
trunk/test/Makefile
Modified: trunk/fltk/draw.h
===================================================================
--- trunk/fltk/draw.h 2007-06-06 20:30:41 UTC (rev 5886)
+++ trunk/fltk/draw.h 2007-06-07 12:36:39 UTC (rev 5887)
@@ -70,7 +70,7 @@
FL_API void transform_distance(float& x, float& y);
FL_API void transform(int& x, int& y);
FL_API void transform(const Rectangle& from, Rectangle& to);
-FL_API void transform(int x, int y, int w, int h, Rectangle& to);
+FL_API void transform(int& x, int& y, int& w, int& h);
//@}
/// \name Clipping
Modified: trunk/src/fillrect.cxx
===================================================================
--- trunk/src/fillrect.cxx 2007-06-06 20:30:41 UTC (rev 5886)
+++ trunk/src/fillrect.cxx 2007-06-07 12:36:39 UTC (rev 5887)
@@ -33,12 +33,12 @@
/*! Fill the rectangle with the current color. */
void fltk::fillrect(int x, int y, int w, int h) {
if (w <= 0 || h <= 0) return;
- transform(x,y);
+ transform(x,y,w,h);
#if USE_CAIRO
cairo_rectangle(cc,x,y,w,h);
cairo_fill(cc);
#elif USE_X11
- XFillRectangle(xdisplay, xwindow, gc, x, y, w, h);
+ if (w && h) XFillRectangle(xdisplay, xwindow, gc, x, y, w, h);
#elif defined(_WIN32)
RECT rect;
rect.left = x; rect.top = y;
@@ -61,12 +61,13 @@
*/
void fltk::strokerect(int x, int y, int w, int h) {
if (w <= 0 || h <= 0) return;
- transform(x,y);
+ transform(x,y,w,h);
#if USE_CAIRO
cairo_rectangle(cc,x+.5,y+.5,w-1,h-1);
cairo_stroke(cc);
#elif USE_X11
- XDrawRectangle(xdisplay, xwindow, gc, x, y, w-1, h-1);
+ if (w && h) XDrawRectangle(xdisplay, xwindow, gc, x, y, w-1, h-1);
+ else XDrawLine(xdisplay, xwindow, gc, x, y, x+w, y+h);
#elif defined(_WIN32)
setpen();
POINT pts[4];
Modified: trunk/src/osx/run.cxx
===================================================================
--- trunk/src/osx/run.cxx 2007-06-06 20:30:41 UTC (rev 5886)
+++ trunk/src/osx/run.cxx 2007-06-07 12:36:39 UTC (rev 5887)
@@ -995,7 +995,10 @@
////////////////////////////////////////////////////////////////
-static bool reload_info = true;
+// this should be turned on by changes to monitor layout, nyi.
+// Apparently CGDisplayReconfigurationCallBack is what you need
+static bool reload_list = true;
+static bool reload_all = true;
/* Return a "monitor" that surrounds all the monitors.
If you have a single monitor, this returns a monitor structure that
@@ -1005,42 +1008,62 @@
//+++ verify port to FLTK2
const Monitor& Monitor::all() {
static Monitor monitor;
- if (reload_info) {
- reload_info = false;
- BitMap r;
- GetQDGlobalsScreenBits(&r);
- monitor.set(r.bounds.left, r.bounds.top,
- r.bounds.right - r.bounds.left,
- r.bounds.bottom - r.bounds.top);
- //++ there is a wonderful call in Carbon that will return exactly
- //++ this information...
- monitor.work.set(r.bounds.left, r.bounds.top+22,
- r.bounds.right - r.bounds.left,
- r.bounds.bottom - r.bounds.top - 22);
- //++ I don't know if this scale info is available...
- monitor.depth_ = 32;
- monitor.dpi_x_ = 100;
- monitor.dpi_y_ = 100;
+ if (reload_list || reload_all) {
+ const Monitor* list;
+ int count = Monitor::list(&list);
+ reload_all = false;
+ monitor = list[0];
+ for (int i=1; i < count; i++) {
+ monitor.merge(list[i]);
+ monitor.work.merge(list[i].work);
+ }
}
return monitor;
}
+static Monitor* monitors = 0;
+static int num_monitors = 0;
+
/* Return an array of all Monitors.
p is set to point to a static array of Monitor structures describing
all monitors connected to the system. Subsequent calls will usually
return the same array, but if a signal comes in indicating a change
it will probably delete the old array and return a new one.
*/
-//+++ verify port to FLTK2
int Monitor::list(const Monitor** p) {
- *p = &all();
- return 1;
+ if (reload_list) {
+ reload_list = false;
+ reload_all = true;
+ const unsigned int Max = 10;
+ CGDirectDisplayID list[Max];
+ CGDisplayCount count = 0;
+ /*CGDisplayErr err =*/ CGGetActiveDisplayList(Max, list, &count);
+ // maybe do something if count < 1?
+ num_monitors = count;
+ delete[] monitors;
+ monitors = new Monitor[count];
+ for (unsigned int d = 0; d < count; ++d) {
+ CGRect bounds = CGDisplayBounds(list[d]);
+ monitors[d].set(bounds.origin.x,
+ bounds.origin.y,
+ bounds.size.width,
+ bounds.size.height);
+ GDHandle gdhandle;
DMGetGDeviceByDisplayID((DisplayIDType)(list[d]),&gdhandle,false);
+ Rect work; GetAvailableWindowPositioningBounds(gdhandle, &work);
+ monitors[d].work.set(work.left, work.top, work.right-work.left,
work.bottom-work.top);
+ monitors[d].depth_ = CGDisplayBitsPerPixel(list[d]);
+ CGSize size = CGDisplayScreenSize(list[d]); //display size in mm
+ monitors[d].dpi_x_ = bounds.size.width*25.4f/size.width;
+ monitors[d].dpi_y_ = bounds.size.height*25.4f/size.height;
+ }
+ }
+ *p = monitors;
+ return num_monitors;
}
/* Return a pointer to a Monitor structure describing the monitor
that contains or is closest to the given x,y, position.
*/
-//+++ verify port to FLTK2
const Monitor& Monitor::find(int x, int y) {
const Monitor* monitors;
int count = list(&monitors);
Modified: trunk/src/path.cxx
===================================================================
--- trunk/src/path.cxx 2007-06-06 20:30:41 UTC (rev 5886)
+++ trunk/src/path.cxx 2007-06-07 12:36:39 UTC (rev 5887)
@@ -305,12 +305,12 @@
}
/**
-Same as transform(Rectangle(X,Y,W,H),to). This may be faster as it
-avoids the rectangle construction.
+Same as transform(Rectangle(X,Y,W,H),to) but replaces XYWH with the transformed
+rectangle. This may be faster as it avoids the rectangle construction.
*/
-void fltk::transform(int X,int Y,int W,int H, Rectangle& to) {
+void fltk::transform(int& X,int& Y,int& W,int& H) {
if (m.trivial) {
- to.set(X+m.ix, Y+m.iy, W, H);
+ X += m.ix; Y += m.iy;
return;
}
float x = X+W*.5f;
@@ -318,11 +318,10 @@
transform(x,y);
float d1x,d1y; d1x = float(W); d1y = 0; transform_distance(d1x, d1y);
float d2x,d2y; d2x = 0; d2y = float(H); transform_distance(d2x, d2y);
- float w = rintf(sqrtf(d1x*d1x+d2x*d2x));
- x = floorf(x - (w+1)/2);
- float h = rintf(sqrtf(d1y*d1y+d2y*d2y));
- y = floorf(y - (h+1)/2);
- to.set(int(x),int(y),int(w),int(h));
+ W = int(sqrtf(d1x*d1x+d2x*d2x)+.5f);
+ H = int(sqrtf(d1y*d1y+d2y*d2y)+.5f);
+ X = int(floorf(x - .5f*(W+1)));
+ Y = int(floorf(y - .5f*(H+1)));
}
////////////////////////////////////////////////////////////////
Modified: trunk/test/Makefile
===================================================================
--- trunk/test/Makefile 2007-06-06 20:30:41 UTC (rev 5886)
+++ trunk/test/Makefile 2007-06-07 12:36:39 UTC (rev 5887)
@@ -82,6 +82,7 @@
mandelbrot.cxx \
menu.cxx \
message.cxx \
+ monitors.cxx \
navigation.cxx \
output.cxx \
overlay.cxx \
@@ -153,6 +154,7 @@
mandelbrot$(EXEEXT) \
menu$(EXEEXT) \
message$(EXEEXT) \
+ monitors$(EXEEXT) \
navigation$(EXEEXT) \
output$(EXEEXT) \
pack$(EXEEXT) \
Added: trunk/test/monitors.cxx
===================================================================
--- trunk/test/monitors.cxx (rev 0)
+++ trunk/test/monitors.cxx 2007-06-07 12:36:39 UTC (rev 5887)
@@ -0,0 +1,92 @@
+// Test of the fltk::Monitor calls
+
+#include <fltk/run.h>
+#include <fltk/Window.h>
+#include <fltk/Monitor.h>
+#include <fltk/draw.h>
+#include <stdio.h>
+
+using namespace fltk;
+
+void print_monitor(const Monitor& m, int i) {
+ if (i < 0) printf("all: ");
+ else printf("%d: ", i);
+ printf("area %d %d %d %d, work %d %d %d %d, depth %d, dpi %g %g\n",
+ m.x(), m.y(), m.w(), m.h(),
+ m.work.x(), m.work.y(), m.work.w(), m.work.h(),
+ m.depth(), m.dpi_x(), m.dpi_y());
+}
+
+class MonitorWindow : public Window {
+public:
+ MonitorWindow() : Window(500,500) {resizable(this);}
+
+ void draw_monitor(const Monitor& m, int i) {
+ setcolor(GRAY50);
+ strokerect(m.work);
+ setcolor(BLACK);
+ strokerect(m);
+ char b[256];
+ char* p = b;
+ if (i < 0) p += sprintf(p,"all: ");
+ else p += sprintf(p, "%d: ", i);
+ sprintf(p, "area %d %d %d %d\nwork %d %d %d %d\ndepth %d, dpi %g %g",
+ m.x(), m.y(), m.w(), m.h(),
+ m.work.x(), m.work.y(), m.work.w(), m.work.h(),
+ m.depth(), m.dpi_x(), m.dpi_y());
+ if (i < 0)
+ drawtext(b, Rectangle(m.x(),m.b(),m.w(),1000),
ALIGN_TOP|ALIGN_RIGHT|ALIGN_WRAP);
+ else
+ drawtext(b, m, ALIGN_CENTER|ALIGN_WRAP|ALIGN_CLIP);
+ }
+
+ void draw() {
+ draw_box();
+ setfont(textfont(), textsize());
+ const Monitor& all = Monitor::all();
+ push_matrix();
+ translate(w()/10,h()/10);
+ float s = w()*.8/all.w();
+ float s2 = h()*.8/all.h();
+ if (s2 < s) s = s2;
+ scale(s,s);
+ translate(-all.x(), -all.y());
+
+ setcolor(GRAY25);
+ Rectangle b; borders(&b);
+ fillrect(this->x()+b.x(), this->y()+b.y(), this->w()+b.w(),
this->h()+b.h());
+ setcolor(GRAY50);
+ fillrect(*this);
+ setcolor(WHITE);
+ drawtext("this window", *this, ALIGN_CENTER|ALIGN_WRAP|ALIGN_CLIP);
+
+ draw_monitor(all, -1);
+
+ const Monitor* list;
+ int size = Monitor::list(&list);
+ for (int i=0; i<size; i++)
+ draw_monitor(list[i], i);
+
+ pop_matrix();
+ }
+
+ void layout() { // make it redraw when user moves window
+ redraw();
+ Window::layout();
+ }
+};
+
+int main(int argc, char** argv) {
+ MonitorWindow window;
+ window.show(argc,argv);
+
+ print_monitor(Monitor::all(),-1);
+
+ const Monitor* list;
+ int size = Monitor::list(&list);
+
+ for (int i=0; i<size; i++)
+ print_monitor(list[i],i);
+
+ return fltk::run();
+}
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit