]> git.saurik.com Git - wxWidgets.git/blobdiff - docs/microwin/readme.txt
define _HPUX_SOURCE under HP-UX, otherwise many things are not defined in standard...
[wxWidgets.git] / docs / microwin / readme.txt
index d7cff792dcc9339a08550093f83472ed9904c45f..2bc10af53d636fcc216678eea9aa863e343e3559 100644 (file)
@@ -1,38 +1,87 @@
 wxMicroWindows port
 ===================
 
-Julian Smart 2001-07-02
+Julian Smart 2001-12-08
 
-This is a snapshot of my experimental port of wxWindows to
-MicroWindows. Widgets are supplied by the wxUniversal project,
-while the underlying port uses the Windows ports with small
-modifications for the MicroWindows API.
+This is a port of wxWidgets to MicroWindows, under Linux.
+Widgets are supplied by the wxUniversal project, while the
+underlying port uses the Windows ports with small modifications
+for the MicroWindows API.
+
+=== NOTE: ===
+
+  Current efforts are being concentrated on a port to Nano-X,
+  which potentially offers greater flexibility than the WIN32
+  API of MicroWindows, such as the ability to run multiple
+  Nano-X processes simultaneously. Please see
+  ../docs/x11/readme-nanox.txt for information.
 
 There are many things missing from MicroWindows that will
-make the port quite limited for the time being. I haven't
-worked out how to create bitmaps, though there is a BMP to C
-converter. There are no menus, no common dialogs, and only
-one WIN32 app may be run at a time.
+make the port quite limited for the time being.
+In particular, only one WIN32 app may be run at a time.
 
-Some things can no doubt be worked around, and/or MicroWindows
-itself tweaked. Lots of wxWin functionality is just switched off or
-commented out.
+Note that you can gain confidence in the WIN32/wxUniversal
+combination by compiling wxUniversal under Windows using VC++,
+using src/wxUniv.dsp. You can compile the minimal
+and widgets samples in wxUniversal mode using the
+UnivDebug and UnivRelease targets. Most of the code is shared
+between this combination, and the wxMicroWindows port.
 
 Installation
 ============
 
-First install MicroWindows - untar it, change config to
-use X11 and any other options you feel fit, apply
-microwindows.patches to fix PeekMessage, and compile
-(type 'make' from within the src directory).
+MicroWindows:
+
+- unarchive MicroWindows 0.89pre8
+
+- change 'config' to use X11 and any other options you feel fit.
+  Suggestions for changes to the defaults:
+
+  ERASEMOVE=N (otherwise moving windows will look messy)
+  X11=Y
+  OPTIMIZE=N
+  DEBUG=Y
+  VERBOSE=Y
+
+  Note: these are already applied by the patch below.
+
+- apply microwindows.patches (from wxWidgets:
+  docs/microwin/microwindows.patches) to fix PeekMessage
+  and other issues. If the patch doesn't apply automatically,
+  you may need to apply it by hand, and the relevant changed
+  functions are given at the end of this file for convenience.
+
+  Example patch command:
+
+  % cd microwindows-0.89pre8.orig
+  % patch -p0 < ~/wx2/docs/microwin/microwindows.patches
+
+- compile by typing 'make' from within the MicroWindows src directory
+
+wxMicroWindows:
+
+- Download wxMSW 2.3.4 or greater, or get it from CVS
+
+- Copy include/wx/msw/setup_microwin.h to include/wx/setup.h if
+  include/wx/setup.h doesn't exist
+
+- EITHER:
+
+  o set the MICROWINDOWS environment variable, e.g.:
+
+    % export MICROWINDOWS=/home/julians/local/microwindows/microwindows-0.89pre8/src
 
-Untar the wxMicroWindows port, and change the TOP variable at the
-top of src/microwin/Makefile to reflect where MicroWindows is installed.
-Type 'make all' from src/microwin. To clean, use cleanwx and NOT clean
-since that will clean MicroWindows itself.
+  OR:
+
+  o change the TOP variable at the top of src/msw/makefile.mic
+    to reflect where MicroWindows is installed
+
+- type 'make -f makefile.mic all' from src/msw. To clean, use
+  cleanwx and NOT clean since that will clean MicroWindows itself
+
+- to make the sample, cd into samples/minimal, edit the TOP variable
+  (or set MICROWINDOWS) as before, and type 'make -f makefile.mic all'
 
-To make the sample, cd into samples/minimal, edit the TOP variable,
-and type 'make all'.
 Running 'minimal' runs the virtual MicroWindows desktop
 and the minimal sample, since in a MicroWindows WIN32 application
 they are one and the same binary.
@@ -40,15 +89,99 @@ they are one and the same binary.
 Status
 ======
 
