nanogui: Win32 screen/mouse/keyboard driver


Previous by date: 14 Feb 2005 06:01:23 +0000 cross compiling microwindows with uclinux, sujatha
Next by date: 14 Feb 2005 06:01:23 +0000 Is 256 color bitmap supported?, Praveen Patil
Previous in thread:
Next in thread:

Subject: Win32 screen/mouse/keyboard driver
From: "wilson loi" ####@####.####
Date: 14 Feb 2005 06:01:23 +0000
Message-Id: <00cd01c5125a$93aea4e0$7201a8c0@S004048NB>



Hi, all,

I have make a beta version of Win32 screen/mouse/keyboard driver for
microwindows-0.90. (just like the X11 driver)
It is useful that I can debug NxLib in Win32 Visual C++ debugger & Borland
C++ Builder CodeGuard.
I have test this code with Nano-X demo ntetris.c program

I submit to here and hope someone can merge this code to 0.92 ???
The driver codes  is attached in the mail. I don't know if this is ok to
mail-list or not??? sorry about that.
Which including
1) src/kbd/mou Win32 driver
2) VC++ 6.0 project
3) ntertris.c demo program modified version

Here is something need to do (at least)
1) Move 'mwin' win32 header to different directory
2) Only support NanoX mode unless you can build a separate DLL file for the
Win32 screen/mouse/keyboard driver.

Also, you need this code 'GsSelect' for Nano-X (I think it should belong to
'srvmain.c' )

'srvmain.c'
#if WIN32
static void HandleKeyMessage(MSG *msg, GR_EVENT_TYPE keyType)
{
    int keystatus = -1;
    MWKEY mwkey = msg->wParam; // virtual-key code
    MWKEYMOD modifiers = 0;
    unsigned char scanCode;
    int  repeat, extended, context, previous;

    repeat = msg->lParam & 0xffff;
    scanCode = (msg->lParam >> 16) & 0xff;
    extended = msg->lParam & 1000000;
    context = msg->lParam & 20000000;
    previous = msg->lParam & 40000000;
    if (extended)
    {

    }
    GsDeliverKeyboardEvent(0, keyType, mwkey, modifiers, scanCode);
}

#define MAX_MOUSEEVENTS 10    /* max number of mouse event to get in 1
select */
#define MAX_KEYBDEVENTS 10    /* max number of mouse event to get in 1
select */
extern HWND rootWindow;
extern MSG *winMouseMsg;
void
GsSelect(GR_TIMEOUT timeout)
{
    MSG msg;
 int mouseevents = 0;
 int keybdevents = 0;
 GR_EVENT_GENERAL *gp;

    if (rootWindow == NULL)
    {
        goto err_exit;
    }

    if (timeout == 0)
    {
        if (!PeekMessage(&msg, rootWindow, 0, 0, PM_REMOVE))
        {
            Sleep(20); /* necessary, otherwise the system may be occupied by
microwindows only */
            return;
        }
    }
    else if (timeout == -1)
    {
        if (GetMessage(&msg, rootWindow, 0, 0) < 0)
        {
            goto err_exit;
        }
    }
    else
    {
        while (1)
        {
            if (PeekMessage(&msg, rootWindow, 0, 0, PM_REMOVE))
            {
                break;
            }
            Sleep(20);
            if (timeout < 20)
            {
                /* Timeout has occured.
                ** Currently return a timeout event regardless of whether
client
                **   has selected for it.
                */
                if ((gp = (GR_EVENT_GENERAL *)GsAllocEvent(curclient)) !=
NULL)
                {
                    gp->type = GR_EVENT_TYPE_TIMEOUT;
                }
                return;
            }
            timeout -=20;
        }
    }

    switch (msg.message)
    {
    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
        HandleKeyMessage(&msg, GR_EVENT_TYPE_KEY_DOWN);
        break;
    case WM_KEYUP:
    case WM_SYSKEYUP:
        HandleKeyMessage(&msg, GR_EVENT_TYPE_KEY_UP);
        break;
    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_LBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONUP:
    case WM_MBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONUP:
    case WM_RBUTTONDBLCLK:
        winMouseMsg = &msg;
        GsCheckMouseEvent();
        winMouseMsg = NULL;
        break;
    }

    TranslateMessage(&msg);
    DispatchMessage(&msg);

    return;

err_exit:
    GsTerminate();
    return;
}

--------------------------
scr_win32.c

