Stefano Bodrato - 2014-03-07

New patch, now bottom text and controls are working. OpenGL32, pthreads libjpeg and MinGw are necessary.. fix the makefile accordingly.

diff -aur src-original/lp_font.cpp src/lp_font.cpp
--- src-original/lp_font.cpp 2008-10-03 13:24:22 +0200
+++ src/lp_font.cpp 2014-02-26 07:01:24 +0100
@@ -1,8 +1,12 @@
+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+#include <GL gl.h="">
+#else
#include <GL gl.h="">
#include <GL glu.h="">
#include <GL glx.h="">
#include <X11 Xlib.h="">
#include <X11 Xutil.h="">
+#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
diff -aur src-original/lp_main.cpp src/lp_main.cpp
--- src-original/lp_main.cpp 2008-10-20 13:29:47 +0200
+++ src/lp_main.cpp 2014-03-05 17:30:37 +0100
@@ -23,8 +23,12 @@

#include <pthread.h>
#include <sys types.h="">
+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+#include <windows.h>
+#else
#include <sys signal.h="">
#include <sys prctl.h="">
+#endif
#include <sys stat.h="">

#include "lpanel.h"
@@ -97,7 +101,7 @@

int start_threads(void)
{
- static pthread_attr_t attr;
+ static pthread_attr_t attr = NULL;
int n;

pthread_mutex_init(&data_lock,NULL);
@@ -189,6 +193,9 @@
int fp_init(char *cfg_fname)
{
printf("\nFrontPanel Simulator v2.0 Copyright (C) 2007-2008 by John Kichury\n");
+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+ printf("Windows version Copyright (C) 2014 by Stefano Bodrato\n");
+#endif

if(panel == NULL) panel = new Lpanel;

@@ -259,7 +266,11 @@
break;
}
pthread_mutex_unlock(&data_lock);
+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+ Sleep(1000);
+#else
sleep(1);
+#endif
}

if(!okay) fprintf(stderr, "Error. lightpanel draw thread did not terminate\n");
diff -aur src-original/lp_window.cpp src/lp_window.cpp
--- src-original/lp_window.cpp 2008-10-18 23:42:01 +0200
+++ src/lp_window.cpp 2014-03-05 15:59:59 +0100
@@ -2,6 +2,7 @@

/* Copyright (c) 2007-2008, John Kichury
+ * Copyright (c) 2014, Stefano Bodrato - Win32 based on an article by Howard "SiCrane" Jeng

This software is freely distributable free of charge and without license fees with the 
following conditions:

@@ -18,19 +19,29 @@
*/

#include <GL glu.h="">
+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+#include <windows.h>
+#include <Commctrl.h>
+#include <GL gl.h="">
+#else
#include <GL glx.h="">
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
#include <X11 Xlib.h="">
#include <X11 keysym.h="">
#include <X11 Xatom.h="">
+#endif
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>

#include "lpanel.h"
#include "lp_materials.h"
#include "lp_font.h"

+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+const char FPClassName[] = "FrontPanel 2.0";
+
+#else
static int RGBA_DB_attributes[] = {
GLX_RGBA,
GLX_RED_SIZE, 1,
@@ -40,7 +51,7 @@
GLX_DEPTH_SIZE, 1,
None,
};
-
+#endif
// OpenGL Light source

static GLfloat light_pos0[] = { 0.,0.5,1.,0.};
@@ -57,6 +68,260 @@
static int mousex, mousey, omx, omy, lmouse, mmouse, rmouse;