-A frame comes up :-)
+The minimal sample is almost fully-functional, apart from some
+presentation issues (no menu borders and status bar in the wrong
+place.
+
+The widgets sample is crashing in DeleteObject (see notes below).
+
+
+Implementation Notes
+====================
+
+wxMicroWindows is essentially the wxMSW port + wxUniversal
+widgets. Lots of things in include/wx/univ/setup.h are switched
+off to allow the port to compile. There are also #ifdefs
+switching off further functionality, such as most wxBitmap
+functions, pending proper implementation.
+
+There are some WIN32 API functions not implemented by MicroWindows
+that are instead stubbed out in include/wx/msw/microwin.c,
+and 'implemented' in src/msw/microwin.c. Some of these functions
+are important, some less so. They will need to be implemented
+in due course. But implementing missing functionality in this way
+is preferably to proliferating many #ifdefs in the
+wxMSW/wxMicroWindows port itself.
+
+
+Errors/warnings
+===============
+
+In file ../../src/msw/window.cpp at line 1294: 'UpdateWindow' failed with error 0x00000000 (Success).
+
+  - caused because there are no paint messages pending. Presumed
+    harmless.
+
+In file ../../src/msw/dc.cpp at line 1838: 'BitBlt' failed with error 0x00000000 (Success).
+
+  - caused because the window isn't mapped, and MwPrepareDC in wingdi.c
+    fails (hwnd->unmapcount is non-zero). Presumed harmless.
+
+Recursive paint problem, e.g. when clicking the 'Press Me!'
+button in the widgets sample a few times, until the text control
+is full.
+
+  - possibly the scrollbar is causing the text control to be
+    updated, which somehow effects the scrollbar, which causes
+    a window update, etc.
 
-Notes
-=====
+Sluggish updates.
 
-No ::GetKeyState (see microwin/private.h). Should probably use GdOpenKeyboard/GdCloseKeyboard/GdReadKeyboard. Could perhaps emulate GetKeyState this way.
+  - probably because many image to bitmap conversions are being
+    done on update, and bitmaps should probably be cached.
 
-No ::CreateBitmap or BITMAPINFO. But BMPs can be converted
-to C using convbmp, then need to use Gr... functions.
+
+Things missing from MicroWindows that need to be worked around
+==============================================================
+
+wxImage/inline XPM/::CreateBitmap support
+-----------------------------------------
+
+This is the main obstacle to getting a good range
+of widgets working, since wxUniversal uses inline XPMs
+to implement most of the widgets.
+
+See src/engine/devimage.c for routines for loading JPEGs,
+XPMs etc. Unfortunately the XPM routines are also #ifdefed
+for FILE_IO, even though for inline XPMs we don't need file I/O.
+(Embedded systems tend not to have file I/O, anyway.)
+
+Now, wxWidgets has its own XPM decoder, src/common/xpmdecod.cpp,
+so in theory we don't need to use MicroWindows' code there.
+wxImage can load an inline XPM, _but_ we need to convert to
+a wxBitmap since this is what the widgets need.
+
+There is no ::CreateBitmap or BITMAPINFO. (BMPs can be converted
+to C using convbmp, then need to use Gr... functions.)
+
+So how can we convert from wxImage to wxBitmap in MicroWindows?
+
+Well, a simple-minded way would be to use CreateCompatibleBitmap
+which returns an HBITMAP, select it into an HDC, and draw
+the pixels from the wxImage to the HDC one by one with SetPixel.
+This is now implemented, but there are problems with masks.
+(a) masks have to be created at screen depth because BitBlt/GrDraw
+can't cope with differing depths, and (b) masked blitting
+is still not working (try enabling mask creation in
+wxBitmap::CreateFromImage by setting USE_MASKS to 1).
+
+
+Other missing features
+----------------------
+
+No ::GetKeyState (see include/wx/msw/private.h). Should probably use
+GdOpenKeyboard/GdCloseKeyboard/GdReadKeyboard. Could perhaps emulate
+GetKeyState this way.
 
 No ::DestroyIcon, ::DestroyCursor - use ::DestroyObject instead?
 Also no LoadCursor, LoadImage. So how do we make cursors? No ::SetCursor.
@@ -56,10 +189,146 @@ Also no LoadCursor, LoadImage. So how do we make cursors? No ::SetCursor.
 wxDC: no ::GetTextColor, ::GetBkColor, ::IntersectClipRect,
 ::GetClipBox
 
-No ::SetMenu, so no menus or menubars.
+No ::SetMenu, so no menus or menubars (now implemented by
+wxUniversal).
 
 No ::GetObject so we can't get LOGFONT from an HFONT
-in wxSystemSettings.
+in wxSystemSettings (worked around by passing HFONT to
+the wxFont constructor).
+
+
+Applying patches by hand
+========================
+
+The full altered functions are given below in case you have
+to apply them by hand.
+
+src/mwin/winevent.c
+-------------------
+
+A second test has been added to this line:
+
+       if(hittest == HTCLIENT || hwnd == GetCapture()) {
+
+in MwTranslateMouseMessage below. This corrects a mouse message
+bug.
+
+/*
+ * Translate and deliver hardware mouse message to proper window.
+ */
+void
+MwTranslateMouseMessage(HWND hwnd,UINT msg,int hittest)
+{
+       POINT           pt;
+       DWORD           tick;
+       static UINT     lastmsg = 0;
+       static HWND     lasthwnd;
+       static DWORD    lasttick;
+       static int      lastx, lasty;
+
+       /* determine double click eligibility*/
+       if(msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN) {
+               tick = GetTickCount();
+               if((hwnd->pClass->style & CS_DBLCLKS) &&
+                   msg == lastmsg && hwnd == lasthwnd &&
+                   tick - lasttick < DBLCLICKSPEED &&
+                   abs(cursorx-lastx) < mwSYSMETRICS_CXDOUBLECLK &&
+                   abs(cursory-lasty) < mwSYSMETRICS_CYDOUBLECLK)
+                       msg += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
+               lastmsg = msg;
+               lasthwnd = hwnd;
+               lasttick = tick;
+               lastx = cursorx;
+               lasty = cursory;
+       }
+
+       /*
+        * We always send nc mouse message
+        * unlike Windows, for HTCLIENT default processing
+        */
+       PostMessage(hwnd, msg + (WM_NCMOUSEMOVE-WM_MOUSEMOVE), hittest,
+               MAKELONG(cursorx, cursory));
+
+       /* then possibly send user mouse message*/
+       if(hittest == HTCLIENT || hwnd == GetCapture()) {
+               pt.x = cursorx;
+               pt.y = cursory;
+               ScreenToClient(hwnd, &pt);
+               PostMessage(hwnd, msg, 0, MAKELONG(pt.x, pt.y));
+       }
+}
+
+winuser.c
+---------
+
+Part of PeekMessage has been factored out into PeekMessageHelper,
+and used in PeekMessage and GetMessage. The three relevant functions
+are:
+
+/*
+ * A helper function for sharing code between PeekMessage and GetMessage
+ */
+
+BOOL WINAPI
+PeekMessageHelper(LPMSG lpMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
+       UINT wRemoveMsg, BOOL returnIfEmptyQueue)
+{
+       HWND    wp;
+       PMSG    pNxtMsg;
+
+       /* check if no messages in queue*/
+       if(mwMsgHead.head == NULL) {
+                /* Added by JACS so it doesn't reach MwSelect */
+                if (returnIfEmptyQueue)
+                    return FALSE;
+
+#if PAINTONCE
+               /* check all windows for pending paint messages*/
+               for(wp=listwp; wp; wp=wp->next) {
+                       if(!(wp->style & WS_CHILD)) {
+                               if(chkPaintMsg(wp, lpMsg))
+                                       return TRUE;
+                       }
+               }
+               for(wp=listwp; wp; wp=wp->next) {
+                       if(wp->style & WS_CHILD) {
+                               if(chkPaintMsg(wp, lpMsg))
+                                       return TRUE;
+                       }
+               }
+#endif
+               MwSelect();
+       }
+
+       if(mwMsgHead.head == NULL)
+               return FALSE;
+
+       pNxtMsg = (PMSG)mwMsgHead.head;
+       if(wRemoveMsg & PM_REMOVE)
+               GdListRemove(&mwMsgHead, &pNxtMsg->link);
+       *lpMsg = *pNxtMsg;
+       if(wRemoveMsg & PM_REMOVE)
+               GdItemFree(pNxtMsg);
+       return TRUE;
+}
+
+BOOL WINAPI
+PeekMessage(LPMSG lpMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
+       UINT wRemoveMsg)
+{
+        /* Never wait in MwSelect: pass TRUE */
+        return PeekMessageHelper(lpMsg, hwnd, uMsgFilterMin, uMsgFilterMax, wRemoveMsg, TRUE);
+}
 
-No ::CreateDialog so how do we create dialogs? Simulate
-one with a frame I guess.
+BOOL WINAPI
+GetMessage(LPMSG lpMsg,HWND hwnd,UINT wMsgFilterMin,UINT wMsgFilterMax)
+{
+       /*
+        * currently MwSelect() must poll for VT switch reasons,
+        * so this code will work
+        */
+        /* Always wait in MwSelect if there are messages: pass FALSE */
+       while(!PeekMessageHelper(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax,PM_REMOVE, FALSE))
+               continue;
+       return lpMsg->message != WM_QUIT;
+}