X11Device.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.4 $
00022 // $Date: 2003/02/18 23:38:04 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/renderer/X11Device.cpp,v $
00024                                                                         
00025                                                                         
00026 #include "X11Device.h"
00027 #include <OPS_Globals.h>
00028 #include <stdlib.h>
00029 
00030 
00031 int X11Device::numX11Device(0);
00032 Display *X11Device::theDisplay;  
00033 Colormap X11Device::cmap;        
00034 int X11Device::theScreen;        
00035 unsigned long X11Device::pixels[X11_MAX_COLORS];
00036 XColor X11Device::colors[X11_MAX_COLORS];
00037 int X11Device::colorFlag;  
00038 
00039 
00040 X11Device::X11Device()
00041 :winOpen(1)
00042 {
00043     hints.x = 50;
00044     hints.y = 50;
00045     hints.width = 0; 
00046     hints.height = 0;
00047     drawingPolygon = 0;
00048     numPoints = 0;
00049 
00050     // call the initX11 method if this is the first object
00051     if (numX11Device == 0) {
00052         this->initX11();
00053         numX11Device++;
00054     }
00055 }
00056 
00057 X11Device::~X11Device()
00058 {
00059     numX11Device--;
00060     if (winOpen == 0) { // we must close the old window
00061         XFreeGC(theDisplay, theGC);
00062         XDestroyWindow(theDisplay, theWindow); 
00063     }
00064     
00065     if (numX11Device == 0) {
00066         if (colorFlag == 0) 
00067             XFreeColors(theDisplay, cmap, pixels, 256, 0);
00068         else if (colorFlag == 1)
00069             XFreeColors(theDisplay, cmap, pixels, 192, 0);
00070         else if (colorFlag == 2)
00071             XFreeColors(theDisplay, cmap, pixels, 64, 0);
00072         
00073         XFreeColormap(theDisplay, cmap);
00074         XCloseDisplay(theDisplay);
00075     }
00076 }
00077 
00078 void
00079 X11Device::WINOPEN(int _width, int _height)
00080 {
00081     if (winOpen == 0) { // we must close the old window
00082         XFreeGC(theDisplay, theGC);
00083         XDestroyWindow(theDisplay, theWindow); 
00084     }
00085 
00086     // define the position and size of the window - only hints
00087     hints.x = 50;
00088     hints.y = 50;
00089     hints.width = _width;
00090     hints.height = _height;
00091     height = _height;
00092 
00093     // now open a window
00094     theWindow = XCreateSimpleWindow(theDisplay,RootWindow(theDisplay,0),
00095                                     hints.x, hints.y,
00096                                     hints.width,hints.height,4,
00097                                     foreground, background);
00098     if (theWindow == 0) {
00099         opserr << "X11Device::WINOPEN() - could not open a window\n";
00100         exit(-1);
00101     }   
00102     
00103     XSetStandardProperties(theDisplay, theWindow, "g3", "g3", None, 0, 0, &hints);
00104     
00105     // create a graphical context
00106     theGC = XCreateGC(theDisplay, theWindow, 0, 0);
00107     XSetBackground(theDisplay, theGC, background);
00108     XSetForeground(theDisplay, theGC, foreground);
00109 
00110     if (colorFlag == 3) {
00111         cmap = XCreateColormap(theDisplay,theWindow,
00112                            DefaultVisual(theDisplay,0),AllocAll);
00113         if (cmap == 0) {
00114             opserr << "X11Device::initX11() - could not get a new color table\n";
00115             exit(-1);
00116         }           
00117 
00118         // we are going to try to allocate 256 new colors -- need 8 planes for this
00119         int depth = DefaultDepth(theDisplay, theScreen);
00120         if (depth < 8) {
00121             opserr << "X11Device::initX11() - needed at least 8 planes\n";
00122             exit(-1);
00123         }           
00124         int cnt = 0;
00125         for (int red = 0; red < 8; red++) {
00126             for (int green = 0; green < 8; green++) {
00127                 for (int blue = 0; blue < 4; blue++) {
00128                     colors[cnt].pixel = pixels[32*red + 4*green + blue];
00129                     colors[cnt].red = (65536/7)*red;
00130                     colors[cnt].green = (65536/7)*green;
00131                     colors[cnt].blue = (65536/3)*blue;
00132                     colors[cnt].flags = DoRed | DoGreen | DoBlue;
00133                     cnt++;
00134                 }                       
00135             }
00136         }
00137         XStoreColors(theDisplay, cmap, colors, cnt);                        
00138 
00139         XSetWindowColormap(theDisplay, theWindow, cmap);    
00140     }
00141 
00142     XMapWindow(theDisplay,theWindow);
00143     XClearWindow(theDisplay, theWindow);      
00144     XFlush(theDisplay);
00145     
00146     winOpen = 0;
00147 }
00148 
00149 void
00150 
00151 X11Device::CLEAR()
00152 {
00153   XSetBackground(theDisplay, theGC, background);
00154   XClearWindow(theDisplay, theWindow);  
00155   XFlush(theDisplay);
00156 }
00157 
00158 void
00159 X11Device::C3F(float r, float g, float b)
00160 {
00161     int index, val;
00162     // check range of rgb values
00163     if (r<0 || r>1.0 || g<0 || g>1.0 || b<0 || b>1.0) {
00164         opserr << "X11Device::X11Device::C3F() rgb val out of range ";
00165         opserr << r << " " << g << " " << b << endln;
00166         return;
00167     }
00168     
00169     if (colorFlag == 0 || colorFlag == 3) {
00170         val = (((int)((r * 7.0)+.5))*32 + ((int)((g * 7.0)+.5))*4 +
00171                  ((int)((b * 3.0)+.5)));        
00172     } else if (colorFlag == 1) {
00173         val = (((int)((r * 7.0)+.5))*24 + ((int)((g * 5.0)+.5))*4 +
00174                  ((int)((b * 3.0)+.5)));  
00175     } else if (colorFlag == 2) {
00176         val = ((int)((r * 3.0)+.5))*16 + ((int)((g * 3.0)+.5))*4 +
00177             ((int)((b * 3.0)+.5));
00178     } else
00179       val = 0; // should never be called
00180 
00181     index = pixels[val];
00182     XSetForeground(theDisplay, theGC, index);
00183 }
00184 
00185 
00186 void
00187 X11Device::V2F(float x, float y)
00188 {
00189   // Flip the Y-Coordinate because X goes from 0->height as we 
00190   // go top->bottom while GL goes from height->0 as we go top->bottom. 
00191   y = height-y; 
00192   if (drawingPolygon)
00193   {
00194     if (numPoints == MAX_NUM_POINTS_FOR_POLYGON)
00195       {
00196         opserr << "ERROR: Maximum number of points has been exceeded" << endln;
00197         return;
00198       }
00199     polygonPointArray[numPoints].x = (int)x;
00200     polygonPointArray[numPoints].y = (int)y;
00201     numPoints++;
00202   }
00203   else
00204   {
00205     XDrawPoint(theDisplay, theWindow, theGC, (int) x, (int) y);
00206   }
00207 }
00208 
00209 void
00210 X11Device::ENDIMAGE()
00211 {
00212   // Copy the image from our internal 
00213   // buffer (theImage) onto the display.
00214   XFlush(theDisplay);           // Update the XServer
00215 }
00216 
00217 
00218 void
00219 X11Device::STARTIMAGE()
00220 {
00221   // Copy the image from our internal 
00222   // buffer (theImage) onto the display.
00223   XFlush(theDisplay);           // Update the XServer
00224 }
00225   
00226 
00227 
00228 
00229 void 
00230 X11Device::BGNPOLYGON()
00231 {
00232   numPoints = 0;
00233   drawingPolygon = 1;
00234 }
00235 
00236 void 
00237 X11Device::ENDPOLYGON()
00238 {
00239   drawingPolygon = 0;
00240   // Draw the polygon with the GCs color
00241   opserr << " NUMPOINTS: "<< numPoints << endln;
00242 
00243   XFillPolygon(theDisplay, theWindow, theGC,            
00244                polygonPointArray, numPoints, Complex, CoordModeOrigin);
00245 
00246 }
00247 
00248 void 
00249 X11Device::BGNCLOSEDLINE()
00250 {
00251   numPoints = 0;
00252   drawingPolygon = 1;
00253 }
00254 
00255 void 
00256 X11Device::ENDCLOSEDLINE()
00257 {
00258   drawingPolygon = 0;
00259   // Draw the polygon with the GCs color
00260   polygonPointArray[numPoints] = polygonPointArray[0]; // Close the loop
00261   XDrawLines(theDisplay, theWindow, theGC,              
00262                polygonPointArray, numPoints+1, CoordModeOrigin);
00263 }
00264 
00265 void
00266 X11Device::BGNPOINT()
00267 {
00268 
00269 }
00270 
00271 void
00272 X11Device::ENDPOINT()
00273 {
00274 
00275 }
00276 
00277 
00278 
00279 
00280 void
00281 X11Device::drawText(float x, float y, char *text, int length)
00282 {
00283   y = height-y; 
00284   XDrawString(theDisplay, theWindow, theGC, (int) x, (int) y, text, length);
00285 }
00286 
00287 
00288 int
00289 X11Device::GetWidth()
00290 {
00291   int x,y;
00292   unsigned int width, h, borderWidth, depth;
00293   
00294   XGetGeometry(theDisplay, theWindow, &RootWindow(theDisplay,0),
00295                &x, &y, &width, &h, &borderWidth, &depth);
00296 
00297   hints.width = width;
00298   hints.height = h;
00299   height = h;
00300   return width;
00301 }
00302 
00303 int
00304 X11Device::GetHeight()
00305 {
00306   int x,y;
00307   unsigned int width, h, borderWidth, depth;
00308 
00309 
00310   XGetGeometry(theDisplay, theWindow, &RootWindow(theDisplay,0),
00311                &x, &y, &width, &h, &borderWidth, &depth);
00312 
00313   hints.width = width;
00314   hints.height = h;
00315   height = h;
00316   return height;    
00317 }
00318   
00319 
00320 
00321 
00322 
00323 void
00324 X11Device::initX11(void) {
00325     // set the display and screen variables
00326     theDisplay = XOpenDisplay("");      // init a display connection
00327     if (theDisplay == 0) {              // and check we got one
00328         opserr << "X11Device::initX11() - could not connect to display\n";
00329         exit(-1);
00330     }
00331 
00332     theScreen = DefaultScreen(theDisplay);
00333     
00334     // set the defualt foreground and background colors
00335     foreground = BlackPixel(theDisplay, theScreen);
00336     background = WhitePixel(theDisplay, theScreen);    
00337 
00338     // lets try using the default colormap
00339     cmap = DefaultColormap(theDisplay, theScreen);
00340     XVisualInfo vinfo;    
00341     if (XMatchVisualInfo(theDisplay, theScreen, 8, PseudoColor, &vinfo) == false)
00342         opserr << "X11Device::initX11 - could not get info\n";
00343 
00344     // we now try to allocate some color cells from the colormap
00345     // we start by tring to obtain 256 colors, then 192, finally 64
00346     // if we can't get these (and as a last resort) we create a new color map
00347 
00348     if (XAllocColorCells(theDisplay, cmap, false, NULL, 0, pixels, 256) != 0) {
00349         // we were able to allocate 256 colors from the table for our use
00350         colorFlag = 0;
00351         int cnt = 0;
00352         for (int red =0; red <8; red++) {
00353             for (int green = 0; green<8; green++) {
00354                 for (int blue =0; blue<4; blue++) {
00355                     colors[cnt].pixel = pixels[32*red + 4*green + blue];
00356                     colors[cnt].red = (65536/7)*red;
00357                     colors[cnt].green = (65536/7)*green;
00358                     colors[cnt].blue = (65536/3)*blue;
00359                     colors[cnt].flags = DoRed | DoGreen | DoBlue;
00360                     cnt++;
00361                 }                       
00362             }
00363         }
00364         XStoreColors(theDisplay, cmap, colors, cnt);
00365         
00366     } else if (XAllocColorCells(theDisplay, cmap, false, NULL, 0, pixels, 192) != 0) {
00367         // we were able to allocate 192 colors from the table for our use       
00368         colorFlag = 1;  
00369         int cnt = 0;
00370         for (int red =0; red <8; red++) {
00371             for (int green = 0; green<6; green++) {
00372                 for (int blue =0; blue<4; blue++) {
00373                     colors[cnt].pixel = pixels[24*red + 4*green + blue];
00374                     colors[cnt].red = (65536/7)*red;
00375                     colors[cnt].green = (65536/5)*green;
00376                     colors[cnt].blue = (65536/3)*blue;
00377                     colors[cnt].flags = DoRed | DoGreen | DoBlue;
00378                     cnt++;
00379                 }                       
00380             }
00381         }
00382         XStoreColors(theDisplay, cmap, colors, cnt);
00383     } else if (XAllocColorCells(theDisplay, cmap, false, NULL, 0, pixels, 64) != 0) {
00384         colorFlag = 2;  
00385         int cnt = 0;
00386         for (int red =0; red <4; red++) {
00387             for (int green = 0; green<4; green++) {
00388                 for (int blue =0; blue<4; blue++) {
00389                     colors[cnt].pixel = pixels[16*red + 4*green + blue];
00390                     colors[cnt].red = (65536/3)*red;
00391                     colors[cnt].green = (65536/3)*green;
00392                     colors[cnt].blue = (65536/3)*blue;
00393                     colors[cnt].flags = DoRed | DoGreen | DoBlue;
00394                     cnt++;
00395                 }                       
00396             }
00397         }
00398         XStoreColors(theDisplay, cmap, colors, cnt);
00399     } else {
00400         colorFlag = 3;
00401         // lets create our own color table - 
00402         // problem with this is that screen colors change as we enter
00403         opserr << "X11Device::initX11() - could not any colors from the default\n";
00404         opserr << "colormap - have to create our own for the app - windows will\n";
00405         opserr << "windows will change color as move mouse from one window to another\n\n";     
00406     }
00407 }    
00408         
00409     
00410 
00411         

Generated on Mon Oct 23 15:05:27 2006 for OpenSees by doxygen 1.5.0