+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+
+
+static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
+
+ if (LONG_PTR user_data = GetWindowLongPtr(hWnd, GWLP_USERDATA)) {
+ Lpanel * this_window = reinterpret_cast<Lpanel *="">(user_data);
+ return this_window->WndProc(hWnd, Msg, wParam, lParam);
+ }
+ return DefWindowProc(hWnd, Msg, wParam, lParam);
+}
+
+
+//
+LRESULT CALLBACK
+Lpanel::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+ unsigned int kcode;
+
+ switch(msg)
+ {
+
+ case WM_KEYUP:
+ if (LOWORD (wParam) == VK_SHIFT) {
+ shift_key_pressed=0;
+ return 0;
+ }
+ return 0;
+ break;
+
+
+ case WM_KEYDOWN:
+ kcode=LOWORD (wParam);
+ switch(kcode)
+ {
+ case VK_SHIFT:
+ shift_key_pressed=1;
+ return 0;
+ break;
+
+ case VK_UP:
+ if(do_cursor)
+ inc_cursor(0.,cursor_inc );
+ else
+ {
+ if(shift_key_pressed)
+ view.pan[1] += -0.1;
+ else
+ view.rot[0] += -1.;
+
+ view.redo_projections = 1;
+ }
+ break;
+ case VK_DOWN:
+ if(do_cursor)
+ inc_cursor(0.,-cursor_inc );
+ else
+ {
+ if(shift_key_pressed)
+ view.pan[1] += 0.1;
+ else
+ view.rot[0] += 1.;
+
+ view.redo_projections = 1;
+ }
+ break;
+ case VK_RIGHT:
+ if(do_cursor)
+ inc_cursor(cursor_inc, 0.);
+ else
+ {
+ if(shift_key_pressed)
+ view.pan[0] += -.1;
+ else
+ view.rot[1] += 1.;
+
+ view.redo_projections = 1;
+ }
+ break;
+ case VK_LEFT:
+ if(do_cursor)
+ inc_cursor(-cursor_inc, 0.);
+ else
+ {
+ if(shift_key_pressed)
+ view.pan[0] += .1;
+ else
+ view.rot[1] += -1.;
+
+ view.redo_projections = 1;
+ }
+ break;
+ }
+ return 0;
+ break;
+
+
+ case WM_CHAR:
+ kcode=LOWORD (wParam);
+
+ switch (kcode)
+ {
+ case VK_ESCAPE:
+ //exit(0);
+ break;
+ case 'c':
+ case 'C':
+ do_cursor = !do_cursor;
+ break;
+ case 'd':
+ case 'D':
+ view.pan[1] -= 0.1;
+ view.redo_projections = 1;
+ break;
+ case 's':
+ case 'S':
+ do_stats = !do_stats ;
+ break;
+
+ case 'l':
+ case 'L':
+ view.rot[1] += -1.;
+ view.redo_projections = 1;
+ break;
+
+ case 'r':
+ case 'R':
+ view.rot[1] -= -1.;
+ view.redo_projections = 1;
+ break;
+
+ case 'u':
+ case 'U':
+ view.pan[1] += 0.1;
+ view.redo_projections = 1;
+ break;
+
+ case 'v':
+ case 'V':
+ if( view.projection == LP_ORTHO)
+ view.projection = LP_PERSPECTIVE;
+ else
+ view.projection = LP_ORTHO;
+
+ view.redo_projections = 1;
+ break;
+
+ case 'z':
+ view.pan[2] -= .1;
+ view.redo_projections = 1;
+ break;
+
+ case 'Z':
+ view.pan[2] += .1;
+ view.redo_projections = 1;
+ break;
+ ////
+ case '1':
+ break;
+ }
+ return 0;
+ break;
+
+
+ case WM_MOUSEWHEEL:
+ view.pan[2] += (float)GET_WHEEL_DELTA_WPARAM(wParam)/250.0;
+ view.redo_projections = 1;
+ return 0;
+ break;
+
+
+ case WM_LBUTTONDOWN:
+ if(!pick(0, 1, LOWORD (lParam), HIWORD (lParam)))
+ {
+ mousex = LOWORD (lParam);
+ mousey = HIWORD (lParam);
+ lmouse = 1;
+ }
+ return 0;
+ break;
+
+
+ case WM_LBUTTONUP:
+ if(!pick(0, 0, LOWORD (lParam), HIWORD (lParam)))
+ lmouse = 0;
+ return 0;
+ break;
+
+
+ case WM_MOUSEMOVE:
+ if(lmouse)
+ {
+ omx = mousex;
+ omy = mousey;
+
+ if(shift_key_pressed)
+ {
+ view.pan[0] += ((float) LOWORD (lParam) - (float) omx) .02;
+ view.pan[1] -= ((float) HIWORD (lParam) - (float) omy)
.02;
+
+ }
+ else
+ {
+ view.rot[1] += ((float) LOWORD (lParam) - (float) omx) .2;
+ view.rot[0] += ((float) HIWORD (lParam) - (float) omy)
.2;
+ }
+
+ mousex = LOWORD (lParam);
+ mousey = HIWORD (lParam);
+ view.redo_projections = 1;
+ }
+ return 0;
+ break;
+
+
+ case WM_SIZE:
+ window_xsize = (GLsizei) LOWORD (lParam);
+ window_ysize = (GLsizei) HIWORD (lParam);
+ view.aspect = (GLdouble)window_xsize/(GLdouble)window_ysize;
+
+ glViewport( 0, 0, window_xsize, window_ysize );
+ glGetIntegerv (GL_VIEWPORT, viewport);
+ setProjection(0);
+ setModelview(0);
+
+ return 0;
+ break;
+
+ case WM_QUIT:
+ case WM_CLOSE:
+ if (hRC) {
+ wglMakeCurrent(NULL,NULL);
+ wglDeleteContext( hRC );
+ }
+ if (hDC) {
+ ReleaseDC(hWnd,hDC);
+ }
+ DestroyWindow(hWnd);
+ return 0;
+ break;
+
+ case WM_DESTROY:
+ UnregisterClass(FPClassName,hInstance);
+ PostQuitMessage( 0 );
+ if(quit_callbackfunc)
+ (quit_callbackfunc)();
+ else
+ exit(0);
+ return 0;
+ break;
+
+ default:
+ return DefWindowProc( hWnd, msg, wParam, lParam );
+ }
+}
+
+
+#else
static Bool WaitForMapNotify(Display
d, XEvent e, char arg)
{
if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
@@ -64,11 +333,21 @@
}
return GL_FALSE;
}
+#endif

