Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phGDIImageWindow.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h>
00031 
00032 #include <phGDIImageWindow.h>
00033 
00034 #if !defined(UNICODE)
00035     #define UNICODE 1
00036 #endif
00037 #if defined(HAVE_WINDOWS_H)
00038     #include <windows.h>
00039     #include <wchar.h>
00040 #endif
00041 
00042 #include <phError.h>
00043 #include <phMemory.h>
00044 #include <phPrint.h>
00045 
00046 #define NOGDIDEBUG() 1
00047 
00048 #if NOGDIDEBUG()
00049 #undef DEBUG_PRINT
00050 #define DEBUG_PRINT(...) ;
00051 #endif
00052 
00053 /* ---------------------------------------------------------------------- */
00054 #define WM_USER_SHOW    (WM_USER)
00055 #define WM_USER_HIDE    (WM_USER + 1)
00056 #define WM_USER_RESIZE  (WM_USER + 2)
00057 #define WM_USER_MOVE    (WM_USER + 3)
00058 #define WM_USER_UPDATE  (WM_USER + 4)
00059 #define WM_USER_REDRAW  (WM_USER + 5)
00060 
00061 #define phBITMAP_REALLOCED 1
00062 #define phDISPLAY_CHANGED  1
00063 
00064 
00065 /* ---------------------------------------------------------------------- */
00066 struct phGDIWindowInfo_t
00067 {
00068     HMODULE     module;
00069     HINSTANCE   instance;
00070     LPTSTR      command_line;
00071     STARTUPINFO startup_info;
00072     HWND        window;
00073     WNDCLASS    window_class;
00074     wchar_t     *window_class_name;
00075     wchar_t     *window_title;
00076     uint32_t    window_title_size;
00077     ATOM        window_atom;
00078 
00079     /* Bitmap image info and structures */
00080     HBITMAP     bitmap;
00081     BITMAPINFO  bitmap_info;
00082     void       *pixels;
00083     uint32_t    bitmap_width;
00084     uint32_t    bitmap_height;
00085 };
00086 
00087 /* ---------------------------------------------------------------------- */
00088 struct phGDI_pair_t
00089 {
00090     phGDIImageWindow    *thisptr;
00091     HHOOK               hook;
00092 };
00093 
00094 /* ---------------------------------------------------------------------- */
00095 struct phGDIHandlerParameters_t
00096 {
00097     HWND    window;
00098     UINT    message;
00099     WPARAM  wp;
00100     LPARAM  lp;
00101 };
00102 /* ---------------------------------------------------------------------- */
00103 #if 0
00104 static void print_POINT(POINT p)
00105 {
00106     DEBUG_PRINT("(%d,%d)",
00107           p.x,
00108           p.y);
00109 }
00110 static void print_RECT(RECT rect)
00111 {
00112     DEBUG_PRINT("(%d,%d,%d,%d)",
00113           rect.left,
00114           rect.top,
00115           rect.right,
00116           rect.bottom);
00117 }
00118 static void print_MINMAXINFO(MINMAXINFO m)
00119 {
00120     DEBUG_PRINT("[reserved:");
00121     print_POINT(m.ptReserved);
00122     DEBUG_PRINT("maxsize:");
00123     print_POINT(m.ptMaxSize);
00124     DEBUG_PRINT("maxpos:");
00125     print_POINT(m.ptMaxPosition);
00126     DEBUG_PRINT("mintrack:");
00127     print_POINT(m.ptMinTrackSize);
00128     DEBUG_PRINT("maxtrack:");
00129     print_POINT(m.ptMaxTrackSize);
00130     DEBUG_PRINT("]");
00131 }
00132 static void print_WINDOWPOS(WINDOWPOS w)
00133 {
00134     DEBUG_PRINT("(%d,%d,x:%d,y:%d,cx:%d,cy:%d)",
00135           w.hwnd,w.hwndInsertAfter,
00136           w.x,w.y,w.cx,w.cy);
00137     if (w.flags & SWP_DRAWFRAME)
00138     {
00139         DEBUG_PRINT("SWP_DRAWFRAME:");
00140     }
00141     if (w.flags & SWP_FRAMECHANGED)
00142     {
00143         DEBUG_PRINT("SWP_FRAMECHANGED:");
00144     }
00145     if (w.flags & SWP_HIDEWINDOW)
00146     {
00147         DEBUG_PRINT("SWP_HIDEWINDOW:");
00148     }
00149     if (w.flags & SWP_NOACTIVATE)
00150     {
00151         DEBUG_PRINT("SWP_NOACTIVATE:");
00152     }
00153     if (w.flags & SWP_NOCOPYBITS)
00154     {
00155         DEBUG_PRINT("SWP_NOCOPYBITS:");
00156     }
00157     if (w.flags & SWP_NOMOVE)
00158     {
00159         DEBUG_PRINT("SWP_NOMOVE:");
00160     }
00161     if (w.flags & SWP_NOOWNERZORDER)
00162     {
00163         DEBUG_PRINT("SWP_NOOWNERZORDER:");
00164     }
00165     if (w.flags & SWP_NOREDRAW)
00166     {
00167         DEBUG_PRINT("SWP_NOREDRAW:");
00168     }
00169     if (w.flags & SWP_NOREPOSITION)
00170     {
00171         DEBUG_PRINT("SWP_NOREPOSITION:");
00172     }
00173     if (w.flags & SWP_NOSENDCHANGING)
00174     {
00175         DEBUG_PRINT("SWP_NOSENDCHANGING:");
00176     }
00177     if (w.flags & SWP_NOSIZE)
00178     {
00179         DEBUG_PRINT("SWP_NOSIZE:");
00180     }
00181     if (w.flags & SWP_NOZORDER)
00182     {
00183         DEBUG_PRINT("SWP_NOZORDER:");
00184     }
00185     if (w.flags & SWP_SHOWWINDOW )
00186     {
00187         DEBUG_PRINT("SWP_SHOWWINDOW:");
00188     }
00189 }
00190 
00191 static void print_CREATESTRUCT(CREATESTRUCT c)
00192 {
00193     DEBUG_PRINT("(%p,%d,%d,%d,cy:%d,cx:%d,y:%d,x:%d,%ld,%s,%s,%ld)",
00194           c.lpCreateParams,
00195           c.hInstance,
00196           c.hMenu,
00197           c.hwndParent,
00198           c.cy,c.cx,c.y,c.x,
00199           c.style,c.lpszName,c.lpszClass,c.dwExStyle);
00200 }
00201 
00202 static void print_SIDE(WPARAM fwSide)
00203 {
00204     if (fwSide & WMSZ_BOTTOM)
00205     {
00206         DEBUG_PRINT("WMSZ_BOTTOM:");
00207     }
00208     if (fwSide == WMSZ_BOTTOMLEFT)
00209     {
00210         DEBUG_PRINT("WMSZ_BOTTOMLEFT:");
00211     }
00212     if (fwSide == WMSZ_BOTTOMRIGHT)
00213     {
00214         DEBUG_PRINT("WMSZ_BOTTOMRIGHT:");
00215     }
00216     if (fwSide & WMSZ_LEFT)
00217     {
00218         DEBUG_PRINT("WMSZ_LEFT:");
00219     }
00220     if (fwSide & WMSZ_RIGHT)
00221     {
00222         DEBUG_PRINT("WMSZ_RIGHT:");
00223     }
00224     if (fwSide & WMSZ_TOP)
00225     {
00226         DEBUG_PRINT("WMSZ_TOP:");
00227     }
00228     if (fwSide == WMSZ_TOPLEFT)
00229     {
00230         DEBUG_PRINT("WMSZ_TOPLEFT:");
00231     }
00232     if (fwSide == WMSZ_TOPRIGHT)
00233     {
00234         DEBUG_PRINT("WMSZ_TOPRIGHT:");
00235     }
00236 }
00237 
00238 static BOOL CALLBACK phGDIImageWindow_enumChildProc( HWND hwnd, LPARAM lParam )
00239 {
00240     wchar_t *text[255];
00241     RECT rect;
00242     
00243     ::GetWindowText(hwnd,(LPWSTR)text,255);
00244     ::GetWindowRect( hwnd, &rect );
00245     //DEBUG_PRINT("%s:%d",text,hwnd);
00246     print_RECT(rect);
00247     //DEBUG_PRINT("\n");
00248     
00249     return TRUE;
00250 }
00251 
00252 static void print_window_info(HWND window)
00253 {
00254     RECT rect;
00255     DEBUG_PRINT("Window(%d):",window);
00256     ::GetWindowRect( window, &rect );
00257     print_RECT(rect);
00258     DEBUG_PRINT("\n");
00259     DEBUG_PRINT("Client:");
00260     ::GetClientRect( window, &rect );
00261     print_RECT(rect);
00262     DEBUG_PRINT("\n");
00263 
00264     ::EnumChildWindows(window,phGDIImageWindow_enumChildProc,0);
00265 }
00266 #endif 
00267 
00268 /* ---------------------------------------------------------------------- */
00269 LRESULT CALLBACK phGDIImageWindow_WndProc( HWND hw, UINT message,
00270                                            WPARAM wp, LPARAM lp )
00271 {
00272     phFUNCTION("phGDIImageWindow_WndProc")
00273 
00274     phGDIImageWindow *win = 
00275         (phGDIImageWindow *)(uint64_t)::GetWindowLongPtr(hw,GWL_USERDATA);
00276 
00277 /*
00278     phPROGRESS("hw:%p msg:%u win:%p wp:%p lp:%p\n",
00279              hw,message,win,wp,lp);
00280 */
00281     if (win != NULL)
00282     {
00283         struct phGDIHandlerParameters_t params;
00284         params.window   = hw;
00285         params.message  = message;
00286         params.wp       = wp;
00287         params.lp       = lp;
00288 
00289         return (LRESULT)win->handle_message(&params);
00290     }
00291     else
00292     {
00293         return DefWindowProc(hw,message,wp,lp);
00294     }
00295     
00296     return 0;
00297 }
00298 /* ---------------------------------------------------------------------- */
00299 /* The HOOK idea came from:
00300  *    http://www.rpi.edu/~pudeyo/articles/wndproc/hook.cpp                */
00301 /* ---------------------------------------------------------------------- */
00302 /* The CBT hook procedure. It is called during CreateWindow call before 
00303  * WndProc receives any messages. Its job is to set per-window Window 
00304  * pointer to the one passed through lpParam to CreateWindow.             */
00305 /* ---------------------------------------------------------------------- */
00306 LRESULT CALLBACK phGDIImageWindow_CBTProc(int code, WPARAM wp, LPARAM lp)
00307 {
00308     phFUNCTION("phGDIImageWindow_CBTProc")
00309 
00310     LONG_PTR        ptr_rc      = NULL;
00311 
00312     if (code != HCBT_CREATEWND) 
00313     {
00314         /* Ignore everything but create window requests
00315          * Note: generally, HCBT_CREATEWND is the only notification we 
00316          * will get, assuming the thread is hooked only for the duration 
00317          * of CreateWindow call. However, we may receive other 
00318          * notifications, in which case they will not be passed to other 
00319          * CBT hooks. */
00320         return 0;
00321     }
00322     /* Grab a pointer passed to CreateWindow as lpParam */
00323     phGDI_pair_t *p = (phGDI_pair_t *)LPCBT_CREATEWND(lp)->lpcs->lpCreateParams;
00324     /* Only handle this window if it wasn't handled before, to prevent
00325      * rehooking windows when CreateWindow is called recursively */
00326     /* ie, when you create windows from a WM_CREATE handler */
00327     if (p->thisptr != NULL) 
00328     {
00329         /* Stash the associated Window pointer, which is the first member 
00330          * of the pair, into per-window data area */
00331         ::SetLastError(ERROR_SUCCESS);
00332         ptr_rc = ::SetWindowLongPtr((HWND)wp,
00333                                     GWL_USERDATA, 
00334                                     (LONG_PTR)p->thisptr);
00335         if ((ptr_rc == NULL) && (::GetLastError() != ERROR_SUCCESS))
00336             rc = phFAIL; 
00337         else 
00338             rc = phSUCCESS;
00339         phPRINT_RC(rc,"SetWindowLongPtr","SetWindowLongPtr failed.");
00340         /* Mark this window as handled */
00341         p->thisptr = NULL;
00342     }
00343     /* Call the next hook in chain, using the second member of the pair */
00344     return ::CallNextHookEx(p->hook, code, wp, lp);
00345 }
00346 
00347 /* ---------------------------------------------------------------------- */
00348 phGDIImageWindow::phGDIImageWindow( int32_t x, int32_t y,
00349                                     uint32_t w, uint32_t h,
00350                                     char *title,
00351                                     uint32_t flags ) :
00352                 phImageWindow(x,y,w,h,title,flags)
00353 {
00354     phFUNCTION("phGDIImageWindow::phGDIImageWindow")
00355     int i = 0;
00356     int locked = 0;
00357     
00358     phTHIS_LOCK(locked);
00359     
00360     this->setName("phGDIImageWindow");
00361     
00362     if (this->m_title == NULL)
00363     {
00364         this->setTitle("Phission: phGDIImageWindow");
00365     }
00366     
00367     this->m_formats = phImageValidFormatMask & 
00368                       (~(phImageYUV9|phImageHSV24));
00369     
00370     this->m_planes      = 0;
00371     this->m_bitspixel   = 0;
00372     this->m_bitdepth    = 0;
00373     this->m_dib_bitdepth= 0;
00374     this->m_dib_depth   = 0;
00375     this->m_red_mask    = 0;
00376     this->m_green_mask  = 0;
00377     this->m_blue_mask   = 0;
00378     this->m_red_shift   = 0;
00379     this->m_green_shift = 0;
00380     this->m_blue_shift  = 0;
00381     this->m_palette     = NULL;
00382     
00383     rc = this->set_display_info();
00384     phPRINT_RC(rc,NULL,"set_display_info");
00385     
00386     this->m_info = NULL;
00387     this->m_show_first = 0;
00388 
00389 error:
00390     phTHIS_UNLOCK(locked);
00391     
00392     return;
00393 }
00394 
00395 /* ---------------------------------------------------------------------- */
00396 phGDIImageWindow::~phGDIImageWindow()
00397 {
00398     phFUNCTION("phGDIImageWindow::~phGDIImageWindow")
00399     int i = 0;
00400     int locked = 0;
00401     
00402     phTHIS_LOCK(locked);
00403 error:
00404     if (this->m_info != NULL)
00405     {
00406         rc = this->destroy_window();
00407     }
00408 
00409     rc  = this->reset_display_info();
00410 }
00411 /* ------------------------------------------------------------------------- */
00412 inline static void phGDI_Align_8bitmask( int32_t *mask, int32_t *shift )
00413 {
00414     /* prevent an infinite loop when mask has no bits */
00415     if (!*mask) return;
00416     
00417     /* Figure out how many bits it has to be shifted left to
00418      * realign it with the total bits available for the color depth */
00419     while (!((*mask) & 0x01)) {
00420         (*mask) >>= 1;
00421         (*shift)++;
00422     }
00423     /* Assume that the mask is used on the high order bits
00424      * of the color value and shift it back */
00425     while (!((*mask) & 0x80)) {
00426         (*mask) <<= 1;
00427         (*shift)--;
00428     }
00429 }
00430 
00431 /* ---------------------------------------------------------------------- */
00432 /* Found out this from the SDL source code:
00433  *                          src/video/windib/SDL_dibvideo.c               
00434  * Had to re-write the function a bit after referencing:
00435  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_0zn6.asp
00436  */
00437 /* ---------------------------------------------------------------------- */
00438 int phGDIImageWindow::set_display_info()
00439 {
00440     phFUNCTION("phGDIImageWindow::set_display_info")
00441     int locked = 0;
00442         
00443     int                 retrc   = phSUCCESS;
00444     HDC                 hdc     = 0;
00445     HBITMAP             tbitmap = NULL;
00446     BITMAPINFO          *bi     = NULL;
00447     LOGPALETTE          palette;
00448     HPALETTE            palette_handle = NULL;
00449     int i           = 0;
00450     int dib_ncolors = 0;
00451     int planes      = 0;
00452     int bitspixel   = 0;
00453     int bitdepth    = 0;
00454     int dib_bitdepth= 0;
00455     int dib_depth   = 0;
00456     int red_mask    = 0x0;
00457     int green_mask  = 0x0;
00458     int blue_mask   = 0x0;
00459     int32_t red_smask   = 0x0;
00460     int32_t green_smask = 0x0;
00461     int32_t blue_smask  = 0x0;
00462     int32_t red_shift   = 0;
00463     int32_t green_shift = 0;
00464     int32_t blue_shift  = 0;
00465     
00467     bi = (BITMAPINFO *)phCalloc(1,sizeof(BITMAPINFO));
00468     phMemset(&palette,0,sizeof(LOGPALETTE));
00469     
00470     /* Get a regular system DC */
00471     hdc = ::GetDC(NULL);
00472 
00473     /* Get info the non-DIB way */
00474     planes   = ::GetDeviceCaps(hdc, PLANES);
00475     bitspixel= ::GetDeviceCaps(hdc, BITSPIXEL);
00476     bitdepth = planes *
00477                bitspixel;
00478     
00479     bi->bmiHeader.biSize= sizeof(BITMAPINFOHEADER);
00480     tbitmap             = ::CreateCompatibleBitmap(hdc,1,1);
00481     
00482     /* fill the BITMAPINFO structure */
00483     rc = ::GetDIBits(hdc,tbitmap,0,1,NULL,(LPBITMAPINFO)bi,DIB_RGB_COLORS);
00484 
00485     if ((bi->bmiHeader.biBitCount) <= 8)
00486     {
00487         bi = (BITMAPINFO *)phRealloc(bi,sizeof(BITMAPINFOHEADER) + 
00488                         (0x2 << bi->bmiHeader.biBitCount) * sizeof(RGBQUAD));
00489         #if 0
00490         phCHECK_RC(-1,NULL,"Palettes are currently unsupported.");
00491         #endif
00492     }
00493     /* If the bitmap header information specifies 16/24/32 bits per
00494      * pixel and biCompression is BI_BITFIELDS then there are 3
00495      * DWORD masks after the header info for RED, GREEN and BLUE
00496      * fields */
00497     else if (((bi->bmiHeader.biBitCount) >= 16) &&
00498              (bi->bmiHeader.biCompression == BI_BITFIELDS))
00499     {
00501         bi = (BITMAPINFO *)phRealloc(bi,sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
00502     }
00503 
00504     /* Get the RGBQuad stuff */
00505     rc = ::GetDIBits(hdc,tbitmap,0,1,NULL,(LPBITMAPINFO)bi,DIB_RGB_COLORS);
00506 
00507     /* Get the palette if necessary */
00508     if ( bi->bmiHeader.biBitCount <= 8 )
00509     {
00510         dib_ncolors = 1;
00511         for ( i = 0; i < bi->bmiHeader.biBitCount; ++i ) 
00512         {
00513             dib_ncolors *= 2;
00514         }
00515         palette.palVersion = 0x300;
00516         palette.palNumEntries = dib_ncolors;
00517         
00518         ::GetSystemPaletteEntries(hdc, 0, dib_ncolors, palette.palPalEntry);
00519         
00520         palette_handle = ::CreatePalette(&palette);
00521     }
00522 
00523     /* Free the objects */
00524     DeleteObject(tbitmap);
00525     ReleaseDC(NULL,hdc);
00526 
00527     dib_bitdepth = bi->bmiHeader.biBitCount;
00528     dib_depth = dib_bitdepth / 8;
00529 
00530     /* Set up the masks */
00531 
00532     if( bi->bmiHeader.biCompression == BI_BITFIELDS ) 
00533     {
00534         red_mask    = red_smask    = (uint32_t)((DWORD *)(bi->bmiColors))[0];
00535         green_mask  = green_smask  = (uint32_t)((DWORD *)(bi->bmiColors))[1];
00536         blue_mask   = blue_smask   = (uint32_t)((DWORD *)(bi->bmiColors))[2];
00537     }
00538     else if (bi->bmiHeader.biCompression == BI_RGB)
00539     {
00540         switch(dib_bitdepth)
00541         {
00542             case 16:
00543                 dib_bitdepth = 15;
00544                 red_mask    = red_smask    = 0x00007c00;
00545                 green_mask  = green_smask  = 0x000003e0;
00546                 blue_mask   = blue_smask   = 0x0000001f;
00547                 break;
00548             case 24:
00549             case 32:
00550                 red_mask    = red_smask    = 0x00ff0000;
00551                 green_mask  = green_smask  = 0x0000ff00;
00552                 blue_mask   = blue_smask   = 0x000000ff;
00553                 break;
00554             default:
00555                 red_mask    = red_smask    = 0x00000000;
00556                 green_mask  = green_smask  = 0x00000000;
00557                 blue_mask   = blue_smask   = 0x00000000;
00558                 break;
00559         }
00560     }
00561 
00562     phFree(bi);
00563 
00564     phGDI_Align_8bitmask( &red_smask,  &red_shift   );
00565     phGDI_Align_8bitmask( &green_smask,&green_shift );
00566     phGDI_Align_8bitmask( &blue_smask, &blue_shift  );
00567     
00568     phTHIS_LOCK(locked);
00569 
00570     if ((this->m_planes         != planes)                  ||
00571         (this->m_bitspixel      != bitspixel)               ||
00572         (this->m_bitdepth       != bitdepth)                ||
00573         (this->m_dib_bitdepth   != dib_bitdepth)            ||
00574         (this->m_dib_depth      != dib_depth)               ||
00575         (this->m_red_mask       != red_mask)                ||
00576         (this->m_green_mask     != green_mask)              ||
00577         (this->m_blue_mask      != blue_mask)               ||
00578         (this->m_palette        != (void *)palette_handle)  ||
00579         (this->m_red_smask      != red_smask)               ||
00580         (this->m_red_shift      != red_shift)               ||
00581         (this->m_green_smask    != green_smask)             ||
00582         (this->m_green_shift    != green_shift)             ||
00583         (this->m_blue_smask     != blue_smask)              ||
00584         (this->m_blue_shift     != blue_shift))
00585     {
00586         rc = reset_display_info();
00587         phPRINT_RC(rc,NULL,"reset_display_info()");
00588 
00589         retrc = phDISPLAY_CHANGED;
00590     }
00591 
00592     this->m_planes      = planes;
00593     this->m_bitspixel   = bitspixel;
00594     this->m_bitdepth    = bitdepth;
00595     this->m_dib_bitdepth= dib_bitdepth;
00596     this->m_dib_depth   = dib_depth;
00597     this->m_red_mask    = red_mask;
00598     this->m_green_mask  = green_mask;
00599     this->m_blue_mask   = blue_mask;
00600     this->m_palette     = (void *)palette_handle;
00601     this->m_red_smask   = red_smask;
00602     this->m_red_shift   = red_shift;
00603     this->m_green_smask = green_smask;
00604     this->m_green_shift = green_shift;
00605     this->m_blue_smask  = blue_smask;
00606     this->m_blue_shift  = blue_shift;
00607     
00608 #if 0
00609     phPRINT("%d:%d:%d:%d:%d:%p\n",
00610           this->m_planes,
00611           this->m_bitspixel,
00612           this->m_bitdepth,
00613           this->m_dib_bitdepth,
00614           this->m_dib_depth,
00615           this->m_palette);
00616     phPRINT("0x%08x:0x%08x:0x%08x:\n0x%08x:0x%08x:0x%08x:\n%d:%d:%d\n",
00617           this->m_red_mask,
00618           this->m_green_mask,
00619           this->m_blue_mask,
00620           this->m_red_smask,
00621           this->m_green_smask,
00622           this->m_blue_smask,
00623           this->m_red_shift,
00624           this->m_green_shift,
00625           this->m_blue_shift);
00626 #endif
00627 
00628     phTHIS_UNLOCK(locked);
00629 
00630     return retrc;
00631 error:
00632     phTHIS_ERROR_UNLOCK(locked);
00633 
00634     return phFAIL;
00635 }
00636 
00637 /* ---------------------------------------------------------------------- */
00638 int phGDIImageWindow::reset_display_info()
00639 {
00640     phFUNCTION("phGDIImageWindow::reset_display_info")
00641     int             locked      = 0;
00642     
00643     phTHIS_LOCK(locked);
00644     
00645     this->m_planes      = 0;
00646     this->m_bitspixel   = 0;
00647     this->m_bitdepth    = 0;
00648     this->m_dib_bitdepth= 0;
00649     this->m_dib_depth   = 0;
00650     this->m_red_mask    = this->m_red_smask     = 0;
00651     this->m_green_mask  = this->m_green_smask   = 0;
00652     this->m_blue_mask   = this->m_blue_smask    = 0;
00653     this->m_red_shift   = 0;
00654     this->m_green_shift = 0;
00655     this->m_blue_shift  = 0;
00656     if (this->m_palette != NULL)
00657     {
00658         ::DeleteObject((HPALETTE)this->m_palette);
00659         this->m_palette     = NULL;
00660     }
00661     
00662     phTHIS_UNLOCK(locked);
00663 
00664     return phSUCCESS;
00665 error:
00666     phTHIS_ERROR_UNLOCK(locked);
00667 
00668     return phFAIL;
00669 }
00670 /* ---------------------------------------------------------------------- */
00671 int phGDIImageWindow::init_window()
00672 {
00673     phFUNCTION("phGDIImageWindow::init_window")
00674     int             locked      = 0;
00675     ATOM            arc         = 0;
00676     BOOL            brc         = TRUE;
00677     HHOOK           hook;
00678     phGDI_pair_t    pair;
00679     RECT            rect;
00680     
00681     phTHIS_LOCK(locked);
00682 
00683     if (this->m_info != NULL) goto error;
00684     
00685     this->m_info = (struct phGDIWindowInfo_t *)phCalloc(1,sizeof(struct phGDIWindowInfo_t));
00686     phPRINT_PTR(this->m_info,"phCalloc","phCalloc failed for m_info");
00687     
00688     this->m_info->window_class_name = (wchar_t *)phCalloc(255,sizeof(wchar_t));
00689     phPRINT_PTR(this->m_info->window_class_name,"phCalloc",
00690               "phCalloc failed.");
00691 
00692     wsprintf(this->m_info->window_class_name,
00693              L"phGDIImageWindow%u%p",
00694              (unsigned int)phGetCurrentThreadId(),
00695              this);
00696 
00697     this->m_info->window_title      = NULL;
00698     this->m_info->window_title_size = 0;
00699     
00700     /* Create Window */
00701     this->m_info->module            = ::GetModuleHandle(NULL);
00702     this->m_info->instance          = (HINSTANCE)this->m_info->module;
00703     this->m_info->command_line      = ::GetCommandLine();
00704     ::GetStartupInfo(&(this->m_info->startup_info));
00705 
00706     /* Register the main window class. */
00707     this->m_info->window_class.style           = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; 
00708     this->m_info->window_class.lpfnWndProc     = (WNDPROC)phGDIImageWindow_WndProc; 
00709     this->m_info->window_class.cbClsExtra      = 0; 
00710     this->m_info->window_class.cbWndExtra      = sizeof(phGDIImageWindow *); 
00711     this->m_info->window_class.hInstance       = this->m_info->instance; 
00712     this->m_info->window_class.hIcon           = ::LoadIcon  (NULL, IDI_APPLICATION); 
00713     this->m_info->window_class.hCursor         = ::LoadCursor(NULL, IDC_ARROW); 
00714     this->m_info->window_class.hbrBackground   = (HBRUSH)(COLOR_WINDOW+1);//(COLOR_BACKGROUND);
00715     this->m_info->window_class.lpszMenuName    = NULL;
00716     this->m_info->window_class.lpszClassName   = (LPCWSTR)this->m_info->window_class_name;
00717  
00718     this->m_info->window_atom = arc = ::RegisterClass(&(this->m_info->window_class));
00719     if (arc == 0) rc = phFAIL; else rc = phSUCCESS;
00720     phPRINT_RC(rc,"RegisterClass","RegisterClass failed.");
00721 
00722     /* Setup the hooks */
00723     hook = ::SetWindowsHookEx(WH_CBT, phGDIImageWindow_CBTProc, 0, ::GetCurrentThreadId());
00724     pair.thisptr    = this;
00725     pair.hook       = hook;
00726     
00727     SetLastError(ERROR_SUCCESS);
00728     /*
00729     phPROGRESS("module:%p instance:%p name:%s atom:%p\n",
00730         this->m_info->module,
00731         this->m_info->instance,
00732         this->m_info->window_class_name,
00733         this->m_info->window_atom );
00734      */
00735 
00736     this->setTitle(this->m_title);
00737     this->m_info->window = ::CreateWindowEx(0,
00738                                     (LPCWSTR)this->m_info->window_class_name,
00739                                     (LPCWSTR)this->m_info->window_title,
00740                                     WS_BORDER | 
00741                                     WS_THICKFRAME | 
00742                                     WS_CAPTION | 
00743                                     WS_MINIMIZEBOX | 
00744                                     WS_MAXIMIZEBOX | 
00745                                     WS_SYSMENU,
00746                                     this->m_x,
00747                                     this->m_y,
00748                                     this->m_w,
00749                                     this->m_h,
00750                                     NULL,
00751                                     NULL,
00752                                     this->m_info->instance,
00753                                     &pair);
00754     phPRINT_PTR(this->m_info->window,"CreateWindow","CreateWindow failed.");
00755 
00756     /* Disable the hooks */
00757     UnhookWindowsHookEx(hook);
00758 
00759     DEBUG_PRINT("CreateWindowEx\n");
00760     //print_window_info(this->m_info->window);
00761     DEBUG_PRINT("\n");
00762             
00763     /* Make sure the client area is sized correctly */
00764     ::GetClientRect( this->m_info->window, &rect );
00765 
00766     ::MoveWindow(this->m_info->window,
00767                  this->m_x, this->m_y,
00768                  this->m_w + (this->m_w - (rect.right  -rect.left)),
00769                  this->m_h + (this->m_h - (rect.bottom - rect.top)),
00770                  FALSE);
00771 
00772     this->m_minimized = 1;
00773     this->m_show_first = 1;
00774     
00775 error:
00776     phTHIS_UNLOCK(locked);
00777     
00778     return phSUCCESS;
00779 }
00780 
00781 /* ---------------------------------------------------------------------- */
00782 int phGDIImageWindow::destroy_window()
00783 {
00784     phFUNCTION("phGDIImageWindow::destroy_window")
00785     BOOL brc = TRUE;
00786     int locked = 0;
00787     
00788     phTHIS_LOCK(locked);
00789     
00790     if (this->m_info != NULL)
00791     {    
00792         brc = ::DestroyWindow(this->m_info->window);
00793         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
00794         phPRINT_RC(rc,"DestroyWindow","DestroyWindow failed.");
00795     
00796         brc = ::UnregisterClass((LPCWSTR)this->m_info->window_class_name,
00797                               this->m_info->instance);
00798         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
00799         phPRINT_RC(rc,"UnregisterClass","UnregisterClass failed");
00800 
00801         phFree(this->m_info->window_class_name);
00802         phFree(this->m_info->window_title);
00803         this->m_info->window_title_size = 0;
00804         phFree(this->m_info);
00805     }
00806     
00807     phTHIS_UNLOCK(locked);
00808     
00809     return phSUCCESS;
00810 error:
00811     phTHIS_ERROR_UNLOCK(locked);
00812 
00813     return phFAIL;
00814 }
00815 
00816 /* ---------------------------------------------------------------------- */
00817 int phGDIImageWindow::alloc_bitmap( )
00818 {
00819     phFUNCTION("phGDIImageWindow::create_bitmap")
00820     int locked = 0;
00821 
00822     phTHIS_LOCK(locked);
00823 
00824     if ((this->m_info != NULL) && 
00825         (this->m_info->window != NULL))
00826     {
00827         HDC hDC = GetDC(this->m_info->window);
00828         if (hDC != NULL)
00829         {
00830             BITMAPINFOHEADER *bih = &(this->m_info->bitmap_info.bmiHeader);
00831         
00832             bih->biSize             =   sizeof(BITMAPINFOHEADER);
00833             bih->biWidth            =   this->m_w;
00834             bih->biHeight           =   -((int32_t)this->m_h);
00835             bih->biPlanes           =   1;
00836             bih->biBitCount         =   this->m_dib_bitdepth;
00837             bih->biCompression      =   BI_RGB;
00838             bih->biSizeImage        =
00839                     ((this->m_w * (this->m_dib_bitdepth / 8) + 3)&0xFFFFFFFC) * this->m_h;
00840             bih->biXPelsPerMeter    =   0;
00841             bih->biYPelsPerMeter    =   0;
00842             bih->biClrUsed          =   0;
00843             bih->biClrImportant     =   0;
00844         
00845             this->m_info->bitmap = ::CreateDIBSection(hDC,
00846                                   (BITMAPINFO*)&this->m_info->bitmap_info,
00847                                   DIB_RGB_COLORS,
00848                                   (void **)&this->m_info->pixels,
00849                                   NULL,
00850                                   NULL);
00851             phPRINT_PTR(this->m_info->bitmap,"CreateDIBSection",
00852                     "CreateDIBSection failed.");
00853 
00854             this->m_info->bitmap_width  = this->m_w;
00855             this->m_info->bitmap_height = this->m_h;
00856                                   
00857             ::ReleaseDC(this->m_info->window,hDC);
00858         }
00859     }
00860     
00861     phTHIS_UNLOCK(locked);
00862 
00863     return phSUCCESS;
00864 error:
00865     phTHIS_ERROR_UNLOCK(locked);
00866     
00867     return phFAIL;
00868 }
00869 
00870 /* ---------------------------------------------------------------------- */
00871 int phGDIImageWindow::free_bitmap( )
00872 {
00873     phFUNCTION("phGDIImageWindow::free_bitmap")
00874     int locked = 0;
00875 
00876     phTHIS_LOCK(locked);
00877            
00878     if (this->m_info != NULL)
00879     {
00880         phMemset(&this->m_info->bitmap_info, 0, sizeof(BITMAPINFO));
00881         
00882         if (this->m_info->bitmap != NULL)
00883         {
00884             ::DeleteObject(this->m_info->bitmap);
00885             this->m_info->bitmap = NULL;
00886         }
00887         
00888         this->m_info->pixels = NULL;
00889         this->m_info->bitmap_width  = 0;
00890         this->m_info->bitmap_height = 0;
00891     }        
00892 
00893     phTHIS_UNLOCK(locked);
00894 
00895     return phSUCCESS;
00896 error:
00897     phTHIS_ERROR_UNLOCK(locked);
00898     
00899     return phFAIL;
00900 }
00901 /* ---------------------------------------------------------------------- */
00902 int phGDIImageWindow::verify_bitmap(int forced_realloc )
00903 {
00904     phFUNCTION("phGDIImageWindow::verify_bitmap")
00905     int locked = 0;
00906     BITMAPINFOHEADER    *bh = &(this->m_info->bitmap_info.bmiHeader);
00907     int                 retrc = phSUCCESS;
00908 
00909     phTHIS_LOCK(locked);
00910            
00911     if ((this->m_info->bitmap_width != this->m_w) ||
00912         (this->m_info->bitmap_height != this->m_h) ||
00913         (forced_realloc == 1))
00914     {
00915         rc = this->free_bitmap();
00916         phPRINT_RC(rc,NULL,"this->free_bitmap");
00917     
00918         rc = this->alloc_bitmap();
00919         phPRINT_RC(rc,NULL,"this->alloc_bitmap");
00920 
00921         retrc = phBITMAP_REALLOCED;
00922     }
00923         
00924     phTHIS_UNLOCK(locked);
00925 
00926     return retrc;
00927 error:
00928     phTHIS_ERROR_UNLOCK(locked);
00929     
00930     return phFAIL;
00931 }
00932 
00933 /* ---------------------------------------------------------------------- */
00934 int64_t phGDIImageWindow::handle_message( phGDIHandlerParameters params )
00935 {
00936     phFUNCTION("phGDIImageWindow::handle_message")
00937     int     locked  = 0;
00938     LRESULT retrc   = 0;
00939     HWND    hw      = params->window;
00940     UINT    message = params->message;
00941     WPARAM  wp      = params->wp;
00942     LPARAM  lp      = params->lp;
00943     int     message_handled = 0;
00944     int     close_window    = 0;
00945     int     redraw          = 0;
00946     int     update          = 0;
00947 
00948     phTHIS_LOCK(locked);
00949     /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/
00950             winui/winui/windowsuserinterface/windowing/windows/
00951             windowreference/windowmessages/wm_size.asp
00952      */
00953     switch (message)
00954     {
00955         case WM_SYSCOMMAND:
00956         {
00957             if ((wp & 0xfff0) == SC_MAXIMIZE)
00958                 this->m_minimized = 0;
00959             else if ((wp & 0xfff0) == SC_RESTORE)
00960                 this->m_minimized = 0;
00961             else if ((wp & 0xfff0) == SC_MINIMIZE)
00962                 this->m_minimized = 1;
00963         }
00964             break;
00965 
00966         case WM_SYSCOLORCHANGE:
00967             DEBUG_PRINT("WM_SYSCOLORCHANGE\n");
00968             break;
00969 
00970         case WM_DESTROY:
00971             DEBUG_PRINT("WM_DESTROY\n");
00972             close_window = 1;
00973             break;
00974             
00975         case WM_CLOSE:
00976         {
00977             DEBUG_PRINT("WM_CLOSE\n");
00978             close_window = 1;
00979         }
00980             break;
00981             
00982         case WM_CHAR:
00983             /* if key pressed is ESC/Q/q then close the window */
00984             if ((wp == 27) || (wp == 'q') || (wp == 'Q'))
00985             {
00986                 message_handled = close_window = 1;
00987             }
00988             break;
00989 
00990         case WM_ACTIVATE:
00991         {
00992             /* activation flag */
00993             int fActive = LOWORD(wp);
00994             /* minimized flag */
00995             BOOL fMinimized = (BOOL) HIWORD(wp);
00996             /* window handle */
00997             HWND hwndPrevious = (HWND) lp;
00998 
00999             DEBUG_PRINT("WM_ACTIVATE(%d,%d,%d)\n",fActive,fMinimized,hwndPrevious);
01000 
01001             this->m_minimized = (fMinimized ? 1 : 0);
01002         }
01003             break;
01004 
01005         case WM_PAINT:
01006         {
01007             //phPRINT("WM_PAINT\n");
01008             //phPRINT("WM_PAINT(%p,%p)\n",wp,lp);
01009             redraw = 1;
01010         }
01011             break;
01012 
01013         case WM_USER_REDRAW:
01014         {
01015             //phPRINT("WM_USER_REDRAW\n");
01016             redraw = 1;
01017         }
01018             break;
01019 
01020         case WM_USER_UPDATE:
01021         {
01022             //phPRINT("WM_USER_UPDATE\n");
01023             update = 1;
01024         }
01025             break;
01026 
01027         case WM_USER_MOVE:
01028         {
01029             int32_t xPos = (int32_t)(short) LOWORD(lp);
01030             int32_t yPos = (int32_t)(short) HIWORD(lp);
01031             
01032             DEBUG_PRINT("WM_USER_MOVE(%d,%d)\n",xPos,yPos);
01033          
01034             rc = this->gui_move(xPos,yPos);
01035             phCHECK_RC(rc,NULL,"this->gui_move");
01036             if (rc == phSUCCESS) message_handled = 1;
01037         }
01038             break;
01039 
01040         case WM_USER_RESIZE:
01041         {
01042             uint32_t width   = (uint32_t)(short) LOWORD(lp);
01043             uint32_t height  = (uint32_t)(short) HIWORD(lp);
01044             RECT rect;
01045 
01046             DEBUG_PRINT("WM_USER_RESIZE(%u,%u)\n",width,height);
01047             
01048             ::GetClientRect( this->m_info->window, &rect );
01049 
01050             //print_RECT(rect);
01051             //DEBUG_PRINT("\n");
01052 
01053             rc = this->gui_resize(width,height);
01054             phCHECK_RC(rc,NULL,"this->gui_resize");
01055             if (rc == phSUCCESS) message_handled = 1;
01056         }
01057             break;
01058 
01059         case WM_USER_SHOW:
01060         {
01061             DEBUG_PRINT("WM_USER_SHOW\n");
01062 
01063             rc = this->gui_show();
01064             phCHECK_RC(rc,NULL,"this->gui_show");
01065             if (rc == phSUCCESS) message_handled = 1;
01066         }
01067             break;
01068 
01069         case WM_USER_HIDE:
01070         {
01071             DEBUG_PRINT("WM_USER_HIDE\n");
01072 
01073             rc = this->gui_hide();
01074             phCHECK_RC(rc,NULL,"this->gui_hide");
01075             if (rc == phSUCCESS) message_handled = 1;
01076         }
01077             break;
01078 #if 0
01079         case WM_CREATE:
01080         {
01081             /* structure with creation data */
01082             LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lp;
01083         
01084             DEBUG_PRINT("WM_CREATE");
01085             print_CREATESTRUCT(*lpcs);
01086             DEBUG_PRINT("\n");
01087             if (this->m_info->window != NULL)
01088             {
01089                 print_window_info(this->m_info->window);
01090             }
01091         }
01092             break;
01093         case WM_KEYDOWN:
01094             DEBUG_PRINT("WM_KEYDOWN\n");
01095             break;
01096         case WM_KEYUP:
01097             DEBUG_PRINT("WM_KEYUP\n");
01098             break;
01099         case WM_SYSKEYDOWN:
01100             DEBUG_PRINT("WM_SYSKEYDOWN\n");
01101             break;
01102         case WM_SYSKEYUP:
01103             DEBUG_PRINT("WM_SYSKEYUP\n");
01104             break;
01105 #endif
01106         case WM_ACTIVATEAPP:
01107         {
01108             /* activation flag */
01109             BOOL fActive = (BOOL) wp;
01110             /* thread identifier */
01111             DWORD dwThreadId = (DWORD) lp;
01112             DEBUG_PRINT("WM_ACTIVATEAPP(%d,%ld)\n",fActive,dwThreadId);
01113 
01114             redraw = 1;
01115         }
01116             break;
01117         case WM_SHOWWINDOW:
01118         {
01119             DEBUG_PRINT("WM_SHOWWINDOW\n");
01120             redraw = 1;
01121         }
01122             break;
01123 #if 0
01124         case WM_CANCELMODE:
01125             DEBUG_PRINT("WM_CANCELMODE\n");
01126             break;
01127 #endif
01128         case WM_CHILDACTIVATE:
01129         {
01130             DEBUG_PRINT("WM_CHILDACTIVATE\n");
01131             redraw = 1;
01132         }
01133             break;
01134 #if 0
01135         case WM_COMPACTING:
01136         {
01137             /* compacting ratio */
01138             WPARAM wCompactRatio = wp;
01139             DEBUG_PRINT("WM_COMPACTING(0x%08x)\n",wCompactRatio);
01140         }
01141             break;
01142         case WM_ENABLE:
01143         {
01144             /* enabled/disabled flag */
01145             BOOL fEnabled = (BOOL) wp;
01146             DEBUG_PRINT("WM_ENABLE(%d)\n",fEnabled);
01147         }
01148             break;
01149         case WM_ENTERSIZEMOVE:
01150             DEBUG_PRINT("WM_ENTERSIZEMOVE\n");
01151             break;
01152         case WM_EXITSIZEMOVE:
01153             DEBUG_PRINT("WM_EXITSIZEMOVE\n");
01154             break;
01155         case WM_GETICON:
01156         {
01157             WPARAM fType = wp;
01158             DEBUG_PRINT("WM_GETICON");
01159             DEBUG_PRINT("%s\n",(fType == ICON_BIG ? " ICON_BIG" : " ICON_SMALL"));
01160         }
01161             break;
01162         case WM_GETMINMAXINFO:
01163         {
01164             LPMINMAXINFO lpmmi = (LPMINMAXINFO) lp;
01165             DEBUG_PRINT("WM_GETMINMAXINFO");
01166             print_MINMAXINFO(*lpmmi);
01167             DEBUG_PRINT("\n");
01168             if (this->m_info->window != NULL)
01169             {
01170                 print_window_info(this->m_info->window);
01171             }
01172         }
01173             break;
01174         case WM_INPUTLANGCHANGE:
01175             DEBUG_PRINT("WM_INPUTLANGCHANGE\n");
01176             break;
01177         case WM_INPUTLANGCHANGEREQUEST:
01178             DEBUG_PRINT("WM_INPUTLANGCHANGEREQUEST\n");
01179             break;
01180 #endif
01181         case WM_MOVE:
01182         {
01183             int32_t xPos = (int32_t)(short) LOWORD(lp);
01184             int32_t yPos = (int32_t)(short) HIWORD(lp);
01185             RECT rect;
01186             
01187             ::GetWindowRect( this->m_info->window, &rect );
01188             
01189             DEBUG_PRINT("WM_MOVE(%d,%d)(%d,%d)\n",
01190                       xPos,yPos,rect.left,rect.top);
01191             //this->m_x=xPos;
01192             //this->m_y=yPos;
01193             if (this->m_info->window != NULL)
01194             {
01195                 //print_window_info(this->m_info->window);
01196             }
01197             this->m_x = rect.left;
01198             this->m_y = rect.top;
01199         }    
01200             break;
01201 #if 0
01202         case WM_MOVING:
01203         {
01204             /* edge of window to be moved */
01205             WPARAM fwSide = wp;
01206             /* screen coordinates of drag rectangle */
01207             LPRECT lprc = (LPRECT) lp;
01208         
01209             DEBUG_PRINT("WM_MOVING");
01210             print_RECT(*lprc);
01211             print_SIDE(fwSide);
01212             DEBUG_PRINT("\n");
01213             if (this->m_info->window != NULL)
01214             {
01215                 print_window_info(this->m_info->window);
01216             }
01217         }
01218             break;
01219 #endif
01220         case WM_NCACTIVATE:
01221         {
01222             DEBUG_PRINT("WM_NCACTIVATE\n");
01223             redraw = 1;
01224         }
01225             break;
01226 #if 0
01227         case WM_NCCALCSIZE:
01228         {
01229             /* valid area flag */
01230             BOOL fCalcValidRects = (BOOL) wp;
01231 
01232             DEBUG_PRINT("WM_NCCALCSIZE");
01233             if (fCalcValidRects )
01234             {
01235                 /* size calculation data */
01236                 LPNCCALCSIZE_PARAMS lpncsp = (LPNCCALCSIZE_PARAMS)lp;
01237                 for (int i = 0; i < 3; i++ ) print_RECT(lpncsp->rgrc[i]);
01238                 print_WINDOWPOS(*(lpncsp->lppos));
01239             }
01240             else
01241             {
01242                 /* new window coordinates */
01243                 LPRECT lpncsp = (LPRECT) lp;
01244                 print_RECT(*lpncsp);
01245             }
01246             DEBUG_PRINT("\n");
01247             if (this->m_info->window != NULL)
01248             {
01249                 print_window_info(this->m_info->window);
01250             }
01251         }
01252             break;
01253         case WM_NCCREATE:
01254             DEBUG_PRINT("WM_NCCREATE\n");
01255             break;
01256         case WM_NCDESTROY:
01257             DEBUG_PRINT("WM_NCDESTROY\n");
01258             break;
01259         case WM_NCPAINT:
01260             //phPRINT("WM_NCPAINT\n");
01261             break;
01262         case WM_NULL:
01263             DEBUG_PRINT("WM_NULL\n");
01264             break;
01265         case WM_PARENTNOTIFY:
01266             DEBUG_PRINT("WM_PARENTNOTIFY\n");
01267             break;
01268         case WM_QUERYDRAGICON:
01269             DEBUG_PRINT("WM_QUERYDRAGICON\n");
01270             break;
01271         case WM_QUERYOPEN:
01272             DEBUG_PRINT("WM_QUERYOPEN\n");
01273             break;
01274 #endif
01275         case WM_SIZE:
01276         {
01277             /*
01278             uint32_t width   = (uint32_t)(short) LOWORD(lp);
01279             uint32_t height  = (uint32_t)(short) HIWORD(lp);
01280             */
01281             RECT rect;
01282             uint32_t width = 0;
01283             uint32_t height = 0;
01284 #if 0 
01285             ::GetWindowRect( this->m_info->window, &rect );
01286 #else
01287             ::GetClientRect( this->m_info->window, &rect );
01288 #endif
01289     
01290             width = rect.right - rect.left;
01291             height = rect.bottom - rect.top;
01292             DEBUG_PRINT("WM_SIZE(%u,%u)\n", width,height);
01293             if (this->m_info->window != NULL)
01294             {
01295                 //print_window_info(this->m_info->window);
01296             }
01297             
01298             //this->m_h = height;
01299             
01300             if (width > 0) this->m_w = width;
01301             if (height > 0) this->m_h = height;
01302         }    
01303             break;
01304 #if 0
01305         case WM_SIZING:
01306         {
01307             RECT    rect            = {0,0,0,0};
01308             POINT   p               = {0,0};
01309             POINT   p_topleft       = {0,0};
01310             POINT   p_botright      = {0,0};
01311             int32_t width           = 0;
01312             int32_t height          = 0;
01313             /* edge of window to be moved */
01314             WPARAM fwSide           = wp;
01315             /* screen coordinates of drag rectangle */
01316             LPRECT lprc             = (LPRECT) lp;
01317         
01318             DEBUG_PRINT("WM_SIZING");
01319             print_RECT(*lprc);
01320             print_SIDE(fwSide);
01321             DEBUG_PRINT("\n");
01322             if (this->m_info->window != NULL)
01323             {
01324                 print_window_info(this->m_info->window);
01325             }
01326             
01327 #if 0
01328             /* Adjust window sizing info */
01329             p.x = lprc->left;
01330             p.y = lprc->top;
01331             ScreenToClient(this->m_info->window, &p );
01332 
01333             GetClientRect( this->m_info->window, &rect );
01334             
01335             p_topleft.x = rect.left;
01336             p_topleft.y = rect.top;
01337             ClientToScreen(this->m_info->window, &p_topleft );
01338             
01339             p_botright.x= rect.right;
01340             p_botright.y= rect.bottom;
01341             ClientToScreen(this->m_info->window, &p_botright );
01342             
01343             width = lprc->right - (lprc->left-p.x);
01344             height= lprc->bottom- (lprc->top-p.y);
01345 
01346             if ((this->m_min_width > 0) &&
01347                 (this->m_min_width > width))
01348             {
01349                 if (fwSide & WMSZ_LEFT)
01350                     lprc->left = p_botright.x-this->m_min_width;
01351                 else
01352                     lprc->right = p_topleft.x+this->m_min_width;
01353             }
01354             if ((this->m_min_height > 0) &&
01355                 (this->m_min_height > height))
01356             {
01357                 if (fwSide & WMSZ_TOP)
01358                     lprc->top = p_botright.y-this->m_min_height;
01359                 else
01360                     lprc->bottom = p_topleft.y+this->m_min_height;
01361             }
01362 #endif
01363         }
01364             break;
01365         case WM_STYLECHANGED:
01366             DEBUG_PRINT("WM_STYLECHANGED\n");
01367             break;
01368         case WM_STYLECHANGING:
01369             DEBUG_PRINT("WM_STYLECHANGING\n");
01370             break;
01371         case WM_USERCHANGED:
01372             DEBUG_PRINT("WM_USERCHANGED\n");
01373             break;
01374         case WM_WINDOWPOSCHANGED:
01375         {
01376             LPWINDOWPOS lpwp = (LPWINDOWPOS)lp;
01377             DEBUG_PRINT("WM_WINDOWPOSCHANGED");
01378             print_WINDOWPOS(*lpwp);
01379             DEBUG_PRINT("\n");
01380             if (this->m_info->window != NULL)
01381             {
01382                 print_window_info(this->m_info->window);
01383             }
01384         }
01385             break;
01386         case WM_WINDOWPOSCHANGING:
01387         {
01388             LPWINDOWPOS lpwp = (LPWINDOWPOS)lp;
01389             DEBUG_PRINT("WM_WINDOWPOSCHANGING");
01390             print_WINDOWPOS(*lpwp);
01391             DEBUG_PRINT("\n");
01392             if (this->m_info->window != NULL)
01393             {
01394                 print_window_info(this->m_info->window);
01395             }
01396         }
01397             break;
01398         default:
01399             //phPRINT("msg:%u:%p:%d\n",message,message,message);
01400             break;
01401 #endif
01402     }
01403 
01404     if (close_window)
01405     {
01406         this->setRunning(0);
01407         this->wakeup();
01408         message_handled = 1;
01409     }
01410     else if (update)
01411     {
01412         rc = this->gui_update();
01413         phCHECK_RC(rc,NULL,"this->gui_update");
01414         if (rc == phSUCCESS) message_handled = 1;
01415     }
01416     else if (redraw)
01417     {
01418         rc = this->gui_redraw();
01419         phCHECK_RC(rc,NULL,"this->gui_redraw");
01420         if (rc == phSUCCESS) message_handled = 1;
01421     }
01422 
01423     if ((message_handled != 1) ||
01424         (message == WM_PAINT))
01425     {
01426         retrc = ::DefWindowProc(hw,message,wp,lp);
01427     }
01428 
01429     phTHIS_UNLOCK(locked);
01430 
01431     return retrc;
01432 error:
01433     phTHIS_ERROR_UNLOCK(locked);
01434 
01435     return phFAIL;
01436 }
01437 
01438 /* ---------------------------------------------------------------------- */
01439 int phGDIImageWindow::isOpen()
01440 {
01441     if (this == NULL)
01442     {
01443         return 0;
01444     }
01445 
01446     return this->isRunning();
01447 }
01448 
01449 /* ---------------------------------------------------------------------- */
01450 int phGDIImageWindow::setTitle(const char *title)
01451 {
01452     phFUNCTION("phGDIImageWindow::setTitle")
01453     int locked = 0;
01454     
01455     phTHIS_LOCK(locked);
01456 
01457     rc = this->phImageWindow::setTitle(title);
01458     phPRINT_RC(rc,NULL,"this->phImageWindow::setTitle(title)");
01459 
01460     if (this->m_info != NULL)
01461     {
01462         uint32_t length = strlen(this->m_title);
01463         mbstate_t state;
01464         const char *str = title;
01465 
01466         phDALLOC(this->m_info->window_title,
01467                  this->m_info->window_title_size,
01468                  (length+1),
01469                  wchar_t);
01470         
01471         mbsrtowcs(this->m_info->window_title,&str,length,&state);
01472         this->m_info->window_title[length] = L'\0';
01473     }
01474 
01475     if (this->isRunning() && 
01476         (this->m_info != NULL) &&
01477         (this->m_info->window != NULL))
01478     {
01479         BOOL brc = ::SetWindowTextW(this->m_info->window,
01480                                     this->m_info->window_title);
01481         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01482         phPRINT_RC(rc,"SetWindowText","SetWindowText");
01483     }    
01484 
01485     /* If the window is valid, then set the title in the window */
01486 
01487     phTHIS_UNLOCK(locked);
01488 
01489     return phSUCCESS;
01490 error:
01491     phTHIS_ERROR_UNLOCK(locked);
01492 
01493     return phFAIL;
01494 }
01495 
01496 /* ---------------------------------------------------------------------- */
01497 int phGDIImageWindow::private_show()
01498 {
01499     phFUNCTION("phGDIImageWindow::private_show")
01500     int locked = 1;
01501     
01502     /* If the thread is running, then we don't want to collide with it 
01503      * so we'll post an event that it can handle */
01504     if ((this->isRunning()) &&
01505         (this->m_info != NULL) && 
01506         (this->m_info->window != NULL))
01507     {
01508         LRESULT res = ::SendNotifyMessage(this->m_info->window, WM_USER_SHOW, 0,0);
01509 
01510         if (res != TRUE)
01511         {
01512             phPROGRESS("SendNotifyMessage-WM_USER_SHOW not handled\n");
01513         }
01514     }
01515     
01516     return phSUCCESS;
01517 }
01518 
01519 /* ---------------------------------------------------------------------- */
01520 int phGDIImageWindow::private_hide()
01521 {
01522     phFUNCTION("phGDIImageWindow::private_hide")
01523     int locked = 1;
01524     
01525     /* If the thread is running, then we don't want to collide with it 
01526      * so we'll post an event that it can handle */
01527     if ((this->isRunning()) &&
01528         (this->m_info != NULL) && 
01529         (this->m_info->window != NULL))
01530     {
01531         LRESULT res = SendNotifyMessage(this->m_info->window, WM_USER_HIDE, 0,0);
01532 
01533         if (res != TRUE)
01534         {
01535             phPROGRESS("SendNotifyMessage-WM_USER_HIDE not handled\n");
01536         }
01537     }
01538         
01539     return phSUCCESS;
01540 }
01541 
01542 /* ---------------------------------------------------------------------- */
01543 int phGDIImageWindow::private_redraw()
01544 {
01545     phFUNCTION("phGDIImageWindow::private_redraw")
01546     int locked = 1;
01547     BOOL brc = FALSE;
01548     
01549     /* If the thread is running, then we don't want to collide with it 
01550      * so we'll post an event that it can handle */
01551     if ((this->isRunning()) &&
01552         (this->m_info != NULL) && 
01553         (this->m_info->window != NULL))
01554     {
01555         LRESULT res = ::SendNotifyMessage(this->m_info->window,WM_USER_REDRAW,0,0);
01556 
01557         if (res != TRUE)
01558         {
01559             phPROGRESS("SendNotifyMessage-WM_USER_REDRAW not handled\n");
01560         }
01561         /*
01562         brc = UpdateWindow(this->m_info->window);
01563         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01564         phCHECK_RC(rc,"UpdateWindow","UpdateWindow failed.");
01565         */
01566     }
01567         
01568     return phSUCCESS;
01569 }
01570 
01571 /* ---------------------------------------------------------------------- */
01572 int phGDIImageWindow::private_update()
01573 {
01574     phFUNCTION("phGDIImageWindow::private_update")
01575     int locked = 1;
01576     BOOL brc = FALSE;
01577     
01578     /* If the thread is running, then we don't want to collide with it 
01579      * so we'll post an event that it can handle */
01580     if ((this->isRunning()) && 
01581         (this->m_info != NULL) && 
01582         (this->m_info->window != NULL))
01583     {
01584         LRESULT res = ::SendNotifyMessage(this->m_info->window,WM_USER_UPDATE,0,0);
01585 
01586         if (res != TRUE)
01587         {
01588             phPROGRESS("SendNotifyMessage-WM_USER_UPDATE not handled\n");
01589         }
01590         /*
01591         brc = UpdateWindow(this->m_info->window);
01592         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01593         phCHECK_RC(rc,"UpdateWindow","UpdateWindow failed.");
01594         */
01595     }
01596     
01597     return phSUCCESS;
01598 }
01599 
01600 /* ---------------------------------------------------------------------- */
01601 int phGDIImageWindow::private_resize(uint32_t width, uint32_t height)
01602 {
01603     phFUNCTION("phGDIImageWindow::private_resize")
01604     int locked = 1;
01605     
01606     if (width == 0)     width   = this->m_w;
01607     if (height == 0)    height  = this->m_h;
01608     
01609     /* If the thread is running, then we don't want to collide with it 
01610      * so we'll post an event that it can handle */
01611     if ((this->isRunning()) &&
01612         (this->m_info != NULL) && 
01613         (this->m_info->window != NULL))
01614     {
01615         LPARAM lp = MAKELPARAM(width,height);
01616         LRESULT res = ::SendNotifyMessage(this->m_info->window, WM_USER_RESIZE,
01617                                   SIZE_RESTORED, lp);
01618 
01619         if (res != TRUE)
01620         {
01621             phPROGRESS("SendNotifyMessage-WM_USER_RESIZE not handled\n");
01622         }
01623     }
01624     else
01625     {
01626         this->m_w = width;
01627         this->m_h = height;
01628     }
01629 
01630     return phSUCCESS;
01631 }
01632 
01633 /* ---------------------------------------------------------------------- */
01634 int phGDIImageWindow::private_move(int32_t x, int32_t y)
01635 {
01636     phFUNCTION("phGDIImageWindow::private_move")
01637     int locked = 1;
01638     
01639     /* If the thread is running, then we don't want to collide with it 
01640      * so we'll post an event that it can handle */
01641     if ((this->isRunning()) &&
01642         (this->m_info != NULL) && 
01643         (this->m_info->window != NULL))
01644     {
01645         LPARAM lp = MAKELPARAM(x,y);
01646         LRESULT res = ::SendNotifyMessage(this->m_info->window, WM_USER_MOVE, 
01647                                   0, lp);
01648 
01649         if (res != TRUE)
01650         {
01651             phPROGRESS("SendNotifyMessage-WM_USER_MOVE not handled\n");
01652         }
01653     }
01654     else
01655     {
01656         this->m_x = x;
01657         this->m_y = y;
01658     }
01659     
01660     return phSUCCESS;
01661 }
01662 
01663 /* ---------------------------------------------------------------------- */
01664 int phGDIImageWindow::private_minsize(uint32_t min_w, uint32_t min_h)
01665 {
01666     phFUNCTION("phGDIImageWindow::private_minsize")
01667     int locked = 0;
01668     
01669     /* If the thread is running, then we don't want to collide with it 
01670      * so we'll post an event that it can handle */
01671     if (!this->isRunning())
01672     {
01673         this->m_min_width = min_w;
01674         this->m_min_height = min_h;
01675     }
01676 
01677     return phSUCCESS;
01678 }
01679 
01680 
01681 /* ---------------------------------------------------------------------- */
01682 int phGDIImageWindow::gui_show()
01683 {
01684     phFUNCTION("phGDIImageWindow::gui_show")
01685     BOOL    brc     = TRUE;
01686     int     locked  = 0;
01687     int     retrc   = phSUCCESS;
01688     
01689     phTHIS_LOCK(locked);
01690 
01691     if (this->m_info != NULL)
01692     {
01693         if (this->m_show_first)
01694         {
01695             brc = ::ShowWindow(this->m_info->window,SW_SHOWNORMAL);
01696             //                 this->m_info->startup_info.wShowWindow);
01697             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01698             brc = ::SetWindowPos(this->m_info->window,
01699                                  HWND_TOP,
01700                                  this->m_x,
01701                                  this->m_y,
01702                                  this->m_w,
01703                                  this->m_h,
01704                                  SWP_NOCOPYBITS | 
01705                                  SWP_NOSIZE | 
01706                                  SWP_NOMOVE |
01707                                  SWP_SHOWWINDOW);
01708             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01709 
01710             ::SetActiveWindow(this->m_info->window);
01711                 
01712             brc = ::SetForegroundWindow(this->m_info->window);
01713             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01714 
01715             this->m_show_first = 0;
01716         }
01717         else
01718         {
01719             brc = ::ShowWindow(this->m_info->window,SW_SHOW);
01720             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01721         }
01722     }
01723     else
01724         retrc = 1;
01725 
01726     phTHIS_UNLOCK(locked);
01727     
01728     return retrc;
01729 
01730 error:
01731     phTHIS_ERROR_UNLOCK(locked);
01732     
01733     return phFAIL;
01734 }
01735 
01736 /* ---------------------------------------------------------------------- */
01737 int phGDIImageWindow::gui_hide()
01738 {
01739     phFUNCTION("phGDIImageWindow::gui_hide")
01740     BOOL brc = TRUE;
01741     int locked = 0;
01742     int retrc = phSUCCESS;
01743     
01744     phTHIS_LOCK(locked);
01745     
01746 /*    rc = phGDIWindow_Hide(this->m_x11window);*/
01747 /*    phPRINT_RC(rc,NULL,"phGDIWindow_Hide");*/
01748     if (this->m_info != NULL)
01749     {
01750         brc = ::ShowWindow(this->m_info->window,SW_HIDE);
01751     }
01752     else
01753         retrc = 1;
01754 
01755     phTHIS_UNLOCK(locked);
01756     
01757     return retrc;
01758 
01759 error:
01760     phTHIS_ERROR_UNLOCK(locked);
01761     
01762     return phFAIL;
01763 }
01764 
01765 /* ------------------------------------------------------------------------- */
01766 #define ph_gdi_repack_rgb_image(cast_t,odbytes)             \
01767     {                                                       \
01768         /* assume rgb always */                             \
01769         int32_t ri = 0;                                     \
01770         int32_t gi = 0;                                     \
01771         int32_t bi = 0;                                     \
01772                                                             \
01773         int32_t i = 0;                                      \
01774         const int32_t width     = this->m_w;                \
01775         const int32_t height    = this->m_h;                \
01776         const int32_t limit     = width * height;           \
01777                                                             \
01778         uint8_t       *buf = (uint8_t*)this->m_info->pixels;\
01779         const int32_t od = (odbytes == 0 ? sizeof(cast_t)  :\
01780                                            odbytes);        \
01781         cast_t        *bufptr = (cast_t *)buf;              \
01782                                                             \
01783         uint8_t       *imgptr =                             \
01784                       (uint8_t*)this->m_image.getData();    \
01785         uint32_t      f = this->m_image.getFormat();        \
01786         int32_t id = 0;                                     \
01787         const int32_t rm = this->m_red_smask;               \
01788         const int32_t rs = this->m_red_shift;               \
01789         const int32_t gm = this->m_green_smask;             \
01790         const int32_t gs = this->m_green_shift;             \
01791         const int32_t bm = this->m_blue_smask;              \
01792         const int32_t bs = this->m_blue_shift;              \
01793                                                             \
01794         const int32_t osize = od * width * height;          \
01795         const int32_t isize = id * width * height;          \
01796                                                             \
01797         const int32_t ori = (int32_t)(rs / 8);              \
01798         const int32_t ogi = (int32_t)(gs / 8);              \
01799         const int32_t obi = (int32_t)(bs / 8);              \
01800                                                             \
01801         phImageFormatIndecies(f,                            \
01802                               (uint8_t*)&ri,                \
01803                               (uint8_t*)&gi,                \
01804                               (uint8_t*)&bi,0);             \
01805         id = phImageFormatToDepth(f);                       \
01806                                                             \
01807         DEBUG_PRINT("buf:%p bufptr:%p imgptr:%p id:%d od:%d\n",   \
01808               buf,bufptr,imgptr,id,od);                     \
01809         DEBUG_PRINT("rs:%d gs:%d bs:%d\n",                  \
01810                      rs,gs,bs);                             \
01811         DEBUG_PRINT("ri:%d gi:%d bi:%d\n",                  \
01812                      ri,gi,bi);                             \
01813         DEBUG_PRINT("ori:%d ogi:%d obi:%d\n",               \
01814                      ori,ogi,obi);                          \
01815                                                             \
01816         /* the shifting lies on byte boundaries so we can   \
01817          * index into the byte array and set the values     \
01818          * that way */                                      \
01819         if (((rs % 8) == 0) &&                              \
01820             ((gs % 8) == 0) &&                              \
01821             ((bs % 8) == 0))                                \
01822         {                                                   \
01823             DEBUG_PRINT("foo:r%d=%d g%d=%d b%d=%d\n",       \
01824                          ori, ri, ogi, gi, obi, bi );       \
01825             if ((ori == ri) && (ogi == gi) && (obi == bi))  \
01826             {                                               \
01827                 DEBUG_PRINT("foo:d%d=%d s:%d=%d\n",         \
01828                          id,od,isize,osize);                \
01829                 if ((id == od) && (isize == osize))         \
01830                 {                                           \
01831                     DEBUG_PRINT("phMemcpy\n");                \
01832                     phMemcpy(buf,imgptr,isize);               \
01833                 }                                           \
01834                 else                                        \
01835                 {                                           \
01836                     DEBUG_PRINT("word copy\n");             \
01837                     for (i = 0; i < limit; i++)             \
01838                     {                                       \
01839                         phMemcpy(buf,imgptr,id);              \
01840                         imgptr += id;                       \
01841                         buf += od;                          \
01842                     }                                       \
01843                 }                                           \
01844             }                                               \
01845             else                                            \
01846             {                                               \
01847                 DEBUG_PRINT("index copy :%d\n",limit);      \
01848                 for (i = 0; i < limit; i++)                 \
01849                 {                                           \
01850                     buf[ori] = imgptr[ri];                  \
01851                     buf[ogi] = imgptr[gi];                  \
01852                     buf[obi] = imgptr[bi];                  \
01853                     imgptr += id;                           \
01854                     buf += od;                              \
01855                 }                                           \
01856             }                                               \
01857         }                                                   \
01858         else                                                \
01859         {                                                   \
01860             DEBUG_PRINT("shift copy\n");                    \
01861             for (i = 0; i < limit; i++)                     \
01862             {                                               \
01863                 /* set this to 0 otherwise we'll end up     \
01864                  * with weird results from the |=           \
01865                  * operation */                             \
01866                     *bufptr = 0;                            \
01867                     *bufptr |= (rs > 0) ?                   \
01868                         ((imgptr[ri] & rm) << rs) :         \
01869                         ((imgptr[ri] & rm) >> (rs*-1));     \
01870                     *bufptr |= (gs > 0) ?                   \
01871                         ((imgptr[gi] & gm) << gs) :         \
01872                         ((imgptr[gi] & gm) >> (gs*-1));     \
01873                     *bufptr |= (bs > 0) ?                   \
01874                         ((imgptr[bi] & bm) << bs) :         \
01875                         ((imgptr[bi] & bm) >> (bs*-1));     \
01876                                                             \
01877                     imgptr += id;                           \
01878                     bufptr++;                               \
01879             }                                               \
01880         }                                                   \
01881     }
01882 
01883 /* ---------------------------------------------------------------------- */
01884 int phGDIImageWindow::gui_redraw()
01885 {
01886     phFUNCTION("phGDIImageWindow::gui_redraw")
01887     int img_locked = 0;
01888     int locked = 0;
01889     uint32_t w = 0;
01890     uint32_t h = 0;
01891     BOOL brc = TRUE;
01892     int retrc = phSUCCESS;
01893     int force = 0;
01894     
01895     phTHIS_LOCK(locked);
01896     
01897     rc = this->m_image.writeLock();
01898     phCHECK_RC(rc,NULL,"this->m_image.writeLock()");
01899     img_locked = 1;
01900             
01901     if ((!this->m_image.isNull()) && (this->m_minimized == 0))
01902     {
01903 /*        rc = phGDIWindow_GetMinSize(this->m_x11window, &w,&h );*/
01904 /*        phCHECK_RC(rc,NULL,"phGDIWindow_GetMinSize");*/
01905     
01906         if ((this->m_min_width != w) || (this->m_min_height != h))
01907         {
01908 /*            rc = phGDIWindow_SetMinSize(this->m_x11window, w,h);*/
01909 /*            phCHECK_RC(rc,NULL,"phGDIWindow_SetMinSize");*/
01910         }
01911 
01912         /* This resizes the image so it must be after we check
01913          * the incoming image data for it's size */
01914         /* The image may come out altered */
01915         /* phGDIImage_Put(this->m_x11window, this->m_imageBuffer, &this->m_image ); */
01916 
01917 #if 0
01918         if ((this->m_info != NULL) && 0)
01919         {
01920             brc = ::UpdateWindow(this->m_info->window);
01921             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01922             phCHECK_RC(rc,"UpdateWindow","UpdateWindow failed.");
01923         }
01924 #endif
01925         if (this->set_display_info() == phDISPLAY_CHANGED)
01926         {
01927             force = 1;
01928         }
01929                 
01930         if (this->m_info != NULL)
01931         {
01932             HDC hDC     = ::GetDC(this->m_info->window);
01933             HDC memDC   = ::CreateCompatibleDC(hDC);
01934 
01935 #if 0
01936             phPRINT("image(%u x %u, %s)\n",
01937                     this->m_image.getWidth(),
01938                     this->m_image.getHeight(),
01939                     phImageFormatToString(this->m_image.getFormat()));
01940 #endif
01941             rc = this->m_image.convert(this->m_formats);
01942             phPRINT_RC(rc,NULL,"convert");
01943 
01944             //phPRINT("GDI(%u x %u)\n",this->m_image.getWidth(),this->m_image.getHeight());
01945             rc = this->m_image.resize(this->m_w,this->m_h);
01946             phPRINT_RC(rc,NULL,"resize");
01947 
01948             rc = this->verify_bitmap(force);
01949             phPRINT_RC(rc,NULL,"verify_bitmap()");
01950             
01951             ::SelectObject(memDC,this->m_info->bitmap);
01952     
01953 #if 0
01954             phMemcpy(this->m_info->pixels,
01955                      this->m_image.getData(),
01956                      this->m_image.getSize());
01957 #else
01958             if (this->m_dib_bitdepth == 8)
01959             {
01960                 ph_gdi_repack_rgb_image(uint8_t,0);
01961             }
01962             else if ((this->m_dib_bitdepth == 15) || 
01963                      (this->m_dib_bitdepth == 16))
01964             {
01965                 ph_gdi_repack_rgb_image(uint16_t,0);
01966             }
01967             else if (this->m_dib_bitdepth == 24)
01968             {
01969                 ph_gdi_repack_rgb_image(uint32_t,3);
01970             }
01971             else if (this->m_dib_bitdepth == 32)
01972             {
01973                 ph_gdi_repack_rgb_image(uint32_t,0);
01974             }
01975 #endif
01976             
01977             ::BitBlt(hDC,0,0,this->m_w,this->m_h,memDC,0,0,SRCCOPY);
01978 
01979             ::DeleteDC(memDC);
01980             ::ReleaseDC(this->m_info->window,hDC);
01981         }
01982 
01983         /* maintain frames-per-second */
01984         this->tickFrame();
01985     }
01986     else
01987         retrc = 1;
01988     
01989     rc = this->m_image.rwUnlock();
01990     img_locked = 0;
01991     phCHECK_RC(rc,NULL,"this->m_image.rwUnlock()");
01992     
01993     phTHIS_UNLOCK(locked);
01994     
01995     return retrc;
01996 error:
01997     if (img_locked)
01998     {
01999         rc = this->m_image.rwUnlock();
02000         phPRINT_RC(rc,NULL,"this->m_image.rwUnlock()");
02001         img_locked = 1;
02002     }
02003     
02004     phTHIS_ERROR_UNLOCK(locked);
02005     
02006     return phFAIL;
02007 }
02008 
02009 /* ---------------------------------------------------------------------- */
02010 int phGDIImageWindow::gui_update()
02011 {
02012     phFUNCTION("phGDIImageWindow::gui_update")
02013     int img_locked = 0;
02014     int locked = 0;
02015     int retrc = phSUCCESS;
02016     
02017     phTHIS_LOCK(locked);
02018     
02019     rc = this->m_image.writeLock();
02020     phCHECK_RC(rc,NULL,"this->m_image.writeLock()");
02021     img_locked = 1;
02022             
02023     if (!this->m_image.isNull())
02024     {
02025         rc = this->gui_redraw();
02026         phPRINT_RC(rc,NULL,"this->gui_redraw() failed.");
02027     }
02028     else
02029         retrc = 1;
02030 
02031     rc = this->m_image.rwUnlock();
02032     img_locked = 0;
02033     phCHECK_RC(rc,NULL,"this->m_image.rwUnlock()");
02034             
02035     phTHIS_UNLOCK(locked);
02036     
02037     return retrc;
02038 error:
02039     if (img_locked)
02040     {
02041         rc = this->m_image.rwUnlock();
02042         phPRINT_RC(rc,NULL,"this->m_image.rwUnlock()");
02043         img_locked = 0;
02044     }
02045         
02046     phTHIS_ERROR_UNLOCK(locked);
02047  
02048     return phFAIL;
02049 }
02050 
02051 /* ---------------------------------------------------------------------- */
02052 int phGDIImageWindow::gui_resize(uint32_t width, uint32_t height)
02053 {
02054     phFUNCTION("phGDIImageWindow::gui_resize")
02055     int         locked      = 0;
02056     int         writeLocked = 0;
02057     uint32_t    image_width = 0;
02058     uint32_t    image_height= 0;
02059     int         retrc       = phSUCCESS;
02060     
02061     phTHIS_LOCK(locked);
02062     
02063     rc = this->m_image.writeLock();
02064     phCHECK_RC(rc,NULL,"this->m_image.writeLock()");
02065     writeLocked = 1;
02066             
02067     if (!(this->m_image.isNull()))
02068     {
02069         if (height <= 0)    height = this->m_h;
02070         if (width <= 0)     width = this->m_w;
02071 
02072         if ((this->m_info != NULL) && (this->m_info->window != NULL))
02073         {
02074             RECT        rect;
02075             long        new_w = 0;
02076             long        new_h = 0;
02077             BOOL        brc;
02078             
02079             brc = ::MoveWindow(this->m_info->window,
02080                                this->m_x,this->m_y,
02081                                width,height,TRUE);
02082             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02083             phCHECK_RC(rc,"MoveWindow","MoveWindow failed.");
02084 
02085             brc = ::GetWindowRect( this->m_info->window, &rect );
02086             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02087             phCHECK_RC(rc,"GetWindowRect","GetWindowRect failed.");
02088     
02089             new_w = rect.right - rect.left;
02090             new_h = rect.bottom - rect.top;
02091         
02092             if (new_w < 0) new_w *= -1;
02093             if (new_h < 0) new_h *= -1;
02094         
02095             this->m_w = new_w;
02096             this->m_h = new_h;
02097         
02098             rc = this->verify_bitmap();
02099             phPRINT_RC(rc,NULL,"verify_bitmap()");
02100 
02101             if (rc == phBITMAP_REALLOCED)
02102             {
02103                 rc = this->gui_redraw();
02104                 phCHECK_RC(rc,NULL,"this->gui_redraw() failed.");
02105             }
02106         }
02107         else
02108             retrc = 1;
02109     }
02110     else
02111         retrc = 1;
02112 
02113     rc = this->m_image.rwUnlock();
02114     writeLocked = 0;
02115     phCHECK_RC(rc,NULL,"this->m_image.rwUnlock()");
02116             
02117     phTHIS_UNLOCK(locked);
02118     
02119     return retrc;
02120     
02121 error:
02122     if (writeLocked)
02123     {
02124         rc = this->m_image.rwUnlock();
02125         phPRINT_RC(rc,NULL,"this->m_image.rwUnlock()");
02126         writeLocked = 0;
02127     }
02128     phTHIS_ERROR_UNLOCK(locked);
02129     
02130     return phFAIL;
02131 }
02132 
02133 /* ---------------------------------------------------------------------- */
02134 int phGDIImageWindow::gui_move(int32_t x, int32_t y)
02135 {
02136     phFUNCTION("phGDIImageWindow::gui_move")
02137     int locked  = 0;
02138     int retrc   = phSUCCESS;
02139     
02140     phTHIS_LOCK(locked);
02141     
02142     if ((this->m_info != NULL) && (this->m_info->window != NULL))
02143     {
02144         BOOL        brc         = TRUE;
02145         RECT        rect;
02146         
02147         brc = ::MoveWindow(this->m_info->window,
02148                            x,y,
02149                            this->m_w,this->m_h,TRUE);
02150         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02151         phCHECK_RC(rc,"MoveWindow","MoveWindow failed.");
02152 
02153         brc = ::GetWindowRect( this->m_info->window, &rect );
02154         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02155         phCHECK_RC(rc,"GetWindowRect","GetWindowRect failed.");
02156 
02157         this->m_x = rect.left;
02158         this->m_y = rect.top;
02159     }
02160     else
02161         retrc = 1;
02162 
02163     phTHIS_UNLOCK(locked);
02164     
02165     return retrc;
02166     
02167 error:
02168     phTHIS_ERROR_UNLOCK(locked);
02169     
02170     return phFAIL;
02171 }
02172 
02173 /* ---------------------------------------------------------------------- */
02174 int phGDIImageWindow::gui_minsize(uint32_t min_w, uint32_t min_h )
02175 {
02176     phFUNCTION("phGDIImageWindow::gui_minsize")
02177     int locked = 0;
02178     uint32_t w = 0;
02179     uint32_t h = 0;
02180     
02181     phTHIS_LOCK(locked);
02182     
02183 /*   rc = phGDIWindow_GetMinSize(this->m_x11window, &w,&h );*/
02184 /*   phCHECK_RC(rc,NULL,"phGDIWindow_GetMinSize");*/
02185    
02186     if ((min_w != w) || (min_h != h))
02187     {
02188 /*       rc = phGDIWindow_SetMinSize(this->m_x11window, min_w,min_h);*/
02189 /*       phCHECK_RC(rc,NULL,"phGDIWindow_SetMinSize");*/
02190 
02191         if (this->m_image.isNull() == 0)
02192         {
02193             rc = this->gui_redraw();
02194             phCHECK_RC(rc,NULL,"this->gui_redraw() failed.");
02195         }
02196     }
02197     
02198     phTHIS_UNLOCK(locked);
02199     
02200     return phSUCCESS;
02201 error:
02202     phTHIS_ERROR_UNLOCK(locked);
02203     
02204     return phFAIL;
02205 }
02206 
02207 /* ---------------------------------------------------------------------- */
02208 int phGDIImageWindow::wakeup()
02209 {
02210     phFUNCTION("phGDIImageWindow::wakeup()")
02211     
02212     if ((this->m_info != NULL) && (this->m_info->window != NULL))
02213     {
02214         BOOL brc = TRUE;
02215         brc = ::PostMessage(this->m_info->window,
02216                             WM_QUIT,
02217                             NULL, NULL);
02218         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02219         phPRINT_RC(rc,NULL,"PostMessage");
02220     }
02221     /*
02222     rc = this->phImageWindow::wakeup();
02223     phPRINT_RC(rc,NULL,"this->phImageWindow::wakeup()");
02224     */  
02225     return phSUCCESS;
02226 }       
02227 
02228 /* ---------------------------------------------------------------------- */
02229 int phGDIImageWindow::cleanup()
02230 {
02231     phFUNCTION("phGDIImageWindow::cleanup()")
02232     int i = 0;
02233 
02234     /* TODO: Flush all the pending events */
02235 
02236     return phSUCCESS;
02237 }
02238 
02239 /* ---------------------------------------------------------------------- */
02240 int phGDIImageWindow::run()
02241 {
02242     phFUNCTION("phGDIImageWindow::run")
02243     int i = 0;
02244     MSG         msg;
02245     BOOL        brc = TRUE;
02246     LRESULT     lrc = 0;
02247    
02248     rc = this->init_window();
02249     phCHECK_RC(rc,NULL,"this->init_window");
02250     
02251     rc = this->alloc_bitmap();
02252     phPRINT_RC(rc,NULL,"this->alloc_bitmap");
02253                 
02254     /* .) Set the variables for remote viewing */
02255     rc = this->gui_show();
02256     phCHECK_RC(rc,NULL,"this->gui_show()");
02257 
02258 /*   rc = phGDIWindow_Move(this->m_x11window,this->m_x,this->m_y);*/
02259 /*   phPRINT_RC(rc,NULL,"phGDIWindow_Move");*/
02260     
02261     rc = this->signal_running();
02262     phCHECK_RC(rc,NULL,"this->signal_running()");
02263    
02264     /* Get the next event */
02265     while (this->isRunning())
02266     {
02267         phYield();
02268         brc = ::GetMessage(&msg,this->m_info->window,0,0);
02269 
02270         if (brc == -1)
02271         {
02272             if (::GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
02273             {
02274                 this->setRunning(0);
02275                 continue;
02276             }
02277             else
02278             {
02279                 phPRINT_RC(phFAIL,"GetMessage","GetMessage failed.");
02280             }
02281         }
02282         else
02283         {
02284             brc = ::TranslateMessage(&msg);
02285             lrc = ::DispatchMessage(&msg);
02286         }
02287     }
02288 
02289     rc = this->getImage()->wakeup_self();
02290     phPRINT_RC(rc,NULL,"this->getImage()->wakeup_self()");
02291     
02292     rc = this->gui_hide();
02293     phCHECK_RC(rc,NULL,"this->gui_hide()");
02294     
02295     rc = this->free_bitmap();
02296     phPRINT_RC(rc,NULL,"this->free_bitmap");
02297                 
02298     rc = this->destroy_window();
02299     phCHECK_RC(rc,NULL,"this->init_window");
02300     
02301     DEBUG_PRINT("Thread returning cleanly\n");
02302     
02303     return phSUCCESS;
02304 error:
02305     phPROGRESS("Thread returning with error\n");
02306 
02307     rc = this->gui_hide();
02308     phPRINT_RC(rc,NULL,"this->gui_hide()");
02309     
02310     rc = this->free_bitmap();
02311     phPRINT_RC(rc,NULL,"this->free_bitmap");
02312                 
02313     rc = this->destroy_window();
02314     phPRINT_RC(rc,NULL,"this->init_window");
02315     
02316     rc = this->signal_error();
02317     phPRINT_RC(rc,NULL,"this->signal_error");
02318 
02319     return phFAIL;
02320 }
02321 
02322 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:03 2007 for phission by  doxygen 1.4.4