/*
 * Copyright (c) 2005, Wilson Loi ####@####.####
 * WIN32 screen driver for Microwindows
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <wingdi.h>
#include <assert.h>
#include "device.h"
#include "fb.h"
#include "genmem.h"
#include "genfont.h"

#define APP_NAME "Microwindows"

#ifndef SCREEN_WIDTH
#error SCREEN_WIDTH not defined
#endif

#ifndef SCREEN_HEIGHT
#error SCREEN_HEIGHT not defined
#endif

#ifndef MWPIXEL_FORMAT
#error MWPIXEL_FORMAT not defined
#endif

/* SCREEN_DEPTH is used only for palette modes*/
#if !defined(SCREEN_DEPTH) && (MWPIXEL_FORMAT == MWPF_PALETTE)
#error SCREEN_DEPTH not defined - must be set for palette modes
#endif

/* externally set override values from nanox/srvmain.c*/
MWCOORD nxres;   /* requested server x res*/
MWCOORD nyres;   /* requested server y res*/

/* specific x11 driver entry points*/
static PSD X11_open(PSD psd);
static void X11_close(PSD psd);
static void X11_getscreeninfo(PSD psd, PMWSCREENINFO psi);
static void X11_setpalette(PSD psd, int first, int count, MWPALENTRY * pal);
static void X11_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c);
static MWPIXELVAL X11_readpixel(PSD psd, MWCOORD x, MWCOORD y);
static void X11_drawhline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y,
  MWPIXELVAL c);
static void X11_drawvline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2,
  MWPIXELVAL c);
static void X11_fillrect(PSD psd, MWCOORD x1, MWCOORD y1, MWCOORD x2,
  MWCOORD y2, MWPIXELVAL c);
static void X11_blit(PSD dstpsd, MWCOORD destx, MWCOORD desty, MWCOORD w,
  MWCOORD h, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op);
static void X11_drawarea(PSD psd, driver_gc_t * gc, int op);
static void X11_stretchblitex(PSD dstpsd, PSD srcpsd, MWCOORD dest_x_start,
  MWCOORD dest_y_start, MWCOORD width, MWCOORD height, int x_denominator,
  int y_denominator, int src_x_fraction, int src_y_fraction,
  int x_step_fraction, int y_step_fraction, long op);

SCREENDEVICE scrdev = {
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
 X11_open,
 X11_close,
 X11_getscreeninfo,
 X11_setpalette,
 X11_drawpixel,
 X11_readpixel,
 X11_drawhline,
 X11_drawvline,
 X11_fillrect,
 gen_fonts,
 X11_blit,
 NULL,
 NULL,
 NULL,   /* SetIOPermissions */
 gen_allocatememgc,
 fb_mapmemgc,
 gen_freememgc,
 NULL,   /* StretchBlit subdriver */
 NULL,   /* SetPortrait */
 0,   /* int portrait */
 NULL,   /* orgsubdriver */
 NULL, /* StretchBlitEx subdriver*/
};

HWND rootWindow = NULL;
static HDC dcBuffer = NULL;
static HBITMAP dcBitmap = NULL;
static HBITMAP dcOldBitmap;
HANDLE dummyEvent = NULL;

LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
 BOOL ret;
 HDC dc;
 PAINTSTRUCT ps;
 switch (Msg)
 {
    case WM_CREATE:
        break;
    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_LBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONUP:
    case WM_MBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONUP:
    case WM_RBUTTONDBLCLK:
        break;
    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
    case WM_SYSKEYUP:
    case WM_KEYUP:
        break;
    case WM_CHAR:
    case WM_DEADCHAR:
    case WM_SYSCHAR:
    case WM_SYSDEADCHAR:
        break;
 case WM_PAINT:
  dc = BeginPaint(hWnd, &ps);
  ret = BitBlt(dc, ps.rcPaint.left, ps.rcPaint.top,
    ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top,
    dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
  assert(ret!=FALSE);
  EndPaint(hWnd, &ps);
  break;
 case WM_DESTROY:
  PostQuitMessage(0);
  SelectObject(dcBuffer, dcOldBitmap);
  DeleteDC(dcBuffer);
  DeleteObject(dcBitmap);
        rootWindow = NULL;
        CloseHandle(dummyEvent);
  break;
 default:
  return DefWindowProc(hWnd, Msg, wParam, lParam);
 }
 return 0;
}

