00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "WindowDevice.h"
00028 #include <OPS_Globals.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031
00032 int WindowDevice::numWindowDevice(0);
00033
00034 #ifdef _UNIX
00035 Display *WindowDevice::theDisplay;
00036 Colormap WindowDevice::cmap;
00037 int WindowDevice::theScreen;
00038 unsigned long WindowDevice::pixels[X11_MAX_COLORS];
00039 XColor WindowDevice::colors[X11_MAX_COLORS];
00040 int WindowDevice::colorFlag;
00041 unsigned long WindowDevice::foreground(0);
00042 unsigned long WindowDevice::background(0);
00043
00044
00045 #else
00046
00047
00048
00049 LONG WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00050 {
00051 LONG lRet = 1;
00052 PAINTSTRUCT ps;
00053
00054 switch(uMsg) {
00055 case WM_CREATE:
00056 break;
00057
00058 case WM_DESTROY:
00059 break;
00060
00061 case WM_PAINT:
00062 BeginPaint(hWnd, &ps);
00063 EndPaint(hWnd, &ps);
00064 break;
00065
00066 default:
00067 lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
00068 break;
00069 }
00070
00071 return lRet;
00072 }
00073
00074
00075
00076
00077
00078 int oglSetPixelFormat(HDC hDC, BYTE type, DWORD flags)
00079 {
00080 int pf;
00081 PIXELFORMATDESCRIPTOR pfd;
00082
00083
00084 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00085 pfd.nVersion = 1;
00086 pfd.dwFlags = flags |
00087 PFD_SUPPORT_OPENGL;
00088 pfd.iPixelType = type;
00089 pfd.cColorBits = 24;
00090 pfd.cRedBits = 8;
00091 pfd.cGreenBits = 8;
00092 pfd.cBlueBits = 8;
00093 pfd.cDepthBits = 16;
00094
00095
00096
00097 pf = ChoosePixelFormat(hDC, &pfd);
00098 if (pf == 0) {
00099 MessageBox(NULL,
00100 "ChoosePixelFormat() failed: Cannot find format specified.",
00101 "Error", MB_OK);
00102 return 0;
00103 }
00104
00105
00106 if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
00107 MessageBox(NULL,
00108 "SetPixelFormat() failed: Cannot set format specified.",
00109 "Error", MB_OK);
00110 return 0;
00111 }
00112
00113 return pf;
00114 }
00115
00116
00117
00118
00119
00120 HWND oglCreateWindow(char* title, int x, int y, int width, int height,
00121 HGLRC *hRC, HDC *hDC)
00122 {
00123 WNDCLASS wc;
00124 HWND hWnd;
00125 HINSTANCE hInstance;
00126
00127
00128 hInstance = GetModuleHandle(NULL);
00129
00130
00131 wc.style = CS_HREDRAW | CS_VREDRAW;
00132 wc.lpfnWndProc = (WNDPROC)WndProc;
00133 wc.cbClsExtra = 0;
00134 wc.cbWndExtra = 0;
00135 wc.hInstance = hInstance;
00136 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
00137 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
00138 wc.hbrBackground = NULL;
00139 wc.lpszMenuName = NULL;
00140 wc.lpszClassName = title;
00141
00142
00143 if (!RegisterClass(&wc)) {
00144 MessageBox(NULL,
00145 "RegisterClass() failed: Cannot register window class,",
00146 "Error", MB_OK);
00147 return NULL;
00148 }
00149
00150
00151 hWnd = CreateWindow(title,
00152 title,
00153 WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
00154 x, y, width, height,
00155 NULL,
00156 NULL,
00157 hInstance,
00158 NULL);
00159
00160
00161 if (hWnd == NULL) {
00162 MessageBox(NULL,
00163 "CreateWindow() failed: Cannot create a window.",
00164 "Error", MB_OK);
00165 return NULL;
00166 }
00167
00168
00169 ShowWindow(hWnd, SW_SHOW);
00170
00171
00172 UpdateWindow(hWnd);
00173
00174
00175 *hDC = GetDC(hWnd);
00176
00177
00178 if (oglSetPixelFormat(*hDC, PFD_TYPE_RGBA,
00179 PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER) == 0)
00180 exit(1);
00181
00182
00183 *hRC = wglCreateContext(*hDC);
00184 wglMakeCurrent(*hDC, *hRC);
00185 glClearColor(1.0f,1.0f,1.0f,1.0f);
00186 glClear(GL_COLOR_BUFFER_BIT);
00187 glViewport(0, 0, (GLsizei)width, (GLsizei)height);
00188 glMatrixMode(GL_PROJECTION);
00189 glLoadIdentity();
00190 gluOrtho2D(0.0, (GLdouble)width, 0.0, (GLdouble)height);
00191 glFlush();
00192
00193
00194 return hWnd;
00195 }
00196
00197
00198
00199
00200
00201 int oglDestroyWindow(char* title, HWND hWnd, HGLRC hRC, HDC hDC)
00202 {
00203 HINSTANCE hInstance;
00204
00205
00206 hInstance = GetModuleHandle(NULL);
00207
00208
00209
00210
00211
00212 wglMakeCurrent(NULL, NULL);
00213 ReleaseDC(hWnd, hDC);
00214 wglDeleteContext(hRC);
00215 DestroyWindow(hWnd);
00216
00217
00218 if (!UnregisterClass(title, hInstance)) {
00219 MessageBox(NULL,
00220 "UnregisterClass() failed: Cannot unregister window class,",
00221 "Error", MB_OK);
00222 return -1;
00223 }
00224
00225 return 0;
00226 }
00227
00228
00229
00230
00231
00232 int oglCreateBitmap(int width, int height, HGLRC *hRC, HDC *hDC,
00233 HBITMAP *theBitmap, BITMAPINFO *info, GLubyte **bits)
00234 {
00235
00236 *hDC = CreateCompatibleDC(NULL);
00237
00238
00239
00240
00241 GLint Width = width;
00242 GLint Height = height;
00243
00244 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00245 info->bmiHeader.biPlanes = 1;
00246 info->bmiHeader.biBitCount = 24;
00247 info->bmiHeader.biCompression = BI_RGB;
00248 info->bmiHeader.biXPelsPerMeter = 11808;
00249 info->bmiHeader.biYPelsPerMeter = 11808;
00250 info->bmiHeader.biClrUsed = 0;
00251 info->bmiHeader.biClrImportant = 0;
00252 info->bmiHeader.biWidth = width;
00253 info->bmiHeader.biHeight = height;
00254
00255
00256
00257
00258
00259
00260
00261 void *theBits = *bits;
00262
00263
00264 *theBitmap = CreateDIBSection(*hDC, info, DIB_RGB_COLORS, &theBits, NULL, 0);
00265 *bits = (GLubyte *)theBits;
00266
00267 SelectObject(*hDC, *theBitmap);
00268
00269 if (oglSetPixelFormat(*hDC, PFD_TYPE_RGBA, PFD_DRAW_TO_BITMAP) == 0)
00270 exit(1);
00271
00272
00273 *hRC = wglCreateContext(*hDC);
00274
00275 return 0;
00276 }
00277
00278
00279
00280
00281
00282 int oglDestroyBitmap(HBITMAP *theBitmap, HGLRC hRC, HDC hDC)
00283 {
00284
00285
00286
00287
00288 wglMakeCurrent(NULL, NULL);
00289 wglDeleteContext(hRC);
00290 DeleteObject(theBitmap);
00291
00292
00293 return 0;
00294 }
00295
00296 #endif
00297
00298
00299 WindowDevice::WindowDevice()
00300 :winOpen(1),height(0),width(0),numPoints(0),drawingPolygon(0)
00301 {
00302 #ifdef _UNIX
00303 hints.x = 50;
00304 hints.y = 50;
00305 hints.width = 0;
00306 hints.height = 0;
00307 #else
00308
00309 #endif
00310
00311 if (numWindowDevice == 0) {
00312 this->initWindow();
00313 }
00314 numWindowDevice++;
00315 }
00316
00317 WindowDevice::~WindowDevice()
00318 {
00319 numWindowDevice--;
00320 #ifdef _UNIX
00321 if (winOpen == 0) {
00322 XFreeGC(theDisplay, theGC);
00323 XDestroyWindow(theDisplay, theWindow);
00324 }
00325
00326 if (numWindowDevice == 0) {
00327 if (colorFlag == 0 )
00328 XFreeColors(theDisplay, cmap, pixels, 256, 0);
00329 else if (colorFlag == 1)
00330 XFreeColors(theDisplay, cmap, pixels, 192, 0);
00331 else if (colorFlag == 2)
00332 XFreeColors(theDisplay, cmap, pixels, 64, 0);
00333
00334 XFreeColormap(theDisplay, cmap);
00335 XCloseDisplay(theDisplay);
00336 }
00337
00338 #else
00339 if (winOpen == 0) {
00340 oglDestroyWindow(title,theWND, theHRC, theHDC);
00341 }
00342 #endif
00343 }
00344
00345 void
00346 WindowDevice::WINOPEN(const char *_title, int _xLoc, int _yLoc, int _width, int _height)
00347 {
00348
00349 strcpy(title, _title);
00350
00351 height = _height;
00352 width = _width;
00353 xLoc = _xLoc;
00354 yLoc = _yLoc;
00355
00356 #ifdef _UNIX
00357 if (winOpen == 0) {
00358 XFreeGC(theDisplay, theGC);
00359 XDestroyWindow(theDisplay, theWindow);
00360 }
00361
00362
00363 hints.x = _xLoc;
00364 hints.y = _yLoc;
00365 hints.width = _width;
00366 hints.height = _height;
00367 hints.flags = PPosition | PSize;
00368
00369
00370 XVisualInfo visual;
00371 visual.visual = 0;
00372 int depth = DefaultDepth(theDisplay, theScreen);
00373
00374 if (background == 0) {
00375 if (XMatchVisualInfo(theDisplay, theScreen, depth, PseudoColor, &visual) == 0) {
00376 foreground = BlackPixel(theDisplay, theScreen);
00377 background = WhitePixel(theDisplay, theScreen);
00378
00379 } else {
00380 foreground = 0;
00381 background = 255;
00382 }
00383 }
00384
00385
00386 theWindow = XCreateSimpleWindow(theDisplay,RootWindow(theDisplay,0),
00387 hints.x, hints.y,
00388 hints.width,hints.height,4,
00389 foreground, background);
00390
00391 if (theWindow == 0) {
00392 opserr << "WindowDevice::WINOPEN() - could not open a window\n";
00393 exit(-1);
00394 }
00395
00396 XSetStandardProperties(theDisplay, theWindow, title, title, None, 0, 0, &hints);
00397
00398
00399 theGC = XCreateGC(theDisplay, theWindow, 0, 0);
00400
00401
00402
00403 if (colorFlag == 3 ) {
00404
00405
00406 if (numWindowDevice == 1) {
00407 int fail = false;
00408
00409 if (XMatchVisualInfo(theDisplay, theScreen, depth, PseudoColor, &visual) == 0) {
00410 opserr << "WindowDevice::initX11() - could not get a visual for PseudoColor\n";
00411 opserr << "Colors diplayed will be all over the place\n";
00412 cmap = DefaultColormap(theDisplay, theScreen);
00413 fail = true;
00414 } else {
00415 opserr << "WindowDevice::WINOPEN have created our own colormap, \n";
00416 opserr << "windows may change color as move mouse from one window to\n";
00417 opserr << "another - depends on your video card to use another colormap\n\n";
00418
00419 cmap = XCreateColormap(theDisplay,theWindow,
00420 visual.visual, AllocAll);
00421 }
00422
00423
00424
00425
00426
00427
00428
00429 if (cmap == 0) {
00430 opserr << "WindowDevice::initX11() - could not get a new color table\n";
00431 exit(-1);
00432 }
00433
00434
00435 depth = DefaultDepth(theDisplay, theScreen);
00436 if (depth < 8) {
00437 opserr << "WindowDevice::initX11() - needed at least 8 planes\n";
00438 exit(-1);
00439 }
00440 if (fail == false) {
00441 int cnt = 0;
00442 for (int red = 0; red < 8; red++) {
00443 for (int green = 0; green < 8; green++) {
00444 for (int blue = 0; blue < 4; blue++) {
00445 pixels[32*red + 4*green + blue] = cnt;
00446 colors[cnt].pixel = pixels[32*red + 4*green + blue];
00447 colors[cnt].red = (65536/7)*red;
00448 colors[cnt].green = (65536/7)*green;
00449 colors[cnt].blue = (65536/3)*blue;
00450 colors[cnt].flags = DoRed | DoGreen | DoBlue;
00451 cnt++;
00452 }
00453 }
00454 }
00455 background = 0;
00456 foreground = 255;
00457 XStoreColors(theDisplay, cmap, colors, cnt);
00458 }
00459 }
00460
00461
00462 XSetWindowColormap(theDisplay, theWindow, cmap);
00463
00464 }
00465
00466 XSetBackground(theDisplay, theGC, background);
00467 XSetForeground(theDisplay, theGC, foreground);
00468
00469 XMapWindow(theDisplay,theWindow);
00470 XClearWindow(theDisplay, theWindow);
00471 XFlush(theDisplay);
00472
00473 #else
00474
00475
00476
00477
00478 if (winOpen == 0)
00479 oglDestroyWindow(title,theWND, theHRC, theHDC);
00480
00481 theWND = oglCreateWindow(title, xLoc, yLoc, width, height, &theHRC, &theHDC);
00482 if (theWND == NULL)
00483 exit(1);
00484 winOpen = 0;
00485
00486 wglMakeCurrent(theHDC, theHRC);
00487 glClearColor(1.0f,1.0f,1.0f,1.0f);
00488 glClear(GL_COLOR_BUFFER_BIT);
00489 glViewport(0, 0, (GLsizei)width, (GLsizei)height);
00490 glMatrixMode(GL_PROJECTION);
00491 glLoadIdentity();
00492 gluOrtho2D(0.0, (GLdouble)width, 0.0, (GLdouble)height);
00493 glFlush();
00494
00495 #endif
00496
00497 winOpen = 0;
00498 }
00499
00500 void
00501
00502 WindowDevice::CLEAR()
00503 {
00504 #ifdef _UNIX
00505 XSetBackground(theDisplay, theGC, background);
00506 XClearWindow(theDisplay, theWindow);
00507 XFlush(theDisplay);
00508 #else
00509 wglMakeCurrent(theHDC, theHRC);
00510 glClearColor(1.0f,1.0f,1.0f,1.0f);
00511 glClear(GL_COLOR_BUFFER_BIT);
00512
00513 glFlush();
00514 #endif
00515 }
00516
00517 void
00518 WindowDevice::C3F(float r, float g, float b)
00519 {
00520
00521
00522 if (r<0 || r>1.0 || g<0 || g>1.0 || b<0 || b>1.0) {
00523 opserr << "WindowDevice::WindowDevice::C3F() rgb val out of range ";
00524 opserr << r << " " << g << " " << b << endln;
00525 return;
00526 }
00527
00528 #ifdef _UNIX
00529 int index, val;
00530 if (colorFlag == 0 || colorFlag == 3) {
00531 val = (((int)((r * 7.0)+.5))*32 + ((int)((g * 7.0)+.5))*4 +
00532 ((int)((b * 3.0)+.5)));
00533 } else if (colorFlag == 1) {
00534 val = (((int)((r * 7.0)+.5))*24 + ((int)((g * 5.0)+.5))*4 +
00535 ((int)((b * 3.0)+.5)));
00536 } else if (colorFlag == 2) {
00537 val = ((int)((r * 3.0)+.5))*16 + ((int)((g * 3.0)+.5))*4 +
00538 ((int)((b * 3.0)+.5));
00539 } else
00540 val = 0;
00541
00542 index = pixels[val];
00543 XSetForeground(theDisplay, theGC, index);
00544 #else
00545
00546 glColor3f(r,g,b);
00547
00548
00549 #endif
00550 }
00551
00552
00553 void
00554 WindowDevice::V2F(float x, float y)
00555 {
00556 #ifdef _UNIX
00557
00558
00559 y = height-y;
00560 if (drawingPolygon)
00561 {
00562 if (numPoints == MAX_NUM_POINTS_FOR_POLYGON)
00563 {
00564 opserr << "ERROR: Maximum number of points has been exceeded" << endln;
00565 return;
00566 }
00567 polygonPointArray[numPoints].x = (int)x;
00568 polygonPointArray[numPoints].y = (int)y;
00569 numPoints++;
00570 }
00571 else
00572 {
00573 XDrawPoint(theDisplay, theWindow, theGC, (int) x, (int) y);
00574 }
00575 #else
00576 glVertex2f(x,y);
00577 #endif
00578 }
00579
00580 void
00581 WindowDevice::ENDIMAGE()
00582 {
00583 #ifdef _UNIX
00584
00585
00586 XFlush(theDisplay);
00587
00588 #else
00589
00590
00591
00592 SwapBuffers(theHDC);
00593 glFlush();
00594 #endif
00595 }
00596
00597 void
00598 WindowDevice::STARTIMAGE()
00599 {
00600 #ifdef _UNIX
00601
00602
00603 XFlush(theDisplay);
00604
00605 #else
00606
00607
00608 wglMakeCurrent(theHDC, theHRC);
00609
00610 #endif
00611 }
00612
00613
00614
00615
00616 void
00617 WindowDevice::BGNPOLYGON()
00618 {
00619 numPoints = 0;
00620 drawingPolygon = 1;
00621 }
00622
00623 void
00624 WindowDevice::ENDPOLYGON()
00625 {
00626 drawingPolygon = 0;
00627
00628 #ifdef _UNIX
00629 XFillPolygon(theDisplay, theWindow, theGC,
00630 polygonPointArray, numPoints, Complex, CoordModeOrigin);
00631 #else
00632
00633 #endif
00634 }
00635
00636 void
00637 WindowDevice::BGNCLOSEDLINE()
00638 {
00639 numPoints = 0;
00640 drawingPolygon = 1;
00641 #ifdef _UNIX
00642
00643 #else
00644 glBegin(GL_LINES);
00645 #endif
00646 }
00647
00648 void
00649 WindowDevice::ENDCLOSEDLINE()
00650 {
00651 drawingPolygon = 0;
00652
00653
00654 #ifdef _UNIX
00655 polygonPointArray[numPoints] = polygonPointArray[0];
00656 XDrawLines(theDisplay, theWindow, theGC,
00657 polygonPointArray, numPoints+1, CoordModeOrigin);
00658 #else
00659 glEnd();
00660 #endif
00661 }
00662
00663 void
00664 WindowDevice::BGNPOINT()
00665 {
00666
00667 }
00668
00669 void
00670 WindowDevice::ENDPOINT()
00671 {
00672
00673 }
00674
00675
00676
00677
00678 void
00679 WindowDevice::drawText(float x, float y, char *text, int length)
00680 {
00681 #ifdef _UNIX
00682 y = height-y;
00683 XDrawString(theDisplay, theWindow, theGC, (int) x, (int) y, text, length);
00684 #else
00685
00686 #endif
00687 }
00688
00689
00690 int
00691 WindowDevice::GetWidth()
00692 {
00693
00694
00695 #ifdef _UNIX
00696 int x,y;
00697 unsigned int borderWidth, depth;
00698 unsigned int w, h;
00699 XGetGeometry(theDisplay, theWindow, &RootWindow(theDisplay,0),
00700 &x, &y, &w, &h, &borderWidth, &depth);
00701 width = w;
00702 height = h;
00703 hints.width = width;
00704 hints.height = h;
00705 height = h;
00706 #else
00707
00708 #endif
00709
00710 return width;
00711 }
00712
00713 int
00714 WindowDevice::GetHeight()
00715 {
00716 #ifdef _UNIX
00717 unsigned int borderWidth, depth;
00718 int x,y;
00719 unsigned int w, h;
00720
00721 XGetGeometry(theDisplay, theWindow, &RootWindow(theDisplay,0),
00722 &x, &y, &w, &h, &borderWidth, &depth);
00723 width = w;
00724 height = h;
00725 hints.width = width;
00726 hints.height = height;
00727 #else
00728
00729 #endif
00730
00731 return height;
00732 }
00733
00734
00735
00736
00737
00738 void
00739 WindowDevice::initWindow(void) {
00740
00741 #ifdef _UNIX
00742 theDisplay = XOpenDisplay("");
00743 if (theDisplay == 0) {
00744 opserr << "WindowDevice::initX11() - could not connect to display\n";
00745 exit(-1);
00746 }
00747
00748 theScreen = DefaultScreen(theDisplay);
00749
00750
00751
00752
00753
00754
00755 cmap = DefaultColormap(theDisplay, theScreen);
00756
00757
00758
00759
00760
00761 if (XAllocColorCells(theDisplay, cmap, false, NULL, 0, pixels, 256) != 0) {
00762
00763 colorFlag = 0;
00764 int cnt = 0;
00765 for (int red =0; red <8; red++) {
00766 for (int green = 0; green<8; green++) {
00767 for (int blue =0; blue<4; blue++) {
00768 colors[cnt].pixel = pixels[32*red + 4*green + blue];
00769 colors[cnt].red = (65536/7)*red;
00770 colors[cnt].green = (65536/7)*green;
00771 colors[cnt].blue = (65536/3)*blue;
00772 colors[cnt].flags = DoRed | DoGreen | DoBlue;
00773 cnt++;
00774 }
00775 }
00776 }
00777 XStoreColors(theDisplay, cmap, colors, cnt);
00778 foreground = pixels[0];
00779 background = pixels[255];
00780
00781 } else if (XAllocColorCells(theDisplay, cmap, false, NULL, 0, pixels, 192) != 0) {
00782
00783 colorFlag = 1;
00784 int cnt = 0;
00785 for (int red =0; red <8; red++) {
00786 for (int green = 0; green<6; green++) {
00787 for (int blue =0; blue<4; blue++) {
00788 colors[cnt].pixel = pixels[24*red + 4*green + blue];
00789 colors[cnt].red = (65536/7)*red;
00790 colors[cnt].green = (65536/5)*green;
00791 colors[cnt].blue = (65536/3)*blue;
00792 colors[cnt].flags = DoRed | DoGreen | DoBlue;
00793 cnt++;
00794 }
00795 }
00796 }
00797 XStoreColors(theDisplay, cmap, colors, cnt);
00798 foreground = pixels[0];
00799 background = pixels[191];
00800 } else if (XAllocColorCells(theDisplay, cmap, false, NULL, 0, pixels, 64) != 0) {
00801 colorFlag = 2;
00802 int cnt = 0;
00803 for (int red =0; red <4; red++) {
00804 for (int green = 0; green<4; green++) {
00805 for (int blue =0; blue<4; blue++) {
00806 colors[cnt].pixel = pixels[16*red + 4*green + blue];
00807 colors[cnt].red = (65536/3)*red;
00808 colors[cnt].green = (65536/3)*green;
00809 colors[cnt].blue = (65536/3)*blue;
00810 colors[cnt].flags = DoRed | DoGreen | DoBlue;
00811 cnt++;
00812 }
00813 }
00814 }
00815 XStoreColors(theDisplay, cmap, colors, cnt);
00816 foreground = pixels[0];
00817 background = pixels[63];
00818 } else {
00819 colorFlag = 3;
00820
00821
00822 opserr << "WindowDevice::initWindow() - could not add any colors to the\n";
00823 opserr << "existing colormap - will try to create our own colormap\n";
00824 }
00825 #else
00826
00827
00828 #endif
00829 }
00830
00831
00832
00833