void
Lpanel::procEvents(void)
{
+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+MSG msg;
+
+ if ( PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE) ) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+

+#else
XEvent event;
char buffer[5];
int bufsize = 5;
@@ -296,12 +575,114 @@
}

} // end while

+#endif
} // end procEvents()

+
+
int
Lpanel::openWindow(const char *title)
{

+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+
+ BOOL err;
+
+ float geom_aspect = (bbox.xyz_max[0] - bbox.xyz_min[0]) / (bbox.xyz_max[1] - bbox.xyz_min[1]);
+ window_ysize = (int) ( (float) window_xsize / geom_aspect);
+ view.aspect = (GLdouble)window_xsize/(GLdouble)window_ysize;
+
+ hInstance = GetModuleHandle( NULL );
+
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = 0;
+ wc.lpfnWndProc = StaticWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(NULL, IDC_HAND);
+ //wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE);
+ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = FPClassName;
+ wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
+
+ if(!RegisterClassEx(&wc))
+ {
+ MessageBox(NULL, "Window registration failed!", "Error!",
+ MB_ICONEXCLAMATION | MB_OK);
+ return 0;
+ }
+
+ hWnd = CreateWindowEx(
+ WS_EX_CLIENTEDGE,
+ FPClassName,
+ title,
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, window_xsize, window_ysize,
+ NULL, NULL, hInstance, NULL);
+
+ if(hWnd == NULL)
+ {
+ MessageBox(NULL, "Window creation failed!", "Error!",
+ MB_ICONEXCLAMATION | MB_OK);
+ return 0;
+ }
+
+ // We put in the window user data area a ponter to the windowproc for its instance
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)reinterpret_cast<Lpanel *="">(this));
+
+ hDC = GetDC (hWnd);
+
+ memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 24;
+ pfd.cDepthBits = 32;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ int pixelFormat = ChoosePixelFormat(hDC, &pfd);
+ if (pixelFormat == 0) {
+ return 0;
+ }
+
+ err = SetPixelFormat (hDC, pixelFormat, &pfd);
+ if (!err) {
+ return 0;
+ }
+
+ hRC = wglCreateContext(hDC);
+ if (!hRC) {
+ MessageBox(NULL, "lightpanel: Can't create window context", "Error!",
+ MB_ICONEXCLAMATION | MB_OK);
+ return 0;
+ }
+
+ err = wglMakeCurrent(hDC, hRC);
+ if (!err) {
+ MessageBox(NULL, "lightpanel: Can't make window current to context", "Error!",
+ MB_ICONEXCLAMATION | MB_OK);
+ //ReleaseDC (hWnd, hDC);
+ return 0;
+ }
+
+ ShowWindow(hWnd, SW_SHOWNORMAL );
+
+ SetForegroundWindow(hWnd);
+ SetFocus(hWnd);
+ initGraphics();
+ UpdateWindow(hWnd);
+
+ cursor[0] = (bbox.xyz_max[0] + bbox.xyz_min[0]) * .5;
+ cursor[1] = (bbox.xyz_max[1] + bbox.xyz_min[1]) * .5;
+ makeRasterFont();
+ make_cursor_text();
+
+//
+#else
int status;