/* called from keyboard/mouse/screen */
static PSD X11_open(PSD psd)
{
 HANDLE hInstance = GetModuleHandle(NULL);
 int size;
 RECT rect;
 HDC rootDC = CreateDC("DISPLAY", NULL, NULL, NULL);
 int depth= GetDeviceCaps(rootDC, BITSPIXEL);
 DeleteDC(rootDC);
    GetWindowRect(GetDesktopWindow(), &rect);
 psd->linelen = psd->xres = psd->xvirtres = rect.right - rect.left;
 psd->yres = psd->yvirtres = rect.bottom - rect.top;




 psd->planes = 1;
 psd->pixtype = MWPIXEL_FORMAT;
 switch (psd->pixtype) {
#if MWPIXEL_FORMAT == MWPF_PALETTE
 case MWPF_PALETTE:
  psd->bpp = SCREEN_DEPTH;
  break;
#endif
 case MWPF_TRUECOLOR0888:
 case MWPF_TRUECOLOR8888:
 default:
  psd->bpp = 32;
  break;
 case MWPF_TRUECOLOR888:
  psd->bpp = 24;
  break;
 case MWPF_TRUECOLOR565:
 case MWPF_TRUECOLOR555:
  psd->bpp = 16;
  break;
 case MWPF_TRUECOLOR332:
  psd->bpp = 8;
  break;
 }

 /* Calculate the correct linelen here */
 GdCalcMemGCAlloc(psd, psd->xres, psd->yres, psd->planes,
    psd->bpp, &size, &psd->linelen);

 psd->ncolors = psd->bpp >= 24 ? (1 << 24) : (1 << psd->bpp);
 psd->flags = PSF_SCREEN | PSF_HAVEBLIT;
 psd->size = 0;
 psd->addr = NULL;
 psd->portrait = MWPORTRAIT_NONE;
 {
  WNDCLASS wc;

  wc.style           = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC;
  wc.lpfnWndProc     = (WNDPROC)myWindowProc;
  wc.cbClsExtra      = 0;
  wc.cbWndExtra      = 0;
  wc.hInstance       = hInstance;
  wc.hIcon           = LoadIcon(NULL, IDI_APPLICATION);
  wc.hCursor         = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground   = GetStockObject(WHITE_BRUSH);
  wc.lpszMenuName    = NULL;
  wc.lpszClassName   = APP_NAME;
  RegisterClass(&wc);
 }

 rootWindow = CreateWindow(APP_NAME, "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT,
   CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, NULL);
 if (rootWindow)
 {
  HDC dc = GetDC(rootWindow);
  GetClientRect(rootWindow, &rect);
  dcBitmap = CreateCompatibleBitmap(dc, rect.right-rect.left,
rect.bottom-rect.top);
  dcBuffer = CreateCompatibleDC(dc);
  dcOldBitmap = SelectObject(dcBuffer, dcBitmap);
  ReleaseDC(rootWindow, dc);
        dummyEvent = CreateEvent(NULL, TRUE, FALSE, "");
  ShowWindow(rootWindow, SW_SHOW);
  UpdateWindow(rootWindow);
 }
 return &scrdev;
}

static void
X11_close(PSD psd)
{
    if (rootWindow)
    {
     SendMessage(rootWindow, WM_DESTROY, 0, 0);
    }
}


static void
X11_getscreeninfo(PSD psd, PMWSCREENINFO psi)
{
 psi->rows = psd->yvirtres;
 psi->cols = psd->xvirtres;
 psi->planes = psd->planes;
 psi->bpp = psd->bpp;
 psi->ncolors = psd->ncolors;
 psi->portrait = psd->portrait;
 psi->fonts = NUMBER_FONTS;
 psi->xdpcm = 0;
 psi->ydpcm = 0;

 psi->fbdriver = FALSE; /* not running fb driver, no direct map */
 psi->pixtype = psd->pixtype;
 switch (psd->pixtype) {
 case MWPF_TRUECOLOR0888:
 case MWPF_TRUECOLOR8888:
 case MWPF_TRUECOLOR888:
  psi->rmask = 0xff0000;
  psi->gmask = 0x00ff00;
  psi->bmask = 0x0000ff;
  break;
 case MWPF_TRUECOLOR565:
  psi->rmask = 0xf800;
  psi->gmask = 0x07e0;
  psi->bmask = 0x001f;
  break;
 case MWPF_TRUECOLOR555:
  psi->rmask = 0x7c00;
  psi->gmask = 0x03e0;
  psi->bmask = 0x001f;
  break;
 case MWPF_TRUECOLOR332:
  psi->rmask = 0xe0;
  psi->gmask = 0x1c;
  psi->bmask = 0x03;
  break;
 case MWPF_PALETTE:
 default:
  psi->rmask = 0xff;
  psi->gmask = 0xff;
  psi->bmask = 0xff;
  break;
 }
}

