int m_style;
wxBitmap m_stipple ;
wxColour m_colour;
-
-/* TODO: implementation
WXHBRUSH m_hBrush;
-*/
};
#define M_BRUSHDATA ((wxBrushRefData *)m_refData)
// Useful helper: create the brush resource
bool RealizeResource();
+ WXHANDLE GetResourceHandle(void) ;
+ bool FreeResource(bool force = FALSE);
+ bool IsFree() const;
+
// When setting properties, we must make sure we're not changing
// another object
void Unshare();
--- /dev/null
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket) for WX
+ * Name: gsockos2.h
+ * Purpose: GSocket OS/2 header
+ * CVSID: $Id$
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef __GSOCK_OS2_H
+#define __GSOCK_OS2_H
+
+#ifndef __GSOCKET_STANDALONE__
+#include "wx/setup.h"
+#endif
+
+#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
+
+#ifndef __GSOCKET_STANDALONE__
+#include "wx/gsocket.h"
+#else
+#include "gsocket.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define SIGPIPE 13
+
+/* Definition of GSocket */
+struct _GSocket
+{
+ int m_fd;
+ GAddress *m_local;
+ GAddress *m_peer;
+ GSocketError m_error;
+
+ bool m_non_blocking;
+ bool m_server;
+ bool m_stream;
+ bool m_oriented;
+ bool m_establishing;
+ unsigned long m_timeout;
+
+ /* Callbacks */
+ GSocketEventFlags m_detected;
+ GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
+ char *m_data[GSOCK_MAX_EVENT];
+
+ char *m_gui_dependent;
+};
+
+/* Definition of GAddress */
+struct _GAddress
+{
+ struct sockaddr *m_addr;
+ size_t m_len;
+
+ GAddressType m_family;
+ int m_realfamily;
+
+ GSocketError m_error;
+};
+
+/* Input / Output */
+
+GSocketError _GSocket_Input_Timeout(GSocket *socket);
+GSocketError _GSocket_Output_Timeout(GSocket *socket);
+int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size);
+int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size);
+int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size);
+int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size);
+
+/* Callbacks */
+
+void _GSocket_Enable(GSocket *socket, GSocketEvent event);
+void _GSocket_Disable(GSocket *socket, GSocketEvent event);
+void _GSocket_Detected_Read(GSocket *socket);
+void _GSocket_Detected_Write(GSocket *socket);
+
+void _GSocket_GUI_Init(GSocket *socket);
+void _GSocket_GUI_Destroy(GSocket *socket);
+void _GSocket_Enable_Events(GSocket *socket);
+void _GSocket_Disable_Events(GSocket *socket);
+void _GSocket_Install_Callback(GSocket *socket, GSocketEvent event);
+void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent event);
+
+/* GAddress */
+
+GSocketError _GAddress_translate_from(GAddress *address,
+ struct sockaddr *addr, int len);
+GSocketError _GAddress_translate_to(GAddress *address,
+ struct sockaddr **addr, int *len);
+
+GSocketError _GAddress_Init_INET(GAddress *address);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
+
+#endif /* __GSOCK_UNX_H */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: helpxxxx.h
+// Purpose: Help system: native implementation for your system.
+// Author: David Webster
+// Modified by:
+// Created: 10/09/99
+// RCS-ID: $Id$
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_HELPWIN_H_
+#define _WX_HELPWIN_H_
+
+#include "wx/wx.h"
+
+#include "wx/helpbase.h"
+
+class WXDLLEXPORT wxWinHelpController: public wxHelpControllerBase
+{
+ DECLARE_CLASS(wxWinHelpController)
+
+ public:
+ wxWinHelpController();
+ ~wxWinHelpController();
+
+ // Must call this to set the filename and server name
+ virtual bool Initialize(const wxString& file);
+
+ // If file is "", reloads file given in Initialize
+ virtual bool LoadFile(const wxString& file = "");
+ virtual bool DisplayContents();
+ virtual bool DisplaySection(int sectionNo);
+ virtual bool DisplayBlock(long blockNo);
+ virtual bool KeywordSearch(const wxString& k);
+
+ virtual bool Quit();
+ virtual void OnQuit();
+
+ inline wxString GetHelpFile() const { return m_helpFile; }
+
+protected:
+ wxString m_helpFile;
+private:
+ // virtual function hiding supression :: do not use
+ bool Initialize(const wxString& file, int WXUNUSED(server) ) { return(Initialize(file)); }
+};
+
+#endif
+ // _WX_HELPWIN_H_
+++ /dev/null
-/////////////////////////////////////////////////////////////////////////////
-// Name: helpxxxx.h
-// Purpose: Help system: native implementation for your system. Replace
-// XXXX with suitable name.
-// Author: AUTHOR
-// Modified by:
-// Created: ??/??/98
-// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-#ifndef _WX_HELPXXXX_H_
-#define _WX_HELPXXXX_H_
-
-#ifdef __GNUG__
-#pragma interface "helpxxxx.h"
-#endif
-
-#include "wx/wx.h"
-
-#include "wx/helpbase.h"
-
-class WXDLLEXPORT wxXXXXHelpController: public wxHelpControllerBase
-{
- DECLARE_CLASS(wxXXXXHelpController)
-
- public:
- wxXXXXHelpController();
- ~wxXXXXHelpController();
-
- // Must call this to set the filename and server name
- virtual bool Initialize(const wxString& file);
-
- // If file is "", reloads file given in Initialize
- virtual bool LoadFile(const wxString& file = "");
- virtual bool DisplayContents();
- virtual bool DisplaySection(int sectionNo);
- virtual bool DisplayBlock(long blockNo);
- virtual bool KeywordSearch(const wxString& k);
-
- virtual bool Quit();
- virtual void OnQuit();
-
- inline wxString GetHelpFile() const { return m_helpFile; }
-
-protected:
- wxString m_helpFile;
-};
-
-#endif
- // _WX_HELPXXXX_H_
/////////////////////////////////////////////////////////////////////////////
// Name: icon.h
// Purpose: wxIcon class
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: ??/??/98
+// Created: 10/09/99
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_ICON_H_
#define _WX_ICON_H_
-#ifdef __GNUG__
-#pragma interface "icon.h"
-#endif
-
#include "wx/bitmap.h"
class WXDLLEXPORT wxIconRefData: public wxBitmapRefData
~wxIconRefData();
public:
-/* TODO: whatever your actual icon handle is
- WXHICON m_hIcon;
-*/
+ WXHICON m_hIcon;
};
#define M_ICONDATA ((wxIconRefData *)m_refData)
inline bool operator == (const wxIcon& icon) { return m_refData == icon.m_refData; }
inline bool operator != (const wxIcon& icon) { return m_refData != icon.m_refData; }
-/* TODO: implementation
void SetHICON(WXHICON ico);
inline WXHICON GetHICON() const { return (M_ICONDATA ? M_ICONDATA->m_hIcon : 0); }
-*/
-/* TODO */
virtual bool Ok() const { return (m_refData != NULL) ; }
private:
// supress virtual function hiding warning
{ return(wxBitmap::LoadFile(name, type)); };
};
-/* Example handlers. TODO: write your own handlers for relevant types.
+// Example handlers. TODO: write your own handlers for relevant types.
class WXDLLEXPORT wxICOFileHandler: public wxBitmapHandler
{
public:
inline wxICOFileHandler()
{
- m_name = "ICO icon file";
- m_extension = "ico";
- m_type = wxBITMAP_TYPE_ICO;
+ m_name = "ICO icon file";
+ m_extension = "ico";
+ m_type = wxBITMAP_TYPE_ICO;
};
virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
public:
inline wxICOResourceHandler()
{
- m_name = "ICO resource";
- m_extension = "ico";
- m_type = wxBITMAP_TYPE_ICO_RESOURCE;
+ m_name = "ICO resource";
+ m_extension = "ico";
+ m_type = wxBITMAP_TYPE_ICO_RESOURCE;
};
virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
};
-*/
-
#endif
// _WX_ICON_H_
+
// Purpose: wxImageList class. Note: if your GUI doesn't have
// an image list equivalent, you can use the generic class
// in src/generic.
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: ??/??/98
+// Created: 10/09/99
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_IMAGLIST_H_
#define _WX_IMAGLIST_H_
-#ifdef __GNUG__
-#pragma interface "imaglist.h"
-#endif
-
#include "wx/bitmap.h"
/*
// 'bitmap' and 'mask' after calling Replace.
bool Replace(int index, const wxBitmap& bitmap, const wxBitmap& mask = wxNullBitmap);
-/* Not supported by Win95
- // Replacing a bitmap, using the specified colour to create the mask bitmap
- // Note that wxImageList creates new bitmaps, so you may delete
- // 'bitmap'.
- bool Replace(int index, const wxBitmap& bitmap, const wxColour& maskColour);
-*/
-
// Replaces a bitmap and mask from an icon.
// You can delete 'icon' after calling Replace.
bool Replace(int index, const wxIcon& icon);
wxIcon *MakeIcon(int index);
*/
-/* TODO
// Implementation
////////////////////////////////////////////////////////////////////////////
protected:
WXHIMAGELIST m_hImageList;
-*/
-
};
#endif
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: include/wx/msw/iniconf.h
+// Purpose: INI-file based wxConfigBase implementation
+// Author: David Webster
+// Modified by:
+// Created: 10/09/99
+// Copyright: David Webster
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _INICONF_H
+#define _INICONF_H
+
+// ----------------------------------------------------------------------------
+// wxIniConfig is a wxConfig implementation which uses MS Windows INI files to
+// store the data. Because INI files don't really support arbitrary nesting of
+// groups, we do the following:
+// (1) in win.ini file we store all entries in the [vendor] section and
+// the value group1/group2/key is mapped to the value group1_group2_key
+// in this section, i.e. all path separators are replaced with underscore
+// (2) in appname.ini file we map group1/group2/group3/key to the entry
+// group2_group3_key in [group1]
+//
+// Of course, it might lead to indesirable results if '_' is also used in key
+// names (i.e. group/key is the same as group_key) and also GetPath() result
+// may be not what you would expect it to be.
+//
+// Another limitation: the keys and section names are never case-sensitive
+// which might differ from wxFileConfig it it was compiled with
+// wxCONFIG_CASE_SENSITIVE option.
+// ----------------------------------------------------------------------------
+
+// for this class, "local" file is the file appname.ini and the global file
+// is the [vendor] subsection of win.ini (default for "vendor" is to be the
+// same as appname). The file name (strAppName parameter) may, in fact,
+// contain the full path to the file. If it doesn't, the file is searched for
+// in the Windows directory.
+class WXDLLEXPORT wxIniConfig : public wxConfigBase
+{
+public:
+ // ctor & dtor
+ // if strAppName doesn't contain the extension and is not an absolute path,
+ // ".ini" is appended to it. if strVendor is empty, it's taken to be the
+ // same as strAppName.
+ wxIniConfig(const wxString& strAppName = wxEmptyString, const wxString& strVendor = wxEmptyString,
+ const wxString& localFilename = wxEmptyString, const wxString& globalFilename = wxEmptyString, long style = wxCONFIG_USE_LOCAL_FILE);
+ virtual ~wxIniConfig();
+
+ // implement inherited pure virtual functions
+ virtual void SetPath(const wxString& strPath);
+ virtual const wxString& GetPath() const;
+
+ virtual bool GetFirstGroup(wxString& str, long& lIndex) const;
+ virtual bool GetNextGroup (wxString& str, long& lIndex) const;
+ virtual bool GetFirstEntry(wxString& str, long& lIndex) const;
+ virtual bool GetNextEntry (wxString& str, long& lIndex) const;
+
+ virtual size_t GetNumberOfEntries(bool bRecursive = FALSE) const;
+ virtual size_t GetNumberOfGroups(bool bRecursive = FALSE) const;
+
+ virtual bool HasGroup(const wxString& strName) const;
+ virtual bool HasEntry(const wxString& strName) const;
+
+ // return TRUE if the current group is empty
+ bool IsEmpty() const;
+
+ // read/write
+ bool Read(const wxString& key, wxString *pStr) const;
+ bool Read(const wxString& key, wxString *pStr, const wxString& szDefault) const;
+ bool Read(const wxString& key, long *plResult) const;
+
+ // The following are necessary to satisfy the compiler
+ wxString Read(const wxString& key, const wxString& defVal) const
+ { return wxConfigBase::Read(key, defVal); }
+ bool Read(const wxString& key, long *pl, long defVal) const
+ { return wxConfigBase::Read(key, pl, defVal); }
+ long Read(const wxString& key, long defVal) const
+ { return wxConfigBase::Read(key, defVal); }
+ bool Read(const wxString& key, int *pi, int defVal) const
+ { return wxConfigBase::Read(key, pi, defVal); }
+ bool Read(const wxString& key, int *pi) const
+ { return wxConfigBase::Read(key, pi); }
+ bool Read(const wxString& key, double* val) const
+ { return wxConfigBase::Read(key, val); }
+ bool Read(const wxString& key, double* val, double defVal) const
+ { return wxConfigBase::Read(key, val, defVal); }
+
+ bool Write(const wxString& key, const wxString& szValue);
+ bool Write(const wxString& key, long lValue);
+
+ virtual bool Flush(bool bCurrentOnly = FALSE);
+
+ virtual bool RenameEntry(const wxString& oldName, const wxString& newName);
+ virtual bool RenameGroup(const wxString& oldName, const wxString& newName);
+
+ virtual bool DeleteEntry(const wxString& Key, bool bGroupIfEmptyAlso);
+ virtual bool DeleteGroup(const wxString& szKey);
+ virtual bool DeleteAll();
+
+private:
+ // helpers
+ wxString GetPrivateKeyName(const wxString& szKey) const;
+ wxString GetKeyName(const wxString& szKey) const;
+
+ wxString m_strLocalFilename; // name of the private INI file
+ wxString m_strGroup, // current group in appname.ini file
+ m_strPath; // the rest of the path (no trailing '_'!)
+ // Virtual function hiding
+ virtual bool Read(const wxString& key, bool* val) const
+ { return(wxConfigBase::Read(key, val));};
+ virtual bool Read(const wxString& key, bool* val, bool defVal) const
+ { return(wxConfigBase::Read(key, val, defVal));};
+ virtual bool Write(const wxString& key, double value)
+ { return(wxConfigBase::Write(key, value));};
+ virtual bool Write(const wxString& key, bool value)
+ { return(wxConfigBase::Write(key, value));};
+};
+
+#endif //_INICONF_H
/////////////////////////////////////////////////////////////////////////////
// Name: joystick.h
// Purpose: wxJoystick class
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: ??/??/98
+// Created: 10/09/99
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_JOYSTICK_H_
#define _WX_JOYSTICK_H_
-#ifdef __GNUG__
-#pragma interface "joystick.h"
-#endif
-
#include "wx/event.h"
class WXDLLEXPORT wxJoystick: public wxObject
/////////////////////////////////////////////////////////////////////////////
// Name: listbox.h
// Purpose: wxListBox class
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: ??/??/98
+// Created: 10/09/99
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_LISTBOX_H_
#define _WX_LISTBOX_H_
-#ifdef __GNUG__
-#pragma interface "listbox.h"
-#endif
-
#include "wx/control.h"
WXDLLEXPORT_DATA(extern const char*) wxListBoxNameStr;
+#if wxUSE_OWNER_DRAWN
+ class WXDLLEXPORT wxOwnerDrawn;
+
+ // define the array of list box items
+ #include <wx/dynarray.h>
+
+ WX_DEFINE_ARRAY(wxOwnerDrawn *, wxListBoxItemsArray);
+#endif
+
// forward decl for GetSelections()
class WXDLLEXPORT wxArrayInt;
~wxListBox();
+ bool OS2Command(WXUINT param, WXWORD id);
+
+#if wxUSE_OWNER_DRAWN
+ bool OS2OnMeasure(WXMEASUREITEMSTRUCT *item);
+ bool OS2OnDraw(WXDRAWITEMSTRUCT *item);
+
+ // plug-in for derived classes
+ virtual wxOwnerDrawn *CreateItem(size_t n);
+
+ // allows to get the item and use SetXXX functions to set it's appearance
+ wxOwnerDrawn *GetItem(size_t n) const { return m_aItems[n]; }
+
+ // get the index of the given item
+ int GetItemIndex(wxOwnerDrawn *item) const { return m_aItems.Index(item); }
+#endif // wxUSE_OWNER_DRAWN
+
virtual void Append(const wxString& item);
virtual void Append(const wxString& item, void *clientData);
virtual void Set(int n, const wxString* choices, char **clientData = NULL);
// For single choice list item only
virtual int GetSelection() const ;
virtual void Delete(int n);
- virtual char *GetClientData(int n) const ;
- virtual void SetClientData(int n, char *clientData);
+ virtual void *GetClientData(int n) const ;
+ virtual void SetClientData(int n, void *clientData);
virtual void SetString(int n, const wxString& s);
// For single or multiple choice list item
virtual int GetSelections(wxArrayInt& aSelections) const;
virtual bool Selected(int n) const ;
virtual wxString GetString(int n) const ;
- virtual void SetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO);
// Set the specified item at the first visible item
// or scroll to max range.
void Command(wxCommandEvent& event);
- protected:
+ // OS/2-PM-specific code to set the horizontal extent of
+ // the listbox, if necessary. If s is non-NULL, it's
+ // used to calculate the horizontal extent.
+ // Otherwise, all strings are used.
+ virtual void SetHorizontalExtent(const wxString& s = wxEmptyString);
+
+ virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
+ WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
+
+ virtual MRESULT OS2WindowProc(HWND hwnd, WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
+ virtual void SetupColours();
+
+protected:
int m_noItems;
int m_selected;
+
+ virtual wxSize DoGetBestSize();
+
+#if wxUSE_OWNER_DRAWN
+ // control items
+ wxListBoxItemsArray m_aItems;
+#endif
+private:
+ //Virtual function hiding suppression, do not use
+ wxControl *CreateItem(const wxItemResource* childResource,
+ const wxItemResource* parentResource,
+ const wxResourceTable *table = (const wxResourceTable *) NULL)
+ { return(wxWindowBase::CreateItem(childResource, parentResource, table));};
};
#endif
wxTheBrushList->AddBrush(this);
}
-void wxBrush::Unshare()
-{
- // Don't change shared data
- if (!m_refData)
- {
- m_refData = new wxBrushRefData();
- }
- else
- {
- wxBrushRefData* ref = new wxBrushRefData(*(wxBrushRefData*)m_refData);
- UnRef();
- m_refData = ref;
- }
-}
void wxBrush::SetColour(const wxColour& col)
{
return FALSE;
}
+WXHANDLE wxBrush::GetResourceHandle(void)
+{
+ return (WXHANDLE) M_BRUSHDATA->m_hBrush;
+}
+
+bool wxBrush::FreeResource(bool WXUNUSED(force))
+{
+ if (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush != 0))
+ {
+// TODO DeleteObject((HBRUSH) M_BRUSHDATA->m_hBrush);
+ M_BRUSHDATA->m_hBrush = 0;
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+bool wxBrush::IsFree() const
+{
+ return (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush == 0));
+}
+
+void wxBrush::Unshare()
+{
+ // Don't change shared data
+ if (!m_refData)
+ {
+ m_refData = new wxBrushRefData();
+ }
+ else
+ {
+ wxBrushRefData* ref = new wxBrushRefData(*(wxBrushRefData*)m_refData);
+ UnRef();
+ m_refData = ref;
+ }
+}
+
--- /dev/null
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket) for WX
+ * Name: gsocket.c
+ * Purpose: GSocket main Unix-style file
+ * CVSID: $Id$
+ * -------------------------------------------------------------------------
+ */
+
+#include "wx/setup.h"
+#include "wx/defs.h"
+
+#if wxUSE_SOCKETS
+
+#define BSD_SELECT // use Berkley Sockets select
+
+#include <assert.h>
+#include <ioctl.h>
+#include <sys\types.h>
+#include <socket.h>
+#include <utils.h>
+#include <sys\time.h>
+#include <in.h>
+#include <netdb.h>
+#include <nerrno.h>
+#include <select.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
+
+#include <signal.h>
+
+#include "wx/gsocket.h"
+#include "wx/os2/gsockos2.h"
+
+#ifndef SOCKLEN_T
+
+#ifdef __GLIBC__
+# if __GLIBC__ == 2
+# define SOCKLEN_T socklen_t
+# endif
+#else
+# define SOCKLEN_T int
+#endif
+
+#endif
+
+/* Global initialisers */
+
+bool GSocket_Init()
+{
+ return TRUE;
+}
+
+void GSocket_Cleanup()
+{
+}
+
+/* Constructors / Destructors */
+
+GSocket *GSocket_new()
+{
+ int i;
+ GSocket *socket;
+
+ socket = (GSocket *)malloc(sizeof(GSocket));
+
+ if (socket == NULL)
+ return NULL;
+
+ socket->m_fd = -1;
+ for (i=0;i<GSOCK_MAX_EVENT;i++)
+ {
+ socket->m_cbacks[i] = NULL;
+ }
+ socket->m_detected = 0;
+ socket->m_local = NULL;
+ socket->m_peer = NULL;
+ socket->m_error = GSOCK_NOERROR;
+ socket->m_server = FALSE;
+ socket->m_stream = TRUE;
+ socket->m_gui_dependent = NULL;
+ socket->m_non_blocking = FALSE;
+ socket->m_timeout = 10*60*1000;
+ /* 10 minutes * 60 sec * 1000 millisec */
+ socket->m_establishing = FALSE;
+
+ /* We initialize the GUI specific entries here */
+ _GSocket_GUI_Init(socket);
+
+ return socket;
+}
+
+void GSocket_destroy(GSocket *socket)
+{
+ assert(socket != NULL);
+
+ /* First, we check that the socket is really shutdowned */
+ if (socket->m_fd != -1)
+ GSocket_Shutdown(socket);
+
+ /* We destroy GUI specific variables */
+ _GSocket_GUI_Destroy(socket);
+
+ /* We destroy private addresses */
+ if (socket->m_local)
+ GAddress_destroy(socket->m_local);
+
+ if (socket->m_peer)
+ GAddress_destroy(socket->m_peer);
+
+ /* We destroy socket itself */
+ free(socket);
+}
+
+void GSocket_Shutdown(GSocket *socket)
+{
+ int evt;
+
+ assert(socket != NULL);
+
+ /* If socket has been created, we shutdown it */
+ if (socket->m_fd != -1)
+ {
+ shutdown(socket->m_fd, 2);
+ soclose(socket->m_fd);
+ socket->m_fd = -1;
+ }
+
+ /* We also disable GUI callbacks */
+ for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
+ socket->m_cbacks[evt] = NULL;
+
+ socket->m_detected = 0;
+ _GSocket_Disable_Events(socket);
+}
+
+/* Address handling */
+
+GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
+{
+ assert(socket != NULL);
+
+ if ((socket->m_fd != -1 && !socket->m_server)) {
+ socket->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
+ socket->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ if (socket->m_local)
+ GAddress_destroy(socket->m_local);
+
+ socket->m_local = GAddress_copy(address);
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
+{
+ assert(socket != NULL);
+
+ if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
+ socket->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ if (socket->m_peer)
+ GAddress_destroy(socket->m_peer);
+
+ socket->m_peer = GAddress_copy(address);
+
+ return GSOCK_NOERROR;
+}
+
+GAddress *GSocket_GetLocal(GSocket *socket)
+{
+ GAddress *address;
+ struct sockaddr addr;
+ SOCKLEN_T size;
+ GSocketError err;
+
+ assert(socket != NULL);
+
+ if (socket->m_local)
+ return GAddress_copy(socket->m_local);
+
+ if (socket->m_fd == -1) {
+ socket->m_error = GSOCK_INVSOCK;
+ return NULL;
+ }
+
+ size = sizeof(addr);
+
+ if (getsockname(socket->m_fd, &addr, &size) < 0) {
+ socket->m_error = GSOCK_IOERR;
+ return NULL;
+ }
+
+ address = GAddress_new();
+ if (address == NULL) {
+ socket->m_error = GSOCK_MEMERR;
+ return NULL;
+ }
+ socket->m_error = _GAddress_translate_from(address, &addr, size);
+ if (socket->m_error != GSOCK_NOERROR) {
+ GAddress_destroy(address);
+ return NULL;
+ }
+
+ return address;
+}
+
+GAddress *GSocket_GetPeer(GSocket *socket)
+{
+ assert(socket != NULL);
+
+ if (socket->m_peer)
+ return GAddress_copy(socket->m_peer);
+
+ return NULL;
+}
+
+/* Server specific parts */
+
+/* GSocket_SetServer:
+ * Sets up the socket as a server. It uses the "Local" field of GSocket.
+ * "Local" must be set by GSocket_SetLocal() before GSocket_SetServer()
+ * is called. Possible error codes are: GSOCK_INVSOCK if socket has not
+ * been initialized, GSOCK_INVADDR if the local address has not been
+ * defined and GSOCK_IOERR for other internal errors.
+ */
+GSocketError GSocket_SetServer(GSocket *sck)
+{
+ int type;
+ int arg = 1;
+
+ assert(sck != NULL);
+
+ if (sck->m_fd != -1) {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (!sck->m_local) {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ /* We always have a stream here */
+ sck->m_stream = TRUE;
+ sck->m_server = TRUE;
+
+ /* Create the socket */
+ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
+
+ if (sck->m_fd == -1) {
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(int));
+ _GSocket_Enable_Events(sck);
+
+ /* Bind the socket to the LOCAL address */
+ if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
+ soclose(sck->m_fd);
+ sck->m_fd = -1;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ /* Enable listening up to 5 connections */
+ if (listen(sck->m_fd, 5) < 0) {
+ soclose(sck->m_fd);
+ sck->m_fd = -1;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ return GSOCK_NOERROR;
+}
+
+/* GSocket_WaitConnection:
+ * Waits for an incoming client connection.
+ */
+GSocket *GSocket_WaitConnection(GSocket *socket)
+{
+ GSocket *connection;
+ int arg = 1;
+
+ assert(socket != NULL);
+
+ /* Reenable CONNECTION events */
+ _GSocket_Enable(socket, GSOCK_CONNECTION);
+
+ /* If the socket has already been created, we exit immediately */
+ if (socket->m_fd == -1 || !socket->m_server)
+ {
+ socket->m_error = GSOCK_INVSOCK;
+ return NULL;
+ }
+
+ /* Create a GSocket object for the new connection */
+ connection = GSocket_new();
+ if (!connection)
+ {
+ connection->m_error = GSOCK_MEMERR;
+ return NULL;
+ }
+
+ /* Accept the incoming connection */
+ if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
+ {
+ GSocket_destroy(connection);
+ /* socket->m_error set by _GSocket_Input_Timeout */
+ return NULL;
+ }
+
+ connection->m_fd = accept(socket->m_fd, NULL, NULL);
+
+ if (connection->m_fd == -1)
+ {
+ if (errno == EWOULDBLOCK)
+ socket->m_error = GSOCK_WOULDBLOCK;
+ else
+ socket->m_error = GSOCK_IOERR;
+
+ GSocket_destroy(connection);
+ return NULL;
+ }
+
+ /* Initialize all fields */
+ connection->m_server = FALSE;
+ connection->m_stream = TRUE;
+ connection->m_oriented = TRUE;
+
+ ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(int));
+ _GSocket_Enable_Events(connection);
+
+ return connection;
+}
+
+/* Non oriented connections */
+
+GSocketError GSocket_SetNonOriented(GSocket *sck)
+{
+ int arg = 1;
+
+ assert(sck != NULL);
+
+ if (sck->m_fd != -1) {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (!sck->m_local) {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ sck->m_stream = FALSE;
+ sck->m_server = FALSE;
+ sck->m_oriented = FALSE;
+
+ /* Create the socket */
+ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
+
+ if (sck->m_fd < 0) {
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(int));
+ _GSocket_Enable_Events(sck);
+
+ /* Bind it to the LOCAL address */
+ if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
+ soclose(sck->m_fd);
+ sck->m_fd = -1;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ return GSOCK_NOERROR;
+}
+
+/* Client specific parts */
+
+/* GSocket_Connect:
+ * Establishes a client connection to a server using the "Peer"
+ * field of GSocket. "Peer" must be set by GSocket_SetPeer() before
+ * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK,
+ * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR.
+ * If a socket is nonblocking and Connect() returns GSOCK_WOULDBLOCK,
+ * the connection request can be completed later. Use GSocket_Select()
+ * to check or wait for a GSOCK_CONNECTION event.
+ */
+GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
+{
+ int type, err, ret;
+ int arg = 1;
+
+ assert(sck != NULL);
+
+ /* Enable CONNECTION events (needed for nonblocking connections) */
+ _GSocket_Enable(sck, GSOCK_CONNECTION);
+
+ if (sck->m_fd != -1)
+ {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (!sck->m_peer)
+ {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ /* Test whether we want the socket to be a stream (e.g. TCP) */
+ sck->m_stream = (stream == GSOCK_STREAMED);
+ sck->m_oriented = TRUE;
+ sck->m_server = FALSE;
+ sck->m_establishing = FALSE;
+
+ if (sck->m_stream)
+ type = SOCK_STREAM;
+ else
+ type = SOCK_DGRAM;
+
+ /* Create the socket */
+ sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
+
+ if (sck->m_fd == -1) {
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(int));
+ _GSocket_Enable_Events(sck);
+
+ /* Connect it to the PEER address */
+ ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
+
+ if (ret == -1)
+ {
+ err = errno;
+
+ /* If connect failed with EINPROGRESS and the GSocket object
+ * is in blocking mode, we select() for the specified timeout
+ * checking for writability to see if the connection request
+ * completes.
+ */
+ if ((err == EINPROGRESS) && (!sck->m_non_blocking))
+ {
+ if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
+ {
+ soclose(sck->m_fd);
+ sck->m_fd = -1;
+ /* sck->m_error is set in _GSocket_Output_Timeout */
+ fprintf(stderr, "Blocking connect timeouts\n");
+ return GSOCK_TIMEDOUT;
+ }
+ else
+ {
+ fprintf(stderr, "Blocking connect OK\n");
+ return GSOCK_NOERROR;
+ }
+ }
+
+ /* If connect failed with EINPROGRESS and the GSocket object
+ * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
+ * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
+ * this way if the connection completes, a GSOCK_CONNECTION
+ * event will be generated, if enabled.
+ */
+ if ((err == EINPROGRESS) && (sck->m_non_blocking))
+ {
+ sck->m_error = GSOCK_WOULDBLOCK;
+ sck->m_establishing = TRUE;
+ fprintf(stderr, "Nonblocking connect in progress\n");
+
+ return GSOCK_WOULDBLOCK;
+ }
+
+ /* If connect failed with an error other than EINPROGRESS,
+ * then the call to GSocket_Connect has failed.
+ */
+ soclose(sck->m_fd);
+ sck->m_fd = -1;
+ sck->m_error = GSOCK_IOERR;
+
+ fprintf(stderr, "Connect failed (generic err)\n");
+ return GSOCK_IOERR;
+ }
+
+ fprintf(stderr, "Connect OK\n");
+ return GSOCK_NOERROR;
+}
+
+/* Generic IO */
+
+/* Like recv(), send(), ... */
+int GSocket_Read(GSocket *socket, char *buffer, int size)
+{
+ int ret;
+
+ assert(socket != NULL);
+
+ /* Reenable INPUT events */
+ _GSocket_Enable(socket, GSOCK_INPUT);
+
+ if (socket->m_fd == -1 || socket->m_server)
+ {
+ socket->m_error = GSOCK_INVSOCK;
+ return -1;
+ }
+
+ if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
+ return -1;
+
+ if (socket->m_stream)
+ ret = _GSocket_Recv_Stream(socket, buffer, size);
+ else
+ ret = _GSocket_Recv_Dgram(socket, buffer, size);
+
+ if (ret == -1)
+ {
+ if (errno == EWOULDBLOCK)
+ socket->m_error = GSOCK_WOULDBLOCK;
+ else
+ socket->m_error = GSOCK_IOERR;
+ }
+
+ return ret;
+}
+
+int GSocket_Write(GSocket *socket, const char *buffer,
+ int size)
+{
+ int ret;
+
+ assert(socket != NULL);
+
+ if (socket->m_fd == -1 || socket->m_server)
+ {
+ socket->m_error = GSOCK_INVSOCK;
+ return -1;
+ }
+
+ if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
+ return -1;
+
+ if (socket->m_stream)
+ ret = _GSocket_Send_Stream(socket, buffer, size);
+ else
+ ret = _GSocket_Send_Dgram(socket, buffer, size);
+
+ if (ret == -1)
+ {
+ if (errno == EWOULDBLOCK)
+ socket->m_error = GSOCK_WOULDBLOCK;
+ else
+ socket->m_error = GSOCK_IOERR;
+
+ /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
+ * in MSW). Once the first OUTPUT event is received, users can assume
+ * that the socket is writable until a read operation fails. Only then
+ * will further OUTPUT events be posted.
+ */
+ _GSocket_Enable(socket, GSOCK_OUTPUT);
+ }
+
+ return ret;
+}
+
+/* GSocket_Select:
+ * Polls the socket to determine its status. This function will
+ * check for the events specified in the 'flags' parameter, and
+ * it will return a mask indicating which operations can be
+ * performed. This function won't block, regardless of the
+ * mode (blocking|nonblocking) of the socket.
+ */
+GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
+{
+ assert(socket != NULL);
+
+ return (flags & socket->m_detected);
+}
+
+/* Flags */
+
+/* GSocket_SetNonBlocking:
+ * Sets the socket to non-blocking mode. This is useful if
+ * we don't want to wait.
+ */
+void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
+{
+ assert(socket != NULL);
+
+ socket->m_non_blocking = non_block;
+}
+
+/* GSocket_SetTimeout:
+ * Sets the timeout for blocking calls. Time is
+ * expressed in milliseconds.
+ */
+void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
+{
+ assert(socket != NULL);
+
+ socket->m_timeout = millisec;
+}
+
+/* GSocket_GetError:
+ * Returns the last error occured for this socket.
+ */
+GSocketError GSocket_GetError(GSocket *socket)
+{
+ assert(socket != NULL);
+
+ return socket->m_error;
+}
+
+/* Callbacks */
+
+/* Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION
+ * and LOST). The callbacks are called in the following situations:
+ *
+ * INPUT: There is at least one byte in the input buffer
+ * OUTPUT: The system is sure that the next write call will not block
+ * CONNECTION: Two cases are possible:
+ * Client socket -> the connection is established
+ * Server socket -> a client requests a connection
+ * LOST: The connection is lost
+ *
+ * An event is generated only once and its state is reseted when the
+ * relative IO call is requested.
+ * For example: INPUT -> GSocket_Read()
+ * CONNECTION -> GSocket_Accept()
+ */
+
+/* GSocket_SetCallback:
+ * Enables the callbacks specified by 'flags'. Note that 'flags'
+ * may be a combination of flags OR'ed toghether, so the same
+ * callback function can be made to accept different events.
+ * The callback function must have the following prototype:
+ *
+ * void function(GSocket *socket, GSocketEvent event, char *cdata)
+ */
+void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
+ GSocketCallback callback, char *cdata)
+{
+ int count;
+
+ assert(socket != NULL);
+
+ for (count = 0; count < GSOCK_MAX_EVENT; count++)
+ {
+ if ((flags & (1 << count)) != 0)
+ {
+ socket->m_cbacks[count] = callback;
+ socket->m_data[count] = cdata;
+ }
+ }
+}
+
+/* GSocket_UnsetCallback:
+ * Disables all callbacks specified by 'flags', which may be a
+ * combination of flags OR'ed toghether.
+ */
+void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
+{
+ int count;
+
+ assert(socket != NULL);
+
+ for (count = 0; count < GSOCK_MAX_EVENT; count++)
+ {
+ if ((flags & (1 << count)) != 0)
+ {
+ socket->m_cbacks[count] = NULL;
+ socket->m_data[count] = NULL;
+ }
+ }
+}
+
+#define CALL_CALLBACK(socket, event) { \
+ _GSocket_Disable(socket, event); \
+ if (socket->m_cbacks[event]) \
+ socket->m_cbacks[event](socket, event, socket->m_data[event]); \
+}
+
+
+void _GSocket_Enable(GSocket *socket, GSocketEvent event)
+{
+ socket->m_detected &= ~(1 << event);
+ _GSocket_Install_Callback(socket, event);
+}
+
+void _GSocket_Disable(GSocket *socket, GSocketEvent event)
+{
+ socket->m_detected |= (1 << event);
+ _GSocket_Uninstall_Callback(socket, event);
+}
+
+/* _GSocket_Input_Timeout:
+ * For blocking sockets, wait until data is available or
+ * until timeout ellapses.
+ */
+GSocketError _GSocket_Input_Timeout(GSocket *socket)
+{
+ struct timeval tv;
+ fd_set readfds;
+
+ tv.tv_sec = (socket->m_timeout / 1000);
+ tv.tv_usec = (socket->m_timeout % 1000) * 1000;
+
+ if (!socket->m_non_blocking)
+ {
+ FD_ZERO(&readfds);
+ FD_SET(socket->m_fd, &readfds);
+ if (select(socket->m_fd + 1, &readfds, NULL, NULL, &tv) == 0)
+ {
+ socket->m_error = GSOCK_TIMEDOUT;
+ return GSOCK_TIMEDOUT;
+ }
+ }
+ return GSOCK_NOERROR;
+}
+
+/* _GSocket_Output_Timeout:
+ * For blocking sockets, wait until data can be sent without
+ * blocking or until timeout ellapses.
+ */
+GSocketError _GSocket_Output_Timeout(GSocket *socket)
+{
+ struct timeval tv;
+ fd_set writefds;
+
+ tv.tv_sec = (socket->m_timeout / 1000);
+ tv.tv_usec = (socket->m_timeout % 1000) * 1000;
+
+ if (!socket->m_non_blocking)
+ {
+ FD_ZERO(&writefds);
+ FD_SET(socket->m_fd, &writefds);
+ if (select(socket->m_fd + 1, NULL, &writefds, NULL, &tv) == 0)
+ {
+ socket->m_error = GSOCK_TIMEDOUT;
+ return GSOCK_TIMEDOUT;
+ }
+ }
+ return GSOCK_NOERROR;
+}
+
+int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
+{
+ int ret;
+
+ ret = recv(socket->m_fd, buffer, size, 0);
+
+ return ret;
+}
+
+int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
+{
+ struct sockaddr from;
+ SOCKLEN_T fromlen;
+ int ret;
+ GSocketError err;
+
+ fromlen = sizeof(from);
+
+ ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
+
+ if (ret == -1)
+ return -1;
+
+ /* Translate a system address into a GSocket address */
+ if (!socket->m_peer)
+ {
+ socket->m_peer = GAddress_new();
+ if (!socket->m_peer)
+ {
+ socket->m_error = GSOCK_MEMERR;
+ return -1;
+ }
+ }
+ err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
+ if (err != GSOCK_NOERROR)
+ {
+ GAddress_destroy(socket->m_peer);
+ socket->m_peer = NULL;
+ socket->m_error = err;
+ return -1;
+ }
+
+ return ret;
+}
+
+int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
+{
+ int ret;
+ GSocketError err;
+
+ ret = send(socket->m_fd, (char*)buffer, size, 0);
+
+ return ret;
+}
+
+int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
+{
+ struct sockaddr *addr;
+ int len, ret;
+ GSocketError err;
+
+ if (!socket->m_peer) {
+ socket->m_error = GSOCK_INVADDR;
+ return -1;
+ }
+
+ err = _GAddress_translate_to(socket->m_peer, &addr, &len);
+ if (err != GSOCK_NOERROR) {
+ socket->m_error = err;
+ return -1;
+ }
+
+ ret = sendto(socket->m_fd, (char*)buffer, size, 0, addr, len);
+
+ /* Frees memory allocated from _GAddress_translate_to */
+ free(addr);
+
+ return ret;
+}
+
+void _GSocket_Detected_Read(GSocket *socket)
+{
+ char c;
+ int ret;
+
+ if (socket->m_stream)
+ {
+ ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
+
+ if (ret < 0 && socket->m_server)
+ {
+ CALL_CALLBACK(socket, GSOCK_CONNECTION);
+ return;
+ }
+
+ if (ret > 0)
+ {
+ CALL_CALLBACK(socket, GSOCK_INPUT);
+ }
+ else
+ {
+ CALL_CALLBACK(socket, GSOCK_LOST);
+ }
+ }
+}
+
+void _GSocket_Detected_Write(GSocket *socket)
+{
+ if (socket->m_establishing && !socket->m_server)
+ {
+ int error, len;
+
+ socket->m_establishing = FALSE;
+
+ len = sizeof(error);
+ getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
+
+ if (error)
+ {
+ CALL_CALLBACK(socket, GSOCK_LOST);
+ }
+ else
+ {
+ CALL_CALLBACK(socket, GSOCK_CONNECTION);
+ /* We have to fire this event by hand because CONNECTION (for clients)
+ * and OUTPUT are internally the same and we just disabled CONNECTION
+ * events with the above macro.
+ */
+ CALL_CALLBACK(socket, GSOCK_OUTPUT);
+ }
+ }
+ else
+ {
+ CALL_CALLBACK(socket, GSOCK_OUTPUT);
+ }
+}
+
+/*
+ * -------------------------------------------------------------------------
+ * GAddress
+ * -------------------------------------------------------------------------
+ */
+
+/* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
+ * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
+ * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
+ */
+#define CHECK_ADDRESS(address, family, retval) \
+{ \
+ if (address->m_family == GSOCK_NOFAMILY) \
+ if (_GAddress_Init_##family(address) != GSOCK_NOERROR) {\
+ return address->m_error; \
+ }\
+ if (address->m_family != GSOCK_##family) {\
+ address->m_error = GSOCK_INVADDR; \
+ return retval; \
+ } \
+}
+
+GAddress *GAddress_new()
+{
+ GAddress *address;
+
+ address = (GAddress *)malloc(sizeof(GAddress));
+
+ if (address == NULL)
+ return NULL;
+
+ address->m_family = GSOCK_NOFAMILY;
+ address->m_addr = NULL;
+ address->m_len = 0;
+
+ return address;
+}
+
+GAddress *GAddress_copy(GAddress *address)
+{
+ GAddress *addr2;
+
+ assert(address != NULL);
+
+ addr2 = (GAddress *)malloc(sizeof(GAddress));
+
+ if (addr2 == NULL)
+ return NULL;
+
+ memcpy(addr2, address, sizeof(GAddress));
+
+ if (address->m_addr) {
+ addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
+ if (addr2->m_addr == NULL) {
+ free(addr2);
+ return NULL;
+ }
+ memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
+ }
+
+ return addr2;
+}
+
+void GAddress_destroy(GAddress *address)
+{
+ assert(address != NULL);
+
+ free(address);
+}
+
+void GAddress_SetFamily(GAddress *address, GAddressType type)
+{
+ assert(address != NULL);
+
+ address->m_family = type;
+}
+
+GAddressType GAddress_GetFamily(GAddress *address)
+{
+ assert(address != NULL);
+
+ return address->m_family;
+}
+
+GSocketError _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
+ address->m_realfamily = addr->sa_family;
+ switch (addr->sa_family) {
+ case AF_INET:
+ address->m_family = GSOCK_INET;
+ break;
+ case AF_UNIX:
+ address->m_family = GSOCK_UNIX;
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ address->m_family = GSOCK_INET6;
+ break;
+#endif
+ default:
+ {
+ address->m_error = GSOCK_INVOP;
+ return GSOCK_INVOP;
+ }
+ }
+
+ if (address->m_addr)
+ free(address->m_addr);
+
+ address->m_len = len;
+ address->m_addr = (struct sockaddr *)malloc(len);
+ if (address->m_addr == NULL) {
+ address->m_error = GSOCK_MEMERR;
+ return GSOCK_MEMERR;
+ }
+ memcpy(address->m_addr, addr, len);
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError _GAddress_translate_to(GAddress *address,
+ struct sockaddr **addr, int *len)
+{
+ if (!address->m_addr) {
+ address->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ *len = address->m_len;
+ *addr = (struct sockaddr *)malloc(address->m_len);
+ if (*addr == NULL) {
+ address->m_error = GSOCK_MEMERR;
+ return GSOCK_MEMERR;
+ }
+
+ memcpy(*addr, address->m_addr, address->m_len);
+ return GSOCK_NOERROR;
+}
+
+/*
+ * -------------------------------------------------------------------------
+ * Internet address family
+ * -------------------------------------------------------------------------
+ */
+
+GSocketError _GAddress_Init_INET(GAddress *address)
+{
+ address->m_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
+ if (address->m_addr == NULL) {
+ address->m_error = GSOCK_MEMERR;
+ return GSOCK_MEMERR;
+ }
+
+ address->m_len = sizeof(struct sockaddr_in);
+
+ address->m_family = GSOCK_INET;
+ address->m_realfamily = PF_INET;
+ ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
+ ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
+{
+ struct hostent *he;
+ struct in_addr *addr;
+
+ assert(address != NULL);
+
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
+
+ /* If it is a numeric host name, convert it now */
+#if defined(HAVE_INET_ATON)
+ if (inet_aton(hostname, addr) == 0) {
+#elif defined(HAVE_INET_ADDR)
+ /* Fix from Guillermo Rodriguez Garcia <guille@iies.es> */
+ if ( (addr->s_addr = inet_addr(hostname)) == -1 ) {
+#endif
+ struct in_addr *array_addr;
+
+ /* It is a real name, we solve it */
+ he = gethostbyname((char*)hostname);
+ if (he == NULL) {
+ address->m_error = GSOCK_NOHOST;
+ return GSOCK_NOHOST;
+ }
+ array_addr = (struct in_addr *) *(he->h_addr_list);
+ addr->s_addr = array_addr[0].s_addr;
+#if defined(HAVE_INET_ATON)
+ }
+#elif defined(HAVE_INET_ADDR)
+ }
+#endif
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetHostAddress(GAddress *address,
+ unsigned long hostaddr)
+{
+ struct in_addr *addr;
+
+ assert(address != NULL);
+
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
+ addr->s_addr = hostaddr;
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
+ const char *protocol)
+{
+ struct servent *se;
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ if (!port) {
+ address->m_error = GSOCK_INVPORT;
+ return GSOCK_INVPORT;
+ }
+
+ se = getservbyname((char*)port, (char*)protocol);
+ if (!se) {
+ if (isdigit(port[0])) {
+ int port_int;
+
+ port_int = atoi(port);
+ addr = (struct sockaddr_in *)address->m_addr;
+ addr->sin_port = htons(port_int);
+ return GSOCK_NOERROR;
+ }
+
+ address->m_error = GSOCK_INVPORT;
+ return GSOCK_INVPORT;
+ }
+
+ addr = (struct sockaddr_in *)address->m_addr;
+ addr->sin_port = se->s_port;
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
+{
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ addr = (struct sockaddr_in *)address->m_addr;
+ addr->sin_port = htons(port);
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
+{
+ struct hostent *he;
+ char *addr_buf;
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ addr = (struct sockaddr_in *)address->m_addr;
+ addr_buf = (char *)&(addr->sin_addr);
+
+ he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
+ if (he == NULL) {
+ address->m_error = GSOCK_NOHOST;
+ return GSOCK_NOHOST;
+ }
+
+ strncpy(hostname, he->h_name, sbuf);
+
+ return GSOCK_NOERROR;
+}
+
+unsigned long GAddress_INET_GetHostAddress(GAddress *address)
+{
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, 0);
+
+ addr = (struct sockaddr_in *)address->m_addr;
+
+ return addr->sin_addr.s_addr;
+}
+
+unsigned short GAddress_INET_GetPort(GAddress *address)
+{
+ struct sockaddr_in *addr;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, 0);
+
+ addr = (struct sockaddr_in *)address->m_addr;
+ return ntohs(addr->sin_port);
+}
+
+#endif
+ /* wxUSE_SOCKETS */
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: helpwin.cpp
+// Purpose: Help system: native implementation
+// Author: David Webster
+// Modified by:
+// Created: 10/09/99
+// RCS-ID: $Id$
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#endif
+
+#include "wx/os2/helpwin.h"
+
+#if wxUSE_HELP
+#include <time.h>
+
+#include <wx/os2/private.h>
+
+#include <string.h>
+
+// MAX path length
+#define _MAXPATHLEN 500
+
+// MAX length of Help descriptor
+#define _MAX_HELP_LEN 500
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxWinHelpController, wxHelpControllerBase)
+#endif
+
+wxWinHelpController::wxWinHelpController()
+{
+ m_helpFile = "";
+}
+
+wxWinHelpController::~wxWinHelpController()
+{
+}
+
+bool wxWinHelpController::Initialize(const wxString& filename)
+{
+ m_helpFile = filename;
+ // TODO any other inits
+ return TRUE;
+}
+
+bool wxWinHelpController::LoadFile(const wxString& file)
+{
+ m_helpFile = file;
+ // TODO
+ return TRUE;
+}
+
+bool wxWinHelpController::DisplayContents()
+{
+ if (m_helpFile == wxT("")) return FALSE;
+
+ wxString str = m_helpFile;
+ size_t len = str.Length();
+ if (!(str[(size_t)(len-1)] == wxT('p') && str[(size_t)(len-2)] == wxT('l') && str[(size_t)(len-3)] == wxT('h') && str[(size_t)(len-4)] == wxT('.')))
+ str += wxT(".hlp");
+
+ if (wxTheApp->GetTopWindow())
+ {
+ // TODO : display the help
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool wxWinHelpController::DisplaySection(int section)
+{
+ // Use context number
+ if (m_helpFile == wxT("")) return FALSE;
+
+ wxString str = m_helpFile;
+ size_t len = str.Length();
+ if (!(str[(size_t)(len-1)] == wxT('p') && str[(size_t)(len-2)] == wxT('l') && str[(size_t)(len-3)] == wxT('h') && str[(size_t)(len-4)] == wxT('.')))
+ str += wxT(".hlp");
+
+ if (wxTheApp->GetTopWindow())
+ {
+ // TODO ::
+ // WinHelp((HWND) wxTheApp->GetTopWindow()->GetHWND(), (const wxChar*) str, HELP_CONTEXT, (DWORD)section);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool wxWinHelpController::DisplayBlock(long block)
+{
+ // Use context number -- a very rough equivalent to block id!
+ if (m_helpFile == wxT("")) return FALSE;
+
+ wxString str = m_helpFile;
+ size_t len = str.Length();
+ if (!(str[(size_t)(len-1)] == 'p' && str[(size_t)(len-2)] == 'l' && str[(size_t)(len-3)] == 'h' && str[(size_t)(len-4)] == '.'))
+ str += wxT(".hlp");
+
+ if (wxTheApp->GetTopWindow())
+ {
+ // TODO:
+ // WinHelp((HWND) wxTheApp->GetTopWindow()->GetHWND(), (const wxChar*) str, HELP_CONTEXT, (DWORD)block);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool wxWinHelpController::KeywordSearch(const wxString& k)
+{
+ if (m_helpFile == "") return FALSE;
+
+ wxString str = m_helpFile;
+ size_t len = str.Length();
+ if (!(str[(size_t)(len-1)] == wxT('p') && str[(size_t)(len-2)] == wxT('l') && str[(size_t)(len-3)] == wxT('h') && str[(size_t)(len-4)] == wxT('.')))
+ str += wxT(".hlp");
+
+ if (wxTheApp->GetTopWindow())
+ {
+ // TODO:
+ // WinHelp((HWND) wxTheApp->GetTopWindow()->GetHWND(), (const wxChar*) str, HELP_PARTIALKEY, (DWORD)(const wxChar*) k);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// Can't close the help window explicitly in WinHelp
+bool wxWinHelpController::Quit()
+{
+ if (wxTheApp->GetTopWindow())
+ {
+ // TODO:
+ // WinHelp((HWND) wxTheApp->GetTopWindow()->GetHWND(), 0, HELP_QUIT, 0L);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+void wxWinHelpController::OnQuit()
+{
+}
+#endif // wxUSE_HELP
+
+++ /dev/null
-/////////////////////////////////////////////////////////////////////////////
-// Name: helpxxxx.cpp
-// Purpose: Help system: native implementation
-// Author: AUTHOR
-// Modified by:
-// Created: ??/??/98
-// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-#ifdef __GNUG__
-#pragma implementation "helpxxxx.h"
-#endif
-
-#include "wx/stubs/helpxxxx.h"
-
-#include <string.h>
-
-#if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxXXXXHelpController, wxHelpControllerBase)
-#endif
-
-wxXXXXHelpController::wxXXXXHelpController()
-{
- m_helpFile = "";
-}
-
-wxXXXXHelpController::~wxXXXXHelpController()
-{
-}
-
-bool wxXXXXHelpController::Initialize(const wxString& filename)
-{
- m_helpFile = filename;
- // TODO any other inits
- return TRUE;
-}
-
-bool wxXXXXHelpController::LoadFile(const wxString& file)
-{
- m_helpFile = file;
- // TODO
- return TRUE;
-}
-
-bool wxXXXXHelpController::DisplayContents()
-{
- // TODO
- return FALSE;
-}
-
-bool wxXXXXHelpController::DisplaySection(int section)
-{
- // TODO
- return FALSE;
-}
-
-bool wxXXXXHelpController::DisplayBlock(long block)
-{
- // TODO
- return FALSE;
-}
-
-bool wxXXXXHelpController::KeywordSearch(const wxString& k)
-{
- if (m_helpFile == "") return FALSE;
-
- // TODO
- return FALSE;
-}
-
-// Can't close the help window explicitly in WinHelp
-bool wxXXXXHelpController::Quit()
-{
- // TODO
- return FALSE;
-}
-
-void wxXXXXHelpController::OnQuit()
-{
-}
-
/////////////////////////////////////////////////////////////////////////////
// Name: icon.cpp
// Purpose: wxIcon class
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: ??/??/98
+// Created: 10/09/99
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "icon.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include "wx/setup.h"
+#include "wx/list.h"
+#include "wx/utils.h"
+#include "wx/app.h"
+#include "wx/icon.h"
#endif
+#include "wx/os2/private.h"
+#include "assert.h"
+
#include "wx/icon.h"
#if !USE_SHARED_LIBRARIES
IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxBitmap)
+IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxBitmapHandler)
#endif
/*
* Icons
*/
-
wxIconRefData::wxIconRefData()
{
- // TODO: init icon handle
+ m_hIcon = (WXHICON) NULL ;
}
wxIconRefData::~wxIconRefData()
{
- // TODO: destroy icon handle
+ if ( m_hIcon )
+ return;
+ // TODO ::DestroyIcon((HICON) m_hIcon);
}
wxIcon::wxIcon()
wxBitmapHandler *handler = FindHandler(type);
if ( handler )
- return handler->LoadFile(this, filename, type, desiredWidth, desiredHeight);
+ return handler->LoadFile(this, filename, type, desiredWidth, desiredHeight);
+ else
+ return FALSE;
+}
+
+void wxIcon::SetHICON(WXHICON ico)
+{
+ if ( !M_ICONDATA )
+ m_refData = new wxIconRefData;
+
+ M_ICONDATA->m_hIcon = ico;
+}
+
+bool wxICOFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+{
+ return FALSE;
+}
+
+bool wxICOResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+{
+// TODO
+/*
+ if ( bitmap->IsKindOf(CLASSINFO(wxIcon)) )
+ {
+ if (desiredWidth > -1 && desiredHeight > -1)
+ {
+ M_ICONHANDLERDATA->m_hIcon = (WXHICON) ::LoadImage(wxGetInstance(), name, IMAGE_ICON, desiredWidth, desiredHeight, LR_DEFAULTCOLOR);
+ }
+ else
+ {
+ M_ICONHANDLERDATA->m_hIcon = (WXHICON) ::LoadIcon(wxGetInstance(), name);
+ }
+
+ ICONINFO info ;
+ if (::GetIconInfo((HICON) M_ICONHANDLERDATA->m_hIcon, &info))
+ {
+ HBITMAP ms_bitmap = info.hbmMask ;
+ if (ms_bitmap)
+ {
+ BITMAP bm;
+ ::GetObject(ms_bitmap, sizeof(BITMAP), (LPSTR) &bm);
+ M_ICONHANDLERDATA->m_width = bm.bmWidth;
+ M_ICONHANDLERDATA->m_height = bm.bmHeight;
+ }
+ if (info.hbmMask)
+ ::DeleteObject(info.hbmMask) ;
+ if (info.hbmColor)
+ ::DeleteObject(info.hbmColor) ;
+ }
+ }
+ // Override the found values with desired values
+ if (desiredWidth > -1 && desiredHeight > -1)
+ {
+ M_ICONHANDLERDATA->m_width = desiredWidth;
+ M_ICONHANDLERDATA->m_height = desiredHeight;
+ }
+
+ M_ICONHANDLERDATA->m_ok = (M_ICONHANDLERDATA->m_hIcon != 0);
+ return M_ICONHANDLERDATA->m_ok;
+ }
else
- return FALSE;
+*/
+ return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Name: imaglist.cpp
// Purpose: wxImageList. You may wish to use the generic version.
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: ??/??/98
+// Created: 10/09/99
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "imaglist.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include "wx/setup.h"
+#include "wx/window.h"
+#include "wx/icon.h"
+#include "wx/dc.h"
+#include "wx/string.h"
#endif
-#include "wx/stubs/imaglist.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+#include "wx/os2/imaglist.h"
+#include "wx/os2/private.h"
#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxImageList, wxObject)
wxImageList::wxImageList()
{
- // TODO: init image list handle, if any
+ m_hImageList = 0;
}
wxImageList::~wxImageList()
{
- // TODO: destroy image list handle, if any
+ if ( m_hImageList )
+ return;
+// TODO: ImageList_Destroy((HIMAGELIST) m_hImageList);
+ m_hImageList = 0;
}
-
// Attributes
////////////////////////////////////////////////////////////////////////////
// Returns the number of images in the image list.
int wxImageList::GetImageCount() const
{
- // TODO
- return 0;
+ // TODO:: return ImageList_GetImageCount((HIMAGELIST) m_hImageList);
+ return 0;
}
// Operations
// Creates an image list
bool wxImageList::Create(int width, int height, bool mask, int initial)
{
- // TODO
- return FALSE;
+ UINT flags = 0;
+// if ( mask )
+ // TODO flags |= ILC_MASK;
+
+ // Grow by 1, I guess this is reasonable behaviour most of the time
+ // m_hImageList = (WXHIMAGELIST) ImageList_Create(width, height, flags, initial, 1);
+ return (m_hImageList != 0);
}
// Adds a bitmap, and optionally a mask bitmap.
// 'bitmap' and 'mask'.
int wxImageList::Add(const wxBitmap& bitmap, const wxBitmap& mask)
{
- // TODO
- return 0;
+ HBITMAP hBitmap1 = (HBITMAP) bitmap.GetHBITMAP();
+ HBITMAP hBitmap2 = 0;
+ if ( mask.Ok() )
+ hBitmap2 = (HBITMAP) mask.GetHBITMAP();
+
+ int index; // = ImageList_Add((HIMAGELIST) GetHIMAGELIST(), hBitmap1, hBitmap2);
+ if ( index == -1 )
+ {
+ wxLogError(wxT("Couldn't add an image to the image list."));
+ }
+ return index;
}
// Adds a bitmap, using the specified colour to create the mask bitmap
// 'bitmap'.
int wxImageList::Add(const wxBitmap& bitmap, const wxColour& maskColour)
{
- // TODO
- return 0;
+ HBITMAP hBitmap1 = (HBITMAP) bitmap.GetHBITMAP();
+ //TODO:
+// COLORREF colorRef = PALETTERGB(maskColour.Red(), maskColour.Green(), maskColour.Blue());
+// return ImageList_AddMasked((HIMAGELIST) GetHIMAGELIST(), hBitmap1, colorRef);
+ return 0;
}
// Adds a bitmap and mask from an icon.
int wxImageList::Add(const wxIcon& icon)
{
- // TODO
- return 0;
+ HICON hIcon = (HICON) icon.GetHICON();
+// TODO: return ImageList_AddIcon((HIMAGELIST) GetHIMAGELIST(), hIcon);
+ return 0;
}
// Replaces a bitmap, optionally passing a mask bitmap.
// 'bitmap' and 'mask'.
bool wxImageList::Replace(int index, const wxBitmap& bitmap, const wxBitmap& mask)
{
- // TODO
- return 0;
+ HBITMAP hBitmap1 = (HBITMAP) bitmap.GetHBITMAP();
+ HBITMAP hBitmap2 = 0;
+ if ( mask.Ok() )
+ hBitmap2 = (HBITMAP) mask.GetHBITMAP();
+ // TODO: return (ImageList_Replace((HIMAGELIST) GetHIMAGELIST(), index, hBitmap1, hBitmap2) != 0);
+ return TRUE;
}
// Replaces a bitmap and mask from an icon.
bool wxImageList::Replace(int index, const wxIcon& icon)
{
- // TODO
- return 0;
+ HICON hIcon = (HICON) icon.GetHICON();
+ // TODO: return (ImageList_ReplaceIcon((HIMAGELIST) GetHIMAGELIST(), index, hIcon) != 0);
+ return FALSE;
}
// Removes the image at the given index.
bool wxImageList::Remove(int index)
{
- // TODO
+ // TODO return (ImageList_Remove((HIMAGELIST) GetHIMAGELIST(), index) != 0);
+
return FALSE;
}
-// Remove all images
-bool wxImageList::RemoveAll()
+bool wxImageList::RemoveAll(void)
{
- // TODO
- return FALSE;
+ // TODO: Is this correct?
+ while ( GetImageCount() > 0 )
+ {
+ Remove(0);
+ }
+ return TRUE;
}
// Draws the given image on a dc at the specified position.
bool wxImageList::Draw(int index, wxDC& dc, int x, int y,
int flags, bool solidBackground)
{
- // TODO
+ HDC hDC = (HDC) dc.GetHDC();
+ if ( !hDC )
return FALSE;
+
+ if ( solidBackground )
+ {
+ wxBrush *brush = & dc.GetBackground();
+ if ( brush && brush->Ok())
+ {
+ wxColour col(brush->GetColour());
+// ImageList_SetBkColor((HIMAGELIST) GetHIMAGELIST(),
+// PALETTERGB(col.Red(), col.Green(), col.Blue()));
+ }
+// else
+// ImageList_SetBkColor((HIMAGELIST) GetHIMAGELIST(),
+// CLR_NONE);
+ }
+// else
+// ImageList_SetBkColor((HIMAGELIST) GetHIMAGELIST(),
+// CLR_NONE);
+
+ UINT style = 0;
+/*
+ if ( flags & wxIMAGELIST_DRAW_NORMAL )
+ style |= ILD_NORMAL;
+ if ( flags & wxIMAGELIST_DRAW_TRANSPARENT )
+ style |= ILD_TRANSPARENT;
+ if ( flags & wxIMAGELIST_DRAW_SELECTED )
+ style |= ILD_SELECTED;
+ if ( flags & wxIMAGELIST_DRAW_FOCUSED )
+ style |= ILD_FOCUS;
+ return (ImageList_Draw((HIMAGELIST) GetHIMAGELIST(), index, hDC,
+ x, y, style) != 0);
+*/
+ return TRUE;
}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: src/os2/iniconf.cpp
+// Purpose: implementation of wxIniConfig class
+// Author: David Webster
+// Modified by:
+// Created: 10/09/99
+// Copyright: David Webster
+// Licence: wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+ #include <wx/string.h>
+ #include <wx/intl.h>
+ #include <wx/event.h>
+ #include <wx/app.h>
+ #include <wx/utils.h>
+#endif //WX_PRECOMP
+
+#include <wx/dynarray.h>
+#include <wx/log.h>
+#include <wx/config.h>
+
+#include <wx/os2/iniconf.h>
+
+#define INCL_PM
+#include <os2.h>
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// we replace all path separators with this character
+#define PATH_SEP_REPLACE '_'
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// ctor & dtor
+// ----------------------------------------------------------------------------
+
+wxIniConfig::wxIniConfig(const wxString& strAppName,
+ const wxString& strVendor,
+ const wxString& localFilename,
+ const wxString& globalFilename,
+ long style)
+ : wxConfigBase(!strAppName && wxTheApp ? wxTheApp->GetAppName()
+ : strAppName,
+ !strVendor ? (wxTheApp ? wxTheApp->GetVendorName()
+ : strAppName)
+ : strVendor,
+ localFilename, globalFilename, style)
+{
+ m_strLocalFilename = localFilename;
+ if (m_strLocalFilename.IsEmpty())
+ {
+ m_strLocalFilename = GetAppName() + ".ini";
+ }
+
+ // append the extension if none given and it's not an absolute file name
+ // (otherwise we assume that they know what they're doing)
+ if ( !wxIsPathSeparator(m_strLocalFilename[0u]) &&
+ m_strLocalFilename.Find('.') == wxNOT_FOUND )
+ {
+ m_strLocalFilename << ".ini";
+ }
+
+ // set root path
+ SetPath("");
+}
+
+wxIniConfig::~wxIniConfig()
+{
+}
+
+// ----------------------------------------------------------------------------
+// path management
+// ----------------------------------------------------------------------------
+
+void wxIniConfig::SetPath(const wxString& strPath)
+{
+ wxArrayString aParts;
+
+ if ( strPath.IsEmpty() ) {
+ // nothing
+ }
+ else if ( strPath[0u] == wxCONFIG_PATH_SEPARATOR ) {
+ // absolute path
+ wxSplitPath(aParts, strPath);
+ }
+ else {
+ // relative path, combine with current one
+ wxString strFullPath = GetPath();
+ strFullPath << wxCONFIG_PATH_SEPARATOR << strPath;
+ wxSplitPath(aParts, strFullPath);
+ }
+
+ size_t nPartsCount = aParts.Count();
+ m_strPath.Empty();
+ if ( nPartsCount == 0 ) {
+ // go to the root
+ m_strGroup = PATH_SEP_REPLACE;
+ }
+ else {
+ // translate
+ m_strGroup = aParts[0u];
+ for ( size_t nPart = 1; nPart < nPartsCount; nPart++ ) {
+ if ( nPart > 1 )
+ m_strPath << PATH_SEP_REPLACE;
+ m_strPath << aParts[nPart];
+ }
+ }
+
+ // other functions assume that all this is true, i.e. there are no trailing
+ // underscores at the end except if the group is the root one
+ wxASSERT( (m_strPath.IsEmpty() || m_strPath.Last() != PATH_SEP_REPLACE) &&
+ (m_strGroup == wxString(PATH_SEP_REPLACE) ||
+ m_strGroup.Last() != PATH_SEP_REPLACE) );
+}
+
+const wxString& wxIniConfig::GetPath() const
+{
+ static wxString s_str;
+
+ // always return abs path
+ s_str = wxCONFIG_PATH_SEPARATOR;
+
+ if ( m_strGroup == wxString(PATH_SEP_REPLACE) ) {
+ // we're at the root level, nothing to do
+ }
+ else {
+ s_str << m_strGroup;
+ if ( !m_strPath.IsEmpty() )
+ s_str << wxCONFIG_PATH_SEPARATOR;
+ for ( const char *p = m_strPath; *p != '\0'; p++ ) {
+ s_str << (*p == PATH_SEP_REPLACE ? wxCONFIG_PATH_SEPARATOR : *p);
+ }
+ }
+
+ return s_str;
+}
+
+wxString wxIniConfig::GetPrivateKeyName(const wxString& szKey) const
+{
+ wxString strKey;
+
+ if ( !m_strPath.IsEmpty() )
+ strKey << m_strPath << PATH_SEP_REPLACE;
+
+ strKey << szKey;
+
+ return strKey;
+}
+
+wxString wxIniConfig::GetKeyName(const wxString& szKey) const
+{
+ wxString strKey;
+
+ if ( m_strGroup != wxString(PATH_SEP_REPLACE) )
+ strKey << m_strGroup << PATH_SEP_REPLACE;
+ if ( !m_strPath.IsEmpty() )
+ strKey << m_strPath << PATH_SEP_REPLACE;
+
+ strKey << szKey;
+
+ return strKey;
+}
+
+// ----------------------------------------------------------------------------
+// enumeration
+// ----------------------------------------------------------------------------
+
+// not implemented
+bool wxIniConfig::GetFirstGroup(wxString& str, long& lIndex) const
+{
+ wxFAIL_MSG("not implemented");
+
+ return FALSE;
+}
+
+bool wxIniConfig::GetNextGroup (wxString& str, long& lIndex) const
+{
+ wxFAIL_MSG("not implemented");
+
+ return FALSE;
+}
+
+bool wxIniConfig::GetFirstEntry(wxString& str, long& lIndex) const
+{
+ wxFAIL_MSG("not implemented");
+
+ return FALSE;
+}
+
+bool wxIniConfig::GetNextEntry (wxString& str, long& lIndex) const
+{
+ wxFAIL_MSG("not implemented");
+
+ return FALSE;
+}
+
+// ----------------------------------------------------------------------------
+// misc info
+// ----------------------------------------------------------------------------
+
+// not implemented
+size_t wxIniConfig::GetNumberOfEntries(bool bRecursive) const
+{
+ wxFAIL_MSG("not implemented");
+
+ return (size_t)-1;
+}
+
+size_t wxIniConfig::GetNumberOfGroups(bool bRecursive) const
+{
+ wxFAIL_MSG("not implemented");
+
+ return (size_t)-1;
+}
+
+bool wxIniConfig::HasGroup(const wxString& strName) const
+{
+ wxFAIL_MSG("not implemented");
+
+ return FALSE;
+}
+
+bool wxIniConfig::HasEntry(const wxString& strName) const
+{
+ wxFAIL_MSG("not implemented");
+
+ return FALSE;
+}
+
+// is current group empty?
+bool wxIniConfig::IsEmpty() const
+{
+ char szBuf[1024];
+
+// GetPrivateProfileString(m_strGroup, NULL, "",
+// szBuf, WXSIZEOF(szBuf), m_strLocalFilename);
+ if ( !::IsEmpty(szBuf) )
+ return FALSE;
+
+// GetProfileString(m_strGroup, NULL, "", szBuf, WXSIZEOF(szBuf));
+// if ( !::IsEmpty(szBuf) )
+ return FALSE;
+
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// read/write
+// ----------------------------------------------------------------------------
+
+bool wxIniConfig::Read(const wxString& szKey, wxString *pstr) const
+{
+ wxConfigPathChanger path(this, szKey);
+ wxString strKey = GetPrivateKeyName(path.Name());
+
+ char szBuf[1024]; // @@ should dynamically allocate memory...
+
+ // first look in the private INI file
+
+ // NB: the lpDefault param to GetPrivateProfileString can't be NULL
+// GetPrivateProfileString(m_strGroup, strKey, "",
+// szBuf, WXSIZEOF(szBuf), m_strLocalFilename);
+ if ( ::IsEmpty(szBuf) ) {
+ // now look in win.ini
+ wxString strKey = GetKeyName(path.Name());
+// GetProfileString(m_strGroup, strKey, "", szBuf, WXSIZEOF(szBuf));
+ }
+
+ if ( ::IsEmpty(szBuf) ) {
+ return FALSE;
+ }
+ else {
+ *pstr = szBuf ;
+ return TRUE;
+ }
+}
+
+bool wxIniConfig::Read(const wxString& szKey, wxString *pstr,
+ const wxString& szDefault) const
+{
+ wxConfigPathChanger path(this, szKey);
+ wxString strKey = GetPrivateKeyName(path.Name());
+
+ char szBuf[1024]; // @@ should dynamically allocate memory...
+
+ // first look in the private INI file
+
+ // NB: the lpDefault param to GetPrivateProfileString can't be NULL
+// GetPrivateProfileString(m_strGroup, strKey, "",
+// szBuf, WXSIZEOF(szBuf), m_strLocalFilename);
+ if ( ::IsEmpty(szBuf) ) {
+ // now look in win.ini
+ wxString strKey = GetKeyName(path.Name());
+// GetProfileString(m_strGroup, strKey, "", szBuf, WXSIZEOF(szBuf));
+ }
+
+ if ( ::IsEmpty(szBuf) ) {
+ *pstr = szDefault;
+ return FALSE;
+ }
+ else {
+ *pstr = szBuf ;
+ return TRUE;
+ }
+}
+
+bool wxIniConfig::Read(const wxString& szKey, long *pl) const
+{
+ wxConfigPathChanger path(this, szKey);
+ wxString strKey = GetPrivateKeyName(path.Name());
+
+ // hack: we have no mean to know if it really found the default value or
+ // didn't find anything, so we call it twice
+
+ static const int nMagic = 17; // 17 is some "rare" number
+ static const int nMagic2 = 28; // arbitrary number != nMagic
+ long lVal; // = GetPrivateProfileInt(m_strGroup, strKey, nMagic, m_strLocalFilename);
+ if ( lVal != nMagic ) {
+ // the value was read from the file
+ *pl = lVal;
+ return TRUE;
+ }
+
+ // is it really nMagic?
+// lVal = GetPrivateProfileInt(m_strGroup, strKey, nMagic2, m_strLocalFilename);
+ if ( lVal == nMagic2 ) {
+ // the nMagic it returned was indeed read from the file
+ *pl = lVal;
+ return TRUE;
+ }
+
+ // no, it was just returning the default value, so now look in win.ini
+// *pl = GetProfileInt(GetVendorName(), GetKeyName(szKey), *pl);
+
+ return TRUE;
+}
+
+bool wxIniConfig::Write(const wxString& szKey, const wxString& szValue)
+{
+ wxConfigPathChanger path(this, szKey);
+ wxString strKey = GetPrivateKeyName(path.Name());
+
+ bool bOk; // = WritePrivateProfileString(m_strGroup, strKey,
+// szValue, m_strLocalFilename) != 0;
+
+ if ( !bOk )
+ wxLogLastError("WritePrivateProfileString");
+
+ return bOk;
+}
+
+bool wxIniConfig::Write(const wxString& szKey, long lValue)
+{
+ // ltoa() is not ANSI :-(
+ char szBuf[40]; // should be good for sizeof(long) <= 16 (128 bits)
+ sprintf(szBuf, "%ld", lValue);
+
+ return Write(szKey, szBuf);
+}
+
+bool wxIniConfig::Flush(bool /* bCurrentOnly */)
+{
+ // this is just the way it works
+// return WritePrivateProfileString(NULL, NULL, NULL, m_strLocalFilename) != 0;
+ return FALSE;
+}
+
+// ----------------------------------------------------------------------------
+// delete
+// ----------------------------------------------------------------------------
+
+bool wxIniConfig::DeleteEntry(const wxString& szKey, bool bGroupIfEmptyAlso)
+{
+ // passing NULL as value to WritePrivateProfileString deletes the key
+// if ( !Write(szKey, (const char *)NULL) )
+// return FALSE;
+ wxConfigPathChanger path(this, szKey);
+ wxString strKey = GetPrivateKeyName(path.Name());
+
+// if (WritePrivateProfileString(m_strGroup, szKey,
+// (const char*) NULL, m_strLocalFilename) == 0)
+// return FALSE;
+
+ if ( !bGroupIfEmptyAlso || !IsEmpty() )
+ return TRUE;
+
+ // delete the current group too
+ bool bOk; // = WritePrivateProfileString(m_strGroup, NULL,
+// NULL, m_strLocalFilename) != 0;
+
+ if ( !bOk )
+ wxLogLastError("WritePrivateProfileString");
+
+ return bOk;
+}
+
+bool wxIniConfig::DeleteGroup(const wxString& szKey)
+{
+ wxConfigPathChanger path(this, szKey);
+
+ // passing NULL as section name to WritePrivateProfileString deletes the
+ // whole section according to the docs
+ bool bOk; // = WritePrivateProfileString(path.Name(), NULL,
+ // NULL, m_strLocalFilename) != 0;
+
+ if ( !bOk )
+ wxLogLastError("WritePrivateProfileString");
+
+ return bOk;
+}
+
+#ifndef MAX_PATH
+#define MAX_PATH 256
+#endif
+
+bool wxIniConfig::DeleteAll()
+{
+ // first delete our group in win.ini
+// WriteProfileString(GetVendorName(), NULL, NULL);
+
+ // then delete our own ini file
+ char szBuf[MAX_PATH];
+ size_t nRc; // = GetWindowsDirectory(szBuf, WXSIZEOF(szBuf));
+ if ( nRc == 0 )
+ {
+ wxLogLastError("GetWindowsDirectory");
+ }
+ else if ( nRc > WXSIZEOF(szBuf) )
+ {
+ wxFAIL_MSG("buffer is too small for Windows directory.");
+ }
+
+ wxString strFile = szBuf;
+ strFile << '\\' << m_strLocalFilename;
+
+ if ( !wxRemoveFile(strFile) ) {
+ wxLogSysError(_("Can't delete the INI file '%s'"), strFile.c_str());
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+bool wxIniConfig::RenameEntry(const wxString& oldName, const wxString& newName)
+{
+ // Not implemented
+ return FALSE;
+}
+
+bool wxIniConfig::RenameGroup(const wxString& oldName, const wxString& newName)
+{
+ // Not implemented
+ return FALSE;
+}
/////////////////////////////////////////////////////////////////////////////
// Name: joystick.cpp
// Purpose: wxJoystick class
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: ??/??/98
+// Created: 10/09/99
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "joystick.h"
-#endif
+#include "wx/string.h"
+#define INCL_PM
+#include "os2.h"
+#include "wx/os2/private.h"
+#define NO_JOYGETPOSEX
+
+#include <wx/window.h>
#include <wx/joystick.h>
IMPLEMENT_DYNAMIC_CLASS(wxJoystick, wxObject)
///////////////////////////////////////////////////////////////////////////////
// Name: listbox.cpp
// Purpose: wxListBox
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: ??/??/98
+// Created: 10/09/99
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
+// Copyright: (c) David Webster
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "listbox.h"
-#endif
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#include "wx/window.h"
+#include "wx/os2/private.h"
+#ifndef WX_PRECOMP
#include "wx/listbox.h"
#include "wx/settings.h"
+#include "wx/brush.h"
+#include "wx/font.h"
+#include "wx/dc.h"
+#include "wx/utils.h"
+#endif
+
+#define INCL_M
+#include <os2.h>
+
#include "wx/dynarray.h"
#include "wx/log.h"
+#if wxUSE_OWNER_DRAWN
+ #include "wx/ownerdrw.h"
+#endif
+
#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
#endif
+// ============================================================================
+// list box item declaration and implementation
+// ============================================================================
+
+#if wxUSE_OWNER_DRAWN
+
+class wxListBoxItem : public wxOwnerDrawn
+{
+public:
+ wxListBoxItem(const wxString& str = "");
+};
+
+wxListBoxItem::wxListBoxItem(const wxString& str) : wxOwnerDrawn(str, FALSE)
+{
+ // no bitmaps/checkmarks
+ SetMarginWidth(0);
+}
+
+wxOwnerDrawn *wxListBox::CreateItem(size_t n)
+{
+ return new wxListBoxItem();
+}
+
+#endif //USE_OWNER_DRAWN
+
// ============================================================================
// list box control implementation
// ============================================================================
+bool wxListBox::OS2Command(WXUINT param, WXWORD WXUNUSED(id))
+{
+/*
+ if (param == LBN_SELCHANGE)
+ {
+ wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
+ wxArrayInt aSelections;
+ int count = GetSelections(aSelections);
+ if ( count > 0 )
+ {
+ event.m_commandInt = aSelections[0] ;
+ event.m_clientData = GetClientData(event.m_commandInt);
+ wxString str(GetString(event.m_commandInt));
+ if (str != wxT(""))
+ {
+ event.m_commandString = str;
+ }
+ }
+ else
+ {
+ event.m_commandInt = -1 ;
+ event.m_commandString.Empty();
+ }
+
+ event.SetEventObject( this );
+ ProcessCommand(event);
+ return TRUE;
+ }
+ else if (param == LBN_DBLCLK)
+ {
+ wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(event) ;
+ return TRUE;
+ }
+*/
+ return FALSE;
+}
// Listbox item
wxListBox::wxListBox()
{
const wxString& name)
{
m_noItems = n;
+ m_hWnd = 0;
m_selected = 0;
SetName(name);
wxSystemSettings settings;
SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
+ SetForegroundColour(parent->GetForegroundColour());
m_windowId = ( id == -1 ) ? (int)NewControlId() : id;
+ int x = pos.x;
+ int y = pos.y;
+ int width = size.x;
+ int height = size.y;
+ m_windowStyle = style;
+
// TODO create listbox
+/*
+ DWORD wstyle = WS_VISIBLE | WS_VSCROLL | WS_TABSTOP |
+ LBS_NOTIFY | LBS_HASSTRINGS;
+ if (m_windowStyle & wxLB_MULTIPLE)
+ wstyle |= LBS_MULTIPLESEL;
+ else if (m_windowStyle & wxLB_EXTENDED)
+ wstyle |= LBS_EXTENDEDSEL;
+
+ if (m_windowStyle & wxLB_ALWAYS_SB)
+ wstyle |= LBS_DISABLENOSCROLL ;
+ if (m_windowStyle & wxLB_HSCROLL)
+ wstyle |= WS_HSCROLL;
+ if (m_windowStyle & wxLB_SORT)
+ wstyle |= LBS_SORT;
+
+#if wxUSE_OWNER_DRAWN
+ if ( m_windowStyle & wxLB_OWNERDRAW ) {
+ // we don't support LBS_OWNERDRAWVARIABLE yet
+ wstyle |= LBS_OWNERDRAWFIXED;
+ }
+#endif
+
+ // Without this style, you get unexpected heights, so e.g. constraint layout
+ // doesn't work properly
+ wstyle |= LBS_NOINTEGRALHEIGHT;
+
+ bool want3D;
+ WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
+
+ // Even with extended styles, need to combine with WS_BORDER
+ // for them to look right.
+ if ( want3D || wxStyleHasBorder(m_windowStyle) )
+ {
+ wstyle |= WS_BORDER;
+ }
+
+ m_hWnd = (WXHWND)::CreateWindowEx(exStyle, wxT("LISTBOX"), NULL,
+ wstyle | WS_CHILD,
+ 0, 0, 0, 0,
+ (HWND)parent->GetHWND(), (HMENU)m_windowId,
+ wxGetInstance(), NULL);
+
+#if wxUSE_CTL3D
+ if (want3D)
+ {
+ Ctl3dSubclassCtl(GetHwnd());
+ m_useCtl3D = TRUE;
+ }
+#endif
+
+ // Subclass again to catch messages
+ SubclassWin(m_hWnd);
+
+ size_t ui;
+ for (ui = 0; ui < (size_t)n; ui++) {
+ Append(choices[ui]);
+ }
+
+ if ( (m_windowStyle & wxLB_MULTIPLE) == 0 )
+ SendMessage(GetHwnd(), LB_SETCURSEL, 0, 0);
+
+ SetFont(parent->GetFont());
+
+ SetSize(x, y, width, height);
+
+ Show(TRUE);
+*/
return FALSE;
}
wxListBox::~wxListBox()
{
+#if wxUSE_OWNER_DRAWN
+ size_t uiCount = m_aItems.Count();
+ while ( uiCount-- != 0 ) {
+ delete m_aItems[uiCount];
+ }
+#endif // wxUSE_OWNER_DRAWN
+}
+
+void wxListBox::SetupColours()
+{
+ SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
+ SetForegroundColour(GetParent()->GetForegroundColour());
}
void wxListBox::SetFirstItem(int N)
{
- // TODO
+ wxCHECK_RET( N >= 0 && N < m_noItems,
+ wxT("invalid index in wxListBox::SetFirstItem") );
+
+ // TODO SendMessage(GetHwnd(),LB_SETTOPINDEX,(WPARAM)N,(LPARAM)0) ;
}
void wxListBox::SetFirstItem(const wxString& s)
{
- // TODO
+ int N = FindString(s) ;
+
+ if ( N >= 0 )
+ SetFirstItem(N) ;
}
void wxListBox::Delete(int N)
{
- m_noItems --;
- // TODO
+ wxCHECK_RET( N >= 0 && N < m_noItems,
+ wxT("invalid index in wxListBox::Delete") );
+
+ // TODO SendMessage(GetHwnd(), LB_DELETESTRING, N, 0);
+ m_noItems --;
+ SetHorizontalExtent("");
}
void wxListBox::Append(const wxString& item)
{
- m_noItems ++;
+ int index=0; // TODO = ListBox_AddString(GetHwnd(), item);
+ m_noItems ++;
+
+#if wxUSE_OWNER_DRAWN
+ if ( m_windowStyle & wxLB_OWNERDRAW ) {
+ wxOwnerDrawn *pNewItem = CreateItem(index); // dummy argument
+ pNewItem->SetName(item);
+ m_aItems.Add(pNewItem);
+// ListBox_SetItemData(GetHwnd(), index, pNewItem);
+ }
+#endif
- // TODO
+ SetHorizontalExtent(item);
}
-void wxListBox::Append(const wxString& item, char *Client_data)
+void wxListBox::Append(const wxString& item, void *Client_data)
{
- m_noItems ++;
+ int index; // TODO = ListBox_AddString(GetHwnd(), item);
+ m_noItems ++;
+
+#if wxUSE_OWNER_DRAWN
+ if ( m_windowStyle & wxLB_OWNERDRAW ) {
+ // client data must be pointer to wxOwnerDrawn, otherwise we would crash
+ // in OnMeasure/OnDraw.
+ wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
+ }
+ else
+#endif
+
+ // TODO ListBox_SetItemData(GetHwnd(), index, Client_data);
- // TODO
+ SetHorizontalExtent(item);
}
void wxListBox::Set(int n, const wxString *choices, char** clientData)
{
- m_noItems = n;
+// ShowWindow(GetHwnd(), SW_HIDE);
+// ListBox_ResetContent(GetHwnd());
+ int i;
+ for (i = 0; i < n; i++)
+ {
+// ListBox_AddString(GetHwnd(), choices[i]);
+// if ( clientData )
+// ListBox_SetItemData(GetHwnd(), i, clientData[i]);
+ }
+ m_noItems = n;
+
+#if wxUSE_OWNER_DRAWN
+ if ( m_windowStyle & wxLB_OWNERDRAW ) {
+ // first delete old items
+ size_t ui = m_aItems.Count();
+ while ( ui-- != 0 ) {
+ delete m_aItems[ui];
+ }
+ m_aItems.Empty();
+
+ // then create new ones
+ for (ui = 0; ui < (size_t)n; ui++) {
+ wxOwnerDrawn *pNewItem = CreateItem(ui);
+ pNewItem->SetName(choices[ui]);
+ m_aItems.Add(pNewItem);
+// ListBox_SetItemData(GetHwnd(), ui, pNewItem);
+
+ wxASSERT_MSG(clientData[ui] == NULL,
+ wxT("Can't use client data with owner-drawn listboxes"));
+ }
+ }
+#endif
- // TODO
+ SetHorizontalExtent("");
+// ShowWindow(GetHwnd(), SW_SHOW);
}
int wxListBox::FindString(const wxString& s) const
{
- // TODO
- return -1;
+ int pos; // = ListBox_FindStringExact(GetHwnd(), (WPARAM)-1, s);
+// if (pos == LB_ERR)
+// return -1;
+// else
+ return pos;
}
void wxListBox::Clear()
{
- m_noItems = 0;
- // TODO
+// ListBox_ResetContent(GetHwnd());
+
+#if wxUSE_OWNER_DRAWN
+ size_t uiCount = m_aItems.Count();
+ while ( uiCount-- != 0 ) {
+ delete m_aItems[uiCount];
+ }
+
+ m_aItems.Clear();
+#endif // wxUSE_OWNER_DRAWN
+
+ m_noItems = 0;
+// ListBox_GetHorizontalExtent(GetHwnd());
}
void wxListBox::SetSelection(int N, bool select)
{
- // TODO
+ wxCHECK_RET( N >= 0 && N < m_noItems,
+ wxT("invalid index in wxListBox::SetSelection") );
+
+ if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
+ {
+// SendMessage(GetHwnd(), LB_SETSEL, select, N);
+ }
+ else
+ {
+ int N1 = N;
+ if (!select)
+ N1 = -1;
+// SendMessage(GetHwnd(), LB_SETCURSEL, N1, 0);
+ }
}
bool wxListBox::Selected(int N) const
{
- // TODO
+ wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE,
+ wxT("invalid index in wxListBox::Selected") );
+
+// return SendMessage(GetHwnd(), LB_GETSEL, N, 0) == 0 ? FALSE : TRUE;
return FALSE;
}
void wxListBox::Deselect(int N)
{
- // TODO
+ wxCHECK_RET( N >= 0 && N < m_noItems,
+ wxT("invalid index in wxListBox::Deselect") );
+
+ if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
+ {
+// SendMessage(GetHwnd(), LB_SETSEL, FALSE, N);
+ }
}
-char *wxListBox::GetClientData(int N) const
+void *wxListBox::GetClientData(int N) const
{
- // TODO
+ wxCHECK_MSG( N >= 0 && N < m_noItems, NULL,
+ wxT("invalid index in wxListBox::GetClientData") );
+
+// return (void *)SendMessage(GetHwnd(), LB_GETITEMDATA, N, 0);
return (char *)NULL;
}
-void wxListBox::SetClientData(int N, char *Client_data)
+void wxListBox::SetClientData(int N, void *Client_data)
{
- // TODO
+ wxCHECK_RET( N >= 0 && N < m_noItems,
+ wxT("invalid index in wxListBox::SetClientData") );
+
+// if ( ListBox_SetItemData(GetHwnd(), N, Client_data) == LB_ERR )
+// wxLogDebug(wxT("LB_SETITEMDATA failed"));
}
// Return number of selections and an array of selected integers
{
aSelections.Empty();
-/* TODO
if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
{
- int no_sel = ??
- for ( int n = 0; n < no_sel; n++ )
- aSelections.Add(??);
+ int no_sel; // = ListBox_GetSelCount(GetHwnd());
+ if (no_sel != 0) {
+ int *selections = new int[no_sel];
+// if ( ListBox_GetSelItems(GetHwnd(), no_sel, selections) == LB_ERR ) {
+// wxFAIL_MSG(wxT("This listbox can't have single-selection style!"));
+// }
+
+ aSelections.Alloc(no_sel);
+ for ( int n = 0; n < no_sel; n++ )
+ aSelections.Add(selections[n]);
+
+ delete [] selections;
+ }
return no_sel;
}
else // single-selection listbox
{
- aSelections.Add(??);
+// aSelections.Add(ListBox_GetCurSel(GetHwnd()));
return 1;
}
-*/
- return 0;
}
// Get single selection, for single choice list items
int wxListBox::GetSelection() const
{
- // TODO
+ wxCHECK_MSG( !(m_windowStyle & wxLB_MULTIPLE) &&
+ !(m_windowStyle & wxLB_EXTENDED),
+ -1,
+ wxT("GetSelection() can't be used with multiple-selection "
+ "listboxes, use GetSelections() instead.") );
+
+// return ListBox_GetCurSel(GetHwnd());
return -1;
}
// Find string for position
wxString wxListBox::GetString(int N) const
{
- // TODO
- return wxString("");
+ wxCHECK_MSG( N >= 0 && N < m_noItems, "",
+ wxT("invalid index in wxListBox::GetClientData") );
+
+// int len = ListBox_GetTextLen(GetHwnd(), N);
+
+ // +1 for terminating NUL
+ wxString result;
+// ListBox_GetText(GetHwnd(), N, result.GetWriteBuf(len + 1));
+ result.UngetWriteBuf();
+
+ return result;
}
-void wxListBox::SetSize(int x, int y, int width, int height, int sizeFlags)
+// OS/2-PM-specific code to set the horizontal extent of the listbox, if
+// necessary. If s is non-NULL, it's used to calculate the horizontal extent.
+// Otherwise, all strings are used.
+void wxListBox::SetHorizontalExtent(const wxString& s)
{
- // TODO
-}
+/*
+ // Only necessary if we want a horizontal scrollbar
+ if (!(m_windowStyle & wxHSCROLL))
+ return;
+ TEXTMETRIC lpTextMetric;
+ if (s != wxT(""))
+ {
+ int existingExtent = (int)SendMessage(GetHwnd(), LB_GETHORIZONTALEXTENT, 0, 0L);
+ HDC dc = GetWindowDC(GetHwnd());
+ HFONT oldFont = 0;
+ if (GetFont().Ok() && GetFont().GetResourceHandle())
+ oldFont = (HFONT) ::SelectObject(dc, (HFONT) GetFont().GetResourceHandle());
+
+ GetTextMetrics(dc, &lpTextMetric);
+ SIZE extentXY;
+ ::GetTextExtentPoint(dc, (LPTSTR) (const wxChar *)s, s.Length(), &extentXY);
+ int extentX = (int)(extentXY.cx + lpTextMetric.tmAveCharWidth);
+
+ if (oldFont)
+ ::SelectObject(dc, oldFont);
+
+ ReleaseDC(GetHwnd(), dc);
+ if (extentX > existingExtent)
+ SendMessage(GetHwnd(), LB_SETHORIZONTALEXTENT, LOWORD(extentX), 0L);
+ return;
+ }
+ else
+ {
+ int largestExtent = 0;
+ HDC dc = GetWindowDC(GetHwnd());
+ HFONT oldFont = 0;
+ if (GetFont().Ok() && GetFont().GetResourceHandle())
+ oldFont = (HFONT) ::SelectObject(dc, (HFONT) GetFont().GetResourceHandle());
+
+ GetTextMetrics(dc, &lpTextMetric);
+ int i;
+ for (i = 0; i < m_noItems; i++)
+ {
+ int len = (int)SendMessage(GetHwnd(), LB_GETTEXT, i, (LONG)wxBuffer);
+ wxBuffer[len] = 0;
+ SIZE extentXY;
+ ::GetTextExtentPoint(dc, (LPTSTR)wxBuffer, len, &extentXY);
+ int extentX = (int)(extentXY.cx + lpTextMetric.tmAveCharWidth);
+ if (extentX > largestExtent)
+ largestExtent = extentX;
+ }
+ if (oldFont)
+ ::SelectObject(dc, oldFont);
+
+ ReleaseDC(GetHwnd(), dc);
+ SendMessage(GetHwnd(), LB_SETHORIZONTALEXTENT, LOWORD(largestExtent), 0L);
+ }
+*/
+}
void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
{
+ wxCHECK_RET( pos >= 0 && pos <= m_noItems,
+ wxT("invalid index in wxListBox::InsertItems") );
+
+ int i;
+// for (i = 0; i < nItems; i++)
+// ListBox_InsertString(GetHwnd(), i + pos, items[i]);
m_noItems += nItems;
- // TODO
+ SetHorizontalExtent(wxT(""));
}
void wxListBox::SetString(int N, const wxString& s)
{
- // TODO
+ wxCHECK_RET( N >= 0 && N < m_noItems,
+ wxT("invalid index in wxListBox::SetString") );
+
+ int sel = -1;
+ if (!(m_windowStyle & wxLB_MULTIPLE) && !(m_windowStyle & wxLB_EXTENDED))
+ sel = GetSelection();
+
+ void *oldData = wxListBox::GetClientData(N);
+
+// SendMessage(GetHwnd(), LB_DELETESTRING, N, 0);
+
+ int newN = N;
+ if (N == (m_noItems - 1))
+ newN = -1;
+
+// SendMessage(GetHwnd(), LB_INSERTSTRING, newN, (LPARAM) (const wxChar *)s);
+ if (oldData)
+ wxListBox::SetClientData(N, oldData);
+
+ // Selection may have changed
+ if (sel >= 0)
+ SetSelection(sel);
+
+#if wxUSE_OWNER_DRAWN
+ if ( m_windowStyle & wxLB_OWNERDRAW )
+ // update item's text
+ m_aItems[N]->SetName(s);
+#endif //USE_OWNER_DRAWN
}
int wxListBox::Number () const
{
- return m_noItems;
+ return m_noItems;
}
// For single selection items only
return FALSE;
}
+wxSize wxListBox::DoGetBestSize()
+{
+ // find the widest string
+ int wLine;
+ int wListbox = 0;
+ for ( int i = 0; i < m_noItems; i++ )
+ {
+ wxString str(GetString(i));
+ GetTextExtent(str, &wLine, NULL);
+ if ( wLine > wListbox )
+ wListbox = wLine;
+ }
+
+ // give it some reasonable default value if there are no strings in the
+ // list
+ if ( wListbox == 0 )
+ wListbox = 100;
+
+ // the listbox should be slightly larger than the widest string
+ int cx, cy;
+ wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
+
+ wListbox += 3*cx;
+
+ int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)*(wxMax(m_noItems, 7));
+
+ return wxSize(wListbox, hListbox);
+}
+
void wxListBox::Command (wxCommandEvent & event)
{
if (event.m_extraLong)
ProcessCommand (event);
}
+WXHBRUSH wxListBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
+ WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+{
+/*
+#if wxUSE_CTL3D
+ if ( m_useCtl3D )
+ {
+ HBRUSH hbrush = Ctl3dCtlColorEx(message, wParam, lParam);
+ return (WXHBRUSH) hbrush;
+ }
+#endif
+
+ if (GetParent()->GetTransparentBackground())
+ SetBkMode((HDC) pDC, TRANSPARENT);
+ else
+ SetBkMode((HDC) pDC, OPAQUE);
+
+ ::SetBkColor((HDC) pDC, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
+ ::SetTextColor((HDC) pDC, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
+
+ wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
+
+ // Note that this will be cleaned up in wxApp::OnIdle, if backgroundBrush
+ // has a zero usage count.
+ backgroundBrush->RealizeResource();
+*/
+ wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
+ return (WXHBRUSH) backgroundBrush->GetResourceHandle();
+}
+
+MRESULT wxListBox::OS2WindowProc(HWND hwnd, WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+ return wxControl::OS2WindowProc(hwnd, nMsg, wParam, lParam);
+}
+
+#if wxUSE_OWNER_DRAWN
+
+// drawing
+// -------
+
+// space beneath/above each row in pixels
+// "standard" checklistbox use 1 here, some might prefer 2. 0 is ugly.
+#define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
+
+// the height is the same for all items
+// TODO should be changed for LBS_OWNERDRAWVARIABLE style listboxes
+
+// NB: can't forward this to wxListBoxItem because LB_SETITEMDATA
+// message is not yet sent when we get here!
+bool wxListBox::OS2OnMeasure(WXMEASUREITEMSTRUCT *item)
+{
+ // only owner-drawn control should receive this message
+ wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
+
+// MEASUREITEMSTRUCT *pStruct = (MEASUREITEMSTRUCT *)item;
+
+ wxDC dc;
+// TODO: dc.SetHDC((WXHDC)CreateIC(wxT("DISPLAY"), NULL, NULL, 0));
+ dc.SetFont(wxSystemSettings::GetSystemFont(wxSYS_ANSI_VAR_FONT));
+
+// pStruct->itemHeight = dc.GetCharHeight() + 2*OWNER_DRAWN_LISTBOX_EXTRA_SPACE;
+// pStruct->itemWidth = dc.GetCharWidth();
+
+ return TRUE;
+}
+
+// forward the message to the appropriate item
+bool wxListBox::OS2OnDraw(WXDRAWITEMSTRUCT *item)
+{
+ // only owner-drawn control should receive this message
+ wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
+/*
+ DRAWITEMSTRUCT *pStruct = (DRAWITEMSTRUCT *)item;
+
+ long data = ListBox_GetItemData(GetHwnd(), pStruct->itemID);
+
+ wxCHECK( data && (data != LB_ERR), FALSE );
+
+ wxListBoxItem *pItem = (wxListBoxItem *)data;
+
+ wxDC dc;
+ dc.SetHDC((WXHDC)pStruct->hDC, FALSE);
+ wxRect rect(wxPoint(pStruct->rcItem.left, pStruct->rcItem.top),
+ wxPoint(pStruct->rcItem.right, pStruct->rcItem.bottom));
+
+ return pItem->OnDrawItem(dc, rect,
+ (wxOwnerDrawn::wxODAction)pStruct->itemAction,
+ (wxOwnerDrawn::wxODStatus)pStruct->itemState);
+*/
+ return FALSE;
+}
+
+#endif
+ // wxUSE_OWNER_DRAWN
$(CPPFLAGS) /Fo$@ /Tp $<
<<
+{..\os2}.c{..\os2\$D}.obj:
+ @echo $<
+ icc @<<
+$(CPPFLAGS) /Fo$@ /Tp $<
+<<
+
{..\html}.cpp{..\html\$D}.obj:
@echo $<
icc @<<
..\os2\$D\frame.obj \
..\os2\$D\gauge.obj \
..\os2\$D\gdiobj.obj \
+ ..\os2\$D\gsocket.obj \
+ ..\os2\$D\helpwin.obj \
+ ..\os2\$D\icon.obj \
+ ..\os2\$D\imaglist.obj \
+ ..\os2\$D\iniconf.obj \
+ ..\os2\$D\joystick.obj \
+ ..\os2\$D\listbox.obj \
..\os2\$D\window.obj
frame.obj \
gauge.obj \
gdiobj.obj \
+ gsocket.obj \
+ helpwin.obj \
+ icon.obj \
+ imaglist.obj \
+ iniconf.obj \
+ joystick.obj \
+ listbox.obj \
window.obj
HTMLOBJS = \
copy ..\os2\$D\frame.obj
copy ..\os2\$D\gauge.obj
copy ..\os2\$D\gdiobj.obj
+ copy ..\os2\$D\gsocket.obj
+ copy ..\os2\$D\helpwin.obj
+ copy ..\os2\$D\icon.obj
+ copy ..\os2\$D\imaglist.obj
+ copy ..\os2\$D\iniconf.obj
+ copy ..\os2\$D\joystick.obj
+ copy ..\os2\$D\listbox.obj
copy ..\os2\$D\window.obj
# wxWindows library as DLL