XVisualInfo *vi = NULL;
@@ -381,6 +762,7 @@
makeRasterFont();
make_cursor_text();

+#endif
return 1;
}

@@ -391,6 +773,12 @@
glFlush();
glFinish();

+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+//
+ wglMakeCurrent(NULL,NULL);
+ ReleaseDC (hWnd, hDC);
+
+#else
if (!glXMakeCurrent(dpy, None, None)) {
printf("lightpanel: destroyWindow: Can't release context\n");
}
@@ -401,7 +789,7 @@
dpy = 0;
cx = 0;
window = 0;
-
+#endif

}
@@ -475,6 +863,9 @@
}

+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+//
+#else
void
Lpanel::resizeWindow(void)
{
@@ -491,8 +882,9 @@
setProjection(0);

setModelview(0);

}
+#endif
+

void
Lpanel::doPickProjection(void)
@@ -512,6 +904,9 @@
void
Lpanel::initGraphics(void)
{
+ // Smooth shading blends colors nicely across a polygon, and smoothes out lighting
+ //glShadeModel(GL_SMOOTH);
+
// initialize materials

lp_init_materials_dlist();
@@ -534,6 +929,8 @@

glDisable(GL_LIGHTING);
//glEnable(GL_LIGHTING);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.,0.,0.,1.);

glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mtl_amb);
@@ -545,8 +942,14 @@

glEnable(GL_NORMALIZE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- glXSwapBuffers(dpy, window);

+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+//
+//UpdateWindow(hWnd);
+//Sleep(100);
+#else
+ glXSwapBuffers(dpy, window);
+#endif
// download any textures that may have been read in

textures.downloadTextures();
@@ -589,6 +992,7 @@
glColor3f(1.,1.,0.);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
+
glBegin(GL_LINES);
glVertex3f( cursor[0] - size , cursor[1] - size, cursor[2]);
glVertex3f( cursor[0] + size , cursor[1] + size, cursor[2]);
diff -aur src-original/lpanel.cpp src/lpanel.cpp
--- src-original/lpanel.cpp 2008-10-17 13:58:49 +0200
+++ src/lpanel.cpp 2014-03-05 09:34:24 +0100
@@ -229,9 +229,12 @@
{
int i;

+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+#else
window = 0;
cx = 0;
dpy = 0;
+#endif

num_lights = 0;
max_lights = 0;
@@ -849,7 +852,11 @@
glDisable(GL_POLYGON_OFFSET_LINE);
}
if(do_stats) draw_stats();
+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+ UpdateWindow(hWnd);
+#else
glXSwapBuffers(dpy, window);
+#endif
}

diff -aur src-original/lpanel.h src/lpanel.h
--- src-original/lpanel.h 2008-10-18 23:34:55 +0200
+++ src/lpanel.h 2014-03-05 15:47:51 +0100
@@ -22,9 +22,14 @@

#include <stdio.h>
+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+#include <GL gl.h="">
+#include <windows.h>
+#else
#include <GL glx.h="">
#include <X11 Xlib.h="">
#include <X11 Xatom.h="">
+#endif

typedef unsigned char uint8;
@@ -35,6 +40,7 @@
#define LP_MAX_LIGHT_GROUPS 10

+
// forward references

class lpLight;
@@ -87,6 +93,9 @@
#include "lp_gfx.h"
#include "lp_switch.h"

+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
+#endif

// light panel class
// -----------------
@@ -108,10 +117,19 @@
int num_switches,
max_switches;

+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+ HINSTANCE hInstance;
+ HWND hWnd;
+ WNDCLASSEX wc;
+ HDC hDC;
+ HGLRC hRC;
+ PIXELFORMATDESCRIPTOR pfd;
+#else
Display *dpy; // Xwindows display
Window window; // Xwindows window
GLXContext cx;
Atom wmDeleteMessage; // for processing window close event
+#endif

view_t view;

@@ -206,7 +224,15 @@
void destroyWindow(void);
void doPickProjection(void);
void doPickModelview(void);
+
+#if defined (MINGW32) || defined (WIN32) || defined (_WIN32) || defined (WIN32)
+
+ LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
+
+#else
void resizeWindow(void);
+#endif
+
void initGraphics();
void procEvents(void);
void resolveObjectInstances(void);