static void
X11_setpalette(PSD psd, int first, int count, MWPALENTRY * pal)
{
}


static void
X11_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c)
{
 HDC dc = GetDC(rootWindow);
 SetPixel(dc, x, y, c);
 ReleaseDC(rootWindow, dc);
 SetPixel(dcBuffer, x, y, c);
}

static MWPIXELVAL
X11_readpixel(PSD psd, MWCOORD x, MWCOORD y)
{
 COLORREF ret = GetPixel(dcBuffer, x, y);
 return ret;
}

static void drawLine(HDC dc, MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2,
MWPIXELVAL c)
{
 HPEN pen = CreatePen(PS_SOLID, 1, c);
 POINT p;
 if (pen)
 {
  HGDIOBJ old = SelectObject(dc, pen);
  MoveToEx(dc, x1, y1, &p);
  LineTo(dc, x2, y2);
  SelectObject(dc, old);
  DeleteObject(pen);
 }
}

static void
X11_drawhline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
{
 HDC dc = GetDC(rootWindow);
 drawLine(dc, x1, y, x2, y, c);
 ReleaseDC(rootWindow, dc);
 drawLine(dcBuffer, x1, y, x2, y, c);
}

static void
X11_drawvline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
{
 HDC dc = GetDC(rootWindow);
 drawLine(dc, x, y1, x, y2, c);
 ReleaseDC(rootWindow, dc);
 drawLine(dcBuffer, x, y1, x, y2, c);
}

static void
X11_fillrect(PSD psd, MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2,
      MWPIXELVAL c)
{
 HBRUSH hbr = CreateSolidBrush(c);
 RECT rect;
 HDC dc;
 if (hbr)
 {
  rect.bottom = y2;
  rect.top = y1;
  rect.left = x1;
  rect.right = x2;
  dc = GetDC(rootWindow);
  FillRect(dc, &rect, hbr);
  ReleaseDC(rootWindow, dc);
  FillRect(dcBuffer, &rect, hbr);
  DeleteObject(hbr);
 }
}

static void
X11_blit(PSD dstpsd, MWCOORD destx, MWCOORD desty, MWCOORD w, MWCOORD h,
  PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op)
{
 HDC dc;
 if (op == MWMODE_NOOP) {
  return;
 }

 if (!(dstpsd->flags & PSF_SCREEN))
 {
  /* memory to memory blit, use offscreen blitter */
  dstpsd->Blit(dstpsd, destx, desty, w, h, srcpsd, srcx, srcy,
        op);
  return;
 }

 dc = GetDC(rootWindow);
 if (srcpsd->flags & PSF_SCREEN)
 {
  /* Use offscreen equivalent as the source */
  BitBlt(dc, destx, desty, w, h, dcBuffer, srcx, srcy, SRCCOPY);
  BitBlt(dcBuffer, destx, desty, w, h, dcBuffer, srcx, srcy, SRCCOPY);
 }
 else if (srcpsd->flags & PSF_MEMORY)
 {
  HBITMAP bitmap = CreateBitmap( srcpsd->xres, srcpsd->yres,
    srcpsd->planes, srcpsd->bpp, srcpsd->addr);
  if (bitmap)
  {
   HDC srcDc = CreateCompatibleDC(dc);
   if (srcDc)
   {
    HBITMAP old = SelectObject(srcDc, bitmap);
    BitBlt(dc, destx, desty, w, h, srcDc, srcx, srcy, SRCCOPY);
    BitBlt(dcBuffer, destx, desty, w, h, srcDc, srcx, srcy, SRCCOPY);
    SelectObject(srcDc, old);
    DeleteDC(srcDc);
   }
   DeleteObject(bitmap);
  }
 }
 ReleaseDC(rootWindow, dc);
}

-----------------------
mou_win32.c

/*
 * Copyright (c) 2005, Wilson Loi ####@####.####
 * WIN32 screen driver for Microwindows
 */
#include <stdio.h>
#include "device.h"
#include <windows.h>
#include <windowsx.h>
extern HWND rootWindow;
#define SCALE  3 /* default scaling factor for acceleration */
#define THRESH  5 /* default threshhold for acceleration */

static int   NUL_Open(MOUSEDEVICE *pmd);
static void  NUL_Close(void);
static int   NUL_GetButtonInfo(void);
static void NUL_GetDefaultAccel(int *pscale,int *pthresh);
static int   NUL_Read(MWCOORD *dx, MWCOORD *dy, MWCOORD *dz, int *bp);
static int   NUL_Poll(void);

MOUSEDEVICE mousedev = {
 NUL_Open,
 NUL_Close,
 NUL_GetButtonInfo,
 NUL_GetDefaultAccel,
 NUL_Read,
 NUL_Poll,
    MOUSE_NORMAL /* flags*/
};

/*
 * Poll for events
 */

static int
NUL_Poll(void)
{
 return 0;
}

/*
 * Open up the mouse device.
 */
static int
NUL_Open(MOUSEDEVICE *pmd)
{
 return -2; /* no mouse*/
}

/*
 * Close the mouse device.
 */
static void
NUL_Close(void)
{
}

/*
 * Get mouse buttons supported
 */
static int
NUL_GetButtonInfo(void)
{
 return MWBUTTON_L | MWBUTTON_M | MWBUTTON_R;
}

/*
 * Get default mouse acceleration settings
 */
static void
NUL_GetDefaultAccel(int *pscale,int *pthresh)
{
 *pscale = SCALE;
 *pthresh = THRESH;
}

/*
 * Attempt to read bytes from the mouse and interpret them.
 * Returns -1 on error, 0 if either no bytes were read or not enough
 * was read for a complete state, or 1 if the new state was read.
 * When a new state is read, the current buttons and x and y deltas
 * are returned.  This routine does not block.
 */

MSG *winMouseMsg = NULL;
static int
NUL_Read(MWCOORD *dx, MWCOORD *dy, MWCOORD *dz, int *bp)
{
    if (winMouseMsg)
    {
        *dx = GET_X_LPARAM(winMouseMsg->lParam);
        *dy = GET_Y_LPARAM(winMouseMsg->lParam);
        *dz = 0;
        *bp = 0;
        if (winMouseMsg->wParam & MK_LBUTTON)
        {
            *bp |= MWBUTTON_L;
        }
        if (winMouseMsg->wParam & MK_MBUTTON)
        {
            *bp |= MWBUTTON_M;
        }
        if (winMouseMsg->wParam & MK_RBUTTON)
        {
            *bp |= MWBUTTON_R;
        }
        return 2;
    }
    return 0;
}
-------------------------------------------------------------
/*
 * Copyright (c) 2005, Wilson Loi ####@####.####
 * WIN32 screen driver for Microwindows
 */
#include <string.h>
#include <stdio.h>
#include "device.h"
#include <windows.h>
extern HWND rootWindow;

static int  NUL_Open(KBDDEVICE *pkd);
static void NUL_Close(void);
static void NUL_GetModifierInfo(MWKEYMOD *modifiers, MWKEYMOD
*curmodifiers);
static int  NUL_Read(MWKEY *buf, MWKEYMOD *modifiers, MWSCANCODE *scancode);
static int  NUL_Poll(void);

KBDDEVICE kbddev = {
 NUL_Open,
 NUL_Close,
 NUL_GetModifierInfo,
 NUL_Read,
 NUL_Poll
};

/*
 * Poll for keyboard events
 */
static int
NUL_Poll(void)
{
 return 0;
}

/*
 * Open the keyboard.
 */
static int
NUL_Open(KBDDEVICE *pkd)
{
 return 0;
}

/*
 * Close the keyboard.
 */
static void
NUL_Close(void)
{

}

/*
 * Return the possible modifiers for the keyboard.
 */
static  void
NUL_GetModifierInfo(MWKEYMOD *modifiers, MWKEYMOD *curmodifiers)
{
 if (modifiers)
  *modifiers = 0;  /* no modifiers available */
 if (curmodifiers)
  *curmodifiers = 0;
}

/*
 * This reads one keystroke from the keyboard, and the current state of
 * the modifier keys (ALT, SHIFT, etc).  Returns -1 on error, 0 if no data
 * is ready, 1 on a keypress, and 2 on keyrelease.
 * This is a non-blocking call.
 */
static int
NUL_Read(MWKEY *mwkey, MWKEYMOD *modifiers, MWSCANCODE *scancode)
{
 return 0;
}




Previous by date: 14 Feb 2005 06:01:23 +0000 cross compiling microwindows with uclinux, sujatha
Next by date: 14 Feb 2005 06:01:23 +0000 Is 256 color bitmap supported?, Praveen Patil
Previous in thread:
Next in thread:


Powered by ezmlm-browse 0.20.