Mercurial > pm123
changeset 1:43def5d33575
Update to DW 2.2 and PM123 files to 1.33... 1.33 completely changed the plugin system and it is still broken right now.
author | Brian Smith <brian@dbsoft.org> |
---|---|
date | Thu, 24 Nov 2011 03:45:48 -0600 |
parents | f840ca9a1a98 |
children | e6f7d2d80b81 |
files | decoder_plug.h dw.c dw.h filter_plug.h format.h nuclear.c output_plug.h plugin.h |
diffstat | 8 files changed, 9951 insertions(+), 7127 deletions(-) [+] |
line wrap: on
line diff
--- a/decoder_plug.h Fri Feb 18 02:50:18 2011 -0600 +++ b/decoder_plug.h Thu Nov 24 03:45:48 2011 -0600 @@ -1,164 +1,238 @@ -#if __cplusplus +#ifndef PM123_DECODER_PLUG_H +#define PM123_DECODER_PLUG_H + +#include "format.h" + +#ifdef __cplusplus extern "C" { #endif -#define WM_PLAYSTOP WM_USER+69 -#define WM_PLAYERROR WM_USER+100 -#define WM_SEEKSTOP WM_USER+666 +#pragma pack(4) - -int _System decoder_init(void **w); -BOOL _System decoder_uninit(void *w); +int DLLENTRY decoder_init ( void** w ); +BOOL DLLENTRY decoder_uninit( void* w ); -#define DECODER_PLAY 1 /* returns 101 -> already playing - 102 -> error, decoder killed */ -#define DECODER_STOP 2 /* returns 101 -> already stopped - 102 -> error, decoder killed (and stopped) */ -#define DECODER_FFWD 3 -#define DECODER_REW 4 -#define DECODER_JUMPTO 5 -#define DECODER_SETUP 6 -#define DECODER_EQ 7 -#define DECODER_BUFFER 8 +/* return value: */ +/* PLUGIN_OK -> ok. */ +/* PLUGIN_UNSUPPORTED -> command unsupported. */ +/* */ +/* DECODER_PLAY can return also: */ +/* PLUGIN_GO_ALREADY -> already playing. */ +/* PLUGIN_GO_ERROR -> error, decoder killed and restarted. */ +/* */ +/* DECODER_STOP can return also: */ +/* PLUGIN_GO_ALREADY -> already stopped. */ +/* PLUGIN_GO_ERROR -> error, decoder killed and stopped. */ -typedef struct { +#define DECODER_PLAY 1 +#define DECODER_STOP 2 +#define DECODER_FFWD 3 +#define DECODER_REW 4 +#define DECODER_JUMPTO 5 +#define DECODER_SETUP 6 +#define DECODER_EQ 7 /* obsolete, don't used anymore */ +#define DECODER_BUFFER 8 /* obsolete, don't used anymore */ +#define DECODER_SAVEDATA 9 + +typedef struct _DECODER_PARAMS +{ int size; /* --- DECODER_PLAY, STOP */ - char *filename; - char *URL; - char *drive; /* for CD ie.: "X:" */ - int track; - int sectors[2]; /* play from sector x to sector y */ - char *other; + char* filename; + void* unused1; /* obsolete, must be NULL */ + char* drive; /* for CD ie.: "X:" */ + int track; + int sectors[2]; /* play from sector x to sector y */ + void* unused2; /* obsolete, must be NULL */ /* --- DECODER_REW, FFWD and JUMPTO */ - int jumpto; /* absolute positioning in milliseconds */ - int ffwd; /* 1 = start ffwd, 0 = end ffwd */ - int rew; /* 1 = start rew, 0 = end rew */ + int jumpto; /* absolute positioning in milliseconds */ + int ffwd; /* 1 = start ffwd, 0 = end ffwd */ + int rew; /* 1 = start rew, 0 = end rew */ /* --- DECODER_SETUP */ /* specify a function which the decoder should use for output */ - int (* _System output_play_samples)(void *a, FORMAT_INFO *format, char *buf, int len, int posmarker); - void *a; /* only to be used with the precedent function */ - int audio_buffersize; + int (DLLENTRYP output_play_samples)( void* a, FORMAT_INFO* format, char* buf, int len, int posmarker ); + void* a; /* only to be used with the precedent function */ + int audio_buffersize; - char *proxyurl; /* NULL = none */ - char *httpauth; /* NULL = none */ + char* proxyurl; /* NULL = none */ + char* httpauth; /* NULL = none */ /* error message function the decoder should use */ - void (* _System error_display)(char *); + void (DLLENTRYP error_display)( char* ); - HEV playsem; /* this semaphore is reseted when DECODER_PLAY is requested - and is posted on stop */ + /* info message function the decoder should use */ + /* this information is always displayed to the user right away */ + void (DLLENTRYP info_display)( char* ); - HWND hwnd; // commodity for PM interface, decoder must send a few messages to this handle + void* unused3; /* obsolete, must be NULL */ + HWND hwnd; /* commodity for PM interface, decoder must send a few + messages to this handle */ /* values used for streaming inputs by the decoder */ - int buffersize; /* read ahead buffer in bytes, 0 = disabled */ - int bufferwait; /* block the first read until the buffer is filled */ + int buffersize; /* read ahead buffer in bytes, 0 = disabled */ + int bufferwait; /* block the first read until the buffer is filled */ - /* -- DECODER_BUFFER */ + char* metadata_buffer; /* the decoder will put streaming metadata in this */ + int metadata_size; /* buffer before posting WM_METADATA */ - int bufferstatus; /* reports how many bytes there are available in the buffer */ - - /* --- DECODER_EQ */ + int unused4; /* obsolete, must be 0 */ + int unused5; /* obsolete, must be 0 */ + int unused6; /* obsolete, must be 0 */ - /* usually only useful with MP3 decoder */ - int equalizer; /* TRUE or FALSE */ - float *bandgain; /* point to an array like this bandgain[#channels][10] */ + /* --- DECODER_SAVEDATA */ + + char* save_filename; } DECODER_PARAMS; -/* returns 0 -> ok - 1 -> command unsupported - 1xx -> msg specific */ -ULONG _System decoder_command(void *w, ULONG msg, DECODER_PARAMS *params); +ULONG DLLENTRY decoder_command( void* w, ULONG msg, DECODER_PARAMS* params ); #define DECODER_STOPPED 0 #define DECODER_PLAYING 1 #define DECODER_STARTING 2 -ULONG _System decoder_status(void *w); +#define DECODER_PAUSED 3 +#define DECODER_ERROR 200 + +ULONG DLLENTRY decoder_status( void* w ); /* WARNING!! this _can_ change in time!!! returns stream length in ms */ /* the decoder should keep in memory a last valid length so the call */ /* remains valid even if decoder_status() == DECODER_STOPPED */ -ULONG _System decoder_length(void *w); +ULONG DLLENTRY decoder_length( void* w ); + +#define DECODER_MODE_STEREO 0 +#define DECODER_MODE_JOINT_STEREO 1 +#define DECODER_MODE_DUAL_CHANNEL 2 +#define DECODER_MODE_SINGLE_CHANNEL 3 + +#define modes(i) ( i == 0 ? "Stereo" : \ + ( i == 1 ? "Joint-Stereo" : \ + ( i == 2 ? "Dual-Channel" : \ + ( i == 3 ? "Single-Channel" : "" )))) -static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" }; +/* See haveinfo field of the DECODER_INFO structure. */ +#define DECODER_HAVE_TITLE 0x0001 +#define DECODER_HAVE_ARTIST 0x0002 +#define DECODER_HAVE_ALBUM 0x0004 +#define DECODER_HAVE_YEAR 0x0008 +#define DECODER_HAVE_COMMENT 0x0010 +#define DECODER_HAVE_GENRE 0x0020 +#define DECODER_HAVE_TRACK 0x0040 +#define DECODER_HAVE_COPYRIGHT 0x0080 +#define DECODER_HAVE_TRACK_GAIN 0x0100 +#define DECODER_HAVE_TRACK_PEAK 0x0200 +#define DECODER_HAVE_ALBUM_GAIN 0x0400 +#define DECODER_HAVE_ALBUM_PEAK 0x0800 + +#define INFO_SIZE_1 976 /* size of the DECODER_INFO structure prior PM123 1.32 */ +#define INFO_SIZE_2 1264 /* size of the DECODER_INFO structure since PM123 1.32 */ /* NOTE: the information returned is only based on the FIRST header */ -typedef struct { - int size; +typedef struct _DECODER_INFO +{ + int size; /* see INFO_SIZE definitions */ - FORMAT_INFO format; /* stream format after decoding */ + FORMAT_INFO format; /* stream format after decoding */ - int songlength; /* in milliseconds, smaller than 0 -> unknown */ - int junklength; /* bytes of junk before stream start, if < 0 -> unknown */ + int songlength; /* in milliseconds, smaller than 0 -> unknown */ + int junklength; /* bytes of junk before stream start, if < 0 -> unknown */ /* mpeg stuff */ - int mpeg; /* 25 = MPEG 2.5, 10 = MPEG 1.0, 20 = MPEG 2.0, 0 = not an MPEG */ - int layer; /* 0 = unknown */ - int mode; /* use it on modes[4] */ - int modext; /* didn't check what this one does */ - int bpf; /* bytes in the mpeg frame including header */ - int bitrate; /* in kbit/s */ - int extention; /* didn't check what this one does */ + int mpeg; /* 25 = MPEG 2.5, 10 = MPEG 1.0, 20 = MPEG 2.0, 0 = not an MPEG */ + int layer; /* 0 = unknown */ + int mode; /* use it on modes(i) */ + int modext; /* didn't check what this one does */ + int bpf; /* bytes in the mpeg frame including header */ + int bitrate; /* in kbit/s */ + int extention; /* didn't check what this one does */ /* track stuff */ - int startsector; - int endsector; + int startsector; + int endsector; - /* module stuff */ - int numchannels; /* 0 = not a MODule */ - int numpatterns; - int numpositions; + /* obsolete stuff */ + int unused1; /* obsolete, must be 0 */ + int unused2; /* obsolete, must be 0 */ + int unused3; /* obsolete, must be 0 */ /* general technical information string */ - char tech_info[128]; + char tech_info[128]; + + /* meta information */ + char title [128]; + char artist [128]; + char album [128]; + char year [128]; + char comment [128]; + char genre [128]; - /* song information */ - char title[80]; - char artist[80]; - char album[80]; - char year[80]; - char comment[80]; - char genre[80]; + /* added since PM123 1.32 */ + char track [128]; + char copyright[128]; + int codepage; /* Code page of the meta info. Must be 0 if the + code page is unknown. Don't place here any another + value if it is not provided by meta info. */ + int haveinfo; /* This flags define what of fields of the block of the + meta information are supported by the decoder. Can + be 0 if the decoder supports all fields. */ + int saveinfo; /* Must be 1 if the decoder can update meta info of + this file. Otherwise, must be 0. */ + int filesize; /* Size of the file. */ + + float track_gain; /* Defines Replay Gain values as specified at */ + float track_peak; /* http://www.replaygain.org/ */ + float album_gain; + float album_peak; } DECODER_INFO; /* returns - 0 = everything's perfect, structure is set - 100 = error reading file (too small?) - 200 = decoder can't play that - 1001 = http error occured, check http_strerror() for string; - other values = errno */ -ULONG _System decoder_fileinfo(char *filename, DECODER_INFO *info); -ULONG _System decoder_trackinfo(char *drive, int track, DECODER_INFO *info); + PLUGIN_OK = everything's perfect, structure is set, + PLUGIN_NO_READ = error reading file (too small?), + PLUGIN_NO_PLAY = decoder can't play that, + other values = errno, check xio_strerror() for string. */ +ULONG DLLENTRY decoder_fileinfo( char* filename, DECODER_INFO* info ); +ULONG DLLENTRY decoder_trackinfo( char* drive, int track, DECODER_INFO* info ); -typedef struct +/* returns + PLUGIN_OK = everything's perfect, structure is saved to filename, + other values = errno, check xio_strerror() for string. */ +ULONG DLLENTRY decoder_saveinfo( char* filename, DECODER_INFO* info ); + +typedef struct _DECODER_CDINFO { int sectors; int firsttrack; int lasttrack; + } DECODER_CDINFO; -ULONG _System decoder_cdinfo(char *drive, DECODER_CDINFO *info); - +/* returns + PLUGIN_OK = everything's perfect, structure is set, + PLUGIN_NO_READ = error reading required info, + other values = errno, check xio_strerror() for string. */ +ULONG DLLENTRY decoder_cdinfo( const char* drive, DECODER_CDINFO* info ); /* returns ORed values */ -#define DECODER_FILENAME 0x1 -#define DECODER_URL 0x2 -#define DECODER_TRACK 0x4 -#define DECODER_OTHER 0x8 +#define DECODER_FILENAME 0x0001 /* Decoder can play a regular file. */ +#define DECODER_URL 0x0002 /* Decoder can play a internet stream or file. */ +#define DECODER_TRACK 0x0004 /* Decoder can play a CD track. */ +#define DECODER_OTHER 0x0008 /* Decoder can play something. */ +#define DECODER_METAINFO 0x8000 /* Decoder can save a meta info. */ /* size is i/o and is the size of the array. each ext should not be bigger than 8bytes */ -ULONG _System decoder_support(char *fileext[], int *size); +ULONG DLLENTRY decoder_support( char* fileext[], int* size ); +#pragma pack() -#if __cplusplus +#ifdef __cplusplus } #endif +#endif /* PM123_DECODER_PLUG_H */ +
--- a/dw.c Fri Feb 18 02:50:18 2011 -0600 +++ b/dw.c Thu Nov 24 03:45:48 2011 -0600 @@ -1,10 +1,9 @@ -/* /* * Dynamic Windows: * A GTK like implementation of the PM GUI * - * (C) 2000-2004 Brian Smith <dbsoft@technologist.com> - * (C) 2003-2004 Mark Hessling <m.hessling@qut.edu.au> + * (C) 2000-2011 Brian Smith <brian@dbsoft.org> + * (C) 2003-2008 Mark Hessling <m.hessling@qut.edu.au> * (C) 2000 Achim Hasenmueller <achimha@innotek.de> * (C) 2000 Peter Nielsen <peter@pmview.com> * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit) @@ -14,6 +13,10 @@ #define INCL_DOSERRORS #define INCL_WIN #define INCL_GPI +#define INCL_DEV +#define INCL_SPL +#define INCL_SPLDOSPRINT +#define INCL_SPLERRORS #include <os2.h> #include <stdlib.h> @@ -25,10 +28,15 @@ #include <process.h> #include <time.h> #include <io.h> +#include <math.h> #ifndef __EMX__ #include <direct.h> #endif #include <sys/time.h> +#include <sys/stat.h> +#ifdef __WATCOMC__ +#include <alloca.h> +#endif #include "dw.h" #define QWP_USER 0 @@ -38,15 +46,18 @@ MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2); MRESULT EXPENTRY _wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2); +MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2); void _do_resize(Box *thisbox, int x, int y); void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y); int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height); void _dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname); void _dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname); void _free_menu_data(HWND menu); +ULONG (* _System _PmPrintfString)(char *String) = 0; char ClassName[] = "dynamicwindows"; char SplitbarClassName[] = "dwsplitbar"; +char ScrollClassName[] = "dwscroll"; char *DefaultFont = "9.WarpSans"; HAB dwhab = 0; @@ -55,28 +66,30 @@ LONG _foreground = 0xAAAAAA, _background = DW_CLR_DEFAULT; HWND hwndApp = NULLHANDLE, hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE; +HWND hwndTrayServer = NULLHANDLE, hwndTaskBar = NULLHANDLE; +; PRECORDCORE pCoreEmph = NULL; -ULONG aulBuffer[4], GlobalID = 10000; +ULONG aulBuffer[4]; HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop; -HMOD wpconfig = 0; +HMOD wpconfig = 0, pmprintf = 0; unsigned long _colors[] = { - CLR_BLACK, - CLR_DARKRED, - CLR_DARKGREEN, - CLR_BROWN, - CLR_DARKBLUE, - CLR_DARKPINK, - CLR_DARKCYAN, - CLR_PALEGRAY, - CLR_DARKGRAY, - CLR_RED, - CLR_GREEN, - CLR_YELLOW, - CLR_BLUE, - CLR_PINK, - CLR_CYAN, - CLR_WHITE + CLR_BLACK, + CLR_DARKRED, + CLR_DARKGREEN, + CLR_BROWN, + CLR_DARKBLUE, + CLR_DARKPINK, + CLR_DARKCYAN, + CLR_PALEGRAY, + CLR_DARKGRAY, + CLR_RED, + CLR_GREEN, + CLR_YELLOW, + CLR_BLUE, + CLR_PINK, + CLR_CYAN, + CLR_WHITE }; #define IS_WARP4() (aulBuffer[0] == 20 && aulBuffer[1] >= 40) @@ -87,12 +100,12 @@ typedef struct _sighandler { - struct _sighandler *next; - ULONG message; - HWND window; - int id; - void *signalfunction; - void *data; + struct _sighandler *next; + ULONG message; + HWND window; + int id; + void *signalfunction; + void *data; } SignalHandler; @@ -100,8 +113,8 @@ typedef struct { - ULONG message; - char name[30]; + ULONG message; + char name[30]; } SignalList; @@ -109,131 +122,144 @@ #define SIGNALMAX 16 SignalList SignalTranslate[SIGNALMAX] = { - { WM_SIZE, DW_SIGNAL_CONFIGURE }, - { WM_CHAR, DW_SIGNAL_KEY_PRESS }, - { WM_BUTTON1DOWN, DW_SIGNAL_BUTTON_PRESS }, - { WM_BUTTON1UP, DW_SIGNAL_BUTTON_RELEASE }, - { WM_MOUSEMOVE, DW_SIGNAL_MOTION_NOTIFY }, - { WM_CLOSE, DW_SIGNAL_DELETE }, - { WM_PAINT, DW_SIGNAL_EXPOSE }, - { WM_COMMAND, DW_SIGNAL_CLICKED }, - { CN_ENTER, DW_SIGNAL_ITEM_ENTER }, - { CN_CONTEXTMENU, DW_SIGNAL_ITEM_CONTEXT }, - { LN_SELECT, DW_SIGNAL_LIST_SELECT }, - { CN_EMPHASIS, DW_SIGNAL_ITEM_SELECT }, - { WM_SETFOCUS, DW_SIGNAL_SET_FOCUS }, - { SLN_SLIDERTRACK, DW_SIGNAL_VALUE_CHANGED }, - { BKN_PAGESELECTED,DW_SIGNAL_SWITCH_PAGE }, - { CN_EXPANDTREE, DW_SIGNAL_TREE_EXPAND } + { WM_SIZE, DW_SIGNAL_CONFIGURE }, + { WM_CHAR, DW_SIGNAL_KEY_PRESS }, + { WM_BUTTON1DOWN, DW_SIGNAL_BUTTON_PRESS }, + { WM_BUTTON1UP, DW_SIGNAL_BUTTON_RELEASE }, + { WM_MOUSEMOVE, DW_SIGNAL_MOTION_NOTIFY }, + { WM_CLOSE, DW_SIGNAL_DELETE }, + { WM_PAINT, DW_SIGNAL_EXPOSE }, + { WM_COMMAND, DW_SIGNAL_CLICKED }, + { CN_ENTER, DW_SIGNAL_ITEM_ENTER }, + { CN_CONTEXTMENU, DW_SIGNAL_ITEM_CONTEXT }, + { LN_SELECT, DW_SIGNAL_LIST_SELECT }, + { CN_EMPHASIS, DW_SIGNAL_ITEM_SELECT }, + { WM_SETFOCUS, DW_SIGNAL_SET_FOCUS }, + { SLN_SLIDERTRACK, DW_SIGNAL_VALUE_CHANGED }, + { BKN_PAGESELECTED,DW_SIGNAL_SWITCH_PAGE }, + { CN_EXPANDTREE, DW_SIGNAL_TREE_EXPAND } }; +/* Internal function to keep a semi-unique ID within valid range */ +USHORT _GlobalID(void) +{ + static USHORT GlobalID = 9999; + + GlobalID++; + if(GlobalID >= 65534) + { + GlobalID = 10000; + } + return GlobalID; +} + /* This function adds a signal handler callback into the linked list. */ void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data) { - SignalHandler *new = malloc(sizeof(SignalHandler)); - - new->message = message; - new->window = window; - new->id = id; - new->signalfunction = signalfunction; - new->data = data; - new->next = NULL; - - if (!Root) - Root = new; - else - { - SignalHandler *prev = NULL, *tmp = Root; - while(tmp) - { - if(tmp->message == message && - tmp->window == window && - tmp->id == id && - tmp->signalfunction == signalfunction) - { - tmp->data = data; - free(new); - return; - } - prev = tmp; - tmp = tmp->next; - } - if(prev) - prev->next = new; - else - Root = new; - } + SignalHandler *new = malloc(sizeof(SignalHandler)); + + new->message = message; + new->window = window; + new->id = id; + new->signalfunction = signalfunction; + new->data = data; + new->next = NULL; + + if (!Root) + Root = new; + else + { + SignalHandler *prev = NULL, *tmp = Root; + while(tmp) + { + if(tmp->message == message && + tmp->window == window && + tmp->id == id && + tmp->signalfunction == signalfunction) + { + tmp->data = data; + free(new); + return; + } + prev = tmp; + tmp = tmp->next; + } + if(prev) + prev->next = new; + else + Root = new; + } } /* Finds the message number for a given signal name */ ULONG _findsigmessage(char *signame) { - int z; - - for(z=0;z<SIGNALMAX;z++) - { - if(stricmp(signame, SignalTranslate[z].name) == 0) - return SignalTranslate[z].message; - } - return 0L; + int z; + + for(z=0;z<SIGNALMAX;z++) + { + if(stricmp(signame, SignalTranslate[z].name) == 0) + return SignalTranslate[z].message; + } + return 0L; } typedef struct _CNRITEM { - MINIRECORDCORE rc; - HPOINTER hptrIcon; - PVOID user; - HTREEITEM parent; + MINIRECORDCORE rc; + HPOINTER hptrIcon; + PVOID user; + HTREEITEM parent; } CNRITEM, *PCNRITEM; int _null_key(HWND window, int key, void *data) { - window = window; /* keep compiler happy */ - key = key; /* keep compiler happy */ - data = data; /* keep compiler happy */ - return TRUE; + window = window; /* keep compiler happy */ + key = key; /* keep compiler happy */ + data = data; /* keep compiler happy */ + return TRUE; } /* Find the desktop window handle */ HWND _toplevel_window(HWND handle) { - HWND box, lastbox = WinQueryWindow(handle, QW_PARENT); - - /* Find the toplevel window */ - while((box = WinQueryWindow(lastbox, QW_PARENT)) != desktop && box > 0) - { - lastbox = box; - } - if(box > 0) - return lastbox; - return handle; + HWND box, lastbox = WinQueryWindow(handle, QW_PARENT); + + /* Find the toplevel window */ + while((box = WinQueryWindow(lastbox, QW_PARENT)) != desktop && box > 0) + { + lastbox = box; + } + if(box > 0) + return lastbox; + return handle; } /* Returns height of specified window. */ int _get_height(HWND handle) { - unsigned long height; - dw_window_get_pos_size(handle, NULL, NULL, NULL, &height); - return (int)height; + unsigned long height; + dw_window_get_pos_size(handle, NULL, NULL, NULL, &height); + return (int)height; } /* Find the height of the frame a desktop style window is sitting on */ int _get_frame_height(HWND handle) { - while(handle) - { - HWND client; - if((client = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE) - { + while(handle) + { + HWND client; + if((client = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE) + { return _get_height(WinQueryWindow(handle, QW_PARENT)); - } + } handle = WinQueryWindow(handle, QW_PARENT); - } - return dw_screen_height(); + } + return dw_screen_height(); } /* A "safe" WinSendMsg() that tries multiple times in case the @@ -241,46 +267,46 @@ */ MRESULT _dw_send_msg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, int failure) { - MRESULT res; - int z = 0; - - while((int)(res = WinSendMsg(hwnd, msg, mp1, mp2)) == failure) - { - z++; - if(z > 5000000) - return (MRESULT)failure; - dw_main_sleep(1); - } - return res; + MRESULT res; + int z = 0; + + while((int)(res = WinSendMsg(hwnd, msg, mp1, mp2)) == failure) + { + z++; + if(z > 5000000) + return (MRESULT)failure; + dw_main_sleep(1); + } + return res; } /* Used in the slider and percent classes internally */ unsigned int _dw_percent_get_range(HWND handle) { - return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0)); + return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0)); } /* Return the entryfield child of a window */ HWND _find_entryfield(HWND handle) { - HENUM henum; - HWND child, entry = 0; - - henum = WinBeginEnumWindows(handle); - while((child = WinGetNextWindow(henum)) != NULLHANDLE) - { - char tmpbuf[100]; - - WinQueryClassName(child, 99, tmpbuf); - - if(strncmp(tmpbuf, "#6", 3)==0) /* Entryfield */ - { - entry = child; - break; - } - } - WinEndEnumWindows(henum); - return entry; + HENUM henum; + HWND child, entry = 0; + + henum = WinBeginEnumWindows(handle); + while((child = WinGetNextWindow(henum)) != NULLHANDLE) + { + char tmpbuf[100]; + + WinQueryClassName(child, 99, (PCH)tmpbuf); + + if(strncmp(tmpbuf, "#6", 3)==0) /* Entryfield */ + { + entry = child; + break; + } + } + WinEndEnumWindows(henum); + return entry; } /* This function changes the owner of buttons in to the @@ -288,58 +314,58 @@ */ void _fix_button_owner(HWND handle, HWND dw) { - HENUM henum; - HWND child; - - henum = WinBeginEnumWindows(handle); - while((child = WinGetNextWindow(henum)) != NULLHANDLE) - { - char tmpbuf[100]; - - WinQueryClassName(child, 99, tmpbuf); - - if(strncmp(tmpbuf, "#3", 3)==0 && dw) /* Button */ - WinSetOwner(child, dw); - else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0) - dw = child; - - _fix_button_owner(child, dw); - } - WinEndEnumWindows(henum); - return; + HENUM henum; + HWND child; + + henum = WinBeginEnumWindows(handle); + while((child = WinGetNextWindow(henum)) != NULLHANDLE) + { + char tmpbuf[100]; + + WinQueryClassName(child, 99, (PCH)tmpbuf); + + if(strncmp(tmpbuf, "#3", 3)==0 && dw) /* Button */ + WinSetOwner(child, dw); + else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0) + dw = child; + + _fix_button_owner(child, dw); + } + WinEndEnumWindows(henum); + return; } /* Free bitmap data associated with a window */ void _free_bitmap(HWND handle) { - HBITMAP hbm = (HBITMAP)dw_window_get_data(handle, "_dw_bitmap"); - HPS hps = (HPS)dw_window_get_data(handle, "_dw_hps"); - HDC hdc = (HDC)dw_window_get_data(handle, "_dw_hdc"); - HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap"); - HPIXMAP disable = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap_disabled"); - HPOINTER icon = (HPOINTER)dw_window_get_data(handle, "_dw_button_icon"); - - if(icon) - WinDestroyPointer(icon); - - if(pixmap) - dw_pixmap_destroy(pixmap); - - if(disable) - dw_pixmap_destroy(disable); - - if(hps) - { - GpiSetBitmap(hps, NULLHANDLE); - GpiAssociate(hps, NULLHANDLE); - GpiDestroyPS(hps); - } - - if(hdc) - DevCloseDC(hdc); - - if(hbm) - GpiDeleteBitmap(hbm); + HBITMAP hbm = (HBITMAP)dw_window_get_data(handle, "_dw_bitmap"); + HPS hps = (HPS)dw_window_get_data(handle, "_dw_hps"); + HDC hdc = (HDC)dw_window_get_data(handle, "_dw_hdc"); + HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap"); + HPIXMAP disable = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap_disabled"); + HPOINTER icon = (HPOINTER)dw_window_get_data(handle, "_dw_button_icon"); + + if(icon) + WinDestroyPointer(icon); + + if(pixmap) + dw_pixmap_destroy(pixmap); + + if(disable) + dw_pixmap_destroy(disable); + + if(hps) + { + GpiSetBitmap(hps, NULLHANDLE); + GpiAssociate(hps, NULLHANDLE); + GpiDestroyPS(hps); + } + + if(hdc) + DevCloseDC(hdc); + + if(hbm) + GpiDeleteBitmap(hbm); } /* This function removes any handlers on windows and frees @@ -347,100 +373,116 @@ */ void _free_window_memory(HWND handle) { - HENUM henum; - HWND child; - void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER); - - dw_signal_disconnect_by_window(handle); - - if((child = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE) - _free_menu_data(child); - - if((child = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE) - { - Box *box = (Box *)WinQueryWindowPtr(child, QWP_USER); - - if(box) - { - if(box->count && box->items) - free(box->items); - - WinSetWindowPtr(child, QWP_USER, 0); - free(box); - } - } - - if(ptr) - { - WindowData *wd = (WindowData *)ptr; - char tmpbuf[100]; - - WinQueryClassName(handle, 99, tmpbuf); - - if(strncmp(tmpbuf, "ColorSelectClass", 17)!=0) - { - /* If this window has an associate bitmap destroy it. */ - _free_bitmap(handle); - - if(strncmp(tmpbuf, "#1", 3)==0 && !WinWindowFromID(handle, FID_CLIENT)) - { - Box *box = (Box *)ptr; - - if(box->count && box->items) - free(box->items); - } - else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) - { - void *data = dw_window_get_data(handle, "_dw_percent"); - - if(data) - free(data); - } - else if(strncmp(tmpbuf, "#37", 4)==0) - { - dw_container_clear(handle, FALSE); - if(wd && dw_window_get_data(handle, "_dw_container")) - { - void *oldflags = wd->data; - - wd->data = NULL; - free(oldflags); - } - } - - if(wd->oldproc) - WinSubclassWindow(handle, wd->oldproc); - - dw_window_set_data(handle, NULL, NULL); - WinSetWindowPtr(handle, QWP_USER, 0); - free(ptr); - } - } - - henum = WinBeginEnumWindows(handle); - while((child = WinGetNextWindow(henum)) != NULLHANDLE) - _free_window_memory(child); - - WinEndEnumWindows(henum); - return; + HENUM henum; + HWND child; + void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER); + + dw_signal_disconnect_by_window(handle); + + if((child = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE) + _free_menu_data(child); + + if((child = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE) + { + Box *box = (Box *)WinQueryWindowPtr(child, QWP_USER); + + if(box && !dw_window_get_data(handle, "_dw_box")) + { + if(box->count && box->items) + free(box->items); + + WinSetWindowPtr(child, QWP_USER, 0); + free(box); + } + } + + if(ptr) + { + WindowData *wd = (WindowData *)ptr; + char tmpbuf[100]; + + WinQueryClassName(handle, 99, (PCH)tmpbuf); + + if(strncmp(tmpbuf, "ColorSelectClass", 17)!=0) + { + /* If this window has an associate bitmap destroy it. */ + _free_bitmap(handle); + + if(strncmp(tmpbuf, "#1", 3)==0 && !WinWindowFromID(handle, FID_CLIENT)) + { + Box *box = (Box *)ptr; + + if(box->count && box->items) + free(box->items); + } + else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) + { + void *data = dw_window_get_data(handle, "_dw_percent"); + + if(data) + free(data); + } + else if(strncmp(tmpbuf, "#37", 4)==0) + { + dw_container_clear(handle, FALSE); + if(wd && dw_window_get_data(handle, "_dw_container")) + { + void *oldflags = wd->data; + + wd->data = NULL; + free(oldflags); + } + } + + if(wd->oldproc) + WinSubclassWindow(handle, wd->oldproc); + + dw_window_set_data(handle, NULL, NULL); + WinSetWindowPtr(handle, QWP_USER, 0); + free(ptr); + } + } + + henum = WinBeginEnumWindows(handle); + while((child = WinGetNextWindow(henum)) != NULLHANDLE) + _free_window_memory(child); + + WinEndEnumWindows(henum); + return; } void _free_menu_data(HWND menu) { - int i, count = (int)WinSendMsg(menu, MM_QUERYITEMCOUNT, 0, 0); - - dw_signal_disconnect_by_name(menu, DW_SIGNAL_CLICKED); - _free_window_memory(menu); - - for(i=0;i<count;i++) - { - SHORT menuid = (SHORT)WinSendMsg(menu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0); - MENUITEM mi; - - if(WinSendMsg(menu, MM_QUERYITEM, MPFROMSHORT(menuid), MPFROMP(&mi)) - && mi.hwndSubMenu) - _free_menu_data(mi.hwndSubMenu); - } + int i, count = (int)WinSendMsg(menu, MM_QUERYITEMCOUNT, 0, 0); + + dw_signal_disconnect_by_name(menu, DW_SIGNAL_CLICKED); + _free_window_memory(menu); + + for(i=0;i<count;i++) + { + SHORT menuid = (SHORT)(LONG)WinSendMsg(menu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0); + MENUITEM mi; + + /* Free the data associated with the ID */ + if(menuid >= 30000) + { + char buffer[31] = {0}; + + sprintf(buffer, "_dw_id%d", menuid); + dw_window_set_data( hwndApp, buffer, NULL ); + sprintf(buffer, "_dw_checkable%d", menuid); + dw_window_set_data( hwndApp, buffer, NULL ); + sprintf(buffer, "_dw_ischecked%d", menuid); + dw_window_set_data( hwndApp, buffer, NULL ); + sprintf(buffer, "_dw_isdisabled%d", menuid); + dw_window_set_data( hwndApp, buffer, NULL ); + } + + /* Check any submenus */ + if(WinSendMsg(menu, MM_QUERYITEM, MPFROMSHORT(menuid), MPFROMP(&mi)) + && mi.hwndSubMenu) + _free_menu_data(mi.hwndSubMenu); + } } /* This function returns 1 if the window (widget) handle @@ -448,274 +490,300 @@ */ int _validate_focus(HWND handle) { - char tmpbuf[100]; - - if(!handle) - return 0; - - WinQueryClassName(handle, 99, tmpbuf); - - if(!WinIsWindowEnabled(handle) || - (strncmp(tmpbuf, "ColorSelectClass", 17) && dw_window_get_data(handle, "_dw_disabled"))) - return 0; - - /* These are the window classes which can - * obtain input focus. - */ - if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */ - strncmp(tmpbuf, "#3", 3)==0 || /* Button */ - strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */ - strncmp(tmpbuf, "#7", 3)==0 || /* List box */ - strncmp(tmpbuf, "#10", 4)==0 || /* MLE */ - strncmp(tmpbuf, "#32", 4)==0 || /* Spinbutton */ - strncmp(tmpbuf, "#37", 4)==0 || /* Container */ - strncmp(tmpbuf, "#38", 4)== 0) /* Slider */ - return 1; - return 0; + char tmpbuf[100]; + + if(!handle) + return 0; + + WinQueryClassName(handle, 99, (PCH)tmpbuf); + + if(!WinIsWindowEnabled(handle) || + (strncmp(tmpbuf, "ColorSelectClass", 17) && dw_window_get_data(handle, "_dw_disabled"))) + return 0; + + /* These are the window classes which can + * obtain input focus. + */ + if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */ + strncmp(tmpbuf, "#3", 3)==0 || /* Button */ + strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */ + strncmp(tmpbuf, "#7", 3)==0 || /* List box */ + strncmp(tmpbuf, "#10", 4)==0 || /* MLE */ + strncmp(tmpbuf, "#32", 4)==0 || /* Spinbutton */ + strncmp(tmpbuf, "#37", 4)==0 || /* Container */ + strncmp(tmpbuf, "#38", 4)== 0) /* Slider */ + return 1; + return 0; } int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem) { - int z; - static HWND lasthwnd, firsthwnd; - static int finish_searching; - - /* Start is 2 when we have cycled completely and - * need to set the focus to the last widget we found - * that was valid. - */ - if(start == 2) - { - if(lasthwnd) - WinSetFocus(HWND_DESKTOP, lasthwnd); - return 0; - } - - /* Start is 1 when we are entering the function - * for the first time, it is zero when entering - * the function recursively. - */ - if(start == 1) - { - lasthwnd = handle; - finish_searching = 0; - firsthwnd = 0; - } - - for(z=box->count-1;z>-1;z--) - { - if(box->items[z].type == TYPEBOX) - { - Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER); - - if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) - return 1; - } - else - { - if(box->items[z].hwnd == handle) - { - if(lasthwnd == handle && firsthwnd) - WinSetFocus(HWND_DESKTOP, firsthwnd); - else if(lasthwnd == handle && !firsthwnd) - finish_searching = 1; - else - WinSetFocus(HWND_DESKTOP, lasthwnd); - - /* If we aren't looking for the last handle, - * return immediately. - */ - if(!finish_searching) - return 1; - } - if(_validate_focus(box->items[z].hwnd)) - { - /* Start is 3 when we are looking for the - * first valid item in the layout. - */ - if(start == 3) - { - if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd)) - { - WinSetFocus(HWND_DESKTOP, box->items[z].hwnd); - return 1; - } - } - - if(!firsthwnd) - firsthwnd = box->items[z].hwnd; - - lasthwnd = box->items[z].hwnd; - } - else - { - char tmpbuf[100] = ""; - - WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); - if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) - { - /* Then try the bottom or right box */ - HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright"); - - if(mybox) - { - Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); - - if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem)) - return 1; - } - - /* Try the top or left box */ - mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft"); - - if(mybox) - { - Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); - - if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem)) - return 1; - } - } - else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */ - { - Box *notebox; - HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, - (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0); - - if(page) - { - notebox = (Box *)WinQueryWindowPtr(page, QWP_USER); - - if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem)) - return 1; - } - } - } - } - } - return 0; + int z; + static HWND lasthwnd, firsthwnd; + static int finish_searching; + + /* Start is 2 when we have cycled completely and + * need to set the focus to the last widget we found + * that was valid. + */ + if(start == 2) + { + if(lasthwnd) + WinSetFocus(HWND_DESKTOP, lasthwnd); + return 0; + } + + /* Start is 1 when we are entering the function + * for the first time, it is zero when entering + * the function recursively. + */ + if(start == 1) + { + lasthwnd = handle; + finish_searching = 0; + firsthwnd = 0; + } + + for(z=box->count-1;z>-1;z--) + { + if(box->items[z].type == TYPEBOX) + { + Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER); + + if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + else + { + if(box->items[z].hwnd == handle) + { + if(lasthwnd == handle && firsthwnd) + WinSetFocus(HWND_DESKTOP, firsthwnd); + else if(lasthwnd == handle && !firsthwnd) + finish_searching = 1; + else + WinSetFocus(HWND_DESKTOP, lasthwnd); + + /* If we aren't looking for the last handle, + * return immediately. + */ + if(!finish_searching) + return 1; + } + if(_validate_focus(box->items[z].hwnd)) + { + /* Start is 3 when we are looking for the + * first valid item in the layout. + */ + if(start == 3) + { + if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd)) + { + WinSetFocus(HWND_DESKTOP, box->items[z].hwnd); + return 1; + } + } + + if(!firsthwnd) + firsthwnd = box->items[z].hwnd; + + lasthwnd = box->items[z].hwnd; + } + else + { + char tmpbuf[100] = ""; + + WinQueryClassName(box->items[z].hwnd, 99, (PCH)tmpbuf); + if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) + { + /* Then try the bottom or right box */ + HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright"); + + if(mybox) + { + Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); + + if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + + /* Try the top or left box */ + mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft"); + + if(mybox) + { + Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); + + if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + } + else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */ + { + Box *notebox; + HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, + (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0); + + if(page) + { + notebox = (Box *)WinQueryWindowPtr(page, QWP_USER); + + if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + } + else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0) /* Scrollbox */ + { + /* Get the box window handle */ + HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_box"); + + if(mybox) + { + Box *scrollbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); + + if(scrollbox && _focus_check_box(scrollbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + } + } + } + } + return 0; } int _focus_check_box_back(Box *box, HWND handle, int start, HWND defaultitem) { - int z; - static HWND lasthwnd, firsthwnd; + int z; + static HWND lasthwnd, firsthwnd; static int finish_searching; - /* Start is 2 when we have cycled completely and - * need to set the focus to the last widget we found - * that was valid. - */ - if(start == 2) - { - if(lasthwnd) - WinSetFocus(HWND_DESKTOP, lasthwnd); - return 0; - } - - /* Start is 1 when we are entering the function - * for the first time, it is zero when entering - * the function recursively. - */ - if(start == 1) - { - lasthwnd = handle; - finish_searching = 0; - firsthwnd = 0; - } - - for(z=0;z<box->count;z++) - { - if(box->items[z].type == TYPEBOX) - { - Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER); - - if(thisbox && _focus_check_box_back(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) - return 1; - } - else - { - if(box->items[z].hwnd == handle) - { - if(lasthwnd == handle && firsthwnd) - WinSetFocus(HWND_DESKTOP, firsthwnd); - else if(lasthwnd == handle && !firsthwnd) - finish_searching = 1; - else - WinSetFocus(HWND_DESKTOP, lasthwnd); - - /* If we aren't looking for the last handle, - * return immediately. - */ - if(!finish_searching) - return 1; - } - if(_validate_focus(box->items[z].hwnd)) - { - /* Start is 3 when we are looking for the - * first valid item in the layout. - */ - if(start == 3) - { - if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd)) - { - WinSetFocus(HWND_DESKTOP, box->items[z].hwnd); - return 1; - } - } - - if(!firsthwnd) - firsthwnd = box->items[z].hwnd; - - lasthwnd = box->items[z].hwnd; - } - else - { - char tmpbuf[100] = ""; - - WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); - if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) - { - /* Try the top or left box */ - HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft"); - - if(mybox) - { - Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); - - if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem)) - return 1; - } - - /* Then try the bottom or right box */ - mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright"); - - if(mybox) - { - Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); - - if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem)) - return 1; - } - } - else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */ - { - Box *notebox; - HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, - (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0); - - if(page) - { - notebox = (Box *)WinQueryWindowPtr(page, QWP_USER); - - if(notebox && _focus_check_box_back(notebox, handle, start == 3 ? 3 : 0, defaultitem)) - return 1; - } - } - } - } - } - return 0; + /* Start is 2 when we have cycled completely and + * need to set the focus to the last widget we found + * that was valid. + */ + if(start == 2) + { + if(lasthwnd) + WinSetFocus(HWND_DESKTOP, lasthwnd); + return 0; + } + + /* Start is 1 when we are entering the function + * for the first time, it is zero when entering + * the function recursively. + */ + if(start == 1) + { + lasthwnd = handle; + finish_searching = 0; + firsthwnd = 0; + } + + for(z=0;z<box->count;z++) + { + if(box->items[z].type == TYPEBOX) + { + Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER); + + if(thisbox && _focus_check_box_back(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + else + { + if(box->items[z].hwnd == handle) + { + if(lasthwnd == handle && firsthwnd) + WinSetFocus(HWND_DESKTOP, firsthwnd); + else if(lasthwnd == handle && !firsthwnd) + finish_searching = 1; + else + WinSetFocus(HWND_DESKTOP, lasthwnd); + + /* If we aren't looking for the last handle, + * return immediately. + */ + if(!finish_searching) + return 1; + } + if(_validate_focus(box->items[z].hwnd)) + { + /* Start is 3 when we are looking for the + * first valid item in the layout. + */ + if(start == 3) + { + if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd)) + { + WinSetFocus(HWND_DESKTOP, box->items[z].hwnd); + return 1; + } + } + + if(!firsthwnd) + firsthwnd = box->items[z].hwnd; + + lasthwnd = box->items[z].hwnd; + } + else + { + char tmpbuf[100] = ""; + + WinQueryClassName(box->items[z].hwnd, 99, (PCH)tmpbuf); + if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) + { + /* Try the top or left box */ + HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft"); + + if(mybox) + { + Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); + + if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + + /* Then try the bottom or right box */ + mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright"); + + if(mybox) + { + Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); + + if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + } + else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */ + { + Box *notebox; + HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, + (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0); + + if(page) + { + notebox = (Box *)WinQueryWindowPtr(page, QWP_USER); + + if(notebox && _focus_check_box_back(notebox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + } + else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0) /* Scrollbox */ + { + /* Get the box window handle */ + HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_box"); + + if(mybox) + { + Box *scrollbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER); + + if(scrollbox && _focus_check_box_back(scrollbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + } + } + } + } + return 0; } /* This function finds the first widget in the @@ -723,18 +791,18 @@ */ int _initial_focus(HWND handle) { - Box *thisbox = NULL; - HWND box; - - box = WinWindowFromID(handle, FID_CLIENT); - if(box) - thisbox = WinQueryWindowPtr(box, QWP_USER); - else - return 1; - - if(thisbox) - _focus_check_box(thisbox, handle, 3, thisbox->defaultitem); - return 0; + Box *thisbox = NULL; + HWND box; + + box = WinWindowFromID(handle, FID_CLIENT); + if(box) + thisbox = WinQueryWindowPtr(box, QWP_USER); + else + return 1; + + if(thisbox) + _focus_check_box(thisbox, handle, 3, thisbox->defaultitem); + return 0; } /* This function finds the current widget in the @@ -742,20 +810,20 @@ */ void _shift_focus(HWND handle) { - Box *thisbox; - HWND box, lastbox = _toplevel_window(handle); - - box = WinWindowFromID(lastbox, FID_CLIENT); - if(box) - thisbox = WinQueryWindowPtr(box, QWP_USER); - else - thisbox = WinQueryWindowPtr(lastbox, QWP_USER); - - if(thisbox) - { - if(_focus_check_box(thisbox, handle, 1, 0) == 0) - _focus_check_box(thisbox, handle, 2, 0); - } + Box *thisbox; + HWND box, lastbox = _toplevel_window(handle); + + box = WinWindowFromID(lastbox, FID_CLIENT); + if(box) + thisbox = WinQueryWindowPtr(box, QWP_USER); + else + thisbox = WinQueryWindowPtr(lastbox, QWP_USER); + + if(thisbox) + { + if(_focus_check_box(thisbox, handle, 1, 0) == 0) + _focus_check_box(thisbox, handle, 2, 0); + } } /* This function finds the current widget in the @@ -763,80 +831,80 @@ */ void _shift_focus_back(HWND handle) { - Box *thisbox; - HWND box, lastbox = _toplevel_window(handle); - - box = WinWindowFromID(lastbox, FID_CLIENT); - if(box) - thisbox = WinQueryWindowPtr(box, QWP_USER); - else - thisbox = WinQueryWindowPtr(lastbox, QWP_USER); - - if(thisbox) - { - if(_focus_check_box_back(thisbox, handle, 1, 0) == 0) - _focus_check_box_back(thisbox, handle, 2, 0); - } + Box *thisbox; + HWND box, lastbox = _toplevel_window(handle); + + box = WinWindowFromID(lastbox, FID_CLIENT); + if(box) + thisbox = WinQueryWindowPtr(box, QWP_USER); + else + thisbox = WinQueryWindowPtr(lastbox, QWP_USER); + + if(thisbox) + { + if(_focus_check_box_back(thisbox, handle, 1, 0) == 0) + _focus_check_box_back(thisbox, handle, 2, 0); + } } /* This function will recursively search a box and add up the total height of it */ void _count_size(HWND box, int type, int *xsize, int *xorigsize) { - int size = 0, origsize = 0, z; - Box *tmp = WinQueryWindowPtr(box, QWP_USER); - - if(!tmp) - { - *xsize = *xorigsize = 0; - return; - } - - if(type == tmp->type) - { - /* If the box is going in the direction we want, then we - * return the entire sum of the items. - */ - for(z=0;z<tmp->count;z++) - { - if(tmp->items[z].type == TYPEBOX) - { - int s, os; - - _count_size(tmp->items[z].hwnd, type, &s, &os); - size += s; - origsize += os; - } - else - { - size += (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height); - origsize += (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight); - } - } - } - else - { - /* If the box is not going in the direction we want, then we only - * want to return the maximum value. - */ - int tmpsize = 0, tmporigsize = 0; - - for(z=0;z<tmp->count;z++) - { - if(tmp->items[z].type == TYPEBOX) - _count_size(tmp->items[z].hwnd, type, &tmpsize, &tmporigsize); - else - { - tmpsize = (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height); - tmporigsize = (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight); - } - - if(tmpsize > size) - size = tmpsize; - } - } - - *xsize = size; - *xorigsize = origsize; + int size = 0, origsize = 0, z; + Box *tmp = WinQueryWindowPtr(box, QWP_USER); + + if(!tmp) + { + *xsize = *xorigsize = 0; + return; + } + + if(type == tmp->type) + { + /* If the box is going in the direction we want, then we + * return the entire sum of the items. + */ + for(z=0;z<tmp->count;z++) + { + if(tmp->items[z].type == TYPEBOX) + { + int s, os; + + _count_size(tmp->items[z].hwnd, type, &s, &os); + size += s; + origsize += os; + } + else + { + size += (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height); + origsize += (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight); + } + } + } + else + { + /* If the box is not going in the direction we want, then we only + * want to return the maximum value. + */ + int tmpsize = 0, tmporigsize = 0; + + for(z=0;z<tmp->count;z++) + { + if(tmp->items[z].type == TYPEBOX) + _count_size(tmp->items[z].hwnd, type, &tmpsize, &tmporigsize); + else + { + tmpsize = (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height); + tmporigsize = (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight); + } + + if(tmpsize > size) + size = tmpsize; + } + } + + *xsize = size; + *xorigsize = origsize; } @@ -850,1032 +918,1454 @@ BOOL _TrackRectangle(HWND hwndBase, RECTL* rclTrack, RECTL* rclBounds) { - TRACKINFO track; - APIRET rc; - - track.cxBorder = 1; - track.cyBorder = 1; - track.cxGrid = 1; - track.cyGrid = 1; - track.cxKeyboard = 8; - track.cyKeyboard = 8; - - if(!rclTrack) - return FALSE; - - if(rclBounds) - { - track.rclBoundary = *rclBounds; - } - else - { - track.rclBoundary.yTop = - track.rclBoundary.xRight = 3000; - track.rclBoundary.yBottom = - track.rclBoundary.xLeft = -3000; - } - - track.rclTrack = *rclTrack; - - WinMapWindowPoints(hwndBase, - HWND_DESKTOP, - (PPOINTL)&track.rclTrack, - 2); - - track.ptlMinTrackSize.x = track.rclTrack.xRight - - track.rclTrack.xLeft; - track.ptlMinTrackSize.y = track.rclTrack.yTop - - track.rclTrack.yBottom; - track.ptlMaxTrackSize.x = track.rclTrack.xRight - - track.rclTrack.xLeft; - track.ptlMaxTrackSize.y = track.rclTrack.yTop - - track.rclTrack.yBottom; - - track.fs = TF_MOVE | TF_ALLINBOUNDARY; - - rc = WinTrackRect(HWND_DESKTOP, 0, &track); - - if(rc) - *rclTrack = track.rclTrack; - - return rc; + TRACKINFO track; + APIRET rc; + + track.cxBorder = 1; + track.cyBorder = 1; + track.cxGrid = 1; + track.cyGrid = 1; + track.cxKeyboard = 8; + track.cyKeyboard = 8; + + if(!rclTrack) + return FALSE; + + if(rclBounds) + { + track.rclBoundary = *rclBounds; + } + else + { + track.rclBoundary.yTop = + track.rclBoundary.xRight = 3000; + track.rclBoundary.yBottom = + track.rclBoundary.xLeft = -3000; + } + + track.rclTrack = *rclTrack; + + WinMapWindowPoints(hwndBase, + HWND_DESKTOP, + (PPOINTL)&track.rclTrack, + 2); + + track.ptlMinTrackSize.x = track.rclTrack.xRight + - track.rclTrack.xLeft; + track.ptlMinTrackSize.y = track.rclTrack.yTop + - track.rclTrack.yBottom; + track.ptlMaxTrackSize.x = track.rclTrack.xRight + - track.rclTrack.xLeft; + track.ptlMaxTrackSize.y = track.rclTrack.yTop + - track.rclTrack.yBottom; + + track.fs = TF_MOVE | TF_ALLINBOUNDARY; + + rc = WinTrackRect(HWND_DESKTOP, 0, &track); + + if(rc) + *rclTrack = track.rclTrack; + + return rc; } void _check_resize_notebook(HWND hwnd) { - char tmpbuf[100]; - - WinQueryClassName(hwnd, 99, tmpbuf); - - /* If we have a notebook we resize the page again. */ - if(strncmp(tmpbuf, "#40", 4)==0) - { - unsigned long x, y, width, height; - ULONG page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, 0, MPFROM2SHORT(BKA_FIRST, BKA_MAJOR)); - - while(page) - { - HWND pagehwnd = (HWND)WinSendMsg(hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0); - RECTL rc; - - Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER); - if(pagebox) - { - dw_window_get_pos_size(hwnd, &x, &y, &width, &height); - - rc.xLeft = x; - rc.yBottom = y; - rc.xRight = x + width; - rc.yTop = y + height; - - WinSendMsg(hwnd, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE); - - _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom); - } - page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, (MPARAM)page, MPFROM2SHORT(BKA_NEXT, BKA_MAJOR)); - } - - } + char tmpbuf[100]; + + WinQueryClassName(hwnd, 99, (PCH)tmpbuf); + + /* If we have a notebook we resize the page again. */ + if(strncmp(tmpbuf, "#40", 4)==0) + { + long x, y; + unsigned long width, height; + ULONG page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, 0, MPFROM2SHORT(BKA_FIRST, BKA_MAJOR)); + + while(page) + { + HWND pagehwnd = (HWND)WinSendMsg(hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0); + RECTL rc; + + Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER); + if(pagebox) + { + dw_window_get_pos_size(hwnd, &x, &y, &width, &height); + + rc.xLeft = x; + rc.yBottom = y; + rc.xRight = x + width; + rc.yTop = y + height; + + WinSendMsg(hwnd, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE); + + _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom); + } + page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, (MPARAM)page, MPFROM2SHORT(BKA_NEXT, BKA_MAJOR)); + } + + } } /* Return the OS/2 color from the DW color */ unsigned long _internal_color(unsigned long color) { - if(color < 16) - return _colors[color]; - return color; + if(color < 16) + return _colors[color]; + return color; } unsigned long _os2_color(unsigned long color) { - return DW_RED_VALUE(color) << 16 | DW_GREEN_VALUE(color) << 8 | DW_BLUE_VALUE(color); + return DW_RED_VALUE(color) << 16 | DW_GREEN_VALUE(color) << 8 | DW_BLUE_VALUE(color); } BOOL _MySetWindowPos(HWND hwnd, HWND parent, HWND behind, LONG x, LONG y, LONG cx, LONG cy, ULONG fl) { - int height = _get_height(parent); - - return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl); -} + int height = _get_height(parent); + + return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl); +} + +#define _DW_DEFAULT_SCROLLBAR_WIDTH 16 /* This function calculates how much space the widgets and boxes require * and does expansion as necessary. */ int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy, - int pass, int *usedpadx, int *usedpady) -{ - int z, currentx = 0, currenty = 0; - int uymax = 0, uxmax = 0; - int upymax = 0, upxmax = 0; - /* Used for the SIZEEXPAND */ - int nux = *usedx, nuy = *usedy; - int nupx = *usedpadx, nupy = *usedpady; - - (*usedx) += (thisbox->pad * 2); - (*usedy) += (thisbox->pad * 2); - - if(thisbox->grouphwnd) - { - char *text = dw_window_get_text(thisbox->grouphwnd); - - thisbox->grouppady = 0; - - if(text) - { - dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady); - dw_free(text); - } - - if(thisbox->grouppady) - thisbox->grouppady += 3; - else - thisbox->grouppady = 6; - - thisbox->grouppadx = 6; - - (*usedx) += thisbox->grouppadx; - (*usedpadx) += thisbox->grouppadx; - (*usedy) += thisbox->grouppady; - (*usedpady) += thisbox->grouppady; - } - - for(z=0;z<thisbox->count;z++) - { - if(thisbox->items[z].type == TYPEBOX) - { - int initialx, initialy; - Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); - - initialx = x - (*usedx); - initialy = y - (*usedy); - - if(tmp) - { - int newx, newy; - int nux = *usedx, nuy = *usedy; - int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2); - - /* On the second pass we know how big the box needs to be and how - * much space we have, so we can calculate a ratio for the new box. - */ - if(pass == 2) - { - int deep = *depth + 1; - - _resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy); - - tmp->upx = upx - *usedpadx; - tmp->upy = upy - *usedpady; - - newx = x - nux; - newy = y - nuy; - - tmp->width = thisbox->items[z].width = initialx - newx; - tmp->height = thisbox->items[z].height = initialy - newy; - - tmp->parentxratio = thisbox->xratio; - tmp->parentyratio = thisbox->yratio; - - tmp->parentpad = tmp->pad; - - /* Just in case */ - tmp->xratio = thisbox->xratio; - tmp->yratio = thisbox->yratio; - - if(thisbox->type == DW_VERT) - { - int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady; - - if((thisbox->items[z].width - tmppad)!=0) - tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad)); - } - else - { - if((thisbox->items[z].width-tmp->upx)!=0) - tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx)); - } - if(thisbox->type == DW_HORZ) - { - int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx; - - if((thisbox->items[z].height-tmppad)!=0) - tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad)); - } - else - { - if((thisbox->items[z].height-tmp->upy)!=0) - tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy)); - } - - nux = *usedx; nuy = *usedy; - upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2); - } - - (*depth)++; - - _resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy); - - (*depth)--; - - newx = x - nux; - newy = y - nuy; - - tmp->minwidth = thisbox->items[z].width = initialx - newx; - tmp->minheight = thisbox->items[z].height = initialy - newy; - } - } - - if(pass > 1 && *depth > 0) - { - if(thisbox->type == DW_VERT) - { - int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx; - - if((thisbox->minwidth-tmppad) == 0) - thisbox->items[z].xratio = 1.0; - else - thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad)); - } - else - { - if(thisbox->minwidth-thisbox->upx == 0) - thisbox->items[z].xratio = 1.0; - else - thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx)); - } - - if(thisbox->type == DW_HORZ) - { - int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady; - - if((thisbox->minheight-tmppad) == 0) - thisbox->items[z].yratio = 1.0; - else - thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad)); - } - else - { - if(thisbox->minheight-thisbox->upy == 0) - thisbox->items[z].yratio = 1.0; - else - thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy)); - } - - if(thisbox->items[z].type == TYPEBOX) - { - Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); - - if(tmp) - { - tmp->parentxratio = thisbox->items[z].xratio; - tmp->parentyratio = thisbox->items[z].yratio; - } - } - } - else - { - thisbox->items[z].xratio = thisbox->xratio; - thisbox->items[z].yratio = thisbox->yratio; - } - - if(thisbox->type == DW_VERT) - { - int itemwidth = thisbox->items[z].width + (thisbox->items[z].pad*2); - - if(itemwidth > uxmax) - uxmax = itemwidth; - if(thisbox->items[z].hsize != SIZEEXPAND) - { - if(itemwidth > upxmax) - upxmax = itemwidth; - } - else - { - if(thisbox->items[z].pad*2 > upxmax) - upxmax = thisbox->items[z].pad*2; - } - } - else - { - if(thisbox->items[z].width == -1) - { - /* figure out how much space this item requires */ - /* thisbox->items[z].width = */ - } - else - { - (*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2); - if(thisbox->items[z].hsize != SIZEEXPAND) - (*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width; - else - (*usedpadx) += thisbox->items[z].pad*2; - } - } - if(thisbox->type == DW_HORZ) - { - int itemheight = thisbox->items[z].height + (thisbox->items[z].pad*2); - - if(itemheight > uymax) - uymax = itemheight; - if(thisbox->items[z].vsize != SIZEEXPAND) - { - if(itemheight > upymax) - upymax = itemheight; - } - else - { - if(thisbox->items[z].pad*2 > upymax) - upymax = thisbox->items[z].pad*2; - } - } - else - { - if(thisbox->items[z].height == -1) - { - /* figure out how much space this item requires */ - /* thisbox->items[z].height = */ - } - else - { - (*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2); - if(thisbox->items[z].vsize != SIZEEXPAND) - (*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height; - else - (*usedpady) += thisbox->items[z].pad*2; - } - } - } - - (*usedx) += uxmax; - (*usedy) += uymax; - (*usedpadx) += upxmax; - (*usedpady) += upymax; - - currentx += thisbox->pad; - currenty += thisbox->pad; - - if(thisbox->grouphwnd) - { - currentx += 3; - currenty += thisbox->grouppady - 3; - } - - /* The second pass is for expansion and actual placement. */ - if(pass > 1) - { - /* Any SIZEEXPAND items should be set to uxmax/uymax */ - for(z=0;z<thisbox->count;z++) - { - if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT) - thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2); - if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ) - thisbox->items[z].height = uymax-(thisbox->items[z].pad*2); - /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */ - if(thisbox->items[z].type == TYPEBOX) - { - Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); - - if(tmp) - { - if(*depth > 0) - { - float calcval; - - if(thisbox->type == DW_VERT) - { - calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2))); - if(calcval == 0.0) - tmp->xratio = thisbox->xratio; - else - tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval; - tmp->width = thisbox->items[z].width; - } - if(thisbox->type == DW_HORZ) - { - calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2))); - if(calcval == 0.0) - tmp->yratio = thisbox->yratio; - else - tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval; - tmp->height = thisbox->items[z].height; - } - } - - (*depth)++; - - _resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy); - - (*depth)--; - - } - } - } - - for(z=0;z<(thisbox->count);z++) - { - int height = thisbox->items[z].height; - int width = thisbox->items[z].width; - int pad = thisbox->items[z].pad; - HWND handle = thisbox->items[z].hwnd; - int vectorx, vectory; - - /* When upxmax != pad*2 then ratios are incorrect. */ - vectorx = (int)((width*thisbox->items[z].xratio)-width); - vectory = (int)((height*thisbox->items[z].yratio)-height); - - if(width > 0 && height > 0) - { - char tmpbuf[100]; - /* This is a hack to fix rounding of the sizing */ - if(*depth == 0) - { - vectorx++; - vectory++; - } - - /* If this item isn't going to expand... reset the vectors to 0 */ - if(thisbox->items[z].vsize != SIZEEXPAND) - vectory = 0; - if(thisbox->items[z].hsize != SIZEEXPAND) - vectorx = 0; - - WinQueryClassName(handle, 99, tmpbuf); - - if(strncmp(tmpbuf, "#2", 3)==0) - { - HWND frame = (HWND)dw_window_get_data(handle, "_dw_combo_box"); - /* Make the combobox big enough to drop down. :) */ - WinSetWindowPos(handle, HWND_TOP, 0, -100, - width + vectorx, (height + vectory) + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER); - _MySetWindowPos(frame, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, - width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); - } - else if(strncmp(tmpbuf, "#6", 3)==0) - { - /* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */ - _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3, - (width + vectorx) - 6, (height + vectory) - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER); - } - else if(strncmp(tmpbuf, "#40", 5)==0) - { - _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, - width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); - _check_resize_notebook(handle); - } - else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) - { - /* Then try the bottom or right box */ - float *percent = (float *)dw_window_get_data(handle, "_dw_percent"); - int type = (int)dw_window_get_data(handle, "_dw_type"); - int cx = width + vectorx; - int cy = height + vectory; - - _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, - cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER); - - if(cx > 0 && cy > 0 && percent) - _handle_splitbar_resize(handle, *percent, type, cx, cy); - } - else - { - _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, - width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); - if(thisbox->items[z].type == TYPEBOX) - { - Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER); - - if(boxinfo && boxinfo->grouphwnd) - WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0, - width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE); - - } - - } - - if(thisbox->type == DW_HORZ) - currentx += width + vectorx + (pad * 2); - if(thisbox->type == DW_VERT) - currenty += height + vectory + (pad * 2); - } - } - } - return 0; + int pass, int *usedpadx, int *usedpady) +{ + int z, currentx = 0, currenty = 0; + int uymax = 0, uxmax = 0; + int upymax = 0, upxmax = 0; + /* Used for the SIZEEXPAND */ + int nux = *usedx, nuy = *usedy; + int nupx = *usedpadx, nupy = *usedpady; + + (*usedx) += (thisbox->pad * 2); + (*usedy) += (thisbox->pad * 2); + + if(thisbox->grouphwnd) + { + char *text = dw_window_get_text(thisbox->grouphwnd); + + thisbox->grouppady = 0; + + if(text) + { + dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady); + dw_free(text); + } + + if(thisbox->grouppady) + thisbox->grouppady += 3; + else + thisbox->grouppady = 6; + + thisbox->grouppadx = 6; + + (*usedx) += thisbox->grouppadx; + (*usedpadx) += thisbox->grouppadx; + (*usedy) += thisbox->grouppady; + (*usedpady) += thisbox->grouppady; + } + + for(z=0;z<thisbox->count;z++) + { + if(thisbox->items[z].type == TYPEBOX) + { + int initialx, initialy; + Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); + + initialx = x - (*usedx); + initialy = y - (*usedy); + + if(tmp) + { + int newx, newy; + int nux = *usedx, nuy = *usedy; + int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2); + + /* On the second pass we know how big the box needs to be and how + * much space we have, so we can calculate a ratio for the new box. + */ + if(pass == 2) + { + int deep = *depth + 1; + + _resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy); + + tmp->upx = upx - *usedpadx; + tmp->upy = upy - *usedpady; + + newx = x - nux; + newy = y - nuy; + + tmp->width = thisbox->items[z].width = initialx - newx; + tmp->height = thisbox->items[z].height = initialy - newy; + + tmp->parentxratio = thisbox->xratio; + tmp->parentyratio = thisbox->yratio; + + tmp->parentpad = tmp->pad; + + /* Just in case */ + tmp->xratio = thisbox->xratio; + tmp->yratio = thisbox->yratio; + + if(thisbox->type == DW_VERT) + { + int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady; + + if((thisbox->items[z].width - tmppad)!=0) + tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad)); + } + else + { + if((thisbox->items[z].width-tmp->upx)!=0) + tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx)); + } + if(thisbox->type == DW_HORZ) + { + int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx; + + if((thisbox->items[z].height-tmppad)!=0) + tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad)); + } + else + { + if((thisbox->items[z].height-tmp->upy)!=0) + tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy)); + } + + nux = *usedx; nuy = *usedy; + upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2); + } + + (*depth)++; + + _resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy); + + (*depth)--; + + newx = x - nux; + newy = y - nuy; + + tmp->minwidth = thisbox->items[z].width = initialx - newx; + tmp->minheight = thisbox->items[z].height = initialy - newy; + } + } + + if(pass > 1 && *depth > 0) + { + if(thisbox->type == DW_VERT) + { + int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx; + + if((thisbox->minwidth-tmppad) == 0) + thisbox->items[z].xratio = 1.0; + else + thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad)); + } + else + { + if(thisbox->minwidth-thisbox->upx == 0) + thisbox->items[z].xratio = 1.0; + else + thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx)); + } + + if(thisbox->type == DW_HORZ) + { + int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady; + + if((thisbox->minheight-tmppad) == 0) + thisbox->items[z].yratio = 1.0; + else + thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad)); + } + else + { + if(thisbox->minheight-thisbox->upy == 0) + thisbox->items[z].yratio = 1.0; + else + thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy)); + } + + if(thisbox->items[z].type == TYPEBOX) + { + Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); + + if(tmp) + { + tmp->parentxratio = thisbox->items[z].xratio; + tmp->parentyratio = thisbox->items[z].yratio; + } + } + } + else + { + thisbox->items[z].xratio = thisbox->xratio; + thisbox->items[z].yratio = thisbox->yratio; + } + + if(thisbox->type == DW_VERT) + { + int itemwidth = thisbox->items[z].width + (thisbox->items[z].pad*2); + + if(itemwidth > uxmax) + uxmax = itemwidth; + if(thisbox->items[z].hsize != SIZEEXPAND) + { + if(itemwidth > upxmax) + upxmax = itemwidth; + } + else + { + if(thisbox->items[z].pad*2 > upxmax) + upxmax = thisbox->items[z].pad*2; + } + } + else + { + if(thisbox->items[z].width == -1) + { + /* figure out how much space this item requires */ + /* thisbox->items[z].width = */ + } + else + { + (*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2); + if(thisbox->items[z].hsize != SIZEEXPAND) + (*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width; + else + (*usedpadx) += thisbox->items[z].pad*2; + } + } + if(thisbox->type == DW_HORZ) + { + int itemheight = thisbox->items[z].height + (thisbox->items[z].pad*2); + + if(itemheight > uymax) + uymax = itemheight; + if(thisbox->items[z].vsize != SIZEEXPAND) + { + if(itemheight > upymax) + upymax = itemheight; + } + else + { + if(thisbox->items[z].pad*2 > upymax) + upymax = thisbox->items[z].pad*2; + } + } + else + { + if(thisbox->items[z].height == -1) + { + /* figure out how much space this item requires */ + /* thisbox->items[z].height = */ + } + else + { + (*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2); + if(thisbox->items[z].vsize != SIZEEXPAND) + (*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height; + else + (*usedpady) += thisbox->items[z].pad*2; + } + } + } + + (*usedx) += uxmax; + (*usedy) += uymax; + (*usedpadx) += upxmax; + (*usedpady) += upymax; + + currentx += thisbox->pad; + currenty += thisbox->pad; + + if(thisbox->grouphwnd) + { + currentx += 3; + currenty += thisbox->grouppady - 3; + } + + /* The second pass is for expansion and actual placement. */ + if(pass > 1) + { + /* Any SIZEEXPAND items should be set to uxmax/uymax */ + for(z=0;z<thisbox->count;z++) + { + if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT) + thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2); + if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ) + thisbox->items[z].height = uymax-(thisbox->items[z].pad*2); + /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */ + if(thisbox->items[z].type == TYPEBOX) + { + Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); + + if(tmp) + { + if(*depth > 0) + { + float calcval; + + if(thisbox->type == DW_VERT) + { + calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2))); + if(calcval == 0.0) + tmp->xratio = thisbox->xratio; + else + tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval; + tmp->width = thisbox->items[z].width; + } + if(thisbox->type == DW_HORZ) + { + calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2))); + if(calcval == 0.0) + tmp->yratio = thisbox->yratio; + else + tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval; + tmp->height = thisbox->items[z].height; + } + } + + (*depth)++; + + _resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy); + + (*depth)--; + + } + } + } + + for(z=0;z<(thisbox->count);z++) + { + int height = thisbox->items[z].height; + int width = thisbox->items[z].width; + int pad = thisbox->items[z].pad; + HWND handle = thisbox->items[z].hwnd; + int vectorx, vectory; + + /* When upxmax != pad*2 then ratios are incorrect. */ + vectorx = (int)((width*thisbox->items[z].xratio)-width); + vectory = (int)((height*thisbox->items[z].yratio)-height); + + if(width > 0 && height > 0) + { + char tmpbuf[100]; + /* This is a hack to fix rounding of the sizing */ + if(*depth == 0) + { + vectorx++; + vectory++; + } + + /* If this item isn't going to expand... reset the vectors to 0 */ + if(thisbox->items[z].vsize != SIZEEXPAND) + vectory = 0; + if(thisbox->items[z].hsize != SIZEEXPAND) + vectorx = 0; + + WinQueryClassName(handle, 99, (PCH)tmpbuf); + + if(strncmp(tmpbuf, "#2", 3)==0) + { + HWND frame = (HWND)dw_window_get_data(handle, "_dw_combo_box"); + /* Make the combobox big enough to drop down. :) */ + WinSetWindowPos(handle, HWND_TOP, 0, -100, + width + vectorx, (height + vectory) + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + _MySetWindowPos(frame, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, + width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + } + else if(strncmp(tmpbuf, "#6", 3)==0) + { + /* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */ + _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3, + (width + vectorx) - 6, (height + vectory) - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + } + else if(strncmp(tmpbuf, "#40", 5)==0) + { + _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, + width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + _check_resize_notebook(handle); + } + else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0) + { + /* Handle special case of scrollbox */ + int cx = width + vectorx; + int cy = height + vectory; + int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0; + HWND box = (HWND)dw_window_get_data(handle, "_dw_resizebox"); + HWND client = WinWindowFromID(handle, FID_CLIENT); + HWND vscroll = WinWindowFromID(handle, FID_VERTSCROLL); + HWND hscroll = WinWindowFromID(handle, FID_HORZSCROLL); + Box *contentbox = (Box *)WinQueryWindowPtr(box, QWP_USER); + int origx, origy; + unsigned int hpos = (unsigned int)WinSendMsg(hscroll, SBM_QUERYPOS, 0, 0); + unsigned int vpos = (unsigned int)WinSendMsg(vscroll, SBM_QUERYPOS, 0, 0); + + /* Position the scrollbox parts */ + _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + WinSetWindowPos(client, HWND_TOP, 0, _DW_DEFAULT_SCROLLBAR_WIDTH, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + WinSetWindowPos(hscroll, HWND_TOP, 0, 0, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + WinSetWindowPos(vscroll, HWND_TOP, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + + origx = cx = cx - _DW_DEFAULT_SCROLLBAR_WIDTH; + origy = cy = cy - _DW_DEFAULT_SCROLLBAR_WIDTH; + + /* Get the required space for the box */ + _resize_box(contentbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady); + + if(cx < usedx) + { + cx = usedx; + } + if(cy < usedy) + { + cy = usedy; + } + + /* Setup vertical scroller */ + WinSendMsg(vscroll, SBM_SETSCROLLBAR, (MPARAM)vpos, MPFROM2SHORT(0, (unsigned short)usedy - origy)); + WinSendMsg(vscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origy, usedy), 0); + if(vpos > usedy) + { + vpos = usedy; + WinSendMsg(vscroll, SBM_SETPOS, (MPARAM)vpos, 0); + } + + /* Setup horizontal scroller */ + WinSendMsg(hscroll, SBM_SETSCROLLBAR, (MPARAM)hpos, MPFROM2SHORT(0, (unsigned short)usedx - origx)); + WinSendMsg(hscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origx, usedx), 0); + if(hpos > usedx) + { + hpos = usedx; + WinSendMsg(hscroll, SBM_SETPOS, (MPARAM)hpos, 0); + } + + /* Position the scrolled box */ + WinSetWindowPos(box, HWND_TOP, 0, -(cy - origy), cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + + dw_window_set_data(handle, "_dw_cy", (void *)(cy - origy)); + + /* Layout the content of the scrollbox */ + _do_resize(contentbox, cx, cy); + } + else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) + { + /* Then try the bottom or right box */ + float *percent = (float *)dw_window_get_data(handle, "_dw_percent"); + int type = (int)dw_window_get_data(handle, "_dw_type"); + int cx = width + vectorx; + int cy = height + vectory; + + _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, + cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + + if(cx > 0 && cy > 0 && percent) + _handle_splitbar_resize(handle, *percent, type, cx, cy); + } + else + { + _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, + width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); + if(thisbox->items[z].type == TYPEBOX) + { + Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER); + + if(boxinfo && boxinfo->grouphwnd) + WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0, + width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE); + + } + + } + + if(thisbox->type == DW_HORZ) + currentx += width + vectorx + (pad * 2); + if(thisbox->type == DW_VERT) + currenty += height + vectory + (pad * 2); + } + } + } + return 0; } void _do_resize(Box *thisbox, int x, int y) { - if(x != 0 && y != 0) - { - if(thisbox) - { - int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0; - - _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady); - - if(usedx-usedpadx == 0 || usedy-usedpady == 0) - return; - - thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx)); - thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady)); - - usedx = usedy = usedpadx = usedpady = depth = 0; - - _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady); - } - } + if(x != 0 && y != 0) + { + if(thisbox) + { + int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0; + + _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady); + + if(usedx-usedpadx == 0 || usedy-usedpady == 0) + return; + + thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx)); + thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady)); + + usedx = usedy = usedpadx = usedpady = depth = 0; + + _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady); + } + } } /* This procedure handles WM_QUERYTRACKINFO requests from the frame */ MRESULT EXPENTRY _sizeproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); - Box *thisbox = NULL; - HWND box; - - box = WinWindowFromID(hWnd, FID_CLIENT); - if(box) - thisbox = WinQueryWindowPtr(box, QWP_USER); - - if(thisbox && !thisbox->titlebar) - { - switch(msg) - { - case WM_QUERYTRACKINFO: - { - if(blah && *blah) - { - PTRACKINFO ptInfo; - int res; - PFNWP myfunc = *blah; - res = (int)myfunc(hWnd, msg, mp1, mp2); - - ptInfo = (PTRACKINFO)(mp2); - - ptInfo->ptlMinTrackSize.y = 8; - ptInfo->ptlMinTrackSize.x = 8; - - return (MRESULT)res; - } - } - } - } - - if(blah && *blah) - { - PFNWP myfunc = *blah; - return myfunc(hWnd, msg, mp1, mp2); - } - - return WinDefWindowProc(hWnd, msg, mp1, mp2); + PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); + Box *thisbox = NULL; + HWND box; + + box = WinWindowFromID(hWnd, FID_CLIENT); + if(box) + thisbox = WinQueryWindowPtr(box, QWP_USER); + + if(thisbox && !thisbox->titlebar) + { + switch(msg) + { + case WM_QUERYTRACKINFO: + { + if(blah && *blah) + { + PTRACKINFO ptInfo; + int res; + PFNWP myfunc = *blah; + res = (int)myfunc(hWnd, msg, mp1, mp2); + + ptInfo = (PTRACKINFO)(mp2); + + ptInfo->ptlMinTrackSize.y = 8; + ptInfo->ptlMinTrackSize.x = 8; + + return (MRESULT)res; + } + } + } + } + + if(blah && *blah) + { + PFNWP myfunc = *blah; + return myfunc(hWnd, msg, mp1, mp2); + } + + return WinDefWindowProc(hWnd, msg, mp1, mp2); } void _Top(HPS hpsPaint, RECTL rclPaint) { - POINTL ptl1, ptl2; - - ptl1.x = rclPaint.xLeft; - ptl2.y = ptl1.y = rclPaint.yTop - 1; - ptl2.x = rclPaint.xRight - 1; - GpiMove(hpsPaint, &ptl1); - GpiLine(hpsPaint, &ptl2); + POINTL ptl1, ptl2; + + ptl1.x = rclPaint.xLeft; + ptl2.y = ptl1.y = rclPaint.yTop - 1; + ptl2.x = rclPaint.xRight - 1; + GpiMove(hpsPaint, &ptl1); + GpiLine(hpsPaint, &ptl2); } /* Left hits the bottom */ void _Left(HPS hpsPaint, RECTL rclPaint) { - POINTL ptl1, ptl2; - - ptl2.x = ptl1.x = rclPaint.xLeft; - ptl1.y = rclPaint.yTop - 1; - ptl2.y = rclPaint.yBottom; - GpiMove(hpsPaint, &ptl1); - GpiLine(hpsPaint, &ptl2); + POINTL ptl1, ptl2; + + ptl2.x = ptl1.x = rclPaint.xLeft; + ptl1.y = rclPaint.yTop - 1; + ptl2.y = rclPaint.yBottom; + GpiMove(hpsPaint, &ptl1); + GpiLine(hpsPaint, &ptl2); } void _Bottom(HPS hpsPaint, RECTL rclPaint) { - POINTL ptl1, ptl2; - - ptl1.x = rclPaint.xRight - 1; - ptl1.y = ptl2.y = rclPaint.yBottom; - ptl2.x = rclPaint.xLeft; - GpiMove(hpsPaint, &ptl1); - GpiLine(hpsPaint, &ptl2); + POINTL ptl1, ptl2; + + ptl1.x = rclPaint.xRight - 1; + ptl1.y = ptl2.y = rclPaint.yBottom; + ptl2.x = rclPaint.xLeft; + GpiMove(hpsPaint, &ptl1); + GpiLine(hpsPaint, &ptl2); } /* Right hits the top */ void _Right(HPS hpsPaint, RECTL rclPaint) { - POINTL ptl1, ptl2; - - ptl2.x = ptl1.x = rclPaint.xRight - 1; - ptl1.y = rclPaint.yBottom + 1; - ptl2.y = rclPaint.yTop - 1; - GpiMove(hpsPaint, &ptl1); - GpiLine(hpsPaint, &ptl2); -} + POINTL ptl1, ptl2; + + ptl2.x = ptl1.x = rclPaint.xRight - 1; + ptl1.y = rclPaint.yBottom + 1; + ptl2.y = rclPaint.yTop - 1; + GpiMove(hpsPaint, &ptl1); + GpiLine(hpsPaint, &ptl2); +} + + +#define CALENDAR_BORDER 3 +#define CALENDAR_ARROW 8 + +/* Returns a rectangle for a single day on the calendar */ +RECTL _CalendarDayRect(int position, RECTL rclPaint) +{ + int height = rclPaint.yTop - rclPaint.yBottom - (CALENDAR_BORDER*2); + int width = rclPaint.xRight - rclPaint.xLeft - (CALENDAR_BORDER*2); + /* There are 7 rows... 5 for the day numbers... + * 1 for the Month/Year and 1 for the day names. + */ + int row = position / 7; + int col = position % 7; + int cellwidth = width / 7; + int cellheight = height / 8; + + /* Create a new box */ + rclPaint.xLeft = (cellwidth * col) + CALENDAR_BORDER; + rclPaint.xRight = rclPaint.xLeft + cellwidth; + /* We only handle 6 of the 7 rows */ + rclPaint.yBottom = (cellheight * (6-row)) + CALENDAR_BORDER; + rclPaint.yTop = rclPaint.yBottom + cellheight; + return rclPaint; +} + +/* This procedure handles drawing of a status border */ +MRESULT EXPENTRY _calendarproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) +{ + /* How many days are in each month usually (not including leap years) */ + static int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + static char *daysofweek[] = { "Sunday", "Monday", "Tuesday","Wednesday", "Thursday", "Friday", "Saturday" }; + WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); + PFNWP oldproc = 0; + + if(blah) + { + oldproc = blah->oldproc; + + switch(msg) + { + case WM_BUTTON1DOWN: + case WM_BUTTON2DOWN: + case WM_BUTTON3DOWN: + { + POINTS pts = (*((POINTS*)&mp1)); + int day = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_day")); + int month = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_month")); + int year = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_year")); + int dayofweek = 1, x, height, isleapyear = ((year+1) % 4 == 0); + int daysthismonth = days[month] + (isleapyear && month == 1); + RECTL rclArea; + + /* Figure out what day of the week the first day of the month falls on */ + for(x=0;x<month;x++) + dayofweek += days[x] + (isleapyear && x == 1); + dayofweek += (year/4) + year - 1; + dayofweek = dayofweek % 7; + + WinQueryWindowRect(hWnd, &rclArea); + height = ((rclArea.yTop - (CALENDAR_BORDER*2))/7); + + /* Check for the left arrow */ + if(pts.x > rclArea.xLeft + CALENDAR_BORDER && pts.x < rclArea.xLeft + CALENDAR_BORDER + CALENDAR_ARROW && + pts.y > rclArea.yTop - (CALENDAR_BORDER + height) && pts.y < rclArea.yTop - CALENDAR_BORDER) + { + int daysthismonth; + + if(month == 0) + { + month = 11; + year--; + dw_window_set_data(hWnd, "_dw_year", DW_INT_TO_POINTER(year)); + } + else if(month > 0) + { + month--; + } + dw_window_set_data(hWnd, "_dw_month", DW_INT_TO_POINTER(month)); + /* Make sure we aren't higher than the number of days + * in our new month... keeping track of leap years. + */ + daysthismonth = days[month] + (isleapyear && month == 1); + if(day >= daysthismonth) + { + day = daysthismonth - 1; + dw_window_set_data(hWnd, "_dw_day", DW_INT_TO_POINTER(day)); + } + WinInvalidateRect(hWnd, &rclArea, FALSE); + WinPostMsg(hWnd, WM_PAINT, 0, 0); + return (MRESULT)TRUE; + } + + /* Check for the right arrow */ + if(pts.x < rclArea.xRight - CALENDAR_BORDER && pts.x > rclArea.xRight - CALENDAR_BORDER - CALENDAR_ARROW && + pts.y > rclArea.yTop - (CALENDAR_BORDER + height) && pts.y < rclArea.yTop - CALENDAR_BORDER) + { + int daysthismonth; + + if(month == 11) + { + month = 0; + year++; + dw_window_set_data(hWnd, "_dw_year", DW_INT_TO_POINTER(year)); + } + else if(month < 11) + { + month++; + } + dw_window_set_data(hWnd, "_dw_month", DW_INT_TO_POINTER(month)); + /* Make sure we aren't higher than the number of days + * in our new month... keeping track of leap years. + */ + daysthismonth = days[month] + (isleapyear && month == 1); + if(day >= daysthismonth) + { + day = daysthismonth - 1; + dw_window_set_data(hWnd, "_dw_day", DW_INT_TO_POINTER(day)); + } + WinInvalidateRect(hWnd, &rclArea, FALSE); + WinPostMsg(hWnd, WM_PAINT, 0, 0); + return (MRESULT)TRUE; + } + + /* Check all the valid days of the month */ + for(x=dayofweek+7;x<(daysthismonth+dayofweek+7);x++) + { + RECTL rclThis = _CalendarDayRect(x, rclArea); + if(pts.x < rclThis.xRight && pts.x > rclThis.xLeft && pts.y < rclThis.yTop && pts.y > rclThis.yBottom) + { + dw_window_set_data(hWnd, "_dw_day", DW_INT_TO_POINTER((x-(dayofweek+7)))); + WinInvalidateRect(hWnd, &rclArea, FALSE); + WinPostMsg(hWnd, WM_PAINT, 0, 0); + return (MRESULT)TRUE; + } + } + } + break; + case WM_PAINT: + { + HPS hpsPaint; + RECTL rclPaint, rclDraw; + char buf[100]; + int day = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_day")); + int month = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_month")); + int year = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_year")); + int dayofweek = 1, x, lastmonth = 11, height, isleapyear = ((year+1) % 4 == 0); + POINTL pptl[3]; + + /* Figure out the previous month for later use */ + if(month > 0) + lastmonth = month - 1; + + /* Make the title */ + sprintf(buf, "%s, %d", months[month], year + 1); + + /* Figure out what day of the week the first day of the month falls on */ + for(x=0;x<month;x++) + dayofweek += days[x] + (isleapyear && x == 1); + dayofweek += (year/4) + year - 1; + dayofweek = dayofweek % 7; + + /* Actually draw the control */ + hpsPaint = WinBeginPaint(hWnd, 0, 0); + WinQueryWindowRect(hWnd, &rclPaint); + WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY); + height = ((rclPaint.yTop - (CALENDAR_BORDER*2))/7); + + /* Draw the Month and Year at the top */ + GpiSetColor(hpsPaint, CLR_BLACK); + rclDraw = rclPaint; + rclDraw.yBottom = height * 6; + WinDrawText(hpsPaint, -1, (PCH)buf, &rclDraw, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_CENTER | DT_TEXTATTRS); + + /* Draw the left arrow */ + GpiSetColor(hpsPaint, CLR_DARKGRAY); + GpiBeginArea(hpsPaint, 0); + pptl[2].x = rclDraw.xLeft + CALENDAR_BORDER + CALENDAR_ARROW; + pptl[2].y = rclDraw.yTop - CALENDAR_BORDER; + GpiMove(hpsPaint, &pptl[2]); + pptl[0].x = rclDraw.xLeft + CALENDAR_BORDER; + pptl[0].y = rclDraw.yTop - (CALENDAR_BORDER+ (height/2)); + pptl[1].x = rclDraw.xLeft + CALENDAR_BORDER + CALENDAR_ARROW; + pptl[1].y = rclDraw.yTop - CALENDAR_BORDER - height; + GpiPolyLine(hpsPaint, 3, pptl); + GpiEndArea(hpsPaint); + + /* Draw the left arrow */ + GpiBeginArea(hpsPaint, 0); + pptl[2].x = rclDraw.xRight - CALENDAR_BORDER - CALENDAR_ARROW; + pptl[2].y = rclDraw.yTop - CALENDAR_BORDER; + GpiMove(hpsPaint, &pptl[2]); + pptl[0].x = rclDraw.xRight - CALENDAR_BORDER; + pptl[0].y = rclDraw.yTop - (CALENDAR_BORDER + (height/2)); + pptl[1].x = rclDraw.xRight - CALENDAR_BORDER - CALENDAR_ARROW; + pptl[1].y = rclDraw.yTop - CALENDAR_BORDER - height; + GpiPolyLine(hpsPaint, 3, pptl); + GpiEndArea(hpsPaint); + + /* Draw a border around control */ + _Top(hpsPaint, rclPaint); + _Left(hpsPaint, rclPaint); + /* With shadow */ + GpiSetColor(hpsPaint, CLR_WHITE); + _Right(hpsPaint, rclPaint); + _Bottom(hpsPaint, rclPaint); + + /* Draw the days of the week */ + GpiSetColor(hpsPaint, CLR_BLACK); + for(x=0;x<7;x++) + { + char *title = daysofweek[x]; + + rclDraw = _CalendarDayRect(x, rclPaint); + + if(rclDraw.xRight - rclDraw.xLeft < 60) + { + buf[0] = daysofweek[x][0]; buf[1] = daysofweek[x][1]; buf[2] = 0; + title = buf; + } + WinDrawText(hpsPaint, -1, (PCH)title, &rclDraw, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_CENTER | DT_TEXTATTRS); + } + + /* Go through all the days */ + for(x=0;x<42;x++) + { + int daysthismonth = days[month] + (isleapyear && month == 1); + int dayslastmonth = days[lastmonth] + (isleapyear && lastmonth == 1); + + rclDraw = _CalendarDayRect(x+7, rclPaint); + if(x < dayofweek) + { + GpiSetColor(hpsPaint, CLR_DARKGRAY); + sprintf(buf, "%d", dayslastmonth - (dayofweek - x - 1)); + } + else if(x - dayofweek + 1 > daysthismonth) + { + GpiSetColor(hpsPaint, CLR_DARKGRAY); + sprintf(buf, "%d", x - dayofweek - daysthismonth + 1); + } + else + { + GpiSetColor(hpsPaint, CLR_DARKBLUE); + sprintf(buf, "%d", x - dayofweek + 1); + } + WinDrawText(hpsPaint, -1, (PCH)buf, &rclDraw, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_CENTER | DT_TEXTATTRS); + } + + /* Draw a border around selected day */ + rclPaint = _CalendarDayRect(day + dayofweek + 7, rclPaint); + GpiSetColor(hpsPaint, CLR_DARKGRAY); + _Top(hpsPaint, rclPaint); + _Left(hpsPaint, rclPaint); + /* With shadow */ + GpiSetColor(hpsPaint, CLR_WHITE); + _Right(hpsPaint, rclPaint); + _Bottom(hpsPaint, rclPaint); + + WinEndPaint(hpsPaint); + + return (MRESULT)TRUE; + } + } + if(oldproc) + return oldproc(hWnd, msg, mp1, mp2); + } + + return WinDefWindowProc(hWnd, msg, mp1, mp2); +} + /* This procedure handles drawing of a status border */ MRESULT EXPENTRY _statusproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); - - if(msg == WM_MOUSEMOVE && _wndproc(hWnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - - if(blah && *blah) - { - PFNWP myfunc = *blah; - - switch(msg) - { - case WM_PAINT: - { - HPS hpsPaint; - RECTL rclPaint; - char buf[1024]; - - hpsPaint = WinBeginPaint(hWnd, 0, 0); - WinQueryWindowRect(hWnd, &rclPaint); - WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY); - - GpiSetColor(hpsPaint, CLR_DARKGRAY); - _Top(hpsPaint, rclPaint); - _Left(hpsPaint, rclPaint); - - GpiSetColor(hpsPaint, CLR_WHITE); - _Right(hpsPaint, rclPaint); - _Bottom(hpsPaint, rclPaint); - - WinQueryWindowText(hWnd, 1024, buf); - rclPaint.xLeft += 3; - rclPaint.xRight--; - rclPaint.yTop--; - rclPaint.yBottom++; - - GpiSetColor(hpsPaint, CLR_BLACK); - WinDrawText(hpsPaint, -1, buf, &rclPaint, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS); - WinEndPaint(hpsPaint); - - return (MRESULT)TRUE; - } - } - return myfunc(hWnd, msg, mp1, mp2); - } - - return WinDefWindowProc(hWnd, msg, mp1, mp2); + PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); + + if(msg == WM_MOUSEMOVE && _wndproc(hWnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + + if(blah && *blah) + { + PFNWP myfunc = *blah; + + switch(msg) + { + case WM_PAINT: + { + HPS hpsPaint; + RECTL rclPaint; + char buf[1024]; + + hpsPaint = WinBeginPaint(hWnd, 0, 0); + WinQueryWindowRect(hWnd, &rclPaint); + WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY); + + GpiSetColor(hpsPaint, CLR_DARKGRAY); + _Top(hpsPaint, rclPaint); + _Left(hpsPaint, rclPaint); + + GpiSetColor(hpsPaint, CLR_WHITE); + _Right(hpsPaint, rclPaint); + _Bottom(hpsPaint, rclPaint); + + WinQueryWindowText(hWnd, 1024, (PSZ)buf); + rclPaint.xLeft += 3; + rclPaint.xRight--; + rclPaint.yTop--; + rclPaint.yBottom++; + + GpiSetColor(hpsPaint, CLR_BLACK); + WinDrawText(hpsPaint, -1, (PCH)buf, &rclPaint, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS); + WinEndPaint(hpsPaint); + + return (MRESULT)TRUE; + } + } + return myfunc(hWnd, msg, mp1, mp2); + } + + return WinDefWindowProc(hWnd, msg, mp1, mp2); } /* This procedure handles pointer changes */ MRESULT EXPENTRY _textproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); - - if(msg == WM_MOUSEMOVE &&_wndproc(hWnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - - if(blah && *blah) - { - PFNWP myfunc = *blah; - - return myfunc(hWnd, msg, mp1, mp2); - } - - return WinDefWindowProc(hWnd, msg, mp1, mp2); + PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); + + if(msg == WM_MOUSEMOVE &&_wndproc(hWnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + + if(blah && *blah) + { + PFNWP myfunc = *blah; + + return myfunc(hWnd, msg, mp1, mp2); + } + + return WinDefWindowProc(hWnd, msg, mp1, mp2); +} + +/* This procedure handles scrollbox */ +MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) +{ + switch(msg) + { + case WM_PAINT: + { + HPS hpsPaint; + RECTL rclPaint; + + hpsPaint = WinBeginPaint(hWnd, 0, 0); + WinQueryWindowRect(hWnd, &rclPaint); + WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY); + WinEndPaint(hpsPaint); + + break; + } + case WM_HSCROLL: + case WM_VSCROLL: + { + MPARAM res; + int *pos, min, max, page, which = SHORT2FROMMP(mp2); + HWND handle, client = WinWindowFromID(hWnd, FID_CLIENT); + HWND box = (HWND)dw_window_get_data(hWnd, "_dw_resizebox"); + HWND hscroll = WinWindowFromID(hWnd, FID_HORZSCROLL); + HWND vscroll = WinWindowFromID(hWnd, FID_VERTSCROLL); + int hpos = dw_scrollbar_get_pos(hscroll); + int vpos = dw_scrollbar_get_pos(vscroll); + int cy = (int)dw_window_get_data(hWnd, "_dw_cy"); + RECTL rect; + + WinQueryWindowRect(client, &rect); + + if(msg == WM_VSCROLL) + { + page = rect.yTop - rect.yBottom; + handle = vscroll; + pos = &vpos; + } + else + { + page = rect.xRight - rect.xLeft; + handle = hscroll; + pos = &hpos; + } + + res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0); + min = SHORT1FROMMP(res); + max = SHORT2FROMMP(res); + + switch(which) + { + case SB_SLIDERTRACK: + *pos = SHORT1FROMMP(mp2); + break; + case SB_LINEUP: + (*pos)--; + if(*pos < min) + *pos = min; + break; + case SB_LINEDOWN: + (*pos)++; + if(*pos > max) + *pos = max; + break; + case SB_PAGEUP: + (*pos) -= page; + if(*pos < min) + *pos = min; + break; + case SB_PAGEDOWN: + (*pos) += page; + if(*pos > max) + *pos = max; + break; + } + WinSendMsg(handle, SBM_SETPOS, (MPARAM)*pos, 0); + /* Position the scrolled box */ + WinSetWindowPos(box, HWND_TOP, -hpos, -(cy - vpos), 0, 0, SWP_MOVE); + break; + } + } + return WinDefWindowProc(hWnd, msg, mp1, mp2); } void _click_default(HWND handle) { - char tmpbuf[100]; - - WinQueryClassName(handle, 99, tmpbuf); - - /* These are the window classes which can - * obtain input focus. - */ - if(strncmp(tmpbuf, "#3", 3)==0) - { - /* Generate click on default item */ - SignalHandler *tmp = Root; - - /* Find any callbacks for this function */ - while(tmp) - { - if(tmp->message == WM_COMMAND) - { - int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; - - /* Make sure it's the right window, and the right ID */ - if(tmp->window == handle) - { - clickfunc(tmp->window, tmp->data); - tmp = NULL; - } - } - if(tmp) - tmp= tmp->next; - } - } - else - WinSetFocus(HWND_DESKTOP, handle); -} - -#define ENTRY_CUT 1001 -#define ENTRY_COPY 1002 -#define ENTRY_PASTE 1003 -#define ENTRY_UNDO 1004 -#define ENTRY_SALL 1005 + char tmpbuf[100]; + + WinQueryClassName(handle, 99, (PCH)tmpbuf); + + /* These are the window classes which can + * obtain input focus. + */ + if(strncmp(tmpbuf, "#3", 3)==0) + { + /* Generate click on default item */ + SignalHandler *tmp = Root; + + /* Find any callbacks for this function */ + while(tmp) + { + if(tmp->message == WM_COMMAND) + { + int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; + + /* Make sure it's the right window, and the right ID */ + if(tmp->window == handle) + { + clickfunc(tmp->window, tmp->data); + tmp = NULL; + } + } + if(tmp) + tmp= tmp->next; + } + } + else + WinSetFocus(HWND_DESKTOP, handle); +} + +#define ENTRY_CUT 60901 +#define ENTRY_COPY 60902 +#define ENTRY_PASTE 60903 +#define ENTRY_UNDO 60904 +#define ENTRY_SALL 60905 /* Originally just intended for entryfields, it now serves as a generic * procedure for handling TAB presses to change input focus on controls. */ MRESULT EXPENTRY _entryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); - PFNWP oldproc = 0; - char tmpbuf[100]; - - if(blah) - oldproc = blah->oldproc; - - WinQueryClassName(hWnd, 99, tmpbuf); - - /* These are the window classes which should get a menu */ - if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */ - strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */ - strncmp(tmpbuf, "#10", 4)==0 || /* MLE */ - strncmp(tmpbuf, "#32", 4)==0) /* Spinbutton */ - { - switch(msg) - { - case WM_CONTEXTMENU: - { - HMENUI hwndMenu = dw_menu_new(0L); - long x, y; - - if(strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0)) - { - dw_menu_append_item(hwndMenu, "Undo", ENTRY_UNDO, 0L, TRUE, FALSE, 0L); - dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, FALSE, 0L); - } - dw_menu_append_item(hwndMenu, "Copy", ENTRY_COPY, 0L, TRUE, FALSE, 0L); - if((strncmp(tmpbuf, "#10", 4)!=0 && !dw_window_get_data(hWnd, "_dw_disabled")) || (strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0))) - { - dw_menu_append_item(hwndMenu, "Cut", ENTRY_CUT, 0L, TRUE, FALSE, 0L); - dw_menu_append_item(hwndMenu, "Paste", ENTRY_PASTE, 0L, TRUE, FALSE, 0L); - } - dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, FALSE, 0L); - dw_menu_append_item(hwndMenu, "Select All", ENTRY_SALL, 0L, TRUE, FALSE, 0L); - - WinSetFocus(HWND_DESKTOP, hWnd); - dw_pointer_query_pos(&x, &y); - dw_menu_popup(&hwndMenu, hWnd, x, y); - } - break; - case WM_COMMAND: - { - ULONG command = COMMANDMSG(&msg)->cmd; - - /* MLE */ - if(strncmp(tmpbuf, "#10", 4)==0) - { - switch(command) - { - case ENTRY_CUT: - return WinSendMsg(hWnd, MLM_CUT, 0, 0); - case ENTRY_COPY: - return WinSendMsg(hWnd, MLM_COPY, 0, 0); - case ENTRY_PASTE: - return WinSendMsg(hWnd, MLM_PASTE, 0, 0); - case ENTRY_UNDO: - return WinSendMsg(hWnd, MLM_UNDO, 0, 0); - case ENTRY_SALL: - { - ULONG len = (ULONG)WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0); - return WinSendMsg(hWnd, MLM_SETSEL, 0, (MPARAM)len); - } - } - } - else /* Other */ - { - HWND handle = hWnd; - - /* Get the entryfield handle from multi window controls */ - if(strncmp(tmpbuf, "#2", 3)==0) - handle = WinWindowFromID(hWnd, 667); - - if(handle) - { - switch(command) - { - case ENTRY_CUT: - return WinSendMsg(handle, EM_CUT, 0, 0); - case ENTRY_COPY: - return WinSendMsg(handle, EM_COPY, 0, 0); - case ENTRY_PASTE: - return WinSendMsg(handle, EM_PASTE, 0, 0); - case ENTRY_SALL: - { - LONG len = WinQueryWindowTextLength(hWnd); - return WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT(0, (SHORT)len), 0); - } - } - } - } - } - break; - } - } - - switch(msg) - { - case WM_BUTTON1DOWN: - case WM_BUTTON2DOWN: - case WM_BUTTON3DOWN: - { - if(strncmp(tmpbuf, "#32", 4)==0) - _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); - } - break; - case WM_CONTROL: - { - if(strncmp(tmpbuf, "#38", 4)==0) - _run_event(hWnd, msg, mp1, mp2); - } - break; - case WM_SETFOCUS: - _run_event(hWnd, msg, mp1, mp2); - break; - case WM_CHAR: - if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE) - return (MRESULT)TRUE; - if(SHORT1FROMMP(mp2) == '\t') - { - if(CHARMSG(&msg)->fs & KC_SHIFT) - _shift_focus_back(hWnd); - else - _shift_focus(hWnd); - return FALSE; - } - else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault) - _click_default(blah->clickdefault); - /* When you hit escape we get this value and the - * window hangs for reasons unknown. (in an MLE) - */ - else if(SHORT1FROMMP(mp2) == 283) - return (MRESULT)TRUE; - - break; - case WM_SIZE: - { - /* If it's a slider... make sure it shows the correct value */ - if(strncmp(tmpbuf, "#38", 4)==0) - WinPostMsg(hWnd, WM_USER+7, 0, 0); - } - break; - case WM_USER+7: - { - int pos = (int)dw_window_get_data(hWnd, "_dw_slider_value"); - WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)pos); - } - break; - case WM_MOUSEMOVE: - if(_wndproc(hWnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - break; - } - - if(oldproc) - return oldproc(hWnd, msg, mp1, mp2); - - return WinDefWindowProc(hWnd, msg, mp1, mp2); + WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); + PFNWP oldproc = 0; + char tmpbuf[100]; + + if(blah) + oldproc = blah->oldproc; + + WinQueryClassName(hWnd, 99, (PCH)tmpbuf); + + /* These are the window classes which should get a menu */ + if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */ + strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */ + strncmp(tmpbuf, "#10", 4)==0 || /* MLE */ + strncmp(tmpbuf, "#32", 4)==0) /* Spinbutton */ + { + switch(msg) + { + case WM_CONTEXTMENU: + { + HMENUI hwndMenu = dw_menu_new(0L); + long x, y; + + if(strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0)) + { + dw_menu_append_item(hwndMenu, "Undo", ENTRY_UNDO, 0L, TRUE, -1, 0L); + dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, -1, 0L); + } + dw_menu_append_item(hwndMenu, "Copy", ENTRY_COPY, 0L, TRUE, -1, 0L); + if((strncmp(tmpbuf, "#10", 4)!=0 && !dw_window_get_data(hWnd, "_dw_disabled")) || (strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0))) + { + dw_menu_append_item(hwndMenu, "Cut", ENTRY_CUT, 0L, TRUE, -1, 0L); + dw_menu_append_item(hwndMenu, "Paste", ENTRY_PASTE, 0L, TRUE, -1, 0L); + } + dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, -1, 0L); + dw_menu_append_item(hwndMenu, "Select All", ENTRY_SALL, 0L, TRUE, -1, 0L); + + WinSetFocus(HWND_DESKTOP, hWnd); + dw_pointer_query_pos(&x, &y); + dw_menu_popup(&hwndMenu, hWnd, x, y); + } + break; + case WM_COMMAND: + { + ULONG command = COMMANDMSG(&msg)->cmd; + + /* MLE */ + if(strncmp(tmpbuf, "#10", 4)==0) + { + switch(command) + { + case ENTRY_CUT: + return WinSendMsg(hWnd, MLM_CUT, 0, 0); + case ENTRY_COPY: + return WinSendMsg(hWnd, MLM_COPY, 0, 0); + case ENTRY_PASTE: + return WinSendMsg(hWnd, MLM_PASTE, 0, 0); + case ENTRY_UNDO: + return WinSendMsg(hWnd, MLM_UNDO, 0, 0); + case ENTRY_SALL: + { + ULONG len = (ULONG)WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0); + return WinSendMsg(hWnd, MLM_SETSEL, 0, (MPARAM)len); + } + } + } + else /* Other */ + { + HWND handle = hWnd; + + /* Get the entryfield handle from multi window controls */ + if(strncmp(tmpbuf, "#2", 3)==0) + handle = WinWindowFromID(hWnd, 667); + + if(handle) + { + switch(command) + { + case ENTRY_CUT: + return WinSendMsg(handle, EM_CUT, 0, 0); + case ENTRY_COPY: + return WinSendMsg(handle, EM_COPY, 0, 0); + case ENTRY_PASTE: + return WinSendMsg(handle, EM_PASTE, 0, 0); + case ENTRY_SALL: + { + LONG len = WinQueryWindowTextLength(hWnd); + return WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT(0, (SHORT)len), 0); + } + } + } + } + } + break; + } + } + + switch(msg) + { + case WM_BUTTON1DOWN: + case WM_BUTTON2DOWN: + case WM_BUTTON3DOWN: + { + if(strncmp(tmpbuf, "#32", 4)==0) + _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); + } + break; + case WM_CONTROL: + { + if(strncmp(tmpbuf, "#38", 4)==0) + _run_event(hWnd, msg, mp1, mp2); + } + break; + case WM_SETFOCUS: + _run_event(hWnd, msg, mp1, mp2); + break; + case WM_CHAR: + if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE) + return (MRESULT)TRUE; + if(SHORT1FROMMP(mp2) == '\t') + { + if(CHARMSG(&msg)->fs & KC_SHIFT) + _shift_focus_back(hWnd); + else + _shift_focus(hWnd); + return FALSE; + } + else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault) + _click_default(blah->clickdefault); + /* When you hit escape we get this value and the + * window hangs for reasons unknown. (in an MLE) + */ + else if(SHORT1FROMMP(mp2) == 283) + return (MRESULT)TRUE; + + break; + case WM_SIZE: + { + /* If it's a slider... make sure it shows the correct value */ + if(strncmp(tmpbuf, "#38", 4)==0) + WinPostMsg(hWnd, WM_USER+7, 0, 0); + } + break; + case WM_USER+7: + { + int pos = (int)dw_window_get_data(hWnd, "_dw_slider_value"); + WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)pos); + } + break; + case WM_MOUSEMOVE: + if(_wndproc(hWnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + break; + } + + if(oldproc) + return oldproc(hWnd, msg, mp1, mp2); + + return WinDefWindowProc(hWnd, msg, mp1, mp2); } /* Deal with combobox specifics and enhancements */ MRESULT EXPENTRY _comboentryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); - - switch(msg) - { - case WM_MOUSEMOVE: - if(_wndproc(hWnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - break; - case WM_CONTEXTMENU: - case WM_COMMAND: - return _entryproc(hWnd, msg, mp1, mp2); - case WM_SETFOCUS: - _run_event(hWnd, msg, mp1, mp2); - break; - case WM_CHAR: - if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE) - return (MRESULT)TRUE; - /* A Similar problem to the MLE, if ESC just return */ - if(SHORT1FROMMP(mp2) == 283) - return (MRESULT)TRUE; - break; - } - - if(blah && blah->oldproc) - return blah->oldproc(hWnd, msg, mp1, mp2); - - return WinDefWindowProc(hWnd, msg, mp1, mp2); + WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); + + switch(msg) + { + case WM_MOUSEMOVE: + if(_wndproc(hWnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + break; + case WM_CONTEXTMENU: + case WM_COMMAND: + return _entryproc(hWnd, msg, mp1, mp2); + case WM_SETFOCUS: + _run_event(hWnd, msg, mp1, mp2); + break; + case WM_CHAR: + if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE) + return (MRESULT)TRUE; + /* A Similar problem to the MLE, if ESC just return */ + if(SHORT1FROMMP(mp2) == 283) + return (MRESULT)TRUE; + break; + } + + if(blah && blah->oldproc) + return blah->oldproc(hWnd, msg, mp1, mp2); + + return WinDefWindowProc(hWnd, msg, mp1, mp2); } /* Enhance the standard OS/2 MLE control */ MRESULT EXPENTRY _mleproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - switch(msg) - { - case WM_VSCROLL: - if(SHORT2FROMMP(mp2) == SB_SLIDERTRACK) - { - USHORT pos = SHORT1FROMMP(mp2); - - WinSendMsg(hWnd, msg, mp1, MPFROM2SHORT(pos, SB_SLIDERPOSITION)); - } - break; - } - return _entryproc(hWnd, msg, mp1, mp2); + switch(msg) + { + case WM_VSCROLL: + if(SHORT2FROMMP(mp2) == SB_SLIDERTRACK) + { + USHORT pos = SHORT1FROMMP(mp2); + + WinSendMsg(hWnd, msg, mp1, MPFROM2SHORT(pos, SB_SLIDERPOSITION)); + } + break; + } + return _entryproc(hWnd, msg, mp1, mp2); } /* Handle special messages for the spinbutton's entryfield */ MRESULT EXPENTRY _spinentryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); - PFNWP oldproc = 0; - - if(blah) - oldproc = blah->oldproc; - - switch(msg) - { - case WM_MOUSEMOVE: - if(_wndproc(hWnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - break; - case WM_CONTEXTMENU: - case WM_COMMAND: - return _entryproc(hWnd, msg, mp1, mp2); - } - - if(oldproc) - return oldproc(hWnd, msg, mp1, mp2); - - return WinDefWindowProc(hWnd, msg, mp1, mp2); + WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); + PFNWP oldproc = 0; + + if(blah) + oldproc = blah->oldproc; + + switch(msg) + { + case WM_MOUSEMOVE: + if(_wndproc(hWnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + break; + case WM_CONTEXTMENU: + case WM_COMMAND: + return _entryproc(hWnd, msg, mp1, mp2); + } + + if(oldproc) + return oldproc(hWnd, msg, mp1, mp2); + + return WinDefWindowProc(hWnd, msg, mp1, mp2); } int _dw_int_pos(HWND hwnd) { - int pos = (int)dw_window_get_data(hwnd, "_dw_percent_value"); - int range = _dw_percent_get_range(hwnd); - float fpos = (float)pos; - float frange = (float)range; - float fnew = (fpos/1000.0)*frange; - return (int)fnew; + int pos = (int)dw_window_get_data(hwnd, "_dw_percent_value"); + int range = _dw_percent_get_range(hwnd); + float fpos = (float)pos; + float frange = (float)range; + float fnew = (fpos/1000.0)*frange; + return (int)fnew; } void _dw_int_set(HWND hwnd, int pos) { - int inew, range = _dw_percent_get_range(hwnd); - if(range) - { - float fpos = (float)pos; - float frange = (float)range; - float fnew = (fpos/frange)*1000.0; - inew = (int)fnew; - dw_window_set_data(hwnd, "_dw_percent_value", (void *)inew); - } + int inew, range = _dw_percent_get_range(hwnd); + if(range) + { + float fpos = (float)pos; + float frange = (float)range; + float fnew = (fpos/frange)*1000.0; + inew = (int)fnew; + dw_window_set_data(hwnd, "_dw_percent_value", (void *)inew); + } } /* Handle size changes in the percent class */ MRESULT EXPENTRY _percentproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); - PFNWP oldproc = 0; - - if(blah) - oldproc = blah->oldproc; - - switch(msg) - { - case WM_MOUSEMOVE: - if(_wndproc(hWnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - break; - case WM_SIZE: - WinPostMsg(hWnd, WM_USER+7, 0, 0); - break; - case WM_USER+7: - WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)_dw_int_pos(hWnd)); - break; - } - - if(oldproc) - return oldproc(hWnd, msg, mp1, mp2); - - return WinDefWindowProc(hWnd, msg, mp1, mp2); + WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); + PFNWP oldproc = 0; + + if(blah) + oldproc = blah->oldproc; + + switch(msg) + { + case WM_MOUSEMOVE: + if(_wndproc(hWnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + break; + case WM_SIZE: + WinPostMsg(hWnd, WM_USER+7, 0, 0); + break; + case WM_USER+7: + WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)_dw_int_pos(hWnd)); + break; + } + + if(oldproc) + return oldproc(hWnd, msg, mp1, mp2); + + return WinDefWindowProc(hWnd, msg, mp1, mp2); } /* Handle correct painting of a combobox with the WS_CLIPCHILDREN @@ -1883,90 +2373,90 @@ */ MRESULT EXPENTRY _comboproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - WindowData *blah = WinQueryWindowPtr(hWnd, QWP_USER); - PFNWP oldproc = 0; - - if(blah) - oldproc = blah->oldproc; - - switch(msg) - { - case WM_MOUSEMOVE: - if(_wndproc(hWnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - break; - case WM_CHAR: - if(SHORT1FROMMP(mp2) == '\t') - { - if(CHARMSG(&msg)->fs & KC_SHIFT) - _shift_focus_back(hWnd); - else - _shift_focus(hWnd); - return FALSE; - } - else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault) - _click_default(blah->clickdefault); - break; - case WM_BUTTON1DBLCLK: - case WM_BUTTON2DBLCLK: - case WM_BUTTON3DBLCLK: - if(dw_window_get_data(hWnd, "_dw_disabled")) - return (MRESULT)TRUE; - break; - case WM_BUTTON1DOWN: - case WM_BUTTON2DOWN: - case WM_BUTTON3DOWN: - if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE) - return (MRESULT)TRUE; - _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); - break; - case WM_SETFOCUS: - _run_event(hWnd, msg, mp1, mp2); - break; - case WM_PAINT: - { - HWND entry, frame = (HWND)dw_window_get_data(hWnd, "_dw_combo_box"), parent = WinQueryWindow(frame, QW_PARENT); - HPS hpsPaint; - POINTL ptl; - unsigned long width, height, thumbheight = 0; - ULONG color; - - if((entry = (HWND)dw_window_get_data(hWnd, "_dw_comboentry")) != NULLHANDLE) - dw_window_get_pos_size(entry, 0, 0, 0, &thumbheight); - - if(!thumbheight) - thumbheight = WinQuerySysValue(HWND_DESKTOP, SV_CYVSCROLLARROW); - - /* Add 6 because it has a thick border like the entryfield */ - thumbheight += 6; - - color = (ULONG)dw_window_get_data(parent, "_dw_fore"); - dw_window_get_pos_size(hWnd, 0, 0, &width, &height); - - if(height > thumbheight) - { - hpsPaint = WinGetPS(hWnd); - if(color) - GpiSetColor(hpsPaint, _internal_color(color-1)); - else - GpiSetColor(hpsPaint, CLR_PALEGRAY); - - ptl.x = ptl.y = 0; - GpiMove(hpsPaint, &ptl); - - ptl.x = width; - ptl.y = height - thumbheight; - GpiBox(hpsPaint, DRO_FILL, &ptl, 0, 0); - - WinReleasePS(hpsPaint); - } - } - break; - } - if(oldproc) - return oldproc(hWnd, msg, mp1, mp2); - - return WinDefWindowProc(hWnd, msg, mp1, mp2); + WindowData *blah = WinQueryWindowPtr(hWnd, QWP_USER); + PFNWP oldproc = 0; + + if(blah) + oldproc = blah->oldproc; + + switch(msg) + { + case WM_MOUSEMOVE: + if(_wndproc(hWnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + break; + case WM_CHAR: + if(SHORT1FROMMP(mp2) == '\t') + { + if(CHARMSG(&msg)->fs & KC_SHIFT) + _shift_focus_back(hWnd); + else + _shift_focus(hWnd); + return FALSE; + } + else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault) + _click_default(blah->clickdefault); + break; + case WM_BUTTON1DBLCLK: + case WM_BUTTON2DBLCLK: + case WM_BUTTON3DBLCLK: + if(dw_window_get_data(hWnd, "_dw_disabled")) + return (MRESULT)TRUE; + break; + case WM_BUTTON1DOWN: + case WM_BUTTON2DOWN: + case WM_BUTTON3DOWN: + if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE) + return (MRESULT)TRUE; + _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); + break; + case WM_SETFOCUS: + _run_event(hWnd, msg, mp1, mp2); + break; + case WM_PAINT: + { + HWND entry, frame = (HWND)dw_window_get_data(hWnd, "_dw_combo_box"), parent = WinQueryWindow(frame, QW_PARENT); + HPS hpsPaint; + POINTL ptl; + unsigned long width, height, thumbheight = 0; + ULONG color; + + if((entry = (HWND)dw_window_get_data(hWnd, "_dw_comboentry")) != NULLHANDLE) + dw_window_get_pos_size(entry, 0, 0, 0, &thumbheight); + + if(!thumbheight) + thumbheight = WinQuerySysValue(HWND_DESKTOP, SV_CYVSCROLLARROW); + + /* Add 6 because it has a thick border like the entryfield */ + thumbheight += 6; + + color = (ULONG)dw_window_get_data(parent, "_dw_fore"); + dw_window_get_pos_size(hWnd, 0, 0, &width, &height); + + if(height > thumbheight) + { + hpsPaint = WinGetPS(hWnd); + if(color) + GpiSetColor(hpsPaint, _internal_color(color-1)); + else + GpiSetColor(hpsPaint, CLR_PALEGRAY); + + ptl.x = ptl.y = 0; + GpiMove(hpsPaint, &ptl); + + ptl.x = width; + ptl.y = height - thumbheight; + GpiBox(hpsPaint, DRO_FILL, &ptl, 0, 0); + + WinReleasePS(hpsPaint); + } + } + break; + } + if(oldproc) + return oldproc(hWnd, msg, mp1, mp2); + + return WinDefWindowProc(hWnd, msg, mp1, mp2); } void _GetPPFont(HWND hwnd, char *buff) @@ -1991,1044 +2481,1056 @@ int _HandleScroller(HWND handle, int pos, int which) { - MPARAM res; - int min, max, page; - - if(which == SB_SLIDERTRACK) - return pos; - - pos = dw_scrollbar_get_pos(handle); - res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0); - - min = SHORT1FROMMP(res); - max = SHORT2FROMMP(res); - page = (int)dw_window_get_data(handle, "_dw_scrollbar_visible"); - - switch(which) - { - case SB_LINEUP: - pos = pos - 1; - if(pos < min) - pos = min; - dw_scrollbar_set_pos(handle, pos); - return pos; - case SB_LINEDOWN: - pos = pos + 1; - if(pos > max) - pos = max; - dw_scrollbar_set_pos(handle, pos); - return pos; - case SB_PAGEUP: - pos = pos - page; - if(pos < min) - pos = min; - dw_scrollbar_set_pos(handle, pos); - return pos; - case SB_PAGEDOWN: - pos = pos + page; - if(pos > max) - pos = max; - dw_scrollbar_set_pos(handle, pos); - return pos; - } - return -1; + MPARAM res; + int min, max, page; + + if(which == SB_SLIDERTRACK) + return pos; + + pos = dw_scrollbar_get_pos(handle); + res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0); + + min = SHORT1FROMMP(res); + max = SHORT2FROMMP(res); + page = (int)dw_window_get_data(handle, "_dw_scrollbar_visible"); + + switch(which) + { + case SB_LINEUP: + pos = pos - 1; + if(pos < min) + pos = min; + dw_scrollbar_set_pos(handle, pos); + return pos; + case SB_LINEDOWN: + pos = pos + 1; + if(pos > max) + pos = max; + dw_scrollbar_set_pos(handle, pos); + return pos; + case SB_PAGEUP: + pos = pos - page; + if(pos < min) + pos = min; + dw_scrollbar_set_pos(handle, pos); + return pos; + case SB_PAGEDOWN: + pos = pos + page; + if(pos > max) + pos = max; + dw_scrollbar_set_pos(handle, pos); + return pos; + } + return -1; } void _clear_emphasis(void) { - if(hwndEmph && WinIsWindow(dwhab, hwndEmph) && pCoreEmph) - WinSendMsg(hwndEmph, CM_SETRECORDEMPHASIS, pCoreEmph, MPFROM2SHORT(FALSE, CRA_SOURCE)); - hwndEmph = NULLHANDLE; - pCoreEmph = NULL; + if(hwndEmph && WinIsWindow(dwhab, hwndEmph) && pCoreEmph) + WinSendMsg(hwndEmph, CM_SETRECORDEMPHASIS, pCoreEmph, MPFROM2SHORT(FALSE, CRA_SOURCE)); + hwndEmph = NULLHANDLE; + pCoreEmph = NULL; } /* Find the desktop window handle */ HWND _menu_owner(HWND handle) { - HWND menuowner = NULLHANDLE, lastowner = (HWND)dw_window_get_data(handle, "_dw_owner"); - int menubar = (int)dw_window_get_data(handle, "_dw_menubar"); - - /* Find the toplevel window */ - while(!menubar && (menuowner = (HWND)dw_window_get_data(lastowner, "_dw_owner")) != NULLHANDLE) - { - menubar = (int)dw_window_get_data(lastowner, "_dw_menubar"); - lastowner = menuowner; - } - if(menuowner && menubar) - { - HWND client = WinWindowFromID(menuowner, FID_CLIENT); - - return client ? client : menuowner; - } - return NULLHANDLE; + HWND menuowner = NULLHANDLE, lastowner = (HWND)dw_window_get_data(handle, "_dw_owner"); + int menubar = (int)dw_window_get_data(handle, "_dw_menubar"); + + /* Find the toplevel window */ + while(!menubar && (menuowner = (HWND)dw_window_get_data(lastowner, "_dw_owner")) != NULLHANDLE) + { + menubar = (int)dw_window_get_data(lastowner, "_dw_menubar"); + lastowner = menuowner; + } + if(menuowner && menubar) + { + HWND client = WinWindowFromID(menuowner, FID_CLIENT); + + return client ? client : menuowner; + } + return NULLHANDLE; } MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - int result = -1; - SignalHandler *tmp = Root; - ULONG origmsg = msg; - - if(msg == WM_BUTTON2DOWN || msg == WM_BUTTON3DOWN) - msg = WM_BUTTON1DOWN; - if(msg == WM_BUTTON2UP || msg == WM_BUTTON3UP) - msg = WM_BUTTON1UP; - if(msg == WM_VSCROLL || msg == WM_HSCROLL) - msg = WM_CONTROL; - - /* Find any callbacks for this function */ - while(tmp) - { - if(tmp->message == msg || msg == WM_CONTROL || tmp->message == WM_USER+1) - { - switch(msg) - { - case WM_SETFOCUS: - { - if((mp2 && tmp->message == WM_SETFOCUS) || (!mp2 && tmp->message == WM_USER+1)) - { - int (* API setfocusfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; - - if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) - { - result = setfocusfunc(tmp->window, tmp->data); - tmp = NULL; - } - } - } - break; - case WM_TIMER: - { - int (* API timerfunc)(void *) = (int (* API)(void *))tmp->signalfunction; - if(tmp->id == (int)mp1) - { - if(!timerfunc(tmp->data)) - dw_timer_disconnect(tmp->id); - tmp = NULL; - } - result = 0; - } - break; - case WM_SIZE: - { - int (* API sizefunc)(HWND, int, int, void *) = (int (* API)(HWND, int, int, void *))tmp->signalfunction; - - if((hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) && SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2)) - { - result = sizefunc(tmp->window, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), tmp->data); - tmp = NULL; - } - } - break; - case WM_BUTTON1DOWN: - { - POINTS pts = (*((POINTS*)&mp1)); - int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction; - - if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window) - { - int button = 0; - - switch(origmsg) - { - case WM_BUTTON1DOWN: - button = 1; - break; - case WM_BUTTON2DOWN: - button = 2; - break; - case WM_BUTTON3DOWN: - button = 3; - break; - } - - result = buttonfunc(tmp->window, pts.x, _get_frame_height(tmp->window) - pts.y, button, tmp->data); - tmp = NULL; - } - } - break; - case WM_BUTTON1UP: - { - POINTS pts = (*((POINTS*)&mp1)); - int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction; - - if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window) - { - int button = 0; - - switch(origmsg) - { - case WM_BUTTON1UP: - button = 1; - break; - case WM_BUTTON2UP: - button = 2; - break; - case WM_BUTTON3UP: - button = 3; - break; - } - - result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data); - tmp = NULL; - } - } - break; - case WM_MOUSEMOVE: - { - int (* API motionfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction; - - if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window) - { - int keys = 0; - SHORT x = SHORT1FROMMP(mp1), y = SHORT2FROMMP(mp1); - - if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000) - keys = DW_BUTTON1_MASK; - if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000) - keys |= DW_BUTTON2_MASK; - if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000) - keys |= DW_BUTTON3_MASK; - - result = motionfunc(tmp->window, x, _get_frame_height(tmp->window) - y, keys, tmp->data); - tmp = NULL; - } - } - break; - case WM_CHAR: - { - int (* API keypressfunc)(HWND, char, int, int, void *) = (int (* API)(HWND, char, int, int, void *))tmp->signalfunction; - - if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP)) - { - int vk; - char ch = 0; - - if(SHORT1FROMMP(mp1) & KC_CHAR) - ch = (char)SHORT1FROMMP(mp2); - if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY) - vk = SHORT2FROMMP(mp2); - else - vk = SHORT1FROMMP(mp2) + 128; - - /* This is a hack to fix shift presses showing - * up as tabs! - */ - if(ch == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR)) - { - ch = 0; - vk = VK_SHIFT; - } - - result = keypressfunc(tmp->window, ch, vk, - SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data); - tmp = NULL; - } - } - break; - case WM_CLOSE: - { - int (* API closefunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; - - if(hWnd == tmp->window || hWnd == WinWindowFromID(tmp->window, FID_CLIENT)) - { - result = closefunc(tmp->window, tmp->data); - if(result) - result = FALSE; - tmp = NULL; - } - } - break; - case WM_PAINT: - { - HPS hps; - DWExpose exp; - int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))tmp->signalfunction; - RECTL rc; - - if(hWnd == tmp->window) - { - int height = _get_height(hWnd); - - hps = WinBeginPaint(hWnd, 0L, &rc); - exp.x = rc.xLeft; - exp.y = height - rc.yTop - 1; - exp.width = rc.xRight - rc. xLeft; - exp.height = rc.yTop - rc.yBottom; - result = exposefunc(hWnd, &exp, tmp->data); - WinEndPaint(hps); - } - } - break; - case WM_COMMAND: - { - int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; - ULONG command = COMMANDMSG(&msg)->cmd; - - if(tmp->id && command == tmp->id) - { - HWND menuowner = _menu_owner(tmp->window); - - if(menuowner == hWnd || menuowner == NULLHANDLE) - { - result = clickfunc(tmp->window, tmp->data); - tmp = NULL; - } - } - else if(tmp->window < 65536 && command == tmp->window) - { - result = clickfunc(popup ? popup : tmp->window, tmp->data); - tmp = NULL; - } - } - break; - case WM_CONTROL: - if(origmsg == WM_VSCROLL || origmsg == WM_HSCROLL || tmp->message == SHORT2FROMMP(mp1) || - (tmp->message == SLN_SLIDERTRACK && SHORT2FROMMP(mp1) == SLN_CHANGE)) - { - int svar = SLN_SLIDERTRACK; - if(origmsg == WM_CONTROL) - svar = SHORT2FROMMP(mp1); - - switch(svar) - { - case CN_ENTER: - { - int (* API containerselectfunc)(HWND, char *, void *) = (int (* API)(HWND, char *, void *))tmp->signalfunction; - int id = SHORT1FROMMP(mp1); - HWND conthwnd = dw_window_from_id(hWnd, id); - char *text = NULL; - - if(mp2) - { - PRECORDCORE pre; - - pre = ((PNOTIFYRECORDENTER)mp2)->pRecord; - if(pre) - text = pre->pszIcon; - } - - if(tmp->window == conthwnd) - { - result = containerselectfunc(tmp->window, text, tmp->data); - tmp = NULL; - } - } - break; - case CN_EXPANDTREE: - { - int (* API treeexpandfunc)(HWND, HTREEITEM, void *) = (int (* API)(HWND, HTREEITEM, void *))tmp->signalfunction; - int id = SHORT1FROMMP(mp1); - HWND conthwnd = dw_window_from_id(hWnd, id); - - if(tmp->window == conthwnd) - { - result = treeexpandfunc(tmp->window, (HTREEITEM)mp2, tmp->data); - tmp = NULL; - } - } - break; - case CN_CONTEXTMENU: - { - int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))tmp->signalfunction; - int id = SHORT1FROMMP(mp1); - HWND conthwnd = dw_window_from_id(hWnd, id); - char *text = NULL; - void *user = NULL; - LONG x,y; - - if(mp2) - { - PCNRITEM pci; - - pci = (PCNRITEM)mp2; - - text = pci->rc.pszIcon; - user = pci->user; - } - - dw_pointer_query_pos(&x, &y); - - if(tmp->window == conthwnd) - { - int container = (int)dw_window_get_data(tmp->window, "_dw_container"); - - if(mp2) - { - if(!container) - { - NOTIFYRECORDEMPHASIS pre; - - dw_tree_item_select(tmp->window, (HTREEITEM)mp2); - pre.pRecord = mp2; - pre.fEmphasisMask = CRA_CURSORED; - pre.hwndCnr = tmp->window; - _run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre); - pre.pRecord->flRecordAttr |= CRA_CURSORED; - } - else - { - if(pCoreEmph) - _clear_emphasis(); - hwndEmph = tmp->window; - pCoreEmph = mp2; - WinSendMsg(tmp->window, CM_SETRECORDEMPHASIS, mp2, MPFROM2SHORT(TRUE, CRA_SOURCE)); - } - } - result = containercontextfunc(tmp->window, text, x, y, tmp->data, user); - tmp = NULL; - } - } - break; - case CN_EMPHASIS: - { - PNOTIFYRECORDEMPHASIS pre = (PNOTIFYRECORDEMPHASIS)mp2; - static int emph_recurse = 0; - - if(!emph_recurse) - { - emph_recurse = 1; - - if(mp2) - { - if(tmp->window == pre->hwndCnr) - { - PCNRITEM pci = (PCNRITEM)pre->pRecord; - - if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED)) - { - int (* API treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = (int (* API)(HWND, HTREEITEM, char *, void *, void *))tmp->signalfunction; - - if(dw_window_get_data(tmp->window, "_dw_container")) - result = treeselectfunc(tmp->window, 0, pci->rc.pszIcon, tmp->data, 0); - else - { - if(lasthcnr == tmp->window && lastitem == (HWND)pci) - { - lasthcnr = 0; - lastitem = 0; - } - else - { - lasthcnr = tmp->window; - lastitem = (HWND)pci; - result = treeselectfunc(tmp->window, (HTREEITEM)pci, pci->rc.pszIcon, tmp->data, pci->user); - } - } - tmp = NULL; - } - } - } - emph_recurse = 0; - } - } - break; - case LN_SELECT: - { - char classbuf[100]; - - WinQueryClassName(tmp->window, 99, classbuf); - - if(strncmp(classbuf, "#38", 4) == 0) - { - int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction; - - if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd) - { - static int lastvalue = -1; - static HWND lasthwnd = NULLHANDLE; - int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0); - if(lastvalue != ulValue || lasthwnd != tmp->window) - { - result = valuechangedfunc(tmp->window, ulValue, tmp->data); - lastvalue = ulValue; - lasthwnd = tmp->window; - } - tmp = NULL; - } - } - else - { - int (* API listboxselectfunc)(HWND, int, void *) = (int (* API )(HWND, int, void *))tmp->signalfunction; - int id = SHORT1FROMMP(mp1); - HWND conthwnd = dw_window_from_id(hWnd, id); - static int _recursing = 0; - - if(_recursing == 0 && (tmp->window == conthwnd || (!id && tmp->window == (HWND)mp2))) - { - char buf1[500]; - unsigned int index = dw_listbox_selected(tmp->window); - - dw_listbox_get_text(tmp->window, index, buf1, 500); - - _recursing = 1; - - if(id && strncmp(classbuf, "#2", 3)==0) - { - char *buf2; - - buf2 = dw_window_get_text(tmp->window); - - /* This is to make sure the listboxselect function doesn't - * get called if the user is modifying the entry text. - */ - if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0) - result = listboxselectfunc(tmp->window, index, tmp->data); - - if(buf2) - free(buf2); - } - else - result = listboxselectfunc(tmp->window, index, tmp->data); - - _recursing = 0; - tmp = NULL; - } - } - } - break; - case SLN_SLIDERTRACK: - { - int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction; - - if(origmsg == WM_CONTROL) - { - /* Handle Slider control */ - if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd) - { - static int lastvalue = -1; - static HWND lasthwnd = NULLHANDLE; - int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0); - if(lastvalue != ulValue || lasthwnd != tmp->window) - { - dw_window_set_data(tmp->window, "_dw_slider_value", (void *)ulValue); - result = valuechangedfunc(tmp->window, ulValue, tmp->data); - lastvalue = ulValue; - lasthwnd = tmp->window; - } - tmp = NULL; - } - } - else - { - /* Handle scrollbar control */ - if(tmp->window > 65535 && tmp->window == WinWindowFromID(hWnd, (ULONG)mp1)) - { - int pos = _HandleScroller(tmp->window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));; - - if(pos > -1) - { - dw_window_set_data(tmp->window, "_dw_scrollbar_value", (void *)pos); - result = valuechangedfunc(tmp->window, pos, tmp->data); - } - result = 0; - tmp = NULL; - } - } - } - break; - case BKN_PAGESELECTED: - { - PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2; - - if(psn && tmp->window == psn->hwndBook) - { - int (* API switchpagefunc)(HWND, unsigned long, void *) = (int (* API)(HWND, unsigned long, void *))tmp->signalfunction; - - result = switchpagefunc(tmp->window, psn->ulPageIdNew, tmp->data); - tmp = NULL; - } - } - break; - } - } - break; - } - } - - if(tmp) - tmp = tmp->next; - - } - return (MRESULT)result; + int result = -1; + SignalHandler *tmp = Root; + ULONG origmsg = msg; + + if(msg == WM_BUTTON2DOWN || msg == WM_BUTTON3DOWN) + msg = WM_BUTTON1DOWN; + if(msg == WM_BUTTON2UP || msg == WM_BUTTON3UP) + msg = WM_BUTTON1UP; + if(msg == WM_VSCROLL || msg == WM_HSCROLL) + msg = WM_CONTROL; + + /* Find any callbacks for this function */ + while(tmp) + { + if(tmp->message == msg || msg == WM_CONTROL || tmp->message == WM_USER+1) + { + switch(msg) + { + case WM_SETFOCUS: + { + if((mp2 && tmp->message == WM_SETFOCUS) || (!mp2 && tmp->message == WM_USER+1)) + { + int (* API setfocusfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; + + if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) + { + result = setfocusfunc(tmp->window, tmp->data); + tmp = NULL; + } + } + } + break; + case WM_TIMER: + { + int (* API timerfunc)(void *) = (int (* API)(void *))tmp->signalfunction; + if(tmp->id == (int)mp1) + { + if(!timerfunc(tmp->data)) + dw_timer_disconnect(tmp->id); + tmp = NULL; + } + result = 0; + } + break; + case WM_SIZE: + { + int (* API sizefunc)(HWND, int, int, void *) = (int (* API)(HWND, int, int, void *))tmp->signalfunction; + + if((hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) && SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2)) + { + result = sizefunc(tmp->window, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), tmp->data); + tmp = NULL; + } + } + break; + case WM_BUTTON1DOWN: + { + POINTS pts = (*((POINTS*)&mp1)); + int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction; + + if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window) + { + int button = 0; + + switch(origmsg) + { + case WM_BUTTON1DOWN: + button = 1; + break; + case WM_BUTTON2DOWN: + button = 2; + break; + case WM_BUTTON3DOWN: + button = 3; + break; + } + + result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data); + tmp = NULL; + } + } + break; + case WM_BUTTON1UP: + { + POINTS pts = (*((POINTS*)&mp1)); + int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction; + + if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window) + { + int button = 0; + + switch(origmsg) + { + case WM_BUTTON1UP: + button = 1; + break; + case WM_BUTTON2UP: + button = 2; + break; + case WM_BUTTON3UP: + button = 3; + break; + } + + result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data); + tmp = NULL; + } + } + break; + case WM_MOUSEMOVE: + { + int (* API motionfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction; + + if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window) + { + int keys = 0; + SHORT x = SHORT1FROMMP(mp1), y = SHORT2FROMMP(mp1); + + if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000) + keys = DW_BUTTON1_MASK; + if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000) + keys |= DW_BUTTON2_MASK; + if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000) + keys |= DW_BUTTON3_MASK; + + result = motionfunc(tmp->window, x, _get_height(hWnd) - y, keys, tmp->data); + tmp = NULL; + } + } + break; + case WM_CHAR: + { + int (* API keypressfunc)(HWND, char, int, int, void *) = (int (* API)(HWND, char, int, int, void *))tmp->signalfunction; + + if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP)) + { + int vk; + char ch = 0; + + if(SHORT1FROMMP(mp1) & KC_CHAR) + ch = (char)SHORT1FROMMP(mp2); + if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY) + vk = SHORT2FROMMP(mp2); + else + vk = SHORT1FROMMP(mp2) + 128; + + /* This is a hack to fix shift presses showing + * up as tabs! + */ + if(ch == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR)) + { + ch = 0; + vk = VK_SHIFT; + } + + result = keypressfunc(tmp->window, ch, vk, + SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data); + tmp = NULL; + } + } + break; + case WM_CLOSE: + { + int (* API closefunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; + + if(hWnd == tmp->window || hWnd == WinWindowFromID(tmp->window, FID_CLIENT)) + { + result = closefunc(tmp->window, tmp->data); + if(result) + result = FALSE; + tmp = NULL; + } + } + break; + case WM_PAINT: + { + HPS hps; + DWExpose exp; + int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))tmp->signalfunction; + RECTL rc; + + if(hWnd == tmp->window) + { + int height = _get_height(hWnd); + + hps = WinBeginPaint(hWnd, 0L, &rc); + exp.x = rc.xLeft; + exp.y = height - rc.yTop - 1; + exp.width = rc.xRight - rc. xLeft; + exp.height = rc.yTop - rc.yBottom; + result = exposefunc(hWnd, &exp, tmp->data); + WinEndPaint(hps); + } + } + break; + case WM_COMMAND: + { + int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; + ULONG command = COMMANDMSG(&msg)->cmd; + + if(tmp->id && command == tmp->id) + { + HWND menuowner = _menu_owner(tmp->window); + + if(menuowner == hWnd || menuowner == NULLHANDLE) + { + result = clickfunc((HWND)tmp->id, tmp->data); + tmp = NULL; + } + } + else if(tmp->window < 65536 && command == tmp->window) + { + result = clickfunc(popup ? popup : tmp->window, tmp->data); + tmp = NULL; + } + } + break; + case WM_CONTROL: + if(origmsg == WM_VSCROLL || origmsg == WM_HSCROLL || tmp->message == SHORT2FROMMP(mp1) || + (tmp->message == SLN_SLIDERTRACK && SHORT2FROMMP(mp1) == SLN_CHANGE)) + { + int svar = SLN_SLIDERTRACK; + int id = SHORT1FROMMP(mp1); + HWND notifyhwnd = dw_window_from_id(hWnd, id); + + if(origmsg == WM_CONTROL) + svar = SHORT2FROMMP(mp1); + + switch(svar) + { + case CN_ENTER: + { + int (* API containerselectfunc)(HWND, char *, void *) = (int (* API)(HWND, char *, void *))tmp->signalfunction; + char *text = NULL; + + if(mp2) + { + PRECORDCORE pre; + + pre = ((PNOTIFYRECORDENTER)mp2)->pRecord; + if(pre) + text = (char *)pre->pszIcon; + } + + if(tmp->window == notifyhwnd) + { + result = containerselectfunc(tmp->window, text, tmp->data); + tmp = NULL; + } + } + break; + case CN_EXPANDTREE: + { + int (* API treeexpandfunc)(HWND, HTREEITEM, void *) = (int (* API)(HWND, HTREEITEM, void *))tmp->signalfunction; + + if(tmp->window == notifyhwnd) + { + result = treeexpandfunc(tmp->window, (HTREEITEM)mp2, tmp->data); + tmp = NULL; + } + } + break; + case CN_CONTEXTMENU: + { + int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))tmp->signalfunction; + char *text = NULL; + void *user = NULL; + LONG x,y; + + if(mp2) + { + PCNRITEM pci; + + pci = (PCNRITEM)mp2; + + text = (char *)pci->rc.pszIcon; + user = pci->user; + } + + dw_pointer_query_pos(&x, &y); + + if(tmp->window == notifyhwnd) + { + int container = (int)dw_window_get_data(tmp->window, "_dw_container"); + + if(mp2) + { + if(!container) + { + NOTIFYRECORDEMPHASIS pre; + + dw_tree_item_select(tmp->window, (HTREEITEM)mp2); + pre.pRecord = mp2; + pre.fEmphasisMask = CRA_CURSORED; + pre.hwndCnr = tmp->window; + _run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre); + pre.pRecord->flRecordAttr |= CRA_CURSORED; + } + else + { + if(pCoreEmph) + _clear_emphasis(); + hwndEmph = tmp->window; + pCoreEmph = mp2; + WinSendMsg(tmp->window, CM_SETRECORDEMPHASIS, mp2, MPFROM2SHORT(TRUE, CRA_SOURCE)); + } + } + result = containercontextfunc(tmp->window, text, x, y, tmp->data, user); + tmp = NULL; + } + } + break; + case CN_EMPHASIS: + { + PNOTIFYRECORDEMPHASIS pre = (PNOTIFYRECORDEMPHASIS)mp2; + static int emph_recurse = 0; + + if(!emph_recurse) + { + emph_recurse = 1; + + if(mp2) + { + if(tmp->window == pre->hwndCnr) + { + PCNRITEM pci = (PCNRITEM)pre->pRecord; + + if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED)) + { + int (* API treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = (int (* API)(HWND, HTREEITEM, char *, void *, void *))tmp->signalfunction; + + if(dw_window_get_data(tmp->window, "_dw_container")) + result = treeselectfunc(tmp->window, 0, (char *)pci->rc.pszIcon, tmp->data, 0); + else + { + if(lasthcnr == tmp->window && lastitem == (HWND)pci) + { + lasthcnr = 0; + lastitem = 0; + } + else + { + lasthcnr = tmp->window; + lastitem = (HWND)pci; + result = treeselectfunc(tmp->window, (HTREEITEM)pci, (char *)pci->rc.pszIcon, tmp->data, pci->user); + } + } + tmp = NULL; + } + } + } + emph_recurse = 0; + } + } + break; + case LN_SELECT: + { + char classbuf[100]; + + WinQueryClassName(tmp->window, 99, (PCH)classbuf); + + if(strncmp(classbuf, "#38", 4) == 0) + { + int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction; + + if(tmp->window == hWnd || tmp->window == notifyhwnd) + { + static int lastvalue = -1; + static HWND lasthwnd = NULLHANDLE; + int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0); + if(lastvalue != ulValue || lasthwnd != tmp->window) + { + result = valuechangedfunc(tmp->window, ulValue, tmp->data); + lastvalue = ulValue; + lasthwnd = tmp->window; + } + tmp = NULL; + } + } + else + { + int (* API listboxselectfunc)(HWND, int, void *) = (int (* API )(HWND, int, void *))tmp->signalfunction; + static int _recursing = 0; + + if(_recursing == 0 && (tmp->window == notifyhwnd || (!id && tmp->window == (HWND)mp2))) + { + char buf1[500]; + int index = dw_listbox_selected(tmp->window); + + dw_listbox_get_text(tmp->window, index, buf1, 500); + + _recursing = 1; + + if(id && strncmp(classbuf, "#2", 3)==0) + { + char *buf2; + + buf2 = dw_window_get_text(tmp->window); + + /* This is to make sure the listboxselect function doesn't + * get called if the user is modifying the entry text. + */ + if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0) + result = listboxselectfunc(tmp->window, index, tmp->data); + + if(buf2) + free(buf2); + } + else + result = listboxselectfunc(tmp->window, index, tmp->data); + + _recursing = 0; + tmp = NULL; + } + } + } + break; + case SLN_SLIDERTRACK: + { + int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction; + + if(origmsg == WM_CONTROL) + { + /* Handle Slider control */ + if(tmp->window == hWnd || tmp->window == notifyhwnd) + { + static int lastvalue = -1; + static HWND lasthwnd = NULLHANDLE; + int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0); + if(lastvalue != ulValue || lasthwnd != tmp->window) + { + dw_window_set_data(tmp->window, "_dw_slider_value", (void *)ulValue); + result = valuechangedfunc(tmp->window, ulValue, tmp->data); + lastvalue = ulValue; + lasthwnd = tmp->window; + } + tmp = NULL; + } + } + else + { + /* Handle scrollbar control */ + if(tmp->window > 65535 && tmp->window == notifyhwnd) + { + int pos = _HandleScroller(tmp->window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));; + + if(pos > -1) + { + dw_window_set_data(tmp->window, "_dw_scrollbar_value", (void *)pos); + result = valuechangedfunc(tmp->window, pos, tmp->data); + } + result = 0; + tmp = NULL; + } + } + } + break; + case BKN_PAGESELECTED: + { + PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2; + + if(psn && tmp->window == psn->hwndBook) + { + int (* API switchpagefunc)(HWND, unsigned long, void *) = (int (* API)(HWND, unsigned long, void *))tmp->signalfunction; + + result = switchpagefunc(tmp->window, psn->ulPageIdNew, tmp->data); + tmp = NULL; + } + } + break; + } + } + break; + } + } + + if(tmp) + tmp = tmp->next; + + } + return (MRESULT)result; } /* Gets a DW_RGB value from the three spinbuttons */ unsigned long _dw_color_spin_get(HWND window) { - HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin"); - long red, green, blue; - - red = dw_spinbutton_get_pos(button); - button = (HWND)dw_window_get_data(window, "_dw_green_spin"); - green = dw_spinbutton_get_pos(button); - button = (HWND)dw_window_get_data(window, "_dw_blue_spin"); - blue = dw_spinbutton_get_pos(button); - - return DW_RGB(red, green, blue); + HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin"); + long red, green, blue; + + red = dw_spinbutton_get_pos(button); + button = (HWND)dw_window_get_data(window, "_dw_green_spin"); + green = dw_spinbutton_get_pos(button); + button = (HWND)dw_window_get_data(window, "_dw_blue_spin"); + blue = dw_spinbutton_get_pos(button); + + return DW_RGB(red, green, blue); } /* Set the three spinbuttons from a DW_RGB value */ void _dw_color_spin_set(HWND window, unsigned long value) { - HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin"); - dw_window_set_data(window, "_dw_updating", (void *)1); - dw_spinbutton_set_pos(button, DW_RED_VALUE(value)); - button = (HWND)dw_window_get_data(window, "_dw_green_spin"); - dw_spinbutton_set_pos(button, DW_GREEN_VALUE(value)); - button = (HWND)dw_window_get_data(window, "_dw_blue_spin"); - dw_spinbutton_set_pos(button, DW_BLUE_VALUE(value)); - dw_window_set_data(window, "_dw_updating", NULL); + HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin"); + dw_window_set_data(window, "_dw_updating", (void *)1); + dw_spinbutton_set_pos(button, DW_RED_VALUE(value)); + button = (HWND)dw_window_get_data(window, "_dw_green_spin"); + dw_spinbutton_set_pos(button, DW_GREEN_VALUE(value)); + button = (HWND)dw_window_get_data(window, "_dw_blue_spin"); + dw_spinbutton_set_pos(button, DW_BLUE_VALUE(value)); + dw_window_set_data(window, "_dw_updating", NULL); } /* Sets the color selection control to be a DW_RGB value */ void _dw_col_set(HWND col, unsigned long value) { - WinSendMsg(col, 0x0602, MPFROMLONG(_os2_color(value)), 0); - if(!IS_WARP4()) - WinSendMsg(col, 0x1384, MPFROMLONG(_os2_color(value)), 0); + WinSendMsg(col, 0x0602, MPFROMLONG(_os2_color(value)), 0); + if(!IS_WARP4()) + WinSendMsg(col, 0x1384, MPFROMLONG(_os2_color(value)), 0); } /* Handles control messages sent to the box (owner). */ MRESULT EXPENTRY _controlproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - Box *blah = WinQueryWindowPtr(hWnd, QWP_USER); - - switch(msg) - { - case WM_MOUSEMOVE: - if(_wndproc(hWnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - break; - case WM_VSCROLL: - case WM_HSCROLL: - if(_run_event(hWnd, msg, mp1, mp2)) - { - HWND window = WinWindowFromID(hWnd, (ULONG)mp1); - _HandleScroller(window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2)); - } - break; - /* Handles Color Selection control messages */ - case 0x0601: - case 0x130C: - { - HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window"); - unsigned long val = (unsigned long)mp1; - - if(window) - _dw_color_spin_set(window, DW_RGB((val & 0xFF0000) >> 16, (val & 0xFF00) >> 8, val & 0xFF)); - } - break; - case WM_CONTROL: - if((SHORT2FROMMP(mp1) == SPBN_CHANGE || SHORT2FROMMP(mp1) == SPBN_ENDSPIN)) - { - HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window"); - - if(window && !dw_window_get_data(window, "_dw_updating")) - { - unsigned long val = _dw_color_spin_get(window); - HWND col = (HWND)dw_window_get_data(window, "_dw_col"); - - _dw_col_set(col, val); - } - } - _run_event(hWnd, msg, mp1, mp2); - break; - } - - if(blah && blah->oldproc) - return blah->oldproc(hWnd, msg, mp1, mp2); - - return WinDefWindowProc(hWnd, msg, mp1, mp2); + Box *blah = WinQueryWindowPtr(hWnd, QWP_USER); + + switch(msg) + { + case WM_MOUSEMOVE: + if(_wndproc(hWnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + break; + case WM_VSCROLL: + case WM_HSCROLL: + if(_run_event(hWnd, msg, mp1, mp2)) + { + HWND window = WinWindowFromID(hWnd, (ULONG)mp1); + _HandleScroller(window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2)); + } + break; + /* Handles Color Selection control messages */ + case 0x0601: + case 0x130C: + { + HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window"); + unsigned long val = (unsigned long)mp1; + + if(window) + _dw_color_spin_set(window, DW_RGB((val & 0xFF0000) >> 16, (val & 0xFF00) >> 8, val & 0xFF)); + } + break; + case WM_CONTROL: + if((SHORT2FROMMP(mp1) == SPBN_CHANGE || SHORT2FROMMP(mp1) == SPBN_ENDSPIN)) + { + HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window"); + + if(window && !dw_window_get_data(window, "_dw_updating")) + { + unsigned long val = _dw_color_spin_get(window); + HWND col = (HWND)dw_window_get_data(window, "_dw_col"); + + _dw_col_set(col, val); + } + } + _run_event(hWnd, msg, mp1, mp2); + break; + } + + if(blah && blah->oldproc) + return blah->oldproc(hWnd, msg, mp1, mp2); + + return WinDefWindowProc(hWnd, msg, mp1, mp2); } /* The main window procedure for Dynamic Windows, all the resizing code is done here. */ MRESULT EXPENTRY _wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - int result = -1; - static int command_active = 0; - void (* API windowfunc)(PVOID) = 0L; - - if(!command_active) - { + int result = -1; + static int command_active = 0; + void (* API windowfunc)(PVOID) = 0L; + + if(!command_active) + { /* Make sure we don't end up in infinite recursion */ - command_active = 1; - - result = (int)_run_event(hWnd, msg, mp1, mp2); - - command_active = 0; - } - - /* Now that any handlers are done... do normal processing */ - switch( msg ) - { + command_active = 1; + + if(msg == WM_ACTIVATE) + result = (int)_run_event((HWND)mp2, WM_SETFOCUS, 0, mp1); + else + result = (int)_run_event(hWnd, msg, mp1, mp2); + + command_active = 0; + } + + /* Now that any handlers are done... do normal processing */ + switch( msg ) + { case WM_ERASEBACKGROUND: return 0; - case WM_PAINT: - { - HPS hps; - RECTL rc; - - hps = WinBeginPaint( hWnd, 0L, &rc ); - WinEndPaint( hps ); - break; - } - - case WM_SIZE: - { - Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER); - - if(!SHORT1FROMMP(mp2) && !SHORT2FROMMP(mp2)) - return (MPARAM)TRUE; - - if(mybox && mybox->flags != DW_MINIMIZED) - { - /* Hide the window when recalculating to reduce - * CPU load. - */ - WinShowWindow(hWnd, FALSE); - - if(mybox->items) - WinSetWindowPos(mybox->items[0].hwnd, HWND_TOP, 0, 0, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SWP_MOVE | SWP_SIZE); - - _do_resize(mybox, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2)); - - WinShowWindow(hWnd, TRUE); - } - } - break; - case WM_MINMAXFRAME: - { - Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER); - SWP *swp = (SWP *)mp1; - - if(mybox && (swp->fl & SWP_MINIMIZE)) - mybox->flags = DW_MINIMIZED; - - if(mybox && (swp->fl & SWP_RESTORE)) - { - if(!mybox->titlebar && mybox->hwndtitle) - WinSetParent(mybox->hwndtitle, HWND_OBJECT, FALSE); - mybox->flags = 0; - } - - if(mybox && (swp->fl & (SWP_MAXIMIZE | SWP_RESTORE))) - { - int z; - SWP swp2; - - WinQueryWindowPos(swp->hwnd, &swp2); - - if(swp2.cx == swp->cx && swp2.cy == swp->cy) - return FALSE; - - mybox->flags = 0; - - /* Hide the window when recalculating to reduce - * CPU load. - */ - WinShowWindow(hWnd, FALSE); - - _do_resize(mybox, swp->cx, swp->cy); - - if(mybox->count == 1 && mybox->items[0].type == TYPEBOX) - { - mybox = (Box *)WinQueryWindowPtr(mybox->items[0].hwnd, QWP_USER); - - for(z=0;z<mybox->count;z++) - _check_resize_notebook(mybox->items[z].hwnd); - - } - - WinShowWindow(hWnd, TRUE); - } - } - break; - case WM_CONTROL: - switch(SHORT2FROMMP(mp1)) - { - case BKN_PAGESELECTEDPENDING: - { - PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2; - HWND pagehwnd = (HWND)WinSendMsg(psn->hwndBook, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(psn->ulPageIdNew), 0); - Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER); - unsigned long x, y, width, height; - RECTL rc; - - if(pagebox && psn->ulPageIdNew != psn->ulPageIdCur) - { - dw_window_get_pos_size(psn->hwndBook, &x, &y, &width, &height); - - rc.xLeft = x; - rc.yBottom = y; - rc.xRight = x + width; - rc.yTop = y + height; - - WinSendMsg(psn->hwndBook, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE); - - _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom); - } - } - break; - } - break; - case WM_CLOSE: - if(result == -1) - { - dw_window_destroy(WinQueryWindow(hWnd, QW_PARENT)); - return (MRESULT)TRUE; - } - break; - case WM_MOUSEMOVE: - { - HPOINTER pointer; - - if((pointer = (HPOINTER)dw_window_get_data(hWnd, "_dw_pointer")) || - (pointer = (HPOINTER)dw_window_get_data(_toplevel_window(hWnd), "_dw_pointer"))) - { - WinSetPointer(HWND_DESKTOP, pointer); - return MRFROMSHORT(TRUE); - } - } - return MRFROMSHORT(FALSE); - case WM_USER: - windowfunc = (void (* API)(void *))mp1; - - if(windowfunc) - windowfunc((void *)mp2); - break; - case WM_CHAR: - if(SHORT1FROMMP(mp2) == '\t') - { - if(CHARMSG(&msg)->fs & KC_SHIFT) - _shift_focus_back(hWnd); - else - _shift_focus(hWnd); - return FALSE; - } - break; - case WM_DESTROY: - { - HWND parent = WinQueryWindow(hWnd, QW_PARENT); - - /* Free memory before destroying */ - if(parent && WinWindowFromID(parent, FID_CLIENT) == hWnd) - _free_window_memory(parent); - else - _free_window_memory(hWnd); - } - break; - case WM_MENUEND: - /* Delay removing the signal until we've executed - * the signal handler. - */ - WinPostMsg(hWnd, WM_USER+2, mp1, mp2); - break; - case WM_USER+2: - _clear_emphasis(); - if(dw_window_get_data((HWND)mp2, "_dw_popup")) - _free_menu_data((HWND)mp2); - break; - } - - if(result != -1) - return (MRESULT)result; - else - return WinDefWindowProc(hWnd, msg, mp1, mp2); + case WM_PAINT: + { + HPS hps; + RECTL rc; + + hps = WinBeginPaint( hWnd, 0L, &rc ); + WinEndPaint( hps ); + break; + } + + case WM_SIZE: + { + Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER); + + if(!SHORT1FROMMP(mp2) && !SHORT2FROMMP(mp2)) + return (MPARAM)TRUE; + + if(mybox && mybox->flags != DW_MINIMIZED) + { + /* Hide the window when recalculating to reduce + * CPU load. + */ + WinShowWindow(hWnd, FALSE); + + if(mybox->items) + WinSetWindowPos(mybox->items[0].hwnd, HWND_TOP, 0, 0, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SWP_MOVE | SWP_SIZE); + + _do_resize(mybox, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2)); + + WinShowWindow(hWnd, TRUE); + } + } + break; + case WM_MINMAXFRAME: + { + Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER); + SWP *swp = (SWP *)mp1; + + if(mybox && (swp->fl & SWP_MINIMIZE)) + mybox->flags = DW_MINIMIZED; + + if(mybox && (swp->fl & SWP_RESTORE)) + { + if(!mybox->titlebar && mybox->hwndtitle) + WinSetParent(mybox->hwndtitle, HWND_OBJECT, FALSE); + mybox->flags = 0; + } + + if(mybox && (swp->fl & (SWP_MAXIMIZE | SWP_RESTORE))) + { + int z; + SWP swp2; + + WinQueryWindowPos(swp->hwnd, &swp2); + + if(swp2.cx == swp->cx && swp2.cy == swp->cy) + return FALSE; + + mybox->flags = 0; + + /* Hide the window when recalculating to reduce + * CPU load. + */ + WinShowWindow(hWnd, FALSE); + + _do_resize(mybox, swp->cx, swp->cy); + + if(mybox->count == 1 && mybox->items[0].type == TYPEBOX) + { + mybox = (Box *)WinQueryWindowPtr(mybox->items[0].hwnd, QWP_USER); + + for(z=0;z<mybox->count;z++) + _check_resize_notebook(mybox->items[z].hwnd); + + } + + WinShowWindow(hWnd, TRUE); + } + } + break; + case WM_CONTROL: + switch(SHORT2FROMMP(mp1)) + { + case BKN_PAGESELECTEDPENDING: + { + PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2; + HWND pagehwnd = (HWND)WinSendMsg(psn->hwndBook, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(psn->ulPageIdNew), 0); + Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER); + long x, y; + unsigned long width, height; + RECTL rc; + + if(pagebox && psn->ulPageIdNew != psn->ulPageIdCur) + { + dw_window_get_pos_size(psn->hwndBook, &x, &y, &width, &height); + + rc.xLeft = x; + rc.yBottom = y; + rc.xRight = x + width; + rc.yTop = y + height; + + WinSendMsg(psn->hwndBook, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE); + + _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom); + } + } + break; + } + break; + case WM_CLOSE: + if(result == -1) + { + dw_window_destroy(WinQueryWindow(hWnd, QW_PARENT)); + return (MRESULT)TRUE; + } + break; + case WM_MOUSEMOVE: + { + HPOINTER pointer; + + if((pointer = (HPOINTER)dw_window_get_data(hWnd, "_dw_pointer")) || + (pointer = (HPOINTER)dw_window_get_data(_toplevel_window(hWnd), "_dw_pointer"))) + { + WinSetPointer(HWND_DESKTOP, pointer); + return MRFROMSHORT(TRUE); + } + } + return MRFROMSHORT(FALSE); + case WM_USER: + windowfunc = (void (* API)(void *))mp1; + + if(windowfunc) + windowfunc((void *)mp2); + break; + case WM_CHAR: + if(SHORT1FROMMP(mp2) == '\t') + { + if(CHARMSG(&msg)->fs & KC_SHIFT) + _shift_focus_back(hWnd); + else + _shift_focus(hWnd); + return FALSE; + } + break; + case WM_DESTROY: + { + HWND parent = WinQueryWindow(hWnd, QW_PARENT); + + /* Free memory before destroying */ + if(parent && WinWindowFromID(parent, FID_CLIENT) == hWnd) + _free_window_memory(parent); + else + _free_window_memory(hWnd); + } + break; + case WM_MENUEND: + /* Delay removing the signal until we've executed + * the signal handler. + */ + WinPostMsg(hWnd, WM_USER+2, mp1, mp2); + break; + case WM_DDE_INITIATEACK: + /* aswer dde server */ + hwndTrayServer = (HWND)mp1; + break; + case WM_BUTTON1DOWN | 0x2000: + case WM_BUTTON2DOWN | 0x2000: + case WM_BUTTON3DOWN | 0x2000: + case WM_BUTTON1UP | 0x2000: + case WM_BUTTON2UP | 0x2000: + case WM_BUTTON3UP | 0x2000: + if(hwndTaskBar) + result = (int)_run_event(hwndTaskBar, msg & ~0x2000, mp1, mp2); + break; + case WM_USER+2: + _clear_emphasis(); + if(dw_window_get_data((HWND)mp2, "_dw_popup")) + _free_menu_data((HWND)mp2); + break; + } + + if(result != -1) + return (MRESULT)result; + else + return WinDefWindowProc(hWnd, msg, mp1, mp2); } void _changebox(Box *thisbox, int percent, int type) { - int z; - - for(z=0;z<thisbox->count;z++) - { - if(thisbox->items[z].type == TYPEBOX) - { - Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); - _changebox(tmp, percent, type); - } - else - { - if(type == DW_HORZ) - { - if(thisbox->items[z].hsize == SIZEEXPAND) - thisbox->items[z].width = (int)(((float)thisbox->items[z].origwidth) * (((float)percent)/((float)100.0))); - } - else - { - if(thisbox->items[z].vsize == SIZEEXPAND) - thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0))); - } - } - } + int z; + + for(z=0;z<thisbox->count;z++) + { + if(thisbox->items[z].type == TYPEBOX) + { + Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); + _changebox(tmp, percent, type); + } + else + { + if(type == DW_HORZ) + { + if(thisbox->items[z].hsize == SIZEEXPAND) + thisbox->items[z].width = (int)(((float)thisbox->items[z].origwidth) * (((float)percent)/((float)100.0))); + } + else + { + if(thisbox->items[z].vsize == SIZEEXPAND) + thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0))); + } + } + } } void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y) { - float ratio = (float)percent/(float)100.0; - HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft"); - HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright"); - Box *tmp = WinQueryWindowPtr(handle1, QWP_USER); - - WinShowWindow(handle1, FALSE); - WinShowWindow(handle2, FALSE); - - if(type == DW_HORZ) - { - int newx = (int)((float)x * ratio) - (SPLITBAR_WIDTH/2); - - WinSetWindowPos(handle1, NULLHANDLE, 0, 0, newx, y, SWP_MOVE | SWP_SIZE); - _do_resize(tmp, newx - 1, y - 1); - - dw_window_set_data(hwnd, "_dw_start", (void *)newx); - - tmp = WinQueryWindowPtr(handle2, QWP_USER); - - newx = x - newx - SPLITBAR_WIDTH; - - WinSetWindowPos(handle2, NULLHANDLE, x - newx, 0, newx, y, SWP_MOVE | SWP_SIZE); - _do_resize(tmp, newx - 1, y - 1); - } - else - { - int newy = (int)((float)y * ratio) - (SPLITBAR_WIDTH/2); - - WinSetWindowPos(handle1, NULLHANDLE, 0, y - newy, x, newy, SWP_MOVE | SWP_SIZE); - _do_resize(tmp, x - 1, newy - 1); - - tmp = WinQueryWindowPtr(handle2, QWP_USER); - - newy = y - newy - SPLITBAR_WIDTH; - - WinSetWindowPos(handle2, NULLHANDLE, 0, 0, x, newy, SWP_MOVE | SWP_SIZE); - _do_resize(tmp, x - 1, newy - 1); - - dw_window_set_data(hwnd, "_dw_start", (void *)newy); - } - - WinShowWindow(handle1, TRUE); - WinShowWindow(handle2, TRUE); + float ratio = (float)percent/(float)100.0; + HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft"); + HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright"); + Box *tmp = WinQueryWindowPtr(handle1, QWP_USER); + + WinShowWindow(handle1, FALSE); + WinShowWindow(handle2, FALSE); + + if(type == DW_HORZ) + { + int newx = (int)((float)x * ratio) - (SPLITBAR_WIDTH/2); + + WinSetWindowPos(handle1, NULLHANDLE, 0, 0, newx, y, SWP_MOVE | SWP_SIZE); + _do_resize(tmp, newx - 1, y - 1); + + dw_window_set_data(hwnd, "_dw_start", (void *)newx); + + tmp = WinQueryWindowPtr(handle2, QWP_USER); + + newx = x - newx - SPLITBAR_WIDTH; + + WinSetWindowPos(handle2, NULLHANDLE, x - newx, 0, newx, y, SWP_MOVE | SWP_SIZE); + _do_resize(tmp, newx - 1, y - 1); + } + else + { + int newy = (int)((float)y * ratio) - (SPLITBAR_WIDTH/2); + + WinSetWindowPos(handle1, NULLHANDLE, 0, y - newy, x, newy, SWP_MOVE | SWP_SIZE); + _do_resize(tmp, x - 1, newy - 1); + + tmp = WinQueryWindowPtr(handle2, QWP_USER); + + newy = y - newy - SPLITBAR_WIDTH; + + WinSetWindowPos(handle2, NULLHANDLE, 0, 0, x, newy, SWP_MOVE | SWP_SIZE); + _do_resize(tmp, x - 1, newy - 1); + + dw_window_set_data(hwnd, "_dw_start", (void *)newy); + } + + WinShowWindow(handle1, TRUE); + WinShowWindow(handle2, TRUE); } /* This handles any activity on the splitbars (sizers) */ MRESULT EXPENTRY _splitwndproc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - switch (msg) - { - case WM_ACTIVATE: - case WM_SETFOCUS: - return (MRESULT)(FALSE); - - case WM_PAINT: - { - HPS hps; - POINTL ptl[2]; - RECTL rcl; - int type = (int)dw_window_get_data(hwnd, "_dw_type"); - int start = (int)dw_window_get_data(hwnd, "_dw_start"); - - hps = WinBeginPaint(hwnd, 0, 0); - - WinQueryWindowRect(hwnd, &rcl); - - if(type == DW_HORZ) - { - ptl[0].x = rcl.xLeft + start; - ptl[0].y = rcl.yBottom; - ptl[1].x = rcl.xRight + start + 3; - ptl[1].y = rcl.yTop; - } - else - { - ptl[0].x = rcl.xLeft; - ptl[0].y = rcl.yBottom + start; - ptl[1].x = rcl.xRight; - ptl[1].y = rcl.yTop + start + 3; - } - - - GpiSetColor(hps, CLR_PALEGRAY); - GpiMove(hps, &ptl[0]); - GpiBox(hps, DRO_OUTLINEFILL, &ptl[1], 0, 0); - WinEndPaint(hps); - } - return MRFROMSHORT(FALSE); - - case WM_MOUSEMOVE: - { - int type = (int)dw_window_get_data(hwnd, "_dw_type"); - - if(type == DW_HORZ) - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, - SPTR_SIZEWE, - FALSE)); - else - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, - SPTR_SIZENS, - FALSE)); - } - return MRFROMSHORT(FALSE); - case WM_BUTTON1DOWN: - { - APIRET rc; - RECTL rclFrame; - RECTL rclBounds; - float *percent = (float *)dw_window_get_data(hwnd, "_dw_percent"); - int type = (int)dw_window_get_data(hwnd, "_dw_type"); - int start = (int)dw_window_get_data(hwnd, "_dw_start"); - - WinQueryWindowRect(hwnd, &rclFrame); - WinQueryWindowRect(hwnd, &rclBounds); - - WinMapWindowPoints(hwnd, HWND_DESKTOP, - (PPOINTL)&rclBounds, 2); - - - if(type == DW_HORZ) - { - rclFrame.xLeft = start; - rclFrame.xRight = start + SPLITBAR_WIDTH; - } - else - { - rclFrame.yBottom = start; - rclFrame.yTop = start + SPLITBAR_WIDTH; - } - - if(percent) - { - rc = _TrackRectangle(hwnd, &rclFrame, &rclBounds); - - if(rc == TRUE) - { - int width = (rclBounds.xRight - rclBounds.xLeft); - int height = (rclBounds.yTop - rclBounds.yBottom); - - if(type == DW_HORZ) - { - start = rclFrame.xLeft - rclBounds.xLeft; - if(width - SPLITBAR_WIDTH > 1 && start < width - SPLITBAR_WIDTH) - *percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * 100.0; - } - else - { - start = rclFrame.yBottom - rclBounds.yBottom; - if(height - SPLITBAR_WIDTH > 1 && start < height - SPLITBAR_WIDTH) - *percent = 100.0 - (((float)start / (float)(height - SPLITBAR_WIDTH)) * 100.0); - } - _handle_splitbar_resize(hwnd, *percent, type, width, height); - _handle_splitbar_resize(hwnd, *percent, type, width, height); - } - } - } - return MRFROMSHORT(FALSE); - } - return WinDefWindowProc(hwnd, msg, mp1, mp2); + switch (msg) + { + case WM_ACTIVATE: + case WM_SETFOCUS: + return (MRESULT)(FALSE); + + case WM_PAINT: + { + HPS hps; + POINTL ptl[2]; + RECTL rcl; + int type = (int)dw_window_get_data(hwnd, "_dw_type"); + int start = (int)dw_window_get_data(hwnd, "_dw_start"); + + hps = WinBeginPaint(hwnd, 0, 0); + + WinQueryWindowRect(hwnd, &rcl); + + if(type == DW_HORZ) + { + ptl[0].x = rcl.xLeft + start; + ptl[0].y = rcl.yBottom; + ptl[1].x = rcl.xRight + start + 3; + ptl[1].y = rcl.yTop; + } + else + { + ptl[0].x = rcl.xLeft; + ptl[0].y = rcl.yBottom + start; + ptl[1].x = rcl.xRight; + ptl[1].y = rcl.yTop + start + 3; + } + + + GpiSetColor(hps, CLR_PALEGRAY); + GpiMove(hps, &ptl[0]); + GpiBox(hps, DRO_OUTLINEFILL, &ptl[1], 0, 0); + WinEndPaint(hps); + } + return MRFROMSHORT(FALSE); + + case WM_MOUSEMOVE: + { + int type = (int)dw_window_get_data(hwnd, "_dw_type"); + + if(type == DW_HORZ) + WinSetPointer(HWND_DESKTOP, + WinQuerySysPointer(HWND_DESKTOP, + SPTR_SIZEWE, + FALSE)); + else + WinSetPointer(HWND_DESKTOP, + WinQuerySysPointer(HWND_DESKTOP, + SPTR_SIZENS, + FALSE)); + } + return MRFROMSHORT(FALSE); + case WM_BUTTON1DOWN: + { + APIRET rc; + RECTL rclFrame; + RECTL rclBounds; + float *percent = (float *)dw_window_get_data(hwnd, "_dw_percent"); + int type = (int)dw_window_get_data(hwnd, "_dw_type"); + int start = (int)dw_window_get_data(hwnd, "_dw_start"); + + WinQueryWindowRect(hwnd, &rclFrame); + WinQueryWindowRect(hwnd, &rclBounds); + + WinMapWindowPoints(hwnd, HWND_DESKTOP, + (PPOINTL)&rclBounds, 2); + + + if(type == DW_HORZ) + { + rclFrame.xLeft = start; + rclFrame.xRight = start + SPLITBAR_WIDTH; + } + else + { + rclFrame.yBottom = start; + rclFrame.yTop = start + SPLITBAR_WIDTH; + } + + if(percent) + { + rc = _TrackRectangle(hwnd, &rclFrame, &rclBounds); + + if(rc == TRUE) + { + int width = (rclBounds.xRight - rclBounds.xLeft); + int height = (rclBounds.yTop - rclBounds.yBottom); + + if(type == DW_HORZ) + { + start = rclFrame.xLeft - rclBounds.xLeft; + if(width - SPLITBAR_WIDTH > 1 && start < width - SPLITBAR_WIDTH) + *percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * 100.0; + } + else + { + start = rclFrame.yBottom - rclBounds.yBottom; + if(height - SPLITBAR_WIDTH > 1 && start < height - SPLITBAR_WIDTH) + *percent = 100.0 - (((float)start / (float)(height - SPLITBAR_WIDTH)) * 100.0); + } + _handle_splitbar_resize(hwnd, *percent, type, width, height); + _handle_splitbar_resize(hwnd, *percent, type, width, height); + } + } + } + return MRFROMSHORT(FALSE); + } + return WinDefWindowProc(hwnd, msg, mp1, mp2); } /* Function: BubbleProc @@ -3036,124 +3538,124 @@ */ MRESULT EXPENTRY _BubbleProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - MRESULT res; - PFNWP proc = (PFNWP)WinQueryWindowPtr(hwnd, QWL_USER); - - if(proc) - res = proc(hwnd, msg, mp1, mp2); - else - res = WinDefWindowProc(hwnd, msg, mp1, mp2); - - if(msg == WM_PAINT) - { - POINTL ptl; - HPS hpsTemp; - RECTL rcl; - int height, width; - - WinQueryWindowRect(hwnd, &rcl); - height = rcl.yTop - rcl.yBottom - 1; - width = rcl.xRight - rcl.xLeft - 1; - - /* Draw a border around the bubble help */ - hpsTemp = WinGetPS(hwnd); - GpiSetColor(hpsTemp, CLR_BLACK); - ptl.x = ptl.y = 0; - GpiMove(hpsTemp, &ptl); - ptl.x = 0; - ptl.y = height; - GpiLine(hpsTemp, &ptl); - ptl.x = ptl.y = 0; - GpiMove(hpsTemp, &ptl); - ptl.y = 0; - ptl.x = width; - GpiLine(hpsTemp, &ptl); - ptl.x = width; - ptl.y = height; - GpiMove(hpsTemp, &ptl); - ptl.x = 0; - ptl.y = height; - GpiLine(hpsTemp, &ptl); - ptl.x = width; - ptl.y = height; - GpiMove(hpsTemp, &ptl); - ptl.y = 0; - ptl.x = width; - GpiLine(hpsTemp, &ptl); - WinReleasePS(hpsTemp); - } - return res; + MRESULT res; + PFNWP proc = (PFNWP)WinQueryWindowPtr(hwnd, QWL_USER); + + if(proc) + res = proc(hwnd, msg, mp1, mp2); + else + res = WinDefWindowProc(hwnd, msg, mp1, mp2); + + if(msg == WM_PAINT) + { + POINTL ptl; + HPS hpsTemp; + RECTL rcl; + int height, width; + + WinQueryWindowRect(hwnd, &rcl); + height = rcl.yTop - rcl.yBottom - 1; + width = rcl.xRight - rcl.xLeft - 1; + + /* Draw a border around the bubble help */ + hpsTemp = WinGetPS(hwnd); + GpiSetColor(hpsTemp, CLR_BLACK); + ptl.x = ptl.y = 0; + GpiMove(hpsTemp, &ptl); + ptl.x = 0; + ptl.y = height; + GpiLine(hpsTemp, &ptl); + ptl.x = ptl.y = 0; + GpiMove(hpsTemp, &ptl); + ptl.y = 0; + ptl.x = width; + GpiLine(hpsTemp, &ptl); + ptl.x = width; + ptl.y = height; + GpiMove(hpsTemp, &ptl); + ptl.x = 0; + ptl.y = height; + GpiLine(hpsTemp, &ptl); + ptl.x = width; + ptl.y = height; + GpiMove(hpsTemp, &ptl); + ptl.y = 0; + ptl.x = width; + GpiLine(hpsTemp, &ptl); + WinReleasePS(hpsTemp); + } + return res; } MRESULT EXPENTRY _button_draw(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, PFNWP oldproc, int indent) { - HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap"); - HPIXMAP disable = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap_disabled"); - HPOINTER icon = (HPOINTER)dw_window_get_data(hwnd, "_dw_button_icon"); - MRESULT res; - unsigned long width, height; - int x = 5, y = 5; - - dw_window_get_pos_size(hwnd, NULL, NULL, &width, &height); - - if(!oldproc) - res = WinDefWindowProc(hwnd, msg, mp1, mp2); - res = oldproc(hwnd, msg, mp1, mp2); - - if(icon) - { - ULONG halftone = DP_NORMAL; - HPS hps = WinGetPS(hwnd); - POINTERINFO pi; - int cx, cy; - - if(dw_window_get_data(hwnd, "_dw_disabled")) - halftone = DP_HALFTONED; - - cx = width - 10; - cy = height - 10; - - if(WinQueryPointerInfo(icon, &pi)) - { - BITMAPINFOHEADER sl; - int newcx = cx, newcy = cy; - - /* Check the mini icon first */ - if(GpiQueryBitmapParameters(pi.hbmMiniColor, &sl)) - { - if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy) - { - newcx = sl.cx; - newcy = sl.cy; - } - } - /* Check the normal icon second */ - if(GpiQueryBitmapParameters(pi.hbmColor, &sl)) - { - if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy) - { - newcx = sl.cx; - newcy = sl.cy; - } - } - cx = newcx; cy = newcy; - x = (width - cx)/2; - y = (height - cy)/2; - } - WinStretchPointer(hps, x + indent, y - indent, cx, cy, icon, halftone); - WinReleasePS(hps); - } - else if(pixmap) - { - x = (width - pixmap->width)/2; - y = (height - pixmap->height)/2; - - if(disable && dw_window_get_data(hwnd, "_dw_disabled")) - dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, disable, 0, 0); - else - dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, pixmap, 0, 0); - } - return res; + HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap"); + HPIXMAP disable = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap_disabled"); + HPOINTER icon = (HPOINTER)dw_window_get_data(hwnd, "_dw_button_icon"); + MRESULT res; + unsigned long width, height; + int x = 5, y = 5; + + dw_window_get_pos_size(hwnd, NULL, NULL, &width, &height); + + if(!oldproc) + res = WinDefWindowProc(hwnd, msg, mp1, mp2); + res = oldproc(hwnd, msg, mp1, mp2); + + if(icon) + { + ULONG halftone = DP_NORMAL; + HPS hps = WinGetPS(hwnd); + POINTERINFO pi; + int cx, cy; + + if(dw_window_get_data(hwnd, "_dw_disabled")) + halftone = DP_HALFTONED; + + cx = width - 10; + cy = height - 10; + + if(WinQueryPointerInfo(icon, &pi)) + { + BITMAPINFOHEADER sl; + int newcx = cx, newcy = cy; + + /* Check the mini icon first */ + if(GpiQueryBitmapParameters(pi.hbmMiniColor, &sl)) + { + if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy) + { + newcx = sl.cx; + newcy = sl.cy; + } + } + /* Check the normal icon second */ + if(GpiQueryBitmapParameters(pi.hbmColor, &sl)) + { + if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy) + { + newcx = sl.cx; + newcy = sl.cy; + } + } + cx = newcx; cy = newcy; + x = (width - cx)/2; + y = (height - cy)/2; + } + WinStretchPointer(hps, x + indent, y - indent, cx, cy, icon, halftone); + WinReleasePS(hps); + } + else if(pixmap) + { + x = (width - pixmap->width)/2; + y = (height - pixmap->height)/2; + + if(disable && dw_window_get_data(hwnd, "_dw_disabled")) + dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, disable, 0, 0); + else + dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, pixmap, 0, 0); + } + return res; } /* Function: BtProc @@ -3162,304 +3664,314 @@ MRESULT EXPENTRY _BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - BubbleButton *bubble; - PFNWP oldproc; - - bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER); - - if(!bubble) - return WinDefWindowProc(hwnd, msg, mp1, mp2); - - oldproc = bubble->pOldProc; - - switch(msg) - { - case WM_MOUSEMOVE: - if(_wndproc(hwnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - break; - case WM_PAINT: - return _button_draw(hwnd, msg, mp1, mp2, oldproc, 0); - case BM_SETHILITE: - return _button_draw(hwnd, msg, mp1, mp2, oldproc, (int)mp1); - case WM_SETFOCUS: - if(mp2) - _run_event(hwnd, msg, mp1, mp2); - else - WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0); - break; - case WM_BUTTON1DOWN: - case WM_BUTTON2DOWN: - case WM_BUTTON3DOWN: - case WM_BUTTON1DBLCLK: - case WM_BUTTON2DBLCLK: - case WM_BUTTON3DBLCLK: - if(dw_window_get_data(hwnd, "_dw_disabled")) - return (MRESULT)FALSE; - break; - case WM_BUTTON1UP: - { - SignalHandler *tmp = Root; - - if(WinIsWindowEnabled(hwnd) && !dw_window_get_data(hwnd, "_dw_disabled")) - { - /* Find any callbacks for this function */ - while(tmp) - { - if(tmp->message == WM_COMMAND) - { - /* Make sure it's the right window, and the right ID */ - if(tmp->window == hwnd) - { - /* Due to the fact that if we run the function - * here, finishing actions on the button will occur - * after we run the signal handler. So we post the - * message so the button can finish what it needs to - * do before we run our handler. - */ - WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0); - tmp = NULL; - } - } - if(tmp) - tmp= tmp->next; - } - } - } - break; - case WM_USER: - { + BubbleButton *bubble; + PFNWP oldproc; + + bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER); + + if(!bubble) + return WinDefWindowProc(hwnd, msg, mp1, mp2); + + oldproc = bubble->pOldProc; + + switch(msg) + { + case WM_MOUSEMOVE: + if(_wndproc(hwnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + break; + case WM_PAINT: + return _button_draw(hwnd, msg, mp1, mp2, oldproc, 0); + case BM_SETHILITE: + return _button_draw(hwnd, msg, mp1, mp2, oldproc, (int)mp1); + case WM_SETFOCUS: + if(mp2) + _run_event(hwnd, msg, mp1, mp2); + else + WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0); + /* FIX: Borderless buttons not displaying properly after gaining focus */ + if((WinQueryWindowULong(hwnd, QWL_STYLE) & BS_NOBORDER)) + { + RECTL rcl; + + WinQueryWindowRect(hwnd, &rcl); + + WinInvalidateRect(hwnd, &rcl, FALSE); + WinPostMsg(hwnd, WM_PAINT, 0, 0); + } + break; + case WM_BUTTON1DOWN: + case WM_BUTTON2DOWN: + case WM_BUTTON3DOWN: + case WM_BUTTON1DBLCLK: + case WM_BUTTON2DBLCLK: + case WM_BUTTON3DBLCLK: + if(dw_window_get_data(hwnd, "_dw_disabled")) + return (MRESULT)FALSE; + break; + case WM_BUTTON1UP: + { + SignalHandler *tmp = Root; + + if(WinIsWindowEnabled(hwnd) && !dw_window_get_data(hwnd, "_dw_disabled")) + { + /* Find any callbacks for this function */ + while(tmp) + { + if(tmp->message == WM_COMMAND) + { + /* Make sure it's the right window, and the right ID */ + if(tmp->window == hwnd) + { + /* Due to the fact that if we run the function + * here, finishing actions on the button will occur + * after we run the signal handler. So we post the + * message so the button can finish what it needs to + * do before we run our handler. + */ + WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0); + tmp = NULL; + } + } + if(tmp) + tmp= tmp->next; + } + } + } + break; + case WM_USER: + { SignalHandler *tmp = (SignalHandler *)mp1; - int (* API clickfunc)(HWND, void *) = NULL; - - if(tmp) - { - clickfunc = (int (* API)(HWND, void *))tmp->signalfunction; - - clickfunc(tmp->window, tmp->data); - } - } + int (* API clickfunc)(HWND, void *) = NULL; + + if(tmp) + { + clickfunc = (int (* API)(HWND, void *))tmp->signalfunction; + + clickfunc(tmp->window, tmp->data); + } + } break; - case WM_CHAR: - { - /* A button press should also occur for an ENTER or SPACE press - * while the button has the active input focus. - */ - if(SHORT1FROMMP(mp2) == '\r' || SHORT1FROMMP(mp2) == ' ') - { - SignalHandler *tmp = Root; - - /* Find any callbacks for this function */ - while(tmp) - { - if(tmp->message == WM_COMMAND) - { - /* Make sure it's the right window, and the right ID */ - if(tmp->window == hwnd) - { - WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0); - tmp = NULL; - } - } - if(tmp) - tmp= tmp->next; - } - } - if(SHORT1FROMMP(mp2) == '\t') - { - if(CHARMSG(&msg)->fs & KC_SHIFT) - _shift_focus_back(hwnd); - else - _shift_focus(hwnd); - WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0); - return FALSE; - } - else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_LEFT || CHARMSG(&msg)->vkey == VK_UP)) - { - _shift_focus_back(hwnd); - return FALSE; - } - else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_RIGHT || CHARMSG(&msg)->vkey == VK_DOWN)) - { - _shift_focus(hwnd); - return FALSE; - } - } - break; - case 0x041f: - if (hwndBubble) - { - WinDestroyWindow(hwndBubble); - hwndBubble = 0; - } - break; - - case 0x041e: - - if(!*bubble->bubbletext) - break; - - if(hwndBubble) - { - WinDestroyWindow(hwndBubble); - hwndBubble = 0; - } - - if(!hwndBubble) - { - HPS hpsTemp = 0; - LONG lHight; - LONG lWidth; - POINTL txtPointl[TXTBOX_COUNT]; - POINTL ptlWork = {0,0}; - ULONG ulColor = CLR_YELLOW; - void *blah; - - hwndBubbleLast = hwnd; - hwndBubble = WinCreateWindow(HWND_DESKTOP, - WC_STATIC, - "", - SS_TEXT | - DT_CENTER | - DT_VCENTER, + case WM_CHAR: + { + /* A button press should also occur for an ENTER or SPACE press + * while the button has the active input focus. + */ + if(SHORT1FROMMP(mp2) == '\r' || SHORT1FROMMP(mp2) == ' ') + { + SignalHandler *tmp = Root; + + /* Find any callbacks for this function */ + while(tmp) + { + if(tmp->message == WM_COMMAND) + { + /* Make sure it's the right window, and the right ID */ + if(tmp->window == hwnd) + { + WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0); + tmp = NULL; + } + } + if(tmp) + tmp= tmp->next; + } + } + if(SHORT1FROMMP(mp2) == '\t') + { + if(CHARMSG(&msg)->fs & KC_SHIFT) + _shift_focus_back(hwnd); + else + _shift_focus(hwnd); + WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0); + return FALSE; + } + else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_LEFT || CHARMSG(&msg)->vkey == VK_UP)) + { + _shift_focus_back(hwnd); + return FALSE; + } + else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_RIGHT || CHARMSG(&msg)->vkey == VK_DOWN)) + { + _shift_focus(hwnd); + return FALSE; + } + } + break; + case 0x041f: + if (hwndBubble) + { + WinDestroyWindow(hwndBubble); + hwndBubble = 0; + } + break; + + case 0x041e: + + if(!*bubble->bubbletext) + break; + + if(hwndBubble) + { + WinDestroyWindow(hwndBubble); + hwndBubble = 0; + } + + if(!hwndBubble) + { + HPS hpsTemp = 0; + LONG lHight; + LONG lWidth; + POINTL txtPointl[TXTBOX_COUNT]; + POINTL ptlWork = {0,0}; + ULONG ulColor = CLR_YELLOW; + void *blah; + + hwndBubbleLast = hwnd; + hwndBubble = WinCreateWindow(HWND_DESKTOP, + WC_STATIC, + NULL, + SS_TEXT | + DT_CENTER | + DT_VCENTER, 0,0,0,0, - HWND_DESKTOP, - HWND_TOP, - 0, - NULL, - NULL); - - WinSetPresParam(hwndBubble, - PP_FONTNAMESIZE, - strlen(DefaultFont)+1, - DefaultFont); - - - WinSetPresParam(hwndBubble, - PP_BACKGROUNDCOLORINDEX, - sizeof(ulColor), - &ulColor); - - WinSetWindowText(hwndBubble, - bubble->bubbletext); - - WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1); - - hpsTemp = WinGetPS(hwndBubble); - GpiQueryTextBox(hpsTemp, - strlen(bubble->bubbletext), - bubble->bubbletext, - TXTBOX_COUNT, - txtPointl); - WinReleasePS(hpsTemp); - - lWidth = txtPointl[TXTBOX_TOPRIGHT].x - - txtPointl[TXTBOX_TOPLEFT ].x + 8; - - lHight = txtPointl[TXTBOX_TOPLEFT].y - - txtPointl[TXTBOX_BOTTOMLEFT].y + 8; - - ptlWork.y -= lHight; - - blah = (void *)WinSubclassWindow(hwndBubble, _BubbleProc); - - if(blah) - WinSetWindowPtr(hwndBubble, QWP_USER, blah); - - WinSetWindowPos(hwndBubble, - HWND_TOP, - ptlWork.x, - ptlWork.y, - lWidth, - lHight, - SWP_SIZE | SWP_MOVE | SWP_SHOW); - } - break; - } - - if(!oldproc) - return WinDefWindowProc(hwnd, msg, mp1, mp2); - return oldproc(hwnd, msg, mp1, mp2); + HWND_DESKTOP, + HWND_TOP, + 0, + NULL, + NULL); + + WinSetPresParam(hwndBubble, + PP_FONTNAMESIZE, + strlen(DefaultFont)+1, + DefaultFont); + + + WinSetPresParam(hwndBubble, + PP_BACKGROUNDCOLORINDEX, + sizeof(ulColor), + &ulColor); + + WinSetWindowText(hwndBubble, + (PSZ)bubble->bubbletext); + + WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1); + + hpsTemp = WinGetPS(hwndBubble); + GpiQueryTextBox(hpsTemp, + strlen(bubble->bubbletext), + (PCH)bubble->bubbletext, + TXTBOX_COUNT, + txtPointl); + WinReleasePS(hpsTemp); + + lWidth = txtPointl[TXTBOX_TOPRIGHT].x - + txtPointl[TXTBOX_TOPLEFT ].x + 8; + + lHight = txtPointl[TXTBOX_TOPLEFT].y - + txtPointl[TXTBOX_BOTTOMLEFT].y + 8; + + ptlWork.y -= lHight; + + blah = (void *)WinSubclassWindow(hwndBubble, _BubbleProc); + + if(blah) + WinSetWindowPtr(hwndBubble, QWP_USER, blah); + + WinSetWindowPos(hwndBubble, + HWND_TOP, + ptlWork.x, + ptlWork.y, + lWidth, + lHight, + SWP_SIZE | SWP_MOVE | SWP_SHOW); + } + break; + } + + if(!oldproc) + return WinDefWindowProc(hwnd, msg, mp1, mp2); + return oldproc(hwnd, msg, mp1, mp2); } MRESULT EXPENTRY _RendProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - int res = 0; - res = (int)_run_event(hwnd, msg, mp1, mp2); - switch(msg) - { - case WM_MOUSEMOVE: - if(_wndproc(hwnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - break; - case WM_BUTTON1DOWN: - case WM_BUTTON2DOWN: - case WM_BUTTON3DOWN: - if(res == -1) - WinSetFocus(HWND_DESKTOP, hwnd); - else if(res) - return (MPARAM)TRUE; - } - return WinDefWindowProc(hwnd, msg, mp1, mp2); + int res = 0; + res = (int)_run_event(hwnd, msg, mp1, mp2); + switch(msg) + { + case WM_MOUSEMOVE: + if(_wndproc(hwnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + break; + case WM_BUTTON1DOWN: + case WM_BUTTON2DOWN: + case WM_BUTTON3DOWN: + if(res == -1) + WinSetFocus(HWND_DESKTOP, hwnd); + else if(res) + return (MPARAM)TRUE; + } + return WinDefWindowProc(hwnd, msg, mp1, mp2); } MRESULT EXPENTRY _TreeProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(hwnd, QWP_USER); - PFNWP oldproc = 0; - - if(blah) - oldproc = blah->oldproc; - - switch(msg) - { - case WM_MOUSEMOVE: - if(_wndproc(hwnd, msg, mp1, mp2)) - return MPFROMSHORT(FALSE); - break; - case WM_PAINT: - { - HPS hps; - RECTL rcl; - POINTL ptl[2]; - - if(oldproc) - oldproc(hwnd, msg, mp1, mp2); - - hps = WinBeginPaint(hwnd, 0, 0); - WinQueryWindowRect(hwnd, &rcl); - ptl[0].x = rcl.xLeft + 1; - ptl[0].y = rcl.yBottom + 1; - ptl[1].x = rcl.xRight - 1; - ptl[1].y = rcl.yTop - 1; - - GpiSetColor(hps, CLR_BLACK); - GpiMove(hps, &ptl[0]); - GpiBox(hps, DRO_OUTLINE, &ptl[1], 0, 0); - WinEndPaint(hps); - } - return MRFROMSHORT(FALSE); - case WM_SETFOCUS: - _run_event(hwnd, msg, mp1, mp2); - break; - case WM_CHAR: - if(SHORT1FROMMP(mp2) == '\t') - { - if(CHARMSG(&msg)->fs & KC_SHIFT) - _shift_focus_back(hwnd); - else - _shift_focus(hwnd); - return FALSE; - } - break; - } - - _run_event(hwnd, msg, mp1, mp2); - - if(oldproc) - return oldproc(hwnd, msg, mp1, mp2); - - return WinDefWindowProc(hwnd, msg, mp1, mp2); + WindowData *blah = (WindowData *)WinQueryWindowPtr(hwnd, QWP_USER); + PFNWP oldproc = 0; + + if(blah) + oldproc = blah->oldproc; + + switch(msg) + { + case WM_MOUSEMOVE: + if(_wndproc(hwnd, msg, mp1, mp2)) + return MPFROMSHORT(FALSE); + break; + case WM_PAINT: + { + HPS hps; + RECTL rcl; + POINTL ptl[2]; + + if(oldproc) + oldproc(hwnd, msg, mp1, mp2); + + hps = WinBeginPaint(hwnd, 0, 0); + WinQueryWindowRect(hwnd, &rcl); + ptl[0].x = rcl.xLeft + 1; + ptl[0].y = rcl.yBottom + 1; + ptl[1].x = rcl.xRight - 1; + ptl[1].y = rcl.yTop - 1; + + GpiSetColor(hps, CLR_BLACK); + GpiMove(hps, &ptl[0]); + GpiBox(hps, DRO_OUTLINE, &ptl[1], 0, 0); + WinEndPaint(hps); + } + return MRFROMSHORT(FALSE); + case WM_SETFOCUS: + _run_event(hwnd, msg, mp1, mp2); + break; + case WM_CHAR: + if(SHORT1FROMMP(mp2) == '\t') + { + if(CHARMSG(&msg)->fs & KC_SHIFT) + _shift_focus_back(hwnd); + else + _shift_focus(hwnd); + return FALSE; + } + break; + } + + _run_event(hwnd, msg, mp1, mp2); + + if(oldproc) + return oldproc(hwnd, msg, mp1, mp2); + + return WinDefWindowProc(hwnd, msg, mp1, mp2); } /* @@ -3470,35 +3982,43 @@ */ int API dw_init(int newthread, int argc, char *argv[]) { - APIRET rc; - char objnamebuf[300] = ""; - - argc = argc; /* keep compiler happy */ - argv = argv; /* keep compiler happy */ - if(newthread) - { - dwhab = WinInitialize(0); - dwhmq = WinCreateMsgQueue(dwhab, 0); - } - - rc = WinRegisterClass(dwhab, ClassName, _wndproc, CS_SIZEREDRAW | CS_CLIPCHILDREN, 32); - rc = WinRegisterClass(dwhab, SplitbarClassName, _splitwndproc, 0L, 32); - - /* Get the OS/2 version. */ - DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG)); - - desktop = WinQueryDesktopWindow(dwhab, NULLHANDLE); - - if(!IS_WARP4()) - DefaultFont = "8.Helv"; - - /* This is a window that hangs around as long as the - * application does and handles menu messages. - */ - hwndApp = dw_window_new(HWND_OBJECT, "", 0); - DosLoadModule(objnamebuf, sizeof(objnamebuf), "WPCONFIG", &wpconfig); - - return rc; + APIRET rc; + char objnamebuf[300] = ""; + + argc = argc; /* keep compiler happy */ + argv = argv; /* keep compiler happy */ + if(newthread) + { + dwhab = WinInitialize(0); + dwhmq = WinCreateMsgQueue(dwhab, 0); + } + + rc = WinRegisterClass(dwhab, (PSZ)ClassName, _wndproc, CS_SIZEREDRAW | CS_CLIPCHILDREN, 32); + rc = WinRegisterClass(dwhab, (PSZ)SplitbarClassName, _splitwndproc, 0L, 32); + rc = WinRegisterClass(dwhab, (PSZ)ScrollClassName, _scrollwndproc, 0L, 32); + + /* Get the OS/2 version. */ + DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG)); + + desktop = WinQueryDesktopWindow(dwhab, NULLHANDLE); + + if(!IS_WARP4()) + DefaultFont = strdup("8.Helv"); + else + DefaultFont = strdup(DefaultFont); + + /* This is a window that hangs around as long as the + * application does and handles menu messages. + */ + hwndApp = dw_window_new(HWND_OBJECT, "", 0); + /* Attempt to locate a tray server */ + WinDdeInitiate(hwndApp, (PSZ)"SystrayServer", (PSZ)"TRAY", NULL); + + /* Load DLLs for providing extra functionality if available */ + DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"WPCONFIG", &wpconfig); + if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"PMPRINTF", &pmprintf)) + DosQueryProcAddr(pmprintf, 0, (PSZ)"PmPrintfString", (PFN*)&_PmPrintfString); + return rc; } /* @@ -3506,19 +4026,19 @@ */ void API dw_main(void) { - QMSG qmsg; - - _dwtid = dw_thread_id(); - - while(WinGetMsg(dwhab, &qmsg, 0, 0, 0)) - { - if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) - _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); - WinDispatchMsg(dwhab, &qmsg); - } - - WinDestroyMsgQueue(dwhmq); - WinTerminate(dwhab); + QMSG qmsg; + + _dwtid = dw_thread_id(); + + while(WinGetMsg(dwhab, &qmsg, 0, 0, 0)) + { + if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) + _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); + WinDispatchMsg(dwhab, &qmsg); + } + + WinDestroyMsgQueue(dwhmq); + WinTerminate(dwhab); } /* @@ -3528,41 +4048,41 @@ */ void API dw_main_sleep(int milliseconds) { - QMSG qmsg; + QMSG qmsg; #ifdef __EMX__ - struct timeval tv, start; - - gettimeofday(&start, NULL); - gettimeofday(&tv, NULL); - - while(((tv.tv_sec - start.tv_sec)*1000) + ((tv.tv_usec - start.tv_usec)/1000) <= milliseconds) - { - if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE)) - { - WinGetMsg(dwhab, &qmsg, 0, 0, 0); - if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) - _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); - WinDispatchMsg(dwhab, &qmsg); - } - else - DosSleep(1); - gettimeofday(&tv, NULL); - } + struct timeval tv, start; + + gettimeofday(&start, NULL); + gettimeofday(&tv, NULL); + + while(((tv.tv_sec - start.tv_sec)*1000) + ((tv.tv_usec - start.tv_usec)/1000) <= milliseconds) + { + if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE)) + { + WinGetMsg(dwhab, &qmsg, 0, 0, 0); + if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) + _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); + WinDispatchMsg(dwhab, &qmsg); + } + else + DosSleep(1); + gettimeofday(&tv, NULL); + } #else - double start = (double)clock(); - - while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds) - { - if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE)) - { - WinGetMsg(dwhab, &qmsg, 0, 0, 0); - if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) - _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); - WinDispatchMsg(dwhab, &qmsg); - } - else - DosSleep(1); - } + double start = (double)clock(); + + while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds) + { + if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE)) + { + WinGetMsg(dwhab, &qmsg, 0, 0, 0); + if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) + _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); + WinDispatchMsg(dwhab, &qmsg); + } + else + DosSleep(1); + } #endif } @@ -3571,16 +4091,16 @@ */ void API dw_main_iteration(void) { - QMSG qmsg; - - _dwtid = dw_thread_id(); - - if(WinGetMsg(dwhab, &qmsg, 0, 0, 0)) - { - if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) - _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); - WinDispatchMsg(dwhab, &qmsg); - } + QMSG qmsg; + + _dwtid = dw_thread_id(); + + if(WinGetMsg(dwhab, &qmsg, 0, 0, 0)) + { + if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) + _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); + WinDispatchMsg(dwhab, &qmsg); + } } /* @@ -3591,7 +4111,7 @@ */ void API dw_free(void *ptr) { - free(ptr); + free(ptr); } /* @@ -3601,13 +4121,13 @@ */ DWDialog * API dw_dialog_new(void *data) { - DWDialog *tmp = malloc(sizeof(DWDialog)); - - tmp->eve = dw_event_new(); - dw_event_reset(tmp->eve); - tmp->data = data; - tmp->done = FALSE; - tmp->result = NULL; + DWDialog *tmp = malloc(sizeof(DWDialog)); + + tmp->eve = dw_event_new(); + dw_event_reset(tmp->eve); + tmp->data = data; + tmp->done = FALSE; + tmp->result = NULL; return tmp; } @@ -3621,10 +4141,10 @@ */ int API dw_dialog_dismiss(DWDialog *dialog, void *result) { - dialog->result = result; - dw_event_post(dialog->eve); - dialog->done = TRUE; - return 0; + dialog->result = result; + dw_event_post(dialog->eve); + dialog->done = TRUE; + return 0; } /* @@ -3635,23 +4155,43 @@ */ void * API dw_dialog_wait(DWDialog *dialog) { - QMSG qmsg; - void *tmp; - - while (WinGetMsg(dwhab, &qmsg, 0, 0, 0)) - { - if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) - _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); - WinDispatchMsg(dwhab, &qmsg); - if(dialog->done) - break; - } - dw_event_close(&dialog->eve); - tmp = dialog->result; - free(dialog); - return tmp; -} - + QMSG qmsg; + void *tmp; + + while (WinGetMsg(dwhab, &qmsg, 0, 0, 0)) + { + if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE) + _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2); + WinDispatchMsg(dwhab, &qmsg); + if(dialog->done) + break; + } + dw_event_close(&dialog->eve); + tmp = dialog->result; + free(dialog); + return tmp; +} + +/* + * Displays a debug message on the console... + * Parameters: + * format: printf style format string. + * ...: Additional variables for use in the format. + */ +void API dw_debug(char *format, ...) +{ + va_list args; + char outbuf[1024]; + + va_start(args, format); + vsprintf(outbuf, format, args); + va_end(args); + + if(_PmPrintfString) + _PmPrintfString(outbuf); + else + fprintf(stderr, "%s", outbuf); +} /* * Displays a Message Box with given text and title.. @@ -3663,24 +4203,24 @@ */ int API dw_messagebox(char *title, int flags, char *format, ...) { - va_list args; - char outbuf[1024]; - int rc; - - va_start(args, format); - vsprintf(outbuf, format, args); - va_end(args); - - rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, outbuf, title, 0, flags | MB_MOVEABLE); - if(rc == MBID_OK) - return DW_MB_RETURN_OK; - else if(rc == MBID_YES) - return DW_MB_RETURN_YES; - else if(rc == MBID_NO) - return DW_MB_RETURN_NO; - else if(rc == MBID_CANCEL) - return DW_MB_RETURN_CANCEL; - else return 0; + va_list args; + char outbuf[1024]; + int rc; + + va_start(args, format); + vsprintf(outbuf, format, args); + va_end(args); + + rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)outbuf, (PSZ)title, 0, flags | MB_MOVEABLE); + if(rc == MBID_OK) + return DW_MB_RETURN_OK; + else if(rc == MBID_YES) + return DW_MB_RETURN_YES; + else if(rc == MBID_NO) + return DW_MB_RETURN_NO; + else if(rc == MBID_CANCEL) + return DW_MB_RETURN_CANCEL; + else return 0; } /* @@ -3690,7 +4230,7 @@ */ int API dw_window_raise(HWND handle) { - return WinSetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER); + return WinSetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER); } /* @@ -3700,7 +4240,7 @@ */ int API dw_window_lower(HWND handle) { - return WinSetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER); + return WinSetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER); } /* @@ -3710,54 +4250,54 @@ */ int API dw_window_show(HWND handle) { - int rc = WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_SHOW); - HSWITCH hswitch; - SWCNTRL swcntrl; - - _fix_button_owner(_toplevel_window(handle), 0); - WinSetFocus(HWND_DESKTOP, handle); - _initial_focus(handle); - - /* If this window has a switch list entry make sure it is visible */ - hswitch = WinQuerySwitchHandle(handle, 0); - if(hswitch) - { - WinQuerySwitchEntry(hswitch, &swcntrl); - swcntrl.uchVisibility = SWL_VISIBLE; - WinChangeSwitchEntry(hswitch, &swcntrl); - } - if(WinWindowFromID(handle, FID_CLIENT)) - { - WindowData *blah = WinQueryWindowPtr(handle, QWP_USER); - - if(blah && !(blah->flags & DW_OS2_NEW_WINDOW)) - { - ULONG cx = dw_screen_width(), cy = dw_screen_height(); - int newx, newy, changed = 0; - SWP swp; - - blah->flags |= DW_OS2_NEW_WINDOW; - - WinQueryWindowPos(handle, &swp); - - newx = swp.x; - newy = swp.y; - - if((swp.x+swp.cx) > cx) - { - newx = (cx - swp.cx)/2; - changed = 1; - } - if((swp.y+swp.cy) > cy) - { - newy = (cy - swp.cy)/2; - changed = 1; - } - if(changed) - WinSetWindowPos(handle, NULLHANDLE, newx, newy, 0, 0, SWP_MOVE); - } - } - return rc; + int rc = WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_SHOW); + HSWITCH hswitch; + SWCNTRL swcntrl; + + _fix_button_owner(_toplevel_window(handle), 0); + WinSetFocus(HWND_DESKTOP, handle); + _initial_focus(handle); + + /* If this window has a switch list entry make sure it is visible */ + hswitch = WinQuerySwitchHandle(handle, 0); + if(hswitch) + { + WinQuerySwitchEntry(hswitch, &swcntrl); + swcntrl.uchVisibility = SWL_VISIBLE; + WinChangeSwitchEntry(hswitch, &swcntrl); + } + if(WinWindowFromID(handle, FID_CLIENT)) + { + WindowData *blah = WinQueryWindowPtr(handle, QWP_USER); + + if(blah && !(blah->flags & DW_OS2_NEW_WINDOW)) + { + ULONG cx = dw_screen_width(), cy = dw_screen_height(); + int newx, newy, changed = 0; + SWP swp; + + blah->flags |= DW_OS2_NEW_WINDOW; + + WinQueryWindowPos(handle, &swp); + + newx = swp.x; + newy = swp.y; + + if((swp.x+swp.cx) > cx) + { + newx = (cx - swp.cx)/2; + changed = 1; + } + if((swp.y+swp.cy) > cy) + { + newy = (cy - swp.cy)/2; + changed = 1; + } + if(changed) + WinSetWindowPos(handle, NULLHANDLE, newx, newy, 0, 0, SWP_MOVE); + } + } + return rc; } /* @@ -3767,20 +4307,20 @@ */ int API dw_window_minimize(HWND handle) { - HWND hwndclient = WinWindowFromID(handle, FID_CLIENT); - - if(hwndclient) - { - Box *box = (Box *)WinQueryWindowPtr(hwndclient, QWP_USER); - - if(box) - { - if(!box->titlebar && box->hwndtitle) - WinSetParent(box->hwndtitle, handle, FALSE); - } - } - - return WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE); + HWND hwndclient = WinWindowFromID(handle, FID_CLIENT); + + if(hwndclient) + { + Box *box = (Box *)WinQueryWindowPtr(hwndclient, QWP_USER); + + if(box) + { + if(!box->titlebar && box->hwndtitle) + WinSetParent(box->hwndtitle, handle, FALSE); + } + } + + return WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE); } /* @@ -3790,18 +4330,18 @@ */ int API dw_window_hide(HWND handle) { - HSWITCH hswitch; - SWCNTRL swcntrl; - - /* If this window has a switch list entry make sure it is invisible */ - hswitch = WinQuerySwitchHandle(handle, 0); - if(hswitch) - { - WinQuerySwitchEntry(hswitch, &swcntrl); - swcntrl.uchVisibility = SWL_INVISIBLE; - WinChangeSwitchEntry(hswitch, &swcntrl); - } - return WinShowWindow(handle, FALSE); + HSWITCH hswitch; + SWCNTRL swcntrl; + + /* If this window has a switch list entry make sure it is invisible */ + hswitch = WinQuerySwitchHandle(handle, 0); + if(hswitch) + { + WinQuerySwitchEntry(hswitch, &swcntrl); + swcntrl.uchVisibility = SWL_INVISIBLE; + WinChangeSwitchEntry(hswitch, &swcntrl); + } + return WinShowWindow(handle, FALSE); } /* @@ -3811,49 +4351,71 @@ */ int API dw_window_destroy(HWND handle) { - HWND frame, menu, parent = WinQueryWindow(handle, QW_PARENT); - Box *thisbox = WinQueryWindowPtr(parent, QWP_USER); - - if(!handle) - return -1; - - frame = (HWND)dw_window_get_data(handle, "_dw_combo_box"); - - if((menu = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE) - _free_menu_data(menu); - - if(parent != desktop && thisbox && thisbox->count) - { - int z, index = -1; - Item *tmpitem, *thisitem = thisbox->items; - - for(z=0;z<thisbox->count;z++) - { - if(thisitem[z].hwnd == handle) - index = z; - } - - if(index == -1) - return 0; - - tmpitem = malloc(sizeof(Item)*(thisbox->count-1)); - - /* Copy all but the current entry to the new list */ - for(z=0;z<index;z++) - { - tmpitem[z] = thisitem[z]; - } - for(z=index+1;z<thisbox->count;z++) - { - tmpitem[z-1] = thisitem[z]; - } - - thisbox->items = tmpitem; - free(thisitem); - thisbox->count--; - _free_window_memory(frame ? frame : handle); - } - return WinDestroyWindow(frame ? frame : handle); + HWND frame, menu, parent; + Box *thisbox; + + if(!handle) + return DW_ERROR_UNKNOWN; + + /* Handle special case for menu handle */ + if(handle < 65536) + { + char buffer[30]; + + sprintf(buffer, "_dw_id%ld", handle); + menu = (HWND)dw_window_get_data(hwndApp, buffer); + + if(menu && WinIsWindow(dwhab, menu)) + return dw_menu_delete_item((HMENUI)menu, handle); + return DW_ERROR_UNKNOWN; + } + + parent = WinQueryWindow(handle, QW_PARENT); + thisbox = WinQueryWindowPtr(parent, QWP_USER); + frame = (HWND)dw_window_get_data(handle, "_dw_combo_box"); + + if((menu = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE) + _free_menu_data(menu); + + /* If it is a desktop window let WM_DESTROY handle it */ + if(parent != desktop) + { + /* If the parent box has items... + * try to remove it from the layout + */ + if(thisbox && thisbox->count) + { + int z, index = -1; + Item *tmpitem, *thisitem = thisbox->items; + + for(z=0;z<thisbox->count;z++) + { + if(thisitem[z].hwnd == handle) + index = z; + } + + if(index == -1) + return 0; + + tmpitem = malloc(sizeof(Item)*(thisbox->count-1)); + + /* Copy all but the current entry to the new list */ + for(z=0;z<index;z++) + { + tmpitem[z] = thisitem[z]; + } + for(z=index+1;z<thisbox->count;z++) + { + tmpitem[z-1] = thisitem[z]; + } + + thisbox->items = tmpitem; + free(thisitem); + thisbox->count--; + } + _free_window_memory(frame ? frame : handle); + } + return WinDestroyWindow(frame ? frame : handle); } /* Causes entire window to be invalidated and redrawn. @@ -3862,21 +4424,24 @@ */ void API dw_window_redraw(HWND handle) { - HWND client = WinWindowFromID(handle, FID_CLIENT); - HWND window = client ? client : handle; - Box *mybox = (Box *)WinQueryWindowPtr(window, QWP_USER); - - _fix_button_owner(_toplevel_window(handle), 0); - if(window && mybox) - { - unsigned long width, height; - - dw_window_get_pos_size(window, NULL, NULL, &width, &height); - - WinShowWindow(client ? mybox->items[0].hwnd : handle, FALSE); - _do_resize(mybox, width, height); - WinShowWindow(client ? mybox->items[0].hwnd : handle, TRUE); - } + HWND client = WinWindowFromID(handle, FID_CLIENT); + HWND window = client ? client : handle; + Box *mybox = (Box *)WinQueryWindowPtr(window, QWP_USER); + + _fix_button_owner(_toplevel_window(handle), 0); + if(window && mybox) + { + unsigned long width, height; + + dw_window_get_pos_size(window, NULL, NULL, &width, &height); + + if(mybox->items) + WinSetWindowPos(mybox->items[0].hwnd, HWND_TOP, 0, 0, width, height, SWP_MOVE | SWP_SIZE); + + WinShowWindow(client && mybox->items ? mybox->items[0].hwnd : handle, FALSE); + _do_resize(mybox, width, height); + WinShowWindow(client && mybox->items ? mybox->items[0].hwnd : handle, TRUE); + } } /* @@ -3887,8 +4452,78 @@ */ void API dw_window_reparent(HWND handle, HWND newparent) { - HWND blah = WinWindowFromID(newparent, FID_CLIENT); - WinSetParent(handle, blah ? blah : newparent, TRUE); + HWND blah = WinWindowFromID(newparent, FID_CLIENT); + WinSetParent(handle, blah ? blah : newparent, TRUE); +} + +/* Allows the user to choose a font using the system's font chooser dialog. + * Parameters: + * currfont: current font + * Returns: + * A malloced buffer with the selected font or NULL on error. + */ +char * API dw_font_choose(char *currfont) +{ + FONTDLG fd = { 0 }; + char *buf = calloc(1,100); + int size = 9; + + /* Fill in the family name if possible */ + if(currfont) + { + char *name = strchr(currfont, '.'); + if(name) + { + int newsize = atoi(currfont); + if(newsize > 0) + size = newsize; + name++; + strcpy(buf, name); + strcpy(fd.fAttrs.szFacename, name); + } + else + { + strcpy(buf, currfont); + strcpy(fd.fAttrs.szFacename, currfont); + } + } + + /* Fill in the font dialog struct */ + fd.cbSize = sizeof(fd); + fd.hpsScreen = WinGetScreenPS(HWND_DESKTOP); + fd.pszTitle = (PSZ)"Choose Font"; + fd.clrFore = CLR_BLACK; + fd.clrBack = CLR_WHITE; + fd.pszFamilyname = (PSZ)buf; + fd.usFamilyBufLen = 100; + fd.fxPointSize = MAKEFIXED(size,0); + fd.fl = FNTS_INITFROMFATTRS; + + /* Show the dialog and wait for a response */ + if(!WinFontDlg(HWND_DESKTOP, HWND_OBJECT, &fd) || fd.lReturn != DID_OK) + { + WinReleasePS(fd.hpsScreen); + free(buf); + return NULL; + } + WinReleasePS(fd.hpsScreen); + /* Figure out what the user selected and return that */ + size = FIXEDINT(fd.fxPointSize); + sprintf(buf, "%d.%s", size, fd.fAttrs.szFacename); + return buf; +} + +/* + * Sets the default font used on text based widgets. + * Parameters: + * fontname: Font name in Dynamic Windows format. + */ +void API dw_font_set_default(char *fontname) +{ + char *oldfont = DefaultFont; + + DefaultFont = strdup(fontname); + free(oldfont); } /* @@ -3899,49 +4534,65 @@ */ int API dw_window_set_font(HWND handle, char *fontname) { - return WinSetPresParam(handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname); + HWND group = (HWND)dw_window_get_data(handle, "_dw_buddy"); + return WinSetPresParam(group ? group : handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname); +} + +/* + * Gets the font used by a specified window (widget) handle. + * Parameters: + * handle: The window (widget) handle. + * fontname: Name and size of the font in the form "size.fontname" + */ +char * API dw_window_get_font(HWND handle) +{ + char *str = (char *)alloca(50); + HWND group = (HWND)dw_window_get_data(handle, "_dw_buddy"); + if(str && WinQueryPresParam(group ? group : handle, PP_FONTNAMESIZE, 0, NULL, 50, str, QPF_NOINHERIT)) + return strdup(str); + return NULL; } /* Internal version */ int _dw_window_set_color(HWND handle, ULONG fore, ULONG back) { - if((fore & DW_RGB_COLOR) == DW_RGB_COLOR) - { - RGB2 rgb2; - - rgb2.bBlue = DW_BLUE_VALUE(fore); - rgb2.bGreen = DW_GREEN_VALUE(fore); - rgb2.bRed = DW_RED_VALUE(fore); - rgb2.fcOptions = 0; - - WinSetPresParam(handle, PP_FOREGROUNDCOLOR, sizeof(RGB2), &rgb2); - - } - else if(fore != DW_CLR_DEFAULT) - { - fore = _internal_color(fore); - - WinSetPresParam(handle, PP_FOREGROUNDCOLORINDEX, sizeof(ULONG), &fore); - } - if((back & DW_RGB_COLOR) == DW_RGB_COLOR) - { - RGB2 rgb2; - - rgb2.bBlue = DW_BLUE_VALUE(back); - rgb2.bGreen = DW_GREEN_VALUE(back); - rgb2.bRed = DW_RED_VALUE(back); - rgb2.fcOptions = 0; - - WinSetPresParam(handle, PP_BACKGROUNDCOLOR, sizeof(RGB2), &rgb2); - return 0; - } - else if(back != DW_CLR_DEFAULT) - { - back = _internal_color(back); - - WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back); - } - return 0; + if((fore & DW_RGB_COLOR) == DW_RGB_COLOR) + { + RGB2 rgb2; + + rgb2.bBlue = DW_BLUE_VALUE(fore); + rgb2.bGreen = DW_GREEN_VALUE(fore); + rgb2.bRed = DW_RED_VALUE(fore); + rgb2.fcOptions = 0; + + WinSetPresParam(handle, PP_FOREGROUNDCOLOR, sizeof(RGB2), &rgb2); + + } + else if(fore != DW_CLR_DEFAULT) + { + fore = _internal_color(fore); + + WinSetPresParam(handle, PP_FOREGROUNDCOLORINDEX, sizeof(ULONG), &fore); + } + if((back & DW_RGB_COLOR) == DW_RGB_COLOR) + { + RGB2 rgb2; + + rgb2.bBlue = DW_BLUE_VALUE(back); + rgb2.bGreen = DW_GREEN_VALUE(back); + rgb2.bRed = DW_RED_VALUE(back); + rgb2.fcOptions = 0; + + WinSetPresParam(handle, PP_BACKGROUNDCOLOR, sizeof(RGB2), &rgb2); + return 0; + } + else if(back != DW_CLR_DEFAULT) + { + back = _internal_color(back); + + WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back); + } + return 0; } /* * Sets the colors used by a specified window (widget) handle. @@ -3952,10 +4603,10 @@ */ int API dw_window_set_color(HWND handle, ULONG fore, ULONG back) { - dw_window_set_data(handle, "_dw_fore", (void *)(fore+1)); - dw_window_set_data(handle, "_dw_back", (void *)(back+1)); - - return _dw_window_set_color(handle, fore, back); + dw_window_set_data(handle, "_dw_fore", (void *)(fore+1)); + dw_window_set_data(handle, "_dw_back", (void *)(back+1)); + + return _dw_window_set_color(handle, fore, back); } /* @@ -3966,8 +4617,8 @@ */ int API dw_window_set_border(HWND handle, int border) { - WinSendMsg(handle, WM_SETBORDERSIZE, MPFROMSHORT(border), MPFROMSHORT(border)); - return 0; + WinSendMsg(handle, WM_SETBORDERSIZE, MPFROMSHORT(border), MPFROMSHORT(border)); + return 0; } /* @@ -3977,7 +4628,7 @@ */ void API dw_window_capture(HWND handle) { - WinSetCapture(HWND_DESKTOP, handle); + WinSetCapture(HWND_DESKTOP, handle); } /* @@ -3985,7 +4636,7 @@ */ void API dw_window_release(void) { - WinSetCapture(HWND_DESKTOP, NULLHANDLE); + WinSetCapture(HWND_DESKTOP, NULLHANDLE); } /* @@ -3995,7 +4646,7 @@ */ void API dw_window_track(HWND handle) { - WinSendMsg(handle, WM_TRACKFRAME, MPFROMSHORT(TF_MOVE), 0); + WinSendMsg(handle, WM_TRACKFRAME, MPFROMSHORT(TF_MOVE), 0); } /* @@ -4006,19 +4657,19 @@ */ void API dw_window_set_pointer(HWND handle, int pointertype) { - HPOINTER pointer = pointertype < 65535 ? - WinQuerySysPointer(HWND_DESKTOP, pointertype, FALSE) - : (HPOINTER)pointertype; - - if(!pointertype) - dw_window_set_data(handle, "_dw_pointer", 0); - else - { - WinSetPointer(HWND_DESKTOP, pointer); - - if(handle != HWND_DESKTOP) - dw_window_set_data(handle, "_dw_pointer", (void *)pointer); - } + HPOINTER pointer = pointertype < 65535 ? + WinQuerySysPointer(HWND_DESKTOP, pointertype, FALSE) + : (HPOINTER)pointertype; + + if(!pointertype) + dw_window_set_data(handle, "_dw_pointer", 0); + else + { + WinSetPointer(HWND_DESKTOP, pointer); + + if(handle != HWND_DESKTOP) + dw_window_set_data(handle, "_dw_pointer", (void *)pointer); + } } /* @@ -4030,45 +4681,45 @@ */ HWND API dw_window_new(HWND hwndOwner, char *title, ULONG flStyle) { - HWND hwndframe; - Box *newbox = calloc(1, sizeof(Box)); - WindowData *blah = calloc(1, sizeof(WindowData)); - ULONG winStyle = 0L; - - newbox->pad = 0; - newbox->type = DW_VERT; - newbox->count = 0; - - flStyle |= FCF_NOBYTEALIGN; - - if(flStyle & DW_FCF_TITLEBAR) - newbox->titlebar = 1; - else - flStyle |= FCF_TITLEBAR; - - if(!(flStyle & FCF_SHELLPOSITION)) - blah->flags |= DW_OS2_NEW_WINDOW; - - if(flStyle & WS_MAXIMIZED) - { - winStyle |= WS_MAXIMIZED; - flStyle &= ~WS_MAXIMIZED; - } - if(flStyle & WS_MINIMIZED) - { - winStyle |= WS_MINIMIZED; - flStyle &= ~WS_MINIMIZED; - } - - hwndframe = WinCreateStdWindow(hwndOwner, winStyle, &flStyle, ClassName, title, 0L, NULLHANDLE, 0L, &newbox->hwnd); - newbox->hwndtitle = WinWindowFromID(hwndframe, FID_TITLEBAR); - if(!newbox->titlebar && newbox->hwndtitle) - WinSetParent(newbox->hwndtitle, HWND_OBJECT, FALSE); - blah->oldproc = WinSubclassWindow(hwndframe, _sizeproc); - WinSetWindowPtr(hwndframe, QWP_USER, blah); - WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox); - - return hwndframe; + HWND hwndframe; + Box *newbox = calloc(1, sizeof(Box)); + WindowData *blah = calloc(1, sizeof(WindowData)); + ULONG winStyle = 0L; + + newbox->pad = 0; + newbox->type = DW_VERT; + newbox->count = 0; + + flStyle |= FCF_NOBYTEALIGN; + + if(flStyle & DW_FCF_TITLEBAR) + newbox->titlebar = 1; + else + flStyle |= FCF_TITLEBAR; + + if(!(flStyle & FCF_SHELLPOSITION)) + blah->flags |= DW_OS2_NEW_WINDOW; + + if(flStyle & WS_MAXIMIZED) + { + winStyle |= WS_MAXIMIZED; + flStyle &= ~WS_MAXIMIZED; + } + if(flStyle & WS_MINIMIZED) + { + winStyle |= WS_MINIMIZED; + flStyle &= ~WS_MINIMIZED; + } + + hwndframe = WinCreateStdWindow(hwndOwner, winStyle, &flStyle, (PSZ)ClassName, (PSZ)title, 0L, NULLHANDLE, 0L, &newbox->hwnd); + newbox->hwndtitle = WinWindowFromID(hwndframe, FID_TITLEBAR); + if(!newbox->titlebar && newbox->hwndtitle) + WinSetParent(newbox->hwndtitle, HWND_OBJECT, FALSE); + blah->oldproc = WinSubclassWindow(hwndframe, _sizeproc); + WinSetWindowPtr(hwndframe, QWP_USER, blah); + WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox); + + return hwndframe; } /* @@ -4079,29 +4730,100 @@ */ HWND API dw_box_new(int type, int pad) { - Box *newbox = calloc(1, sizeof(Box)); - - newbox->pad = pad; - newbox->type = type; - newbox->count = 0; - newbox->grouphwnd = NULLHANDLE; - - newbox->hwnd = WinCreateWindow(HWND_OBJECT, - WC_FRAME, - NULL, - WS_VISIBLE | WS_CLIPCHILDREN | - FS_NOBYTEALIGN, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - 0L, - NULL, - NULL); - - newbox->oldproc = WinSubclassWindow(newbox->hwnd, _controlproc); - WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox); - dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY); - return newbox->hwnd; + Box *newbox = calloc(1, sizeof(Box)); + + newbox->pad = pad; + newbox->type = type; + newbox->count = 0; + newbox->grouphwnd = NULLHANDLE; + + newbox->hwnd = WinCreateWindow(HWND_OBJECT, + WC_FRAME, + NULL, + WS_VISIBLE | WS_CLIPCHILDREN | + FS_NOBYTEALIGN, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + 0L, + NULL, + NULL); + + newbox->oldproc = WinSubclassWindow(newbox->hwnd, _controlproc); + WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox); + dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY); + return newbox->hwnd; +} + +/* + * Create a new scroll Box to be packed. + * Parameters: + * type: Either DW_VERT (vertical) or DW_HORZ (horizontal). + * pad: Number of pixels to pad around the box. + */ +HWND API dw_scrollbox_new(int type, int pad) +{ + HWND hwndframe, box = dw_box_new(type, pad); + HWND client, tmpbox = dw_box_new(DW_VERT, 0); + Box *blah = calloc(sizeof(Box), 1); + dw_box_pack_start(tmpbox, box, 1, 1, TRUE, TRUE, 0); + hwndframe = WinCreateWindow(HWND_OBJECT, (PSZ)ScrollClassName, NULL, WS_VISIBLE | WS_CLIPCHILDREN, + 0, 0, 2000, 1000, NULLHANDLE, HWND_TOP, 0, NULL, NULL); + WinCreateWindow(hwndframe, WC_SCROLLBAR, NULL, WS_VISIBLE | SBS_AUTOTRACK | SBS_VERT, + 0,0,2000,1000, hwndframe, HWND_TOP, FID_VERTSCROLL, NULL, NULL); + WinCreateWindow(hwndframe, WC_SCROLLBAR, NULL, WS_VISIBLE | SBS_AUTOTRACK | SBS_HORZ, + 0,0,2000,1000, hwndframe, HWND_TOP, FID_HORZSCROLL, NULL, NULL); + client = WinCreateWindow(hwndframe, WC_FRAME, NULL, WS_VISIBLE | WS_CLIPCHILDREN, + 0,0,2000,1000, NULLHANDLE, HWND_TOP, FID_CLIENT, NULL, NULL); + WinSetParent(tmpbox, client, FALSE); + WinSetWindowPtr(client, QWP_USER, blah); + dw_window_set_data(hwndframe, "_dw_resizebox", (void *)tmpbox); + dw_window_set_data(hwndframe, "_dw_box", (void *)box); + dw_window_set_color(hwndframe, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY); + dw_window_set_color(client, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY); + return hwndframe; +} + +/* + * Returns the position of the scrollbar in the scrollbox + * Parameters: + * handle: Handle to the scrollbox to be queried. + * orient: The vertical or horizontal scrollbar. + */ +int API dw_scrollbox_get_pos( HWND handle, int orient ) +{ + HWND scroll; + + if(orient == DW_VERT) + { + scroll = WinWindowFromID(handle, FID_VERTSCROLL); + } + else + { + scroll = WinWindowFromID(handle, FID_HORZSCROLL); + } + return (int)WinSendMsg(scroll, SBM_QUERYPOS, 0, 0); +} + +/* + * Gets the range for the scrollbar in the scrollbox. + * Parameters: + * handle: Handle to the scrollbox to be queried. + * orient: The vertical or horizontal scrollbar. + */ +int API dw_scrollbox_get_range( HWND handle, int orient ) +{ + HWND scroll; + + if(orient == DW_VERT) + { + scroll = WinWindowFromID(handle, FID_VERTSCROLL); + } + else + { + scroll = WinWindowFromID(handle, FID_HORZSCROLL); + } + return SHORT2FROMMP(WinSendMsg(scroll, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0)); } /* @@ -4113,40 +4835,41 @@ */ HWND API dw_groupbox_new(int type, int pad, char *title) { - Box *newbox = calloc(1, sizeof(Box)); - newbox->pad = pad; - newbox->type = type; - newbox->count = 0; - - newbox->hwnd = WinCreateWindow(HWND_OBJECT, - WC_FRAME, - NULL, - WS_VISIBLE | - FS_NOBYTEALIGN, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - 0L, - NULL, - NULL); - - newbox->grouphwnd = WinCreateWindow(newbox->hwnd, - WC_STATIC, - title, - WS_VISIBLE | SS_GROUPBOX | - WS_GROUP, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - 0L, - NULL, - NULL); - - WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox); - dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY); - dw_window_set_color(newbox->grouphwnd, DW_CLR_BLACK, DW_CLR_PALEGRAY); - dw_window_set_font(newbox->grouphwnd, DefaultFont); - return newbox->hwnd; + Box *newbox = calloc(1, sizeof(Box)); + newbox->pad = pad; + newbox->type = type; + newbox->count = 0; + + newbox->hwnd = WinCreateWindow(HWND_OBJECT, + WC_FRAME, + NULL, + WS_VISIBLE | + FS_NOBYTEALIGN, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + 0L, + NULL, + NULL); + + newbox->grouphwnd = WinCreateWindow(newbox->hwnd, + WC_STATIC, + (PSZ)title, + WS_VISIBLE | SS_GROUPBOX | + WS_GROUP, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + 0L, + NULL, + NULL); + + WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox); + dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY); + dw_window_set_color(newbox->grouphwnd, DW_CLR_BLACK, DW_CLR_PALEGRAY); + dw_window_set_font(newbox->grouphwnd, DefaultFont); + dw_window_set_data(newbox->hwnd, "_dw_buddy", (void *)newbox->grouphwnd); + return newbox->hwnd; } /* @@ -4156,23 +4879,23 @@ */ HWND API dw_mdi_new(unsigned long id) { - HWND hwndframe; - ULONG back = CLR_DARKGRAY; - - hwndframe = WinCreateWindow(HWND_OBJECT, - WC_FRAME, - NULL, - WS_VISIBLE | WS_CLIPCHILDREN | - FS_NOBYTEALIGN, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - /* Make the MDI Client area the same color as Windows and Unix */ - WinSetPresParam(hwndframe, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back); - return hwndframe; + HWND hwndframe; + ULONG back = CLR_DARKGRAY; + + hwndframe = WinCreateWindow(HWND_OBJECT, + WC_FRAME, + NULL, + WS_VISIBLE | WS_CLIPCHILDREN | + FS_NOBYTEALIGN, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + /* Make the MDI Client area the same color as Windows and Unix */ + WinSetPresParam(hwndframe, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back); + return hwndframe; } /* @@ -4182,16 +4905,16 @@ */ HWND API dw_bitmap_new(ULONG id) { - return WinCreateWindow(HWND_OBJECT, - WC_STATIC, - NULL, - WS_VISIBLE | SS_TEXT, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); + return WinCreateWindow(HWND_OBJECT, + WC_STATIC, + NULL, + WS_VISIBLE | SS_TEXT, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); } /* @@ -4202,38 +4925,38 @@ */ HWND API dw_notebook_new(ULONG id, int top) { - ULONG flags; - HWND tmp; - - if(top) - flags = BKS_MAJORTABTOP; - else - flags = BKS_MAJORTABBOTTOM; - - tmp = WinCreateWindow(HWND_OBJECT, - WC_NOTEBOOK, - NULL, - WS_VISIBLE | + ULONG flags; + HWND tmp; + + if(top) + flags = BKS_MAJORTABTOP; + else + flags = BKS_MAJORTABBOTTOM; + + tmp = WinCreateWindow(HWND_OBJECT, + WC_NOTEBOOK, + NULL, + WS_VISIBLE | #ifdef BKS_TABBEDDIALOG - BKS_TABBEDDIALOG | + BKS_TABBEDDIALOG | #endif - flags, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - - /* Fix tab sizes on Warp 3 */ - if(!IS_WARP4()) - { - /* best sizes to be determined by trial and error */ - WinSendMsg(tmp, BKM_SETDIMENSIONS,MPFROM2SHORT(102, 28), MPFROMSHORT( BKA_MAJORTAB)); - } - - dw_window_set_font(tmp, DefaultFont); - return tmp; + flags, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + + /* Fix tab sizes on Warp 3 */ + if(!IS_WARP4()) + { + /* best sizes to be determined by trial and error */ + WinSendMsg(tmp, BKM_SETDIMENSIONS,MPFROM2SHORT(102, 28), MPFROMSHORT( BKA_MAJORTAB)); + } + + dw_window_set_font(tmp, DefaultFont); + return tmp; } /* @@ -4244,17 +4967,17 @@ */ HMENUI API dw_menu_new(ULONG id) { - HMENUI tmp = WinCreateWindow(HWND_OBJECT, - WC_MENU, - NULL, - WS_VISIBLE, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - return tmp; + HMENUI tmp = WinCreateWindow(HWND_OBJECT, + WC_MENU, + NULL, + WS_VISIBLE, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + return tmp; } /* @@ -4264,19 +4987,19 @@ */ HMENUI API dw_menubar_new(HWND location) { - HMENUI tmp = WinCreateWindow(location, - WC_MENU, - NULL, - WS_VISIBLE | MS_ACTIONBAR, - 0,0,2000,1000, - location, - HWND_TOP, - FID_MENU, - NULL, - NULL); - dw_window_set_data(tmp, "_dw_owner", (void *)location); - dw_window_set_data(tmp, "_dw_menubar", (void *)location); - return tmp; + HMENUI tmp = WinCreateWindow(location, + WC_MENU, + NULL, + WS_VISIBLE | MS_ACTIONBAR, + 0,0,2000,1000, + location, + HWND_TOP, + FID_MENU, + NULL, + NULL); + dw_window_set_data(tmp, "_dw_owner", (void *)location); + dw_window_set_data(tmp, "_dw_menubar", (void *)location); + return tmp; } /* @@ -4286,8 +5009,22 @@ */ void API dw_menu_destroy(HMENUI *menu) { - if(menu) - WinDestroyWindow(*menu); + if(menu) + WinDestroyWindow(*menu); +} + +/* Internal function to make sure menu ID isn't in use */ +int _menuid_allocated(int id) +{ + SignalHandler *tmp = Root; + + while(tmp) + { + if(tmp->id == id) + return TRUE; + tmp = tmp->next; + } + return FALSE; } /* @@ -4299,46 +5036,94 @@ * flags: Extended attributes to set on the menu. * end: If TRUE memu is positioned at the end of the menu. * check: If TRUE menu is "check"able. + * flags: Extended attributes to set on the menu. * submenu: Handle to an existing menu to be a submenu or NULL. */ HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu) { - MENUITEM miSubMenu; - char buffer[15]; - - check = check; /* keep compiler happy */ - if(!menux || id > 65536) - return NULLHANDLE; - - if(end) - miSubMenu.iPosition=MIT_END; - else - miSubMenu.iPosition=0; - - if(strlen(title) == 0) - miSubMenu.afStyle=MIS_SEPARATOR | flags; - else - miSubMenu.afStyle=MIS_TEXT | flags; - miSubMenu.afAttribute=0; - miSubMenu.id=id; - miSubMenu.hwndSubMenu = submenu; - miSubMenu.hItem=NULLHANDLE; - - WinSendMsg(menux, - MM_INSERTITEM, - MPFROMP(&miSubMenu), - MPFROMP(title)); - - sprintf(buffer, "_dw_id%d", (int)id); - dw_window_set_data(hwndApp, buffer, (void *)menux); - - if(submenu) - dw_window_set_data(submenu, "_dw_owner", (void *)menux); - return (HWND)id; + MENUITEM miSubMenu; + char buffer[30]; + int is_checked, is_disabled; + + if ( !menux || !WinIsWindow(dwhab, menux) ) + return NULLHANDLE; + + if ( end ) + miSubMenu.iPosition=MIT_END; + else + miSubMenu.iPosition=0; + /* + * Handle flags + */ + miSubMenu.afAttribute = 0; + is_checked = (flags & DW_MIS_CHECKED) ? 1 : 0; + if ( is_checked ) + miSubMenu.afAttribute |= MIA_CHECKED; + is_disabled = (flags & DW_MIS_DISABLED) ? 1 : 0; + if ( is_disabled ) + miSubMenu.afAttribute |= MIA_DISABLED; + + if (title && *title) + { + /* Code to autogenerate a menu ID if not specified or invalid + * First pool is smaller for transient popup menus + */ + if(id == (ULONG)-1) + { + static ULONG tempid = 61000; + + tempid++; + id = tempid; + + if(tempid > 65500) + tempid = 61000; + } + /* Special internal case */ + else if(id > 60000 && check == -1) + { + check = 0; + } + /* Second pool is larger for more static windows */ + else if(!id || id >= 30000) + { + static ULONG menuid = 30000; + + do + { + menuid++; + if(menuid > 60000) + menuid = 30000; + } + while(_menuid_allocated(menuid)); + id = menuid; + } + miSubMenu.afStyle = MIS_TEXT; + } + else + miSubMenu.afStyle = MIS_SEPARATOR; + miSubMenu.id=id; + miSubMenu.hwndSubMenu = submenu; + miSubMenu.hItem=NULLHANDLE; + + WinSendMsg(menux, MM_INSERTITEM, MPFROMP(&miSubMenu), MPFROMP(title)); + + sprintf(buffer, "_dw_id%d", (int)id); + dw_window_set_data(hwndApp, buffer, (void *)menux); + sprintf(buffer, "_dw_checkable%ld", id); + dw_window_set_data( hwndApp, buffer, (void *)check ); + sprintf(buffer, "_dw_ischecked%ld", id); + dw_window_set_data( hwndApp, buffer, (void *)is_checked ); + sprintf(buffer, "_dw_isdisabled%ld", id); + dw_window_set_data( hwndApp, buffer, (void *)is_disabled ); + + if ( submenu ) + dw_window_set_data(submenu, "_dw_owner", (void *)menux); + return (HWND)id; } /* * Sets the state of a menu item check. + * Deprecated; use dw_menu_item_set_state() * Parameters: * menu: The handle the the existing menu. * id: Menuitem id. @@ -4346,12 +5131,106 @@ */ void API dw_menu_item_set_check(HMENUI menux, unsigned long id, int check) { - if(check) - WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), - MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED)); - else - WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), - MPFROM2SHORT(MIA_CHECKED, 0)); + if ( check ) + WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED)); + else + WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),MPFROM2SHORT(MIA_CHECKED, 0)); +} + +/* + * Sets the state of a menu item. + * Parameters: + * menu: The handle to the existing menu. + * id: Menuitem id. + * flags: DW_MIS_ENABLED/DW_MIS_DISABLED + * DW_MIS_CHECKED/DW_MIS_UNCHECKED + */ +void API dw_menu_item_set_state( HMENUI menux, unsigned long id, unsigned long state) +{ + char buffer1[30],buffer2[30]; + int check; + int disabled; + USHORT fAttribute=0; + + sprintf( buffer1, "_dw_ischecked%ld", id ); + check = (int)dw_window_get_data( hwndApp, buffer1 ); + sprintf( buffer2, "_dw_isdisabled%ld", id ); + disabled = (int)dw_window_get_data( hwndApp, buffer2 ); + + if ( (state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED) ) + { + /* + * If we are changing state of "checked" base our setting on the passed flag... + */ + if ( state & DW_MIS_CHECKED ) + { + fAttribute |= MIA_CHECKED; + check = 1; + } + else + { + check = 0; + } + } + else + { + /* + * ...otherwise base our setting on the current "checked" state. + */ + if ( check ) + { + fAttribute |= MIA_CHECKED; + } + } + if ( (state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED) ) + { + if ( state & DW_MIS_DISABLED ) + { + fAttribute |= MIA_DISABLED; + disabled = 1; + } + else + { + disabled = 0; + } + } + else + { + /* + * ...otherwise base our setting on the current "disabled" state. + */ + if ( disabled ) + { + fAttribute |= MIA_DISABLED; + } + } + WinSendMsg( menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), MPFROM2SHORT( MIA_CHECKED|MIA_DISABLED, fAttribute ) ); + /* + * Keep our internal checked state consistent + */ + dw_window_set_data( hwndApp, buffer1, (void *)check ); + dw_window_set_data( hwndApp, buffer2, (void *)disabled ); +} + +/* + * Deletes the menu item specified + * Parameters: + * menu: The handle to the menu in which the item was appended. + * id: Menuitem id. + * Returns: + * DW_ERROR_NONE (0) on success or DW_ERROR_UNKNOWN on failure. + */ +int API dw_menu_delete_item(HMENUI menux, unsigned long id) +{ + if(id < 65536 && menux) + { + WinSendMsg(menux, MM_DELETEITEM, MPFROM2SHORT(id, FALSE), 0); + /* If the ID was autogenerated it is safe to remove it */ + if(id >= 30000) + dw_signal_disconnect_by_window((HWND)id); + return DW_ERROR_NONE; + } + return DW_ERROR_UNKNOWN; } /* @@ -4364,12 +5243,12 @@ */ void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y) { - if(menu) - { - popup = parent; - dw_window_set_data(*menu, "_dw_popup", (void *)1); - WinPopupMenu(HWND_DESKTOP, parent, *menu, x, dw_screen_height() - y, 0, PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_VCONSTRAIN | PU_HCONSTRAIN); - } + if(menu) + { + popup = parent; + dw_window_set_data(*menu, "_dw_popup", (void *)1); + WinPopupMenu(HWND_DESKTOP, parent, *menu, x, dw_screen_height() - y, 0, PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_VCONSTRAIN | PU_HCONSTRAIN); + } } /* @@ -4380,14 +5259,14 @@ */ void API dw_pointer_query_pos(long *x, long *y) { - POINTL ptl; - - WinQueryPointerPos(HWND_DESKTOP, &ptl); - if(x && y) - { - *x = ptl.x; - *y = dw_screen_height() - ptl.y; - } + POINTL ptl; + + WinQueryPointerPos(HWND_DESKTOP, &ptl); + if(x && y) + { + *x = ptl.x; + *y = dw_screen_height() - ptl.y; + } } /* @@ -4398,7 +5277,7 @@ */ void API dw_pointer_set_pos(long x, long y) { - WinSetPointerPos(HWND_DESKTOP, x, dw_screen_height() - y); + WinSetPointerPos(HWND_DESKTOP, x, dw_screen_height() - y); } @@ -4410,24 +5289,24 @@ */ HWND API dw_container_new(ULONG id, int multi) { - WindowData *blah = calloc(1, sizeof(WindowData)); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_CONTAINER, - NULL, - WS_VISIBLE | CCS_READONLY | - (multi ? CCS_EXTENDSEL : CCS_SINGLESEL) | - CCS_AUTOPOSITION, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id ? id : (GlobalID++), - NULL, - NULL); - blah->oldproc = WinSubclassWindow(tmp, _TreeProc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_data(tmp, "_dw_container", (void *)1); - return tmp; + WindowData *blah = calloc(1, sizeof(WindowData)); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_CONTAINER, + NULL, + WS_VISIBLE | CCS_READONLY | + (multi ? CCS_EXTENDSEL : CCS_SINGLESEL) | + CCS_AUTOPOSITION, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id ? id : _GlobalID(), + NULL, + NULL); + blah->oldproc = WinSubclassWindow(tmp, _TreeProc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_data(tmp, "_dw_container", (void *)1); + return tmp; } /* @@ -4438,33 +5317,33 @@ */ HWND API dw_tree_new(ULONG id) { - CNRINFO cnrinfo; - WindowData *blah = calloc(1, sizeof(WindowData)); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_CONTAINER, - NULL, - WS_VISIBLE | CCS_READONLY | - CCS_SINGLESEL | CCS_AUTOPOSITION, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id ? id : (GlobalID++), - NULL, - NULL); - - cnrinfo.flWindowAttr = CV_TREE | CA_TREELINE; - cnrinfo.slBitmapOrIcon.cx = 16; - cnrinfo.slBitmapOrIcon.cy = 16; - cnrinfo.cyLineSpacing = 0; - cnrinfo.cxTreeIndent = 16; - cnrinfo.cxTreeLine = 1; - - WinSendMsg(tmp, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON | - CMA_LINESPACING | CMA_CXTREEINDENT | CMA_CXTREELINE)); - blah->oldproc = WinSubclassWindow(tmp, _TreeProc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - return tmp; + CNRINFO cnrinfo; + WindowData *blah = calloc(1, sizeof(WindowData)); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_CONTAINER, + NULL, + WS_VISIBLE | CCS_READONLY | + CCS_SINGLESEL | CCS_AUTOPOSITION, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id ? id : _GlobalID(), + NULL, + NULL); + + cnrinfo.flWindowAttr = CV_TREE | CA_TREELINE; + cnrinfo.slBitmapOrIcon.cx = 16; + cnrinfo.slBitmapOrIcon.cy = 16; + cnrinfo.cyLineSpacing = 0; + cnrinfo.cxTreeIndent = 16; + cnrinfo.cxTreeLine = 1; + + WinSendMsg(tmp, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON | + CMA_LINESPACING | CMA_CXTREEINDENT | CMA_CXTREELINE)); + blah->oldproc = WinSubclassWindow(tmp, _TreeProc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + return tmp; } /* @@ -4475,22 +5354,22 @@ */ HWND API dw_text_new(char *text, ULONG id) { - WindowData *blah = calloc(sizeof(WindowData), 1); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_STATIC, - text, - WS_VISIBLE | SS_TEXT, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - blah->oldproc = WinSubclassWindow(tmp, _textproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); - return tmp; + WindowData *blah = calloc(sizeof(WindowData), 1); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_STATIC, + (PSZ)text, + WS_VISIBLE | SS_TEXT, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + blah->oldproc = WinSubclassWindow(tmp, _textproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); + return tmp; } /* @@ -4501,22 +5380,22 @@ */ HWND API dw_status_text_new(char *text, ULONG id) { - WindowData *blah = calloc(sizeof(WindowData), 1); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_STATIC, - text, - WS_VISIBLE | SS_TEXT, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - blah->oldproc = WinSubclassWindow(tmp, _statusproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); - return tmp; + WindowData *blah = calloc(sizeof(WindowData), 1); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_STATIC, + (PSZ)text, + WS_VISIBLE | SS_TEXT, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + blah->oldproc = WinSubclassWindow(tmp, _statusproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); + return tmp; } #ifndef MLS_LIMITVSCROLL @@ -4530,24 +5409,25 @@ */ HWND API dw_mle_new(ULONG id) { - WindowData *blah = calloc(1, sizeof(WindowData)); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_MLE, - "", - WS_VISIBLE | - MLS_BORDER | MLS_IGNORETAB | - MLS_READONLY | MLS_VSCROLL | - MLS_LIMITVSCROLL, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - blah->oldproc = WinSubclassWindow(tmp, _mleproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - return tmp; + WindowData *blah = calloc(1, sizeof(WindowData)); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_MLE, + NULL, + WS_VISIBLE | + MLS_BORDER | MLS_IGNORETAB | + MLS_VSCROLL | + MLS_LIMITVSCROLL, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + WinSendMsg(tmp, MLM_FORMAT, (MPARAM)MLFIE_NOTRANS, 0); + blah->oldproc = WinSubclassWindow(tmp, _mleproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + return tmp; } /* @@ -4559,23 +5439,23 @@ HWND API dw_entryfield_new(char *text, ULONG id) { - WindowData *blah = calloc(1, sizeof(WindowData)); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_ENTRYFIELD, - text, - WS_VISIBLE | ES_MARGIN | - ES_AUTOSCROLL | WS_TABSTOP, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - blah->oldproc = WinSubclassWindow(tmp, _entryproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); - return tmp; + WindowData *blah = calloc(1, sizeof(WindowData)); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_ENTRYFIELD, + (PSZ)text, + WS_VISIBLE | ES_MARGIN | + ES_AUTOSCROLL | WS_TABSTOP, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + blah->oldproc = WinSubclassWindow(tmp, _entryproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); + return tmp; } /* @@ -4586,23 +5466,23 @@ */ HWND API dw_entryfield_password_new(char *text, ULONG id) { - WindowData *blah = calloc(1, sizeof(WindowData)); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_ENTRYFIELD, - text, - WS_VISIBLE | ES_MARGIN | ES_UNREADABLE | - ES_AUTOSCROLL | WS_TABSTOP, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - blah->oldproc = WinSubclassWindow(tmp, _entryproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); - return tmp; + WindowData *blah = calloc(1, sizeof(WindowData)); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_ENTRYFIELD, + (PSZ)text, + WS_VISIBLE | ES_MARGIN | ES_UNREADABLE | + ES_AUTOSCROLL | WS_TABSTOP, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + blah->oldproc = WinSubclassWindow(tmp, _entryproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); + return tmp; } /* @@ -4613,38 +5493,38 @@ */ HWND API dw_combobox_new(char *text, ULONG id) { - WindowData *blah = calloc(1, sizeof(WindowData)); - HWND frame = dw_box_new(DW_HORZ, 0); - HWND tmp = WinCreateWindow(frame, - WC_COMBOBOX, - text, - WS_VISIBLE | CBS_DROPDOWN | WS_GROUP, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - HENUM henum = WinBeginEnumWindows(tmp); - HWND child, last = NULLHANDLE; - - while((child = WinGetNextWindow(henum)) != NULLHANDLE) - { - WindowData *moreblah = calloc(1, sizeof(WindowData)); - moreblah->oldproc = WinSubclassWindow(child, _comboentryproc); - WinSetWindowPtr(child, QWP_USER, moreblah); - dw_window_set_color(child, DW_CLR_BLACK, DW_CLR_WHITE); - last = child; - } - WinEndEnumWindows(henum); - blah->oldproc = WinSubclassWindow(tmp, _comboproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); - dw_window_set_data(tmp, "_dw_comboentry", (void *)last); - dw_window_set_data(tmp, "_dw_combo_box", (void *)frame); - WinSetOwner(tmp, frame); - return tmp; + WindowData *blah = calloc(1, sizeof(WindowData)); + HWND frame = dw_box_new(DW_HORZ, 0); + HWND tmp = WinCreateWindow(frame, + WC_COMBOBOX, + (PSZ)text, + WS_VISIBLE | CBS_DROPDOWN | WS_GROUP, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id ? id : _GlobalID(), + NULL, + NULL); + HENUM henum = WinBeginEnumWindows(tmp); + HWND child, last = NULLHANDLE; + + while((child = WinGetNextWindow(henum)) != NULLHANDLE) + { + WindowData *moreblah = calloc(1, sizeof(WindowData)); + moreblah->oldproc = WinSubclassWindow(child, _comboentryproc); + WinSetWindowPtr(child, QWP_USER, moreblah); + dw_window_set_color(child, DW_CLR_BLACK, DW_CLR_WHITE); + last = child; + } + WinEndEnumWindows(henum); + blah->oldproc = WinSubclassWindow(tmp, _comboproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); + dw_window_set_data(tmp, "_dw_comboentry", (void *)last); + dw_window_set_data(tmp, "_dw_combo_box", (void *)frame); + WinSetOwner(tmp, frame); + return tmp; } /* @@ -4655,27 +5535,27 @@ */ HWND API dw_button_new(char *text, ULONG id) { - BubbleButton *bubble = calloc(sizeof(BubbleButton), 1); - - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_BUTTON, - text, - WS_VISIBLE, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - - bubble->id = id; - bubble->bubbletext[0] = '\0'; - bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); - - WinSetWindowPtr(tmp, QWP_USER, bubble); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); - return tmp; + BubbleButton *bubble = calloc(sizeof(BubbleButton), 1); + + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_BUTTON, + (PSZ)text, + WS_VISIBLE, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + + bubble->id = id; + bubble->bubbletext[0] = '\0'; + bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); + + WinSetWindowPtr(tmp, QWP_USER, bubble); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); + return tmp; } /* Function: GenResIDStr @@ -4685,29 +5565,29 @@ void _GenResIDStr(CHAR *buff, ULONG ulID) { - char *str; - int slen = 0; - - *buff++ = '#'; - - str = buff; - - do - { - *str++ = (ulID % 10) + '0'; - ulID /= 10; - slen++; - } - while(ulID); - - *str-- = 0; - - for(; str > buff; str--, buff++) - { - *buff ^= *str; - *str ^= *buff; - *buff ^= *str; - } + char *str; + int slen = 0; + + *buff++ = '#'; + + str = buff; + + do + { + *str++ = (ulID % 10) + '0'; + ulID /= 10; + slen++; + } + while(ulID); + + *str-- = 0; + + for(; str > buff; str--, buff++) + { + *buff ^= *str; + *str ^= *buff; + *buff ^= *str; + } } @@ -4719,41 +5599,41 @@ */ HWND API dw_bitmapbutton_new(char *text, ULONG id) { - char idbuf[256], *name = NULL; - HWND tmp; - BubbleButton *bubble = calloc(sizeof(BubbleButton), 1); - HPOINTER icon = WinLoadPointer(HWND_DESKTOP, 0L, id); - - if(!icon) - { - name = idbuf; - _GenResIDStr(idbuf, id); - } - - tmp = WinCreateWindow(HWND_OBJECT, - WC_BUTTON, - name, - WS_VISIBLE | BS_PUSHBUTTON | - BS_NOPOINTERFOCUS | BS_AUTOSIZE | - (icon ? 0 : BS_BITMAP), - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - - bubble->id = id; - strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1); - bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0'; - bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); - - WinSetWindowPtr(tmp, QWP_USER, bubble); - - if(icon) - dw_window_set_data(tmp, "_dw_button_icon", (void *)icon); - dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1); - return tmp; + char idbuf[256], *name = NULL; + HWND tmp; + BubbleButton *bubble = calloc(sizeof(BubbleButton), 1); + HPOINTER icon = WinLoadPointer(HWND_DESKTOP, 0L, id); + + if(!icon) + { + name = idbuf; + _GenResIDStr(idbuf, id); + } + + tmp = WinCreateWindow(HWND_OBJECT, + WC_BUTTON, + (PSZ)name, + WS_VISIBLE | BS_PUSHBUTTON | + BS_NOPOINTERFOCUS | BS_AUTOSIZE | + (icon ? 0 : BS_BITMAP), + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + + bubble->id = id; + strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1); + bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0'; + bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); + + WinSetWindowPtr(tmp, QWP_USER, bubble); + + if(icon) + dw_window_set_data(tmp, "_dw_button_icon", (void *)icon); + dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1); + return tmp; } /* @@ -4767,97 +5647,197 @@ */ HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename) { - BubbleButton *bubble = calloc(sizeof(BubbleButton), 1); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_BUTTON, - "", - WS_VISIBLE | BS_PUSHBUTTON | - BS_AUTOSIZE | BS_NOPOINTERFOCUS, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - char *file = alloca(strlen(filename) + 5); - HPIXMAP pixmap = NULL, disabled = NULL; - HPOINTER icon = 0; - - if(file && (pixmap = calloc(1,sizeof(struct _hpixmap)))) - { - int z, j, lim, len; - LONG fore; - - strcpy(file, filename); - - /* check if we can read from this file (it exists and read permission) */ - if(access(file, 04) == 0) - { - len = strlen( file ); - if(len > 4) - { - if(stricmp(file + len - 4, ".ico") == 0) - icon = WinLoadFileIcon(file, FALSE); - else - _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height); - } - } - else - { - /* Try with .ico extension first...*/ - strcat(file, ".ico"); - if(access(file, 04) == 0) - icon = WinLoadFileIcon(file, FALSE); - else - { - strcpy(file, filename); - strcat(file, ".bmp"); - if(access(file, 04) == 0) - _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height); - } - } - - if(icon) - { - free(pixmap); - pixmap = NULL; - } - else - { - /* Create a disabled style pixmap */ - disabled = dw_pixmap_new(tmp, pixmap->width, pixmap->height, dw_color_depth_get()); - dw_pixmap_bitblt(0, disabled, 0, 0, pixmap->width, pixmap->height, 0, pixmap, 0, 0); - - fore = _foreground; - dw_color_foreground_set(DW_CLR_PALEGRAY); - lim = pixmap->width/2; - for(j=0;j<pixmap->height;j++) - { - int mod = j%2; - - for(z=0;z<lim;z++) - dw_draw_point(0, disabled, (z*2)+mod, j); - } - _foreground = fore; - } - } - - bubble->id = id; - strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1); - bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0'; - bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); - - WinSetWindowPtr(tmp, QWP_USER, bubble); - - if(icon) - dw_window_set_data(tmp, "_dw_button_icon", (void *)icon); - else - { - dw_window_set_data(tmp, "_dw_hpixmap", (void *)pixmap); - dw_window_set_data(tmp, "_dw_hpixmap_disabled", (void *)disabled); - } - dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1); - return tmp; + BubbleButton *bubble = calloc(sizeof(BubbleButton), 1); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_BUTTON, + NULL, + WS_VISIBLE | BS_PUSHBUTTON | + BS_AUTOSIZE | BS_NOPOINTERFOCUS, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + char *file = alloca(strlen(filename) + 5); + HPIXMAP pixmap = NULL, disabled = NULL; + HPOINTER icon = 0; + + if(file && (pixmap = calloc(1,sizeof(struct _hpixmap)))) + { + int z, j, lim, len; + LONG fore; + + strcpy(file, filename); + + /* check if we can read from this file (it exists and read permission) */ + if(access(file, 04) == 0) + { + len = strlen( file ); + if(len > 4) + { + if(stricmp(file + len - 4, ".ico") == 0) + icon = WinLoadFileIcon((PSZ)file, FALSE); + else + _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height); + } + } + else + { + /* Try with .ico extension first...*/ + strcat(file, ".ico"); + if(access(file, 04) == 0) + icon = WinLoadFileIcon((PSZ)file, FALSE); + else + { + strcpy(file, filename); + strcat(file, ".bmp"); + if(access(file, 04) == 0) + _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height); + } + } + + if(icon) + { + free(pixmap); + pixmap = NULL; + } + else + { + /* Create a disabled style pixmap */ + disabled = dw_pixmap_new(tmp, pixmap->width, pixmap->height, dw_color_depth_get()); + dw_pixmap_bitblt(0, disabled, 0, 0, pixmap->width, pixmap->height, 0, pixmap, 0, 0); + + fore = _foreground; + dw_color_foreground_set(DW_CLR_PALEGRAY); + lim = pixmap->width/2; + for(j=0;j<pixmap->height;j++) + { + int mod = j%2; + + for(z=0;z<lim;z++) + dw_draw_point(0, disabled, (z*2)+mod, j); + } + _foreground = fore; + } + } + + bubble->id = id; + strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1); + bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0'; + bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); + + WinSetWindowPtr(tmp, QWP_USER, bubble); + + if(icon) + dw_window_set_data(tmp, "_dw_button_icon", (void *)icon); + else + { + dw_window_set_data(tmp, "_dw_hpixmap", (void *)pixmap); + dw_window_set_data(tmp, "_dw_hpixmap_disabled", (void *)disabled); + } + dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1); + return tmp; +} + +/* + * Create a new bitmap button window (widget) to be packed from data. + * Parameters: + * text: Bubble help text to be displayed. + * id: An ID to be used with dw_window_from_id() or 0L. + * data: The contents of the image + * (BMP or ICO on OS/2 or Windows, XPM on Unix) + * len: length of str + */ +HWND API dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *data, int len) +{ + FILE *fp; + BubbleButton *bubble = calloc(sizeof(BubbleButton), 1); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_BUTTON, + NULL, + WS_VISIBLE | BS_PUSHBUTTON | + BS_AUTOSIZE | BS_NOPOINTERFOCUS, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + char *file; + HPIXMAP pixmap = NULL, disabled = NULL; + HPOINTER icon = 0; + + if ( ( pixmap = calloc( 1, sizeof(struct _hpixmap) ) ) ) + { + int z, j, lim; + LONG fore; + file = tmpnam( NULL ); + if ( file != NULL ) + { + fp = fopen( file, "wb" ); + if ( fp != NULL ) + { + fwrite( data, 1, len, fp ); + fclose( fp ); + if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */ + { + _load_bitmap_file( file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height ); + } + else /* otherwise its assumed to be an ico */ + { + icon = WinLoadFileIcon((PSZ)file, FALSE); + } + } + else + { + unlink( file ); + return 0; + } + unlink( file ); + } + + if ( icon ) + { + free(pixmap); + pixmap = NULL; + } + else + { + /* Create a disabled style pixmap */ + disabled = dw_pixmap_new(tmp, pixmap->width, pixmap->height, dw_color_depth_get()); + dw_pixmap_bitblt(0, disabled, 0, 0, pixmap->width, pixmap->height, 0, pixmap, 0, 0); + + fore = _foreground; + dw_color_foreground_set(DW_CLR_PALEGRAY); + lim = pixmap->width/2; + for(j=0;j<pixmap->height;j++) + { + int mod = j%2; + + for(z=0;z<lim;z++) + dw_draw_point(0, disabled, (z*2)+mod, j); + } + _foreground = fore; + } + } + + bubble->id = id; + strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1); + bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0'; + bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); + + WinSetWindowPtr(tmp, QWP_USER, bubble); + + if(icon) + dw_window_set_data(tmp, "_dw_button_icon", (void *)icon); + else + { + dw_window_set_data(tmp, "_dw_hpixmap", (void *)pixmap); + dw_window_set_data(tmp, "_dw_hpixmap_disabled", (void *)disabled); + } + dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1); + return tmp; } /* @@ -4868,26 +5848,29 @@ */ HWND API dw_spinbutton_new(char *text, ULONG id) { - WindowData *blah = calloc(sizeof(WindowData), 1); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_SPINBUTTON, - text, - WS_VISIBLE | SPBS_MASTER, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - HWND entry = _find_entryfield(tmp); - blah->oldproc = WinSubclassWindow(tmp, _entryproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - blah = calloc(sizeof(WindowData), 1); - blah->oldproc = WinSubclassWindow(entry, _spinentryproc); - WinSetWindowPtr(entry, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(entry, DW_CLR_BLACK, DW_CLR_WHITE); - return tmp; + WindowData *blah = calloc(sizeof(WindowData), 1); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_SPINBUTTON, + (PSZ)text, + WS_VISIBLE | SPBS_MASTER, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + HWND entry = _find_entryfield(tmp); + WinSendMsg(tmp, SPBM_SETLIMITS, MPFROMLONG(65536), MPFROMLONG(-65536)); + WinSendMsg(tmp, SPBM_SETCURRENTVALUE, MPFROMLONG(atoi(text)), 0L); + blah->oldproc = WinSubclassWindow(tmp, _entryproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + blah = calloc(sizeof(WindowData), 1); + blah->oldproc = WinSubclassWindow(entry, _spinentryproc); + WinSetWindowPtr(entry, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(entry, DW_CLR_BLACK, DW_CLR_WHITE); + dw_window_set_data(tmp, "_dw_buddy", (void *)entry); + return tmp; } /* @@ -4898,23 +5881,23 @@ */ HWND API dw_radiobutton_new(char *text, ULONG id) { - WindowData *blah = calloc(sizeof(WindowData), 1); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_BUTTON, - text, - WS_VISIBLE | - BS_AUTORADIOBUTTON, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - blah->oldproc = WinSubclassWindow(tmp, _entryproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); - return tmp; + WindowData *blah = calloc(sizeof(WindowData), 1); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_BUTTON, + (PSZ)text, + WS_VISIBLE | + BS_AUTORADIOBUTTON, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + blah->oldproc = WinSubclassWindow(tmp, _entryproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); + return tmp; } @@ -4927,28 +5910,28 @@ */ HWND API dw_slider_new(int vertical, int increments, ULONG id) { - WindowData *blah = calloc(1, sizeof(WindowData)); - SLDCDATA sldcData = { 0, 0, 0, 0, 0 }; - HWND tmp; - - sldcData.cbSize = sizeof(SLDCDATA); + WindowData *blah = calloc(1, sizeof(WindowData)); + SLDCDATA sldcData = { 0, 0, 0, 0, 0 }; + HWND tmp; + + sldcData.cbSize = sizeof(SLDCDATA); sldcData.usScale1Increments = increments; - tmp = WinCreateWindow(HWND_OBJECT, - WC_SLIDER, - "", - WS_VISIBLE | SLS_SNAPTOINCREMENT | - (vertical ? SLS_VERTICAL : SLS_HORIZONTAL), - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - &sldcData, - NULL); - - blah->oldproc = WinSubclassWindow(tmp, _entryproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - return tmp; + tmp = WinCreateWindow(HWND_OBJECT, + WC_SLIDER, + NULL, + WS_VISIBLE | SLS_SNAPTOINCREMENT | + (vertical ? SLS_VERTICAL : SLS_HORIZONTAL), + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id ? id : _GlobalID(), + &sldcData, + NULL); + + blah->oldproc = WinSubclassWindow(tmp, _entryproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + return tmp; } /* @@ -4960,17 +5943,17 @@ */ HWND API dw_scrollbar_new(int vertical, ULONG id) { - return WinCreateWindow(HWND_OBJECT, - WC_SCROLLBAR, - "", - WS_VISIBLE | SBS_AUTOTRACK | - (vertical ? SBS_VERT : SBS_HORZ), - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id ? id : (GlobalID++), - NULL, - NULL); + return WinCreateWindow(HWND_OBJECT, + WC_SCROLLBAR, + NULL, + WS_VISIBLE | SBS_AUTOTRACK | + (vertical ? SBS_VERT : SBS_HORZ), + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id ? id : _GlobalID(), + NULL, + NULL); } /* @@ -4980,22 +5963,22 @@ */ HWND API dw_percent_new(ULONG id) { - WindowData *blah = calloc(1, sizeof(WindowData)); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_SLIDER, - "", - WS_VISIBLE | SLS_READONLY - | SLS_RIBBONSTRIP, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - blah->oldproc = WinSubclassWindow(tmp, _percentproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_disable(tmp); - return tmp; + WindowData *blah = calloc(1, sizeof(WindowData)); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_SLIDER, + NULL, + WS_VISIBLE | SLS_READONLY + | SLS_RIBBONSTRIP, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id ? id : _GlobalID(), + NULL, + NULL); + blah->oldproc = WinSubclassWindow(tmp, _percentproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_disable(tmp); + return tmp; } /* @@ -5006,24 +5989,24 @@ */ HWND API dw_checkbox_new(char *text, ULONG id) { - BubbleButton *bubble = calloc(sizeof(BubbleButton), 1); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_BUTTON, - text, - WS_VISIBLE | BS_AUTOCHECKBOX, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - bubble->id = id; - bubble->bubbletext[0] = '\0'; - bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); - WinSetWindowPtr(tmp, QWP_USER, bubble); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); - return tmp; + BubbleButton *bubble = calloc(sizeof(BubbleButton), 1); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_BUTTON, + (PSZ)text, + WS_VISIBLE | BS_AUTOCHECKBOX, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + bubble->id = id; + bubble->bubbletext[0] = '\0'; + bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); + WinSetWindowPtr(tmp, QWP_USER, bubble); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); + return tmp; } /* @@ -5034,23 +6017,23 @@ */ HWND API dw_listbox_new(ULONG id, int multi) { - WindowData *blah = calloc(sizeof(WindowData), 1); - HWND tmp = WinCreateWindow(HWND_OBJECT, - WC_LISTBOX, - NULL, - WS_VISIBLE | LS_NOADJUSTPOS | - (multi ? LS_MULTIPLESEL : 0), - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id ? id : (GlobalID++), - NULL, - NULL); - blah->oldproc = WinSubclassWindow(tmp, _entryproc); - WinSetWindowPtr(tmp, QWP_USER, blah); - dw_window_set_font(tmp, DefaultFont); - dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); - return tmp; + WindowData *blah = calloc(sizeof(WindowData), 1); + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_LISTBOX, + NULL, + WS_VISIBLE | LS_NOADJUSTPOS | + (multi ? LS_MULTIPLESEL : 0), + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id ? id : _GlobalID(), + NULL, + NULL); + blah->oldproc = WinSubclassWindow(tmp, _entryproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); + return tmp; } /* @@ -5059,10 +6042,10 @@ * handle: Handle to the window. * id: An ID to be used to specify the icon. */ -void API dw_window_set_icon(HWND handle, ULONG id) -{ - HPOINTER icon = id < 65536 ? WinLoadPointer(HWND_DESKTOP,NULLHANDLE,id) : (HPOINTER)id; - WinSendMsg(handle, WM_SETICON, (MPARAM)icon, 0); +void API dw_window_set_icon(HWND handle, HICN icon) +{ + HPOINTER hptr = icon < 65536 ? WinLoadPointer(HWND_DESKTOP,NULLHANDLE,icon) : (HPOINTER)icon; + WinSendMsg(handle, WM_SETICON, (MPARAM)hptr, 0); } /* Internal function to load a bitmap from a file and return handles @@ -5070,104 +6053,104 @@ */ int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height) { - HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */ - ULONG OpenAction = 0; - PBYTE BitmapFileBegin; /* pointer to the first byte of bitmap data */ - FILESTATUS BitmapStatus; - ULONG cbRead; - PBITMAPFILEHEADER2 pBitmapFileHeader; - PBITMAPINFOHEADER2 pBitmapInfoHeader; - ULONG ScanLines, ulFlags; - HPS hps1; - HDC hdc1; - SIZEL sizl = { 0, 0 }; - - /* open bitmap file */ - DosOpen(file, &BitmapFileHandle, &OpenAction, 0L, - FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY, - OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, - OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY | - OPEN_FLAGS_NOINHERIT, 0L); - - if(!BitmapFileHandle) - return 0; - - /* find out how big the file is */ - DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus, - sizeof(BitmapStatus)); - - /* allocate memory to load the bitmap */ - DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile, - PAG_READ | PAG_WRITE | PAG_COMMIT); - - /* read bitmap file into memory buffer */ - DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin, - BitmapStatus.cbFile, &cbRead); - - /* access first bytes as bitmap header */ - pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin; - - /* check if it's a valid bitmap data file */ - if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) && - (pBitmapFileHeader->usType != BFT_BMAP)) - { - /* free memory of bitmap file buffer */ - DosFreeMem(BitmapFileBegin); - /* close the bitmap file */ - DosClose(BitmapFileHandle); - return 0; - } - - /* check if it's a file with multiple bitmaps */ - if(pBitmapFileHeader->usType == BFT_BITMAPARRAY) - { - /* we'll just use the first bitmap and ignore the others */ - pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2); - } - - /* set pointer to bitmap information block */ - pBitmapInfoHeader = &pBitmapFileHeader->bmp2; - - /* find out if it's the new 2.0 format or the old format */ - /* and query number of lines */ - if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER)) - { - *height = ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy; - *width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx; - } - else - { - *height = ScanLines = pBitmapInfoHeader->cy; - *width = pBitmapInfoHeader->cx; - } - - /* now we need a presentation space, get it from static control */ - hps1 = WinGetPS(handle); - - hdc1 = GpiQueryDevice(hps1); - ulFlags = GpiQueryPS(hps1, &sizl); - - *hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc1); - *hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC); - - /* create bitmap now using the parameters from the info block */ - *hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL); - - /* select the new bitmap into presentation space */ - GpiSetBitmap(*hps, *hbm); - - /* now copy the bitmap data into the bitmap */ - GpiSetBitmapBits(*hps, 0L, ScanLines, - BitmapFileBegin + pBitmapFileHeader->offBits, - (PBITMAPINFO2)pBitmapInfoHeader); - - WinReleasePS(hps1); - - /* free memory of bitmap file buffer */ - DosFreeMem(BitmapFileBegin); - /* close the bitmap file */ - DosClose(BitmapFileHandle); - return 1; + HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */ + ULONG OpenAction = 0; + PBYTE BitmapFileBegin; /* pointer to the first byte of bitmap data */ + FILESTATUS BitmapStatus; + ULONG cbRead; + PBITMAPFILEHEADER2 pBitmapFileHeader; + PBITMAPINFOHEADER2 pBitmapInfoHeader; + ULONG ScanLines, ulFlags; + HPS hps1; + HDC hdc1; + SIZEL sizl = { 0, 0 }; + + /* open bitmap file */ + DosOpen((PSZ)file, &BitmapFileHandle, &OpenAction, 0L, + FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY, + OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY | + OPEN_FLAGS_NOINHERIT, 0L); + + if(!BitmapFileHandle) + return 0; + + /* find out how big the file is */ + DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus, + sizeof(BitmapStatus)); + + /* allocate memory to load the bitmap */ + DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile, + PAG_READ | PAG_WRITE | PAG_COMMIT); + + /* read bitmap file into memory buffer */ + DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin, + BitmapStatus.cbFile, &cbRead); + + /* access first bytes as bitmap header */ + pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin; + + /* check if it's a valid bitmap data file */ + if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) && + (pBitmapFileHeader->usType != BFT_BMAP)) + { + /* free memory of bitmap file buffer */ + DosFreeMem(BitmapFileBegin); + /* close the bitmap file */ + DosClose(BitmapFileHandle); + return 0; + } + + /* check if it's a file with multiple bitmaps */ + if(pBitmapFileHeader->usType == BFT_BITMAPARRAY) + { + /* we'll just use the first bitmap and ignore the others */ + pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2); + } + + /* set pointer to bitmap information block */ + pBitmapInfoHeader = &pBitmapFileHeader->bmp2; + + /* find out if it's the new 2.0 format or the old format */ + /* and query number of lines */ + if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER)) + { + *height = ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy; + *width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx; + } + else + { + *height = ScanLines = pBitmapInfoHeader->cy; + *width = pBitmapInfoHeader->cx; + } + + /* now we need a presentation space, get it from static control */ + hps1 = WinGetPS(handle); + + hdc1 = GpiQueryDevice(hps1); + ulFlags = GpiQueryPS(hps1, &sizl); + + *hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc1); + *hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC); + + /* create bitmap now using the parameters from the info block */ + *hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL); + + /* select the new bitmap into presentation space */ + GpiSetBitmap(*hps, *hbm); + + /* now copy the bitmap data into the bitmap */ + GpiSetBitmapBits(*hps, 0L, ScanLines, + BitmapFileBegin + pBitmapFileHeader->offBits, + (PBITMAPINFO2)pBitmapInfoHeader); + + WinReleasePS(hps1); + + /* free memory of bitmap file buffer */ + DosFreeMem(BitmapFileBegin); + /* close the bitmap file */ + DosClose(BitmapFileHandle); + return 1; } /* @@ -5182,55 +6165,124 @@ */ void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename) { - HBITMAP hbm; - HPS hps; - - /* Destroy any old bitmap data */ - _free_bitmap(handle); - - /* If id is non-zero use the resource */ - if(id) - { - hps = WinGetPS(handle); - - hbm = GpiLoadBitmap(hps, NULLHANDLE, id, 0, 0); - } - else if(filename) - { - HDC hdc; - unsigned long width, height; - char *file = alloca(strlen(filename) + 5); - - if(!file) - return; - - strcpy(file, filename); - - /* check if we can read from this file (it exists and read permission) */ - if(access(file, 04) != 0) - { - /* Try with .bmp extention */ - strcat(file, ".bmp"); - if(access(file, 04) != 0) - return; - } - - if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height)) - return; - - dw_window_set_data(handle, "_dw_hps", (void *)hps); - dw_window_set_data(handle, "_dw_hdc", (void *)hdc); - dw_window_set_data(handle, "_dw_width", (void *)width); - dw_window_set_data(handle, "_dw_height", (void *)height); - } - else - return; - - WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f); - WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL ); - if(id) - WinReleasePS(hps); - dw_window_set_data(handle, "_dw_bitmap", (void *)hbm); + HBITMAP hbm; + HPS hps; + + /* Destroy any old bitmap data */ + _free_bitmap(handle); + + /* If id is non-zero use the resource */ + if ( id ) + { + hps = WinGetPS( handle ); + hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 ); + } + else if ( filename ) + { + HDC hdc; + unsigned long width, height; + char *file = alloca(strlen(filename) + 5); + + if(!file) + return; + + strcpy(file, filename); + + /* check if we can read from this file (it exists and read permission) */ + if(access(file, 04) != 0) + { + /* Try with .bmp extention */ + strcat(file, ".bmp"); + if(access(file, 04) != 0) + return; + } + + if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height)) + return; + + dw_window_set_data(handle, "_dw_hps", (void *)hps); + dw_window_set_data(handle, "_dw_hdc", (void *)hdc); + dw_window_set_data(handle, "_dw_width", (void *)width); + dw_window_set_data(handle, "_dw_height", (void *)height); + } + else + return; + + WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f); + WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL ); + if ( id ) + WinReleasePS(hps); + dw_window_set_data(handle, "_dw_bitmap", (void *)hbm); +} + +/* + * Sets the bitmap used for a given static window. + * Parameters: + * handle: Handle to the window. + * id: An ID to be used to specify the icon, + * (pass 0 if you use the filename param) + * filename: a path to a file (Bitmap on OS/2 or + * Windows and a pixmap on Unix, pass + * NULL if you use the id param) + */ +void API dw_window_set_bitmap_from_data(HWND handle, unsigned long id, char *data, int len) +{ + HBITMAP hbm; + HPS hps; + HDC hdc; + unsigned long width, height; + char *file; + FILE *fp; + + /* Destroy any old bitmap data */ + _free_bitmap(handle); + + /* If id is non-zero use the resource */ + if ( id ) + { + hps = WinGetPS( handle ); + hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 ); + } + else if ( data ) + { + file = tmpnam( NULL ); + if ( file != NULL ) + { + fp = fopen( file, "wb" ); + if ( fp != NULL ) + { + fwrite( data, 1, len, fp ); + fclose( fp ); + if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */ + _load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height); + else /* otherwise its assumed to be an ico */ + { + /* con't use ICO ? */ + unlink( file ); + return; + } + } + else + { + unlink( file ); + return; + } + unlink( file ); + } + + dw_window_set_data(handle, "_dw_hps", (void *)hps); + dw_window_set_data(handle, "_dw_hdc", (void *)hdc); + dw_window_set_data(handle, "_dw_width", (void *)width); + dw_window_set_data(handle, "_dw_height", (void *)height); + } + else + return; + + WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f); + WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL ); + if ( id ) + WinReleasePS(hps); + dw_window_set_data(handle, "_dw_bitmap", (void *)hbm); } /* @@ -5241,7 +6293,8 @@ */ void API dw_window_set_text(HWND handle, char *text) { - WinSetWindowText(handle, text); + HWND entryfield = (HWND)dw_window_get_data(handle, "_dw_buddy"); + WinSetWindowText(entryfield ? entryfield : handle, (PSZ)text); } /* @@ -5253,12 +6306,13 @@ */ char * API dw_window_get_text(HWND handle) { - int len = WinQueryWindowTextLength(handle); - char *tempbuf = calloc(1, len + 2); - - WinQueryWindowText(handle, len + 1, tempbuf); - - return tempbuf; + HWND entryfield = (HWND)dw_window_get_data(handle, "_dw_buddy"); + int len = WinQueryWindowTextLength(entryfield ? entryfield : handle); + char *tempbuf = calloc(1, len + 2); + + WinQueryWindowText(entryfield ? entryfield : handle, len + 1, (PSZ)tempbuf); + + return tempbuf; } /* @@ -5268,47 +6322,60 @@ */ void API dw_window_disable(HWND handle) { - char tmpbuf[100]; - - if(dw_window_get_data(handle, "_dw_disabled")) - return; - - WinQueryClassName(handle, 99, tmpbuf); - dw_window_set_data(handle, "_dw_disabled", (void *)1); - - if(tmpbuf[0] == '#') - { - int val = atoi(&tmpbuf[1]); - HWND hwnd; - - switch(val) - { - case 2: - case 6: - case 10: - case 32: - case 7: - hwnd = _find_entryfield(handle); - _dw_window_set_color(hwnd ? hwnd : handle, DW_CLR_BLACK, DW_CLR_PALEGRAY); - dw_signal_connect(hwnd ? hwnd : handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100); + char tmpbuf[100]; + + if(handle < 65536) + { + char buffer[30]; + HMENUI mymenu; + + sprintf(buffer, "_dw_id%ld", handle); + mymenu = (HMENUI)dw_window_get_data(hwndApp, buffer); + + if(mymenu && WinIsWindow(dwhab, mymenu)) + dw_menu_item_set_state(mymenu, handle, DW_MIS_DISABLED); + return; + } + + if(dw_window_get_data(handle, "_dw_disabled")) + return; + + WinQueryClassName(handle, 99, (PCH)tmpbuf); + dw_window_set_data(handle, "_dw_disabled", (void *)1); + + if(tmpbuf[0] == '#') + { + int val = atoi(&tmpbuf[1]); + HWND hwnd; + + switch(val) + { + case 2: + case 6: + case 10: + case 32: + case 7: + hwnd = _find_entryfield(handle); + _dw_window_set_color(hwnd ? hwnd : handle, DW_CLR_BLACK, DW_CLR_PALEGRAY); + dw_signal_connect(hwnd ? hwnd : handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100); if(val == 2) - dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100); - if(hwnd) - dw_window_set_data(hwnd, "_dw_disabled", (void *)1); - return; - case 3: - if(dw_window_get_data(handle, "_dw_bitmapbutton") && !dw_window_get_data(handle, "_dw_hpixmap")) - WinEnableWindow(handle, FALSE); - else if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled")) - WinInvalidateRect(handle, NULL, FALSE); - else - _dw_window_set_color(handle, DW_CLR_DARKGRAY, DW_CLR_PALEGRAY); - dw_signal_connect(handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100); - dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100); - return; - } - } - WinEnableWindow(handle, FALSE); + dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100); + if(hwnd) + dw_window_set_data(hwnd, "_dw_disabled", (void *)1); + return; + case 3: + if(dw_window_get_data(handle, "_dw_bitmapbutton") && !dw_window_get_data(handle, "_dw_hpixmap")) + WinEnableWindow(handle, FALSE); + else if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled")) + WinInvalidateRect(handle, NULL, FALSE); + else + _dw_window_set_color(handle, DW_CLR_DARKGRAY, DW_CLR_PALEGRAY); + dw_signal_connect(handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100); + dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100); + return; + } + } + WinEnableWindow(handle, FALSE); } /* @@ -5318,19 +6385,32 @@ */ void API dw_window_enable(HWND handle) { - ULONG fore = (ULONG)dw_window_get_data(handle, "_dw_fore"); - ULONG back = (ULONG)dw_window_get_data(handle, "_dw_back"); - HWND hwnd = _find_entryfield(handle); - - dw_window_set_data(handle, "_dw_disabled", 0); - if(hwnd) - dw_window_set_data(hwnd, "_dw_disabled", 0); - if(fore && back) - _dw_window_set_color(hwnd ? hwnd : handle, fore-1, back-1); - dw_signal_disconnect_by_data(handle, (void *)100); - WinEnableWindow(handle, TRUE); - if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled")) - WinInvalidateRect(handle, NULL, FALSE); + ULONG fore = (ULONG)dw_window_get_data(handle, "_dw_fore"); + ULONG back = (ULONG)dw_window_get_data(handle, "_dw_back"); + HWND hwnd = _find_entryfield(handle); + + if(handle < 65536) + { + char buffer[30]; + HMENUI mymenu; + + sprintf(buffer, "_dw_id%ld", handle); + mymenu = (HMENUI)dw_window_get_data(hwndApp, buffer); + + if(mymenu && WinIsWindow(dwhab, mymenu)) + dw_menu_item_set_state(mymenu, handle, DW_MIS_ENABLED); + return; + } + + dw_window_set_data(handle, "_dw_disabled", 0); + if(hwnd) + dw_window_set_data(hwnd, "_dw_disabled", 0); + if(fore && back) + _dw_window_set_color(hwnd ? hwnd : handle, fore-1, back-1); + dw_signal_disconnect_by_data(handle, (void *)100); + WinEnableWindow(handle, TRUE); + if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled")) + WinInvalidateRect(handle, NULL, FALSE); } /* @@ -5341,31 +6421,170 @@ */ HWND API dw_window_from_id(HWND handle, int id) { - HENUM henum; - HWND child; - char tmpbuf[100]; - - henum = WinBeginEnumWindows(handle); - while((child = WinGetNextWindow(henum)) != NULLHANDLE) - { - int windowid = WinQueryWindowUShort(child, QWS_ID); - HWND found; - - WinQueryClassName(child, 99, tmpbuf); - - /* If the child is a box (frame) then recurse into it */ - if(strncmp(tmpbuf, "#1", 3)==0) - if((found = dw_window_from_id(child, id)) != NULLHANDLE) - return found; - - if(windowid && windowid == id) - { - WinEndEnumWindows(henum); - return child; - } - } - WinEndEnumWindows(henum); - return NULLHANDLE; + HENUM henum; + HWND child; + char tmpbuf[100]; + + henum = WinBeginEnumWindows(handle); + while((child = WinGetNextWindow(henum)) != NULLHANDLE) + { + int windowid = WinQueryWindowUShort(child, QWS_ID); + HWND found; + + WinQueryClassName(child, 99, (PCH)tmpbuf); + + /* If the child is a box (frame) then recurse into it */ + if(strncmp(tmpbuf, "#1", 3)==0) + if((found = dw_window_from_id(child, id)) != NULLHANDLE) + return found; + + if(windowid && windowid == id) + { + WinEndEnumWindows(henum); + return child; + } + } + WinEndEnumWindows(henum); + return NULLHANDLE; +} + +/* Internal box packing function called by the other 3 functions */ +void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname) +{ + Box *thisbox; + + /* + * If you try and pack an item into itself VERY bad things can happen; like at least an + * infinite loop on GTK! Lets be safe! + */ + if(box == item) + { + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); + return; + } + + if(WinWindowFromID(box, FID_CLIENT)) + { + HWND intbox = (HWND)dw_window_get_data(box, "_dw_box"); + if(intbox) + { + box = intbox; + } + else + { + box = WinWindowFromID(box, FID_CLIENT); + hsize = vsize = TRUE; + } + } + + thisbox = WinQueryWindowPtr(box, QWP_USER); + + if(thisbox) + { + int z, x = 0; + Item *tmpitem, *thisitem = thisbox->items; + char tmpbuf[100]; + HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box"); + + /* Do some sanity bounds checking */ + if(index < 0) + index = 0; + if(index > thisbox->count) + index = thisbox->count; + + tmpitem = malloc(sizeof(Item)*(thisbox->count+1)); + + for(z=0;z<thisbox->count;z++) + { + if(z == index) + x++; + tmpitem[x] = thisitem[z]; + x++; + } + + + WinQueryClassName(item, 99, (PCH)tmpbuf); + + if(vsize && !height) + height = 1; + if(hsize && !width) + width = 1; + + if(strncmp(tmpbuf, "#1", 3)==0) + tmpitem[index].type = TYPEBOX; + else + { + if ( width == 0 && hsize == FALSE ) + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); + if ( height == 0 && vsize == FALSE ) + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); + + tmpitem[index].type = TYPEITEM; + } + + tmpitem[index].hwnd = item; + tmpitem[index].origwidth = tmpitem[index].width = width; + tmpitem[index].origheight = tmpitem[index].height = height; + tmpitem[index].pad = pad; + if(hsize) + tmpitem[index].hsize = SIZEEXPAND; + else + tmpitem[index].hsize = SIZESTATIC; + + if(vsize) + tmpitem[index].vsize = SIZEEXPAND; + else + tmpitem[index].vsize = SIZESTATIC; + + thisbox->items = tmpitem; + + if(thisbox->count) + free(thisitem); + + thisbox->count++; + + WinQueryClassName(item, 99, (PCH)tmpbuf); + /* Don't set the ownership if it's an entryfield or spinbutton */ + if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0) + WinSetOwner(item, box); + WinSetParent(frame ? frame : item, box, FALSE); + } +} + +/* + * Pack windows (widgets) into a box at an arbitrary location. + * Parameters: + * box: Window handle of the box to be packed into. + * item: Window handle of the item to be back. + * index: 0 based index of packed items. + * width: Width in pixels of the item or -1 to be self determined. + * height: Height in pixels of the item or -1 to be self determined. + * hsize: TRUE if the window (widget) should expand horizontally to fill space given. + * vsize: TRUE if the window (widget) should expand vertically to fill space given. + * pad: Number of pixels of padding around the item. + */ +void API dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad) +{ + _dw_box_pack(box, item, index, width, height, hsize, vsize, pad, "dw_box_pack_at_index()"); +} + +/* + * Pack windows (widgets) into a box from the start (or top). + * Parameters: + * box: Window handle of the box to be packed into. + * item: Window handle of the item to be back. + * width: Width in pixels of the item or -1 to be self determined. + * height: Height in pixels of the item or -1 to be self determined. + * hsize: TRUE if the window (widget) should expand horizontally to fill space given. + * vsize: TRUE if the window (widget) should expand vertically to fill space given. + * pad: Number of pixels of padding around the item. + */ +void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) +{ + /* 65536 is the table limit on GTK... + * seems like a high enough value we will never hit it here either. + */ + _dw_box_pack(box, item, 65536, width, height, hsize, vsize, pad, "dw_box_pack_start()"); } /* @@ -5381,91 +6600,7 @@ */ void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) { - char *funcname = "dw_box_pack_end()"; - - /* - * If you try and pack an item into itself VERY bad things can happen; like at least an - * infinite loop on GTK! Lets be safe! - */ - if(box == item) - { - dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); - return; - } - - if(WinWindowFromID(box, FID_CLIENT)) - { - box = WinWindowFromID(box, FID_CLIENT); - hsize = TRUE; - vsize = TRUE; - } - _dw_box_pack_end(box, item, width, height, hsize, vsize, pad, funcname); -} - -void _dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname) -{ - Box *thisbox = WinQueryWindowPtr(box, QWP_USER); - - if(thisbox) - { - int z; - Item *tmpitem, *thisitem = thisbox->items; - char tmpbuf[100]; - HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box"); - - tmpitem = malloc(sizeof(Item)*(thisbox->count+1)); - - for(z=0;z<thisbox->count;z++) - { - tmpitem[z+1] = thisitem[z]; - } - - WinQueryClassName(item, 99, tmpbuf); - - if(vsize && !height) - height = 1; - if(hsize && !width) - width = 1; - - if(strncmp(tmpbuf, "#1", 3)==0) - tmpitem[0].type = TYPEBOX; - else - { - if ( width == 0 && hsize == FALSE ) - dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); - if ( height == 0 && vsize == FALSE ) - dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); - - tmpitem[0].type = TYPEITEM; - } - - tmpitem[0].hwnd = item; - tmpitem[0].origwidth = tmpitem[0].width = width; - tmpitem[0].origheight = tmpitem[0].height = height; - tmpitem[0].pad = pad; - if(hsize) - tmpitem[0].hsize = SIZEEXPAND; - else - tmpitem[0].hsize = SIZESTATIC; - - if(vsize) - tmpitem[0].vsize = SIZEEXPAND; - else - tmpitem[0].vsize = SIZESTATIC; - - thisbox->items = tmpitem; - - if(thisbox->count) - free(thisitem); - - thisbox->count++; - - WinQueryClassName(item, 99, tmpbuf); - /* Don't set the ownership if it's an entryfield or spinbutton */ - if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0) - WinSetOwner(item, box); - WinSetParent(frame ? frame : item, box, FALSE); - } + _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()"); } /* @@ -5477,7 +6612,7 @@ */ void API dw_window_set_size(HWND handle, ULONG width, ULONG height) { - WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE); + WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE); } /* @@ -5485,7 +6620,7 @@ */ int API dw_screen_width(void) { - return WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN); + return WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN); } /* @@ -5493,18 +6628,18 @@ */ int API dw_screen_height(void) { - return WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN); + return WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN); } /* This should return the current color depth */ unsigned long API dw_color_depth_get(void) { - HDC hdc = WinOpenWindowDC(HWND_DESKTOP); - long colors; - - DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &colors); - DevCloseDC(hdc); - return colors; + HDC hdc = WinOpenWindowDC(HWND_DESKTOP); + long colors; + + DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &colors); + DevCloseDC(hdc); + return colors; } @@ -5515,11 +6650,11 @@ * x: X location from the bottom left. * y: Y location from the bottom left. */ -void API dw_window_set_pos(HWND handle, ULONG x, ULONG y) -{ - int myy = _get_frame_height(handle) - (y + _get_height(handle)); - - WinSetWindowPos(handle, NULLHANDLE, x, myy, 0, 0, SWP_MOVE); +void API dw_window_set_pos(HWND handle, LONG x, LONG y) +{ + int myy = _get_frame_height(handle) - (y + _get_height(handle)); + + WinSetWindowPos(handle, NULLHANDLE, x, myy, 0, 0, SWP_MOVE); } /* @@ -5531,11 +6666,11 @@ * width: Width of the widget. * height: Height of the widget. */ -void API dw_window_set_pos_size(HWND handle, ULONG x, ULONG y, ULONG width, ULONG height) -{ - int myy = _get_frame_height(handle) - (y + height); - - WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW); +void API dw_window_set_pos_size(HWND handle, LONG x, LONG y, ULONG width, ULONG height) +{ + int myy = _get_frame_height(handle) - (y + height); + + WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW); } /* @@ -5547,18 +6682,18 @@ * width: Width of the widget. * height: Height of the widget. */ -void API dw_window_get_pos_size(HWND handle, ULONG *x, ULONG *y, ULONG *width, ULONG *height) -{ - SWP swp; - WinQueryWindowPos(handle, &swp); - if(x) - *x = swp.x; - if(y) - *y = _get_frame_height(handle) - (swp.y + swp.cy); - if(width) - *width = swp.cx; - if(height) - *height = swp.cy; +void API dw_window_get_pos_size(HWND handle, LONG *x, LONG *y, ULONG *width, ULONG *height) +{ + SWP swp; + WinQueryWindowPos(handle, &swp); + if(x) + *x = swp.x; + if(y) + *y = _get_frame_height(handle) - (swp.y + swp.cy); + if(width) + *width = swp.cx; + if(height) + *height = swp.cy; } /* @@ -5570,7 +6705,19 @@ */ void API dw_window_set_style(HWND handle, ULONG style, ULONG mask) { - WinSetWindowBits(handle, QWL_STYLE, style, mask); + if(handle < 65536) + { + char buffer[30]; + HMENUI mymenu; + + sprintf(buffer, "_dw_id%ld", handle); + mymenu = (HMENUI)dw_window_get_data(hwndApp, buffer); + + if(mymenu && WinIsWindow(dwhab, mymenu)) + dw_menu_item_set_state(mymenu, handle, style & mask); + } + else + WinSetWindowBits(handle, QWL_STYLE, style, mask); } /* @@ -5582,8 +6729,8 @@ */ unsigned long API dw_notebook_page_new(HWND handle, ULONG flags, int front) { - return (ULONG)WinSendMsg(handle, BKM_INSERTPAGE, 0L, - MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | BKA_MAJOR | flags), front ? BKA_FIRST : BKA_LAST)); + return (ULONG)WinSendMsg(handle, BKM_INSERTPAGE, 0L, + MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | BKA_MAJOR | flags), front ? BKA_FIRST : BKA_LAST)); } /* @@ -5594,8 +6741,12 @@ */ void API dw_notebook_page_destroy(HWND handle, unsigned int pageid) { - WinSendMsg(handle, BKM_DELETEPAGE, - MPFROMLONG(pageid), (MPARAM)BKA_SINGLE); + HWND pagehwnd = (HWND)WinSendMsg(handle, BKM_QUERYPAGEWINDOWHWND, + MPFROMLONG(pageid), 0L); + WinSendMsg(handle, BKM_DELETEPAGE, + MPFROMLONG(pageid), (MPARAM)BKA_SINGLE); + if(pagehwnd) + dw_window_destroy(pagehwnd); } /* @@ -5605,7 +6756,7 @@ */ unsigned long API dw_notebook_page_get(HWND handle) { - return (unsigned long)WinSendMsg(handle, BKM_QUERYPAGEID,0L, MPFROM2SHORT(BKA_TOP, BKA_MAJOR)); + return (unsigned long)WinSendMsg(handle, BKM_QUERYPAGEID,0L, MPFROM2SHORT(BKA_TOP, BKA_MAJOR)); } /* @@ -5616,7 +6767,7 @@ */ void API dw_notebook_page_set(HWND handle, unsigned int pageid) { - WinSendMsg(handle, BKM_TURNTOPAGE, MPFROMLONG(pageid), 0L); + WinSendMsg(handle, BKM_TURNTOPAGE, MPFROMLONG(pageid), 0L); } /* @@ -5628,8 +6779,8 @@ */ void API dw_notebook_page_set_text(HWND handle, ULONG pageid, char *text) { - WinSendMsg(handle, BKM_SETTABTEXT, - MPFROMLONG(pageid), MPFROMP(text)); + WinSendMsg(handle, BKM_SETTABTEXT, + MPFROMLONG(pageid), MPFROMP(text)); } /* @@ -5641,8 +6792,8 @@ */ void API dw_notebook_page_set_status_text(HWND handle, ULONG pageid, char *text) { - WinSendMsg(handle, BKM_SETSTATUSLINETEXT, - MPFROMLONG(pageid), MPFROMP(text)); + WinSendMsg(handle, BKM_SETSTATUSLINETEXT, + MPFROMLONG(pageid), MPFROMP(text)); } /* @@ -5654,12 +6805,12 @@ */ void API dw_notebook_pack(HWND handle, ULONG pageid, HWND page) { - HWND tmpbox = dw_box_new(DW_VERT, 0); - - dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0); - WinSubclassWindow(tmpbox, _wndproc); - WinSendMsg(handle, BKM_SETPAGEWINDOWHWND, - MPFROMLONG(pageid), MPFROMHWND(tmpbox)); + HWND tmpbox = dw_box_new(DW_VERT, 0); + + dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0); + WinSubclassWindow(tmpbox, _wndproc); + WinSendMsg(handle, BKM_SETPAGEWINDOWHWND, + MPFROMLONG(pageid), MPFROMHWND(tmpbox)); } /* @@ -5670,10 +6821,25 @@ */ void API dw_listbox_append(HWND handle, char *text) { - WinSendMsg(handle, - LM_INSERTITEM, - MPFROMSHORT(LIT_END), - MPFROMP(text)); + WinSendMsg(handle, + LM_INSERTITEM, + MPFROMSHORT(LIT_END), + MPFROMP(text)); +} + +/* + * Inserts the specified text into the listbox's (or combobox) entry list. + * Parameters: + * handle: Handle to the listbox to be inserted into. + * text: Text to insert into listbox. + * pos: 0-based position to insert text + */ +void API dw_listbox_insert(HWND handle, char *text, int pos) +{ + WinSendMsg(handle, + LM_INSERTITEM, + MPFROMSHORT(pos), + MPFROMP(text)); } /* @@ -5685,12 +6851,12 @@ */ void API dw_listbox_list_append(HWND handle, char **text, int count) { - int i; - for(i=0;i<count;i++) - WinSendMsg(handle, - LM_INSERTITEM, - MPFROMSHORT(LIT_END), - MPFROMP(text[i])); + int i; + for(i=0;i<count;i++) + WinSendMsg(handle, + LM_INSERTITEM, + MPFROMSHORT(LIT_END), + MPFROMP(text[i])); } /* @@ -5700,8 +6866,8 @@ */ void API dw_listbox_clear(HWND handle) { - WinSendMsg(handle, - LM_DELETEALL, 0L, 0L); + WinSendMsg(handle, + LM_DELETEALL, 0L, 0L); } /* @@ -5711,8 +6877,8 @@ */ int API dw_listbox_count(HWND handle) { - return (int)WinSendMsg(handle, - LM_QUERYITEMCOUNT,0L, 0L); + return (int)WinSendMsg(handle, + LM_QUERYITEMCOUNT,0L, 0L); } /* @@ -5723,10 +6889,10 @@ */ void API dw_listbox_set_top(HWND handle, int top) { - WinSendMsg(handle, - LM_SETTOPINDEX, - MPFROMSHORT(top), - 0L); + WinSendMsg(handle, + LM_SETTOPINDEX, + MPFROMSHORT(top), + 0L); } /* @@ -5739,7 +6905,7 @@ */ void API dw_listbox_get_text(HWND handle, unsigned int index, char *buffer, unsigned int length) { - WinSendMsg(handle, LM_QUERYITEMTEXT, MPFROM2SHORT(index, length), (MPARAM)buffer); + WinSendMsg(handle, LM_QUERYITEMTEXT, MPFROM2SHORT(index, length), (MPARAM)buffer); } /* @@ -5751,7 +6917,7 @@ */ void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer) { - WinSendMsg(handle, LM_SETITEMTEXT, MPFROMSHORT(index), (MPARAM)buffer); + WinSendMsg(handle, LM_SETITEMTEXT, MPFROMSHORT(index), (MPARAM)buffer); } /* @@ -5759,12 +6925,12 @@ * Parameters: * handle: Handle to the listbox to be queried. */ -unsigned int API dw_listbox_selected(HWND handle) -{ - return (unsigned int)WinSendMsg(handle, - LM_QUERYSELECTION, - MPFROMSHORT(LIT_CURSOR), - 0); +int API dw_listbox_selected(HWND handle) +{ + return (unsigned int)WinSendMsg(handle, + LM_QUERYSELECTION, + MPFROMSHORT(LIT_CURSOR), + 0); } /* @@ -5775,17 +6941,17 @@ */ int API dw_listbox_selected_multi(HWND handle, int where) { - int place = where; - - if(where == -1) - place = LIT_FIRST; - - place = (int)WinSendMsg(handle, - LM_QUERYSELECTION, - MPFROMSHORT(place),0L); - if(place == LIT_NONE) - return -1; - return place; + int place = where; + + if(where == -1) + place = LIT_FIRST; + + place = (int)WinSendMsg(handle, + LM_QUERYSELECTION, + MPFROMSHORT(place),0L); + if(place == LIT_NONE) + return -1; + return place; } /* @@ -5797,15 +6963,15 @@ */ void API dw_listbox_select(HWND handle, int index, int state) { - char tmpbuf[100]; - - WinSendMsg(handle, LM_SELECTITEM, MPFROMSHORT(index), (MPARAM)state); - - WinQueryClassName(handle, 99, tmpbuf); - - /* If we are setting a combobox call the event handler manually */ - if(strncmp(tmpbuf, "#6", 3)==0) - _run_event(handle, WM_CONTROL, MPFROM2SHORT(0, LN_SELECT), (MPARAM)handle); + char tmpbuf[100]; + + WinSendMsg(handle, LM_SELECTITEM, MPFROMSHORT(index), (MPARAM)state); + + WinQueryClassName(handle, 99, (PCH)tmpbuf); + + /* If we are setting a combobox call the event handler manually */ + if(strncmp(tmpbuf, "#6", 3)==0) + _run_event(handle, WM_CONTROL, MPFROM2SHORT(0, LN_SELECT), (MPARAM)handle); } /* @@ -5816,7 +6982,7 @@ */ void API dw_listbox_delete(HWND handle, int index) { - WinSendMsg(handle, LM_DELETEITEM, MPFROMSHORT(index), 0); + WinSendMsg(handle, LM_DELETEITEM, MPFROMSHORT(index), 0); } /* @@ -5828,33 +6994,43 @@ */ unsigned int API dw_mle_import(HWND handle, char *buffer, int startpoint) { - unsigned long point = startpoint; - PBYTE mlebuf; - - /* Work around 64K limit */ - if(!DosAllocMem((PPVOID) &mlebuf, 65536, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE)) - { - int amount, len = strlen(buffer), written = 0; - - while(written < len) - { - if((len - written) > 65535) - amount = 65535; - else - amount = len - written; - - memcpy(mlebuf, &buffer[written], amount); - mlebuf[amount] = '\0'; - - WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount+1)); - WinSendMsg(handle, MLM_IMPORT, MPFROMP(&point), MPFROMLONG(amount + 1)); - dw_mle_delete(handle, point, 1); - - written += amount; - } - DosFreeMem(mlebuf); - } - return point - 1; + long point = startpoint < 0 ? 0 : startpoint; + PBYTE mlebuf; + + /* Work around 64K limit */ + if(!DosAllocMem((PPVOID) &mlebuf, 65536, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE)) + { + int amount, len = strlen(buffer), written = 0; + + while(written < len) + { + int z, x = 0; + + if((len - written) > 65535) + amount = 65535; + else + amount = len - written; + + /* Remove Carriage Returns \r */ + for(z=0;z<amount;z++) + { + if(buffer[z] != '\r') + { + mlebuf[x] = buffer[z]; + x++; + } + } + + if(point < 0) + point = 0; + WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(x)); + WinSendMsg(handle, MLM_IMPORT, MPFROMP(&point), MPFROMLONG(x)); + + written += amount; + } + DosFreeMem(mlebuf); + } + return point; } /* @@ -5867,34 +7043,34 @@ */ void API dw_mle_export(HWND handle, char *buffer, int startpoint, int length) { - PBYTE mlebuf; - - /* Work around 64K limit */ - if(!DosAllocMem((PPVOID) &mlebuf, 65535, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE)) - { - int amount, copied, written = 0; - - while(written < length) - { - if((length - written) > 65535) - amount = 65535; - else - amount = length - written; - - WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount)); - copied = (int)WinSendMsg(handle, MLM_EXPORT, MPFROMP(&startpoint), MPFROMLONG(&amount)); - - if(copied) - { - memcpy(&buffer[written], mlebuf, copied); - - written += copied; - } - else - break; - } - DosFreeMem(mlebuf); - } + PBYTE mlebuf; + + /* Work around 64K limit */ + if(!DosAllocMem((PPVOID) &mlebuf, 65535, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE)) + { + int amount, copied, written = 0; + + while(written < length) + { + if((length - written) > 65535) + amount = 65535; + else + amount = length - written; + + WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount)); + copied = (int)WinSendMsg(handle, MLM_EXPORT, MPFROMP(&startpoint), MPFROMLONG(&amount)); + + if(copied) + { + memcpy(&buffer[written], mlebuf, copied); + + written += copied; + } + else + break; + } + DosFreeMem(mlebuf); + } } /* @@ -5906,10 +7082,10 @@ */ void API dw_mle_get_size(HWND handle, unsigned long *bytes, unsigned long *lines) { - if(bytes) - *bytes = (unsigned long)WinSendMsg(handle, MLM_QUERYTEXTLENGTH, 0, 0); - if(lines) - *lines = (unsigned long)WinSendMsg(handle, MLM_QUERYLINECOUNT, 0, 0); + if(bytes) + *bytes = (unsigned long)WinSendMsg(handle, MLM_QUERYTEXTLENGTH, 0, 0); + if(lines) + *lines = (unsigned long)WinSendMsg(handle, MLM_QUERYLINECOUNT, 0, 0); } /* @@ -5921,18 +7097,7 @@ */ void API dw_mle_delete(HWND handle, int startpoint, int length) { - char *buf = malloc(length+1); - int z, dellen = length; - - dw_mle_export(handle, buf, startpoint, length); - - for(z=0;z<length-1;z++) - { - if(strncmp(&buf[z], "\r\n", 2) == 0) - dellen--; - } - WinSendMsg(handle, MLM_DELETE, MPFROMLONG(startpoint), MPFROMLONG(dellen)); - free(buf); + WinSendMsg(handle, MLM_DELETE, MPFROMLONG(startpoint), MPFROMLONG(length)); } /* @@ -5942,11 +7107,11 @@ */ void API dw_mle_clear(HWND handle) { - unsigned long bytes; - - dw_mle_get_size(handle, &bytes, NULL); - - WinSendMsg(handle, MLM_DELETE, MPFROMLONG(0), MPFROMLONG(bytes)); + unsigned long bytes; + + dw_mle_get_size(handle, &bytes, NULL); + + WinSendMsg(handle, MLM_DELETE, MPFROMLONG(0), MPFROMLONG(bytes)); } /* @@ -5957,8 +7122,8 @@ */ void API dw_mle_set_visible(HWND handle, int line) { - int tmppnt = (int)WinSendMsg(handle, MLM_CHARFROMLINE, MPFROMLONG(line), 0); - WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(tmppnt), MPFROMLONG(tmppnt)); + int tmppnt = (int)WinSendMsg(handle, MLM_CHARFROMLINE, MPFROMLONG(line), 0); + WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(tmppnt), MPFROMLONG(tmppnt)); } /* @@ -5969,7 +7134,7 @@ */ void API dw_mle_set_editable(HWND handle, int state) { - WinSendMsg(handle, MLM_SETREADONLY, MPFROMLONG(state ? FALSE : TRUE), 0); + WinSendMsg(handle, MLM_SETREADONLY, MPFROMLONG(state ? FALSE : TRUE), 0); } /* @@ -5980,7 +7145,7 @@ */ void API dw_mle_set_word_wrap(HWND handle, int state) { - WinSendMsg(handle, MLM_SETWRAP, MPFROMLONG(state), 0); + WinSendMsg(handle, MLM_SETWRAP, MPFROMLONG(state), 0); } /* @@ -5991,7 +7156,7 @@ */ void API dw_mle_set_cursor(HWND handle, int point) { - WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(point), MPFROMLONG(point)); + WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(point), MPFROMLONG(point)); } /* @@ -6004,22 +7169,22 @@ */ int API dw_mle_search(HWND handle, char *text, int point, unsigned long flags) { - MLE_SEARCHDATA msd; - - /* This code breaks with structure packing set to 1 (/Sp1 in VAC) - * if this is needed we need to add a pragma here. - */ - msd.cb = sizeof(msd); - msd.pchFind = text; - msd.pchReplace = NULL; - msd.cchFind = strlen(text); - msd.cchReplace = 0; - msd.iptStart = point; - msd.iptStop = -1; - - if(WinSendMsg(handle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH | flags), (MPARAM)&msd)) - return (int)WinSendMsg(handle, MLM_QUERYSEL,(MPARAM)MLFQS_MAXSEL, 0); - return 0; + MLE_SEARCHDATA msd; + + /* This code breaks with structure packing set to 1 (/Sp1 in VAC) + * if this is needed we need to add a pragma here. + */ + msd.cb = sizeof(msd); + msd.pchFind = text; + msd.pchReplace = NULL; + msd.cchFind = strlen(text); + msd.cchReplace = 0; + msd.iptStart = point; + msd.iptStop = -1; + + if(WinSendMsg(handle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH | flags), (MPARAM)&msd)) + return (int)WinSendMsg(handle, MLM_QUERYSEL,(MPARAM)MLFQS_MAXSEL, 0); + return 0; } /* @@ -6029,7 +7194,7 @@ */ void API dw_mle_freeze(HWND handle) { - WinSendMsg(handle, MLM_DISABLEREFRESH, 0, 0); + WinSendMsg(handle, MLM_DISABLEREFRESH, 0, 0); } /* @@ -6039,7 +7204,51 @@ */ void API dw_mle_thaw(HWND handle) { - WinSendMsg(handle, MLM_ENABLEREFRESH, 0, 0); + WinSendMsg(handle, MLM_ENABLEREFRESH, 0, 0); +} + +/* Internal version that can be called from _percentthread */ +void _dw_percent_set_pos(HWND handle, unsigned int position) +{ + int range = _dw_percent_get_range(handle); + + if(range) + { + int mypos = (((float)position)/100)*range; + + if(mypos >= range) + mypos = range - 1; + + _dw_int_set(handle, mypos); + WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)mypos); + } +} + +/* Move the percentage bar backwards to simulate indeterminate */ +void _percentthread(void *data) +{ + HWND percent = (HWND)data; + + if(percent) + { + HAB thishab = WinInitialize(0); + HMQ thishmq = WinCreateMsgQueue(dwhab, 0); + + int pos = 100; + + do + { + pos--; + if(pos < 1) + pos = 100; + _dw_percent_set_pos(percent, pos); + DosSleep(100); + } + while(dw_window_get_data(percent, "_dw_ind")); + + WinDestroyMsgQueue(thishmq); + WinTerminate(thishab); + } } /* @@ -6050,14 +7259,23 @@ */ void API dw_percent_set_pos(HWND handle, unsigned int position) { - int range = _dw_percent_get_range(handle); - int mypos = ((float)position/100)*range; - - if(range) - { - _dw_int_set(handle, mypos); - WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)mypos); - } + /* OS/2 doesn't really support indeterminate... */ + if(position == DW_PERCENT_INDETERMINATE) + { + if(!dw_window_get_data(handle, "_dw_ind")) + { + /* So we fake it with a thread */ + dw_window_set_data(handle, "_dw_ind", (void *)1); + _beginthread(_percentthread, NULL, 100, (void *)handle); + } + } + else + { + /* Make sure we are no longer indeterminate */ + dw_window_set_data(handle, "_dw_ind", NULL); + /* Otherwise set the position as usual */ + _dw_percent_set_pos(handle, position); + } } /* @@ -6067,7 +7285,7 @@ */ unsigned int API dw_slider_get_pos(HWND handle) { - return (unsigned int)WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0); + return (unsigned int)WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0); } /* @@ -6078,8 +7296,8 @@ */ void API dw_slider_set_pos(HWND handle, unsigned int position) { - dw_window_set_data(handle, "_dw_slider_value", (void *)position); - WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)position); + dw_window_set_data(handle, "_dw_slider_value", (void *)position); + WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)position); } /* @@ -6089,7 +7307,7 @@ */ unsigned int API dw_scrollbar_get_pos(HWND handle) { - return (unsigned int)WinSendMsg(handle, SBM_QUERYPOS, 0, 0); + return (unsigned int)WinSendMsg(handle, SBM_QUERYPOS, 0, 0); } /* @@ -6100,8 +7318,8 @@ */ void API dw_scrollbar_set_pos(HWND handle, unsigned int position) { - dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position); - WinSendMsg(handle, SBM_SETPOS, (MPARAM)position, 0); + dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position); + WinSendMsg(handle, SBM_SETPOS, (MPARAM)position, 0); } /* @@ -6113,10 +7331,10 @@ */ void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible) { - unsigned int pos = (unsigned int)dw_window_get_data(handle, "_dw_scrollbar_value"); - WinSendMsg(handle, SBM_SETSCROLLBAR, (MPARAM)pos, MPFROM2SHORT(0, (unsigned short)range - visible)); - WinSendMsg(handle, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)visible, range), 0); - dw_window_set_data(handle, "_dw_scrollbar_visible", (void *)visible); + unsigned int pos = (unsigned int)dw_window_get_data(handle, "_dw_scrollbar_value"); + WinSendMsg(handle, SBM_SETSCROLLBAR, (MPARAM)pos, MPFROM2SHORT(0, (unsigned short)range - visible)); + WinSendMsg(handle, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)visible, range), 0); + dw_window_set_data(handle, "_dw_scrollbar_visible", (void *)visible); } /* @@ -6127,7 +7345,7 @@ */ void API dw_spinbutton_set_pos(HWND handle, long position) { - WinSendMsg(handle, SPBM_SETCURRENTVALUE, MPFROMLONG((long)position), 0L); + WinSendMsg(handle, SPBM_SETCURRENTVALUE, MPFROMLONG((long)position), 0L); } /* @@ -6139,7 +7357,7 @@ */ void API dw_spinbutton_set_limits(HWND handle, long upper, long lower) { - WinSendMsg(handle, SPBM_SETLIMITS, MPFROMLONG(upper), MPFROMLONG(lower)); + WinSendMsg(handle, SPBM_SETLIMITS, MPFROMLONG(upper), MPFROMLONG(lower)); } /* @@ -6150,7 +7368,7 @@ */ void API dw_entryfield_set_limit(HWND handle, ULONG limit) { - WinSendMsg(handle, EM_SETTEXTLIMIT, (MPARAM)limit, (MPARAM)0); + WinSendMsg(handle, EM_SETTEXTLIMIT, (MPARAM)limit, (MPARAM)0); } @@ -6161,10 +7379,10 @@ */ long API dw_spinbutton_get_pos(HWND handle) { - long tmpval = 0L; - - WinSendMsg(handle, SPBM_QUERYVALUE, (MPARAM)&tmpval,0L); - return tmpval; + long tmpval = 0L; + + WinSendMsg(handle, SPBM_QUERYVALUE, (MPARAM)&tmpval,0L); + return tmpval; } /* @@ -6174,7 +7392,7 @@ */ int API dw_checkbox_get(HWND handle) { - return (int)WinSendMsg(handle,BM_QUERYCHECK,0,0); + return (int)WinSendMsg(handle,BM_QUERYCHECK,0,0); } /* @@ -6185,7 +7403,7 @@ */ void API dw_checkbox_set(HWND handle, int value) { - WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0); + WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0); } /* @@ -6198,53 +7416,53 @@ * parent: Parent handle or 0 if root. * itemdata: Item specific data. */ -HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, unsigned long icon, HTREEITEM parent, void *itemdata) -{ - ULONG cbExtra; - PCNRITEM pci; - RECORDINSERT ri; - - if(!item) - item = (HTREEITEM)CMA_FIRST; - - /* Calculate extra bytes needed for each record besides that needed for the - * MINIRECORDCORE structure - */ - - cbExtra = sizeof(CNRITEM) - sizeof(MINIRECORDCORE); - - /* Allocate memory for the parent record */ - - if((pci = (PCNRITEM)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1), 0)) == 0) - return 0; - - /* Fill in the parent record data */ - - pci->rc.cb = sizeof(MINIRECORDCORE); - pci->rc.pszIcon = strdup(title); - pci->rc.hptrIcon = icon; - - pci->hptrIcon = icon; - pci->user = itemdata; - pci->parent = parent; - - memset(&ri, 0, sizeof(RECORDINSERT)); - - ri.cb = sizeof(RECORDINSERT); - ri.pRecordOrder = (PRECORDCORE)item; - ri.zOrder = (USHORT)CMA_TOP; - ri.cRecordsInsert = 1; - ri.fInvalidateRecord = TRUE; - - /* We are about to insert the child records. Set the parent record to be - * the one we just inserted. - */ - ri.pRecordParent = (PRECORDCORE)parent; - - /* Insert the record */ - WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri)); - - return (HTREEITEM)pci; +HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, HICN icon, HTREEITEM parent, void *itemdata) +{ + ULONG cbExtra; + PCNRITEM pci; + RECORDINSERT ri; + + if(!item) + item = (HTREEITEM)CMA_FIRST; + + /* Calculate extra bytes needed for each record besides that needed for the + * MINIRECORDCORE structure + */ + + cbExtra = sizeof(CNRITEM) - sizeof(MINIRECORDCORE); + + /* Allocate memory for the parent record */ + + if((pci = (PCNRITEM)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1), 0)) == 0) + return 0; + + /* Fill in the parent record data */ + + pci->rc.cb = sizeof(MINIRECORDCORE); + pci->rc.pszIcon = (PSZ)strdup(title); + pci->rc.hptrIcon = icon; + + pci->hptrIcon = icon; + pci->user = itemdata; + pci->parent = parent; + + memset(&ri, 0, sizeof(RECORDINSERT)); + + ri.cb = sizeof(RECORDINSERT); + ri.pRecordOrder = (PRECORDCORE)item; + ri.zOrder = (USHORT)CMA_TOP; + ri.cRecordsInsert = 1; + ri.fInvalidateRecord = TRUE; + + /* We are about to insert the child records. Set the parent record to be + * the one we just inserted. + */ + ri.pRecordParent = (PRECORDCORE)parent; + + /* Insert the record */ + WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri)); + + return (HTREEITEM)pci; } /* @@ -6256,9 +7474,9 @@ * parent: Parent handle or 0 if root. * itemdata: Item specific data. */ -HTREEITEM API dw_tree_insert(HWND handle, char *title, unsigned long icon, HTREEITEM parent, void *itemdata) -{ - return dw_tree_insert_after(handle, (HTREEITEM)CMA_END, title, icon, parent, itemdata); +HTREEITEM API dw_tree_insert(HWND handle, char *title, HICN icon, HTREEITEM parent, void *itemdata) +{ + return dw_tree_insert_after(handle, (HTREEITEM)CMA_END, title, icon, parent, itemdata); } /* @@ -6269,22 +7487,22 @@ * title: The text title of the entry. * icon: Handle to coresponding icon. */ -void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, unsigned long icon) -{ - PCNRITEM pci = (PCNRITEM)item; - - if(!pci) - return; - - if(pci->rc.pszIcon) - free(pci->rc.pszIcon); - - pci->rc.pszIcon = strdup(title); - pci->rc.hptrIcon = icon; - - pci->hptrIcon = icon; - - WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED)); +void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon) +{ + PCNRITEM pci = (PCNRITEM)item; + + if(!pci) + return; + + if(pci->rc.pszIcon) + free(pci->rc.pszIcon); + + pci->rc.pszIcon = (PSZ)strdup(title); + pci->rc.hptrIcon = icon; + + pci->hptrIcon = icon; + + WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED)); } /* @@ -6295,12 +7513,12 @@ */ char * API dw_tree_get_title(HWND handle, HTREEITEM item) { - PCNRITEM pci = (PCNRITEM)item; - - handle = handle; /* keep compiler happy */ - if(pci) - return pci->rc.pszIcon; - return NULL; + PCNRITEM pci = (PCNRITEM)item; + + handle = handle; /* keep compiler happy */ + if(pci) + return (char *)pci->rc.pszIcon; + return NULL; } /* @@ -6311,12 +7529,12 @@ */ HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item) { - PCNRITEM pci = (PCNRITEM)item; - - handle = handle; /* keep compiler happy */ - if(pci) - return pci->parent; - return (HTREEITEM)0; + PCNRITEM pci = (PCNRITEM)item; + + handle = handle; /* keep compiler happy */ + if(pci) + return pci->parent; + return (HTREEITEM)0; } /* @@ -6328,13 +7546,13 @@ */ void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata) { - PCNRITEM pci = (PCNRITEM)item; - - handle = handle; /* keep compiler happy */ - if(!pci) - return; - - pci->user = itemdata; + PCNRITEM pci = (PCNRITEM)item; + + handle = handle; /* keep compiler happy */ + if(!pci) + return; + + pci->user = itemdata; } /* @@ -6345,12 +7563,12 @@ */ void * API dw_tree_item_get_data(HWND handle, HTREEITEM item) { - PCNRITEM pci = (PCNRITEM)item; - - handle = handle; /* keep compiler happy */ - if(!pci) - return NULL; - return pci->user; + PCNRITEM pci = (PCNRITEM)item; + + handle = handle; /* keep compiler happy */ + if(!pci) + return NULL; + return pci->user; } /* @@ -6361,17 +7579,17 @@ */ void API dw_tree_item_select(HWND handle, HTREEITEM item) { - PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); - - while(pCore) - { - if(pCore->flRecordAttr & CRA_SELECTED) - WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED)); - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); - } - WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED)); - lastitem = 0; - lasthcnr = 0; + PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + + while(pCore) + { + if(pCore->flRecordAttr & CRA_SELECTED) + WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED)); + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + } + WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED)); + lastitem = 0; + lasthcnr = 0; } /* @@ -6381,7 +7599,7 @@ */ void API dw_tree_clear(HWND handle) { - dw_container_clear(handle, TRUE); + dw_container_clear(handle, TRUE); } /* @@ -6392,7 +7610,7 @@ */ void API dw_tree_item_expand(HWND handle, HTREEITEM item) { - WinSendMsg(handle, CM_EXPANDTREE, MPFROMP(item), 0); + WinSendMsg(handle, CM_EXPANDTREE, MPFROMP(item), 0); } /* @@ -6403,7 +7621,7 @@ */ void API dw_tree_item_collapse(HWND handle, HTREEITEM item) { - WinSendMsg(handle, CM_COLLAPSETREE, MPFROMP(item), 0); + WinSendMsg(handle, CM_COLLAPSETREE, MPFROMP(item), 0); } /* @@ -6414,25 +7632,25 @@ */ void API dw_tree_item_delete(HWND handle, HTREEITEM item) { - PCNRITEM pci = (PCNRITEM)item; - - if(!item) - return; - - if(pci->rc.pszIcon) - { - free(pci->rc.pszIcon); - pci->rc.pszIcon = 0; - } - - WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_INVALIDATE | CMA_FREE)); + PCNRITEM pci = (PCNRITEM)item; + + if(!item) + return; + + if(pci->rc.pszIcon) + { + free(pci->rc.pszIcon); + pci->rc.pszIcon = 0; + } + + WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_INVALIDATE | CMA_FREE)); } /* Some OS/2 specific container structs */ typedef struct _containerinfo { - int count; - void *data; - HWND handle; + int count; + void *data; + HWND handle; } ContainerInfo; /* @@ -6447,93 +7665,93 @@ */ int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator) { - PFIELDINFO details, first, left = NULL; - FIELDINFOINSERT detin; - CNRINFO cnri; - int z; - ULONG size = sizeof(RECORDCORE); - ULONG *offStruct = malloc(count * sizeof(ULONG)); - ULONG *tempflags = malloc((count+1) * sizeof(ULONG)); - WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); - ULONG *oldflags = blah ? blah->data : 0; - - if(!offStruct || !tempflags) - return FALSE; - - memcpy(tempflags, flags, count * sizeof(ULONG)); - tempflags[count] = 0; - - blah->data = tempflags; - blah->flags = separator; - - if(oldflags) - free(oldflags); - - while((first = (PFIELDINFO)WinSendMsg(handle, CM_QUERYDETAILFIELDINFO, 0, MPFROMSHORT(CMA_FIRST))) != NULL) - { - WinSendMsg(handle, CM_REMOVEDETAILFIELDINFO, (MPARAM)&first, MPFROM2SHORT(1, CMA_FREE)); - } - - /* Figure out the offsets to the items in the struct */ - for(z=0;z<count;z++) - { - offStruct[z] = size; - if(flags[z] & DW_CFA_BITMAPORICON) - size += sizeof(HPOINTER); - else if(flags[z] & DW_CFA_STRING) - size += sizeof(char *); - else if(flags[z] & DW_CFA_ULONG) - size += sizeof(ULONG); - else if(flags[z] & DW_CFA_DATE) - size += sizeof(CDATE); - else if(flags[z] & DW_CFA_TIME) - size += sizeof(CTIME); - } - - first = details = (PFIELDINFO)WinSendMsg(handle, CM_ALLOCDETAILFIELDINFO, MPFROMLONG(count), 0L); - - if(!first) - { - free(offStruct); - return FALSE; - } - - for(z=0;z<count;z++) - { - if(z==separator-1) - left=details; - details->cb = sizeof(FIELDINFO); - details->flData = flags[z]; - details->flTitle = CFA_FITITLEREADONLY; - details->pTitleData = titles[z]; - details->offStruct = offStruct[z]; - details = details->pNextFieldInfo; - } - - detin.cb = sizeof(FIELDINFOINSERT); - detin.fInvalidateFieldInfo = FALSE; - detin.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST; - detin.cFieldInfoInsert = (ULONG)count; - - WinSendMsg(handle, CM_INSERTDETAILFIELDINFO, MPFROMP(first), MPFROMP(&detin)); - - if(count > separator && separator > 0) - { - cnri.cb = sizeof(CNRINFO); - cnri.pFieldInfoLast = left; - cnri.xVertSplitbar = 150; - - WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR)); - } - - cnri.flWindowAttr = CV_DETAIL | CV_MINI | CA_DETAILSVIEWTITLES; - cnri.slBitmapOrIcon.cx = 16; - cnri.slBitmapOrIcon.cy = 16; - - WinSendMsg(handle, CM_SETCNRINFO, &cnri, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON)); - - free(offStruct); - return TRUE; + PFIELDINFO details, first, left = NULL; + FIELDINFOINSERT detin; + CNRINFO cnri; + int z; + ULONG size = sizeof(RECORDCORE); + ULONG *offStruct = malloc(count * sizeof(ULONG)); + ULONG *tempflags = malloc((count+1) * sizeof(ULONG)); + WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); + ULONG *oldflags = blah ? blah->data : 0; + + if(!offStruct || !tempflags) + return FALSE; + + memcpy(tempflags, flags, count * sizeof(ULONG)); + tempflags[count] = 0; + + blah->data = tempflags; + blah->flags = separator; + + if(oldflags) + free(oldflags); + + while((first = (PFIELDINFO)WinSendMsg(handle, CM_QUERYDETAILFIELDINFO, 0, MPFROMSHORT(CMA_FIRST))) != NULL) + { + WinSendMsg(handle, CM_REMOVEDETAILFIELDINFO, (MPARAM)&first, MPFROM2SHORT(1, CMA_FREE)); + } + + /* Figure out the offsets to the items in the struct */ + for(z=0;z<count;z++) + { + offStruct[z] = size; + if(flags[z] & DW_CFA_BITMAPORICON) + size += sizeof(HPOINTER); + else if(flags[z] & DW_CFA_STRING) + size += sizeof(char *); + else if(flags[z] & DW_CFA_ULONG) + size += sizeof(ULONG); + else if(flags[z] & DW_CFA_DATE) + size += sizeof(CDATE); + else if(flags[z] & DW_CFA_TIME) + size += sizeof(CTIME); + } + + first = details = (PFIELDINFO)WinSendMsg(handle, CM_ALLOCDETAILFIELDINFO, MPFROMLONG(count), 0L); + + if(!first) + { + free(offStruct); + return FALSE; + } + + for(z=0;z<count;z++) + { + if(z==separator-1) + left=details; + details->cb = sizeof(FIELDINFO); + details->flData = flags[z]; + details->flTitle = CFA_FITITLEREADONLY; + details->pTitleData = titles[z]; + details->offStruct = offStruct[z]; + details = details->pNextFieldInfo; + } + + detin.cb = sizeof(FIELDINFOINSERT); + detin.fInvalidateFieldInfo = FALSE; + detin.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST; + detin.cFieldInfoInsert = (ULONG)count; + + WinSendMsg(handle, CM_INSERTDETAILFIELDINFO, MPFROMP(first), MPFROMP(&detin)); + + if(count > separator && separator > 0) + { + cnri.cb = sizeof(CNRINFO); + cnri.pFieldInfoLast = left; + cnri.xVertSplitbar = 150; + + WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR)); + } + + cnri.flWindowAttr = CV_DETAIL | CV_MINI | CA_DETAILSVIEWTITLES; + cnri.slBitmapOrIcon.cx = 16; + cnri.slBitmapOrIcon.cy = 16; + + WinSendMsg(handle, CM_SETCNRINFO, &cnri, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON)); + + free(offStruct); + return DW_ERROR_NONE; } /* @@ -6546,23 +7764,23 @@ */ int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count) { - char **newtitles = malloc(sizeof(char *) * (count + 2)); - unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2)); - - newtitles[0] = "Icon"; - newtitles[1] = "Filename"; - - newflags[0] = DW_CFA_BITMAPORICON | DW_CFA_CENTER | DW_CFA_HORZSEPARATOR | DW_CFA_SEPARATOR; - newflags[1] = DW_CFA_STRING | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR; - - memcpy(&newtitles[2], titles, sizeof(char *) * count); - memcpy(&newflags[2], flags, sizeof(unsigned long) * count); - - dw_container_setup(handle, newflags, newtitles, count + 2, count ? 2 : 0); - - free(newtitles); - free(newflags); - return TRUE; + char **newtitles = malloc(sizeof(char *) * (count + 2)); + unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2)); + + newtitles[0] = "Icon"; + newtitles[1] = "Filename"; + + newflags[0] = DW_CFA_BITMAPORICON | DW_CFA_CENTER | DW_CFA_HORZSEPARATOR | DW_CFA_SEPARATOR; + newflags[1] = DW_CFA_STRING | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR; + + memcpy(&newtitles[2], titles, sizeof(char *) * count); + memcpy(&newflags[2], flags, sizeof(unsigned long) * count); + + dw_container_setup(handle, newflags, newtitles, count + 2, count ? 2 : 0); + + free(newtitles); + free(newflags); + return DW_ERROR_NONE; } /* @@ -6573,9 +7791,9 @@ * Windows, on GTK this is converted to a pointer * to an embedded XPM. */ -unsigned long API dw_icon_load(unsigned long module, unsigned long id) -{ - return WinLoadPointer(HWND_DESKTOP,module,id); +HICN API dw_icon_load(unsigned long module, unsigned long id) +{ + return WinLoadPointer(HWND_DESKTOP,module,id); } /* @@ -6585,24 +7803,59 @@ * DW pick the appropriate file extension. * (ICO on OS/2 or Windows, XPM on Unix) */ -unsigned long API dw_icon_load_from_file(char *filename) -{ - char *file = alloca(strlen(filename) + 5); - - if(!file) - return 0; - - strcpy(file, filename); - - /* check if we can read from this file (it exists and read permission) */ - if(access(file, 04) != 0) - { - /* Try with .bmp extention */ - strcat(file, ".ico"); - if(access(file, 04) != 0) - return 0; - } - return WinLoadFileIcon(file, FALSE); +HICN API dw_icon_load_from_file(char *filename) +{ + char *file = alloca(strlen(filename) + 5); + + if(!file) + return 0; + + strcpy(file, filename); + + /* check if we can read from this file (it exists and read permission) */ + if(access(file, 04) != 0) + { + /* Try with .bmp extention */ + strcat(file, ".ico"); + if(access(file, 04) != 0) + return 0; + } + return WinLoadFileIcon((PSZ)file, FALSE); +} + +/* + * Obtains an icon from data + * Parameters: + * filename: Name of the file, omit extention to have + * DW pick the appropriate file extension. + * (ICO on OS/2 or Windows, XPM on Unix) + */ +HICN API dw_icon_load_from_data(char *data, int len) +{ + HICN icon=0; + char *file; + FILE *fp; + + if ( !data ) + return 0; + file = tmpnam( NULL ); + if ( file != NULL ) + { + fp = fopen( file, "wb" ); + if ( fp != NULL ) + { + fwrite( data, 1, len, fp ); + fclose( fp ); + icon = WinLoadFileIcon( (PSZ)file, FALSE ); + } + else + { + unlink( file ); + return 0; + } + unlink( file ); + } + return icon; } /* @@ -6610,9 +7863,9 @@ * Parameters: * handle: Handle to icon returned by dw_icon_load(). */ -void API dw_icon_free(unsigned long handle) -{ - WinDestroyPointer(handle); +void API dw_icon_free(HICN handle) +{ + WinDestroyPointer(handle); } /* @@ -6623,159 +7876,159 @@ */ void * API dw_container_alloc(HWND handle, int rowcount) { - WindowData *wd = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); - ULONG *flags = wd ? wd->data : 0; - int z, size = 0, totalsize, count = 0; - PRECORDCORE temp; - ContainerInfo *ci; - void *blah = NULL; - - if(!flags || rowcount < 1) - return NULL; - - while(flags[count]) - count++; - - /* Figure out the offsets to the items in the struct */ - for(z=0;z<count;z++) - { - if(flags[z] & DW_CFA_BITMAPORICON) - size += sizeof(HPOINTER); - else if(flags[z] & DW_CFA_STRING) - size += sizeof(char *); - else if(flags[z] & DW_CFA_ULONG) - size += sizeof(ULONG); - else if(flags[z] & DW_CFA_DATE) - size += sizeof(CDATE); - else if(flags[z] & DW_CFA_TIME) - size += sizeof(CTIME); - } - - totalsize = size + sizeof(RECORDCORE); - - z = 0; - - if(!(blah = (void *)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(size), MPFROMLONG(rowcount), 0))) - return NULL; - - temp = (PRECORDCORE)blah; - - for(z=0;z<rowcount;z++) - { - temp->cb = totalsize; - temp = temp->preccNextRecord; - } - - ci = malloc(sizeof(struct _containerinfo)); - - ci->count = rowcount; - ci->data = blah; - ci->handle = handle; - - return (void *)ci; + WindowData *wd = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); + ULONG *flags = wd ? wd->data : 0; + int z, size = 0, totalsize, count = 0; + PRECORDCORE temp; + ContainerInfo *ci; + void *blah = NULL; + + if(!flags || rowcount < 1) + return NULL; + + while(flags[count]) + count++; + + /* Figure out the offsets to the items in the struct */ + for(z=0;z<count;z++) + { + if(flags[z] & DW_CFA_BITMAPORICON) + size += sizeof(HPOINTER); + else if(flags[z] & DW_CFA_STRING) + size += sizeof(char *); + else if(flags[z] & DW_CFA_ULONG) + size += sizeof(ULONG); + else if(flags[z] & DW_CFA_DATE) + size += sizeof(CDATE); + else if(flags[z] & DW_CFA_TIME) + size += sizeof(CTIME); + } + + totalsize = size + sizeof(RECORDCORE); + + z = 0; + + if(!(blah = (void *)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(size), MPFROMLONG(rowcount), 0))) + return NULL; + + temp = (PRECORDCORE)blah; + + for(z=0;z<rowcount;z++) + { + temp->cb = totalsize; + temp = temp->preccNextRecord; + } + + ci = malloc(sizeof(struct _containerinfo)); + + ci->count = rowcount; + ci->data = blah; + ci->handle = handle; + + return (void *)ci; } /* Internal function that does the work for set_item and change_item */ void _dw_container_set_item(HWND handle, PRECORDCORE temp, int column, int row, void *data) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); - ULONG totalsize, size = 0, *flags = blah ? blah->data : 0; - int z, currentcount; - CNRINFO cnr; + WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); + ULONG totalsize, size = 0, *flags = blah ? blah->data : 0; + int z, currentcount; + CNRINFO cnr; void *dest; - if(!flags) - return; - - if(!_dw_send_msg(handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0)) - return; - - currentcount = cnr.cRecords; - - /* Figure out the offsets to the items in the struct */ - for(z=0;z<column;z++) - { - if(flags[z] & DW_CFA_BITMAPORICON) - size += sizeof(HPOINTER); - else if(flags[z] & DW_CFA_STRING) - size += sizeof(char *); - else if(flags[z] & DW_CFA_ULONG) - size += sizeof(ULONG); - else if(flags[z] & DW_CFA_DATE) - size += sizeof(CDATE); - else if(flags[z] & DW_CFA_TIME) - size += sizeof(CTIME); - } - - totalsize = size + sizeof(RECORDCORE); - - for(z=0;z<(row-currentcount);z++) - temp = temp->preccNextRecord; - - dest = (void *)(((ULONG)temp)+((ULONG)totalsize)); - - if(flags[column] & DW_CFA_BITMAPORICON) - memcpy(dest, data, sizeof(HPOINTER)); - else if(flags[column] & DW_CFA_STRING) - { - char **newstr = (char **)data, **str = dest; - - if(*str) - free(*str); - - if(newstr && *newstr) - *str = strdup(*newstr); - else - *str = NULL; - } - else if(flags[column] & DW_CFA_ULONG) - memcpy(dest, data, sizeof(ULONG)); - else if(flags[column] & DW_CFA_DATE) - memcpy(dest, data, sizeof(CDATE)); - else if(flags[column] & DW_CFA_TIME) - memcpy(dest, data, sizeof(CTIME)); + if(!flags) + return; + + if(!_dw_send_msg(handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0)) + return; + + currentcount = cnr.cRecords; + + /* Figure out the offsets to the items in the struct */ + for(z=0;z<column;z++) + { + if(flags[z] & DW_CFA_BITMAPORICON) + size += sizeof(HPOINTER); + else if(flags[z] & DW_CFA_STRING) + size += sizeof(char *); + else if(flags[z] & DW_CFA_ULONG) + size += sizeof(ULONG); + else if(flags[z] & DW_CFA_DATE) + size += sizeof(CDATE); + else if(flags[z] & DW_CFA_TIME) + size += sizeof(CTIME); + } + + totalsize = size + sizeof(RECORDCORE); + + for(z=0;z<(row-currentcount);z++) + temp = temp->preccNextRecord; + + dest = (void *)(((ULONG)temp)+((ULONG)totalsize)); + + if(flags[column] & DW_CFA_BITMAPORICON) + memcpy(dest, data, sizeof(HPOINTER)); + else if(flags[column] & DW_CFA_STRING) + { + char **newstr = (char **)data, **str = dest; + + if(*str) + free(*str); + + if(newstr && *newstr) + *str = strdup(*newstr); + else + *str = NULL; + } + else if(flags[column] & DW_CFA_ULONG) + memcpy(dest, data, sizeof(ULONG)); + else if(flags[column] & DW_CFA_DATE) + memcpy(dest, data, sizeof(CDATE)); + else if(flags[column] & DW_CFA_TIME) + memcpy(dest, data, sizeof(CTIME)); } /* Internal function that free()s any strings allocated for a container item */ void _dw_container_free_strings(HWND handle, PRECORDCORE temp) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); - ULONG totalsize, size = 0, *flags = blah ? blah->data : 0; - int z, count = 0; - - if(!flags) - return; - - while(flags[count]) - count++; - - /* Figure out the offsets to the items in the struct */ - for(z=0;z<count;z++) - { - if(flags[z] & DW_CFA_BITMAPORICON) - size += sizeof(HPOINTER); - else if(flags[z] & DW_CFA_STRING) - { - char **str; - - totalsize = size + sizeof(RECORDCORE); - - str = (char **)(((ULONG)temp)+((ULONG)totalsize)); - - if(*str) - { - free(*str); - *str = NULL; - } - size += sizeof(char *); - } - else if(flags[z] & DW_CFA_ULONG) - size += sizeof(ULONG); - else if(flags[z] & DW_CFA_DATE) - size += sizeof(CDATE); - else if(flags[z] & DW_CFA_TIME) - size += sizeof(CTIME); - } + WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); + ULONG totalsize, size = 0, *flags = blah ? blah->data : 0; + int z, count = 0; + + if(!flags) + return; + + while(flags[count]) + count++; + + /* Figure out the offsets to the items in the struct */ + for(z=0;z<count;z++) + { + if(flags[z] & DW_CFA_BITMAPORICON) + size += sizeof(HPOINTER); + else if(flags[z] & DW_CFA_STRING) + { + char **str; + + totalsize = size + sizeof(RECORDCORE); + + str = (char **)(((ULONG)temp)+((ULONG)totalsize)); + + if(*str) + { + free(*str); + *str = NULL; + } + size += sizeof(char *); + } + else if(flags[z] & DW_CFA_ULONG) + size += sizeof(ULONG); + else if(flags[z] & DW_CFA_DATE) + size += sizeof(CDATE); + else if(flags[z] & DW_CFA_TIME) + size += sizeof(CTIME); + } } /* @@ -6789,12 +8042,12 @@ */ void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data) { - ContainerInfo *ci = (ContainerInfo *)pointer; - - if(!ci) - return; - - _dw_container_set_item(handle, (PRECORDCORE)ci->data, column, row, data); + ContainerInfo *ci = (ContainerInfo *)pointer; + + if(!ci) + return; + + _dw_container_set_item(handle, (PRECORDCORE)ci->data, column, row, data); } /* @@ -6807,20 +8060,20 @@ */ void API dw_container_change_item(HWND handle, int column, int row, void *data) { - PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); - int count = 0; - - while(pCore) - { - if(count == row) - { - _dw_container_set_item(handle, pCore, column, 0, data); - WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED)); - return; - } - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); - count++; - } + PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + int count = 0; + + while(pCore) + { + if(count == row) + { + _dw_container_set_item(handle, pCore, column, 0, data); + WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED)); + return; + } + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + count++; + } } /* @@ -6833,7 +8086,7 @@ */ void API dw_filesystem_change_item(HWND handle, int column, int row, void *data) { - dw_container_change_item(handle, column + 2, row, data); + dw_container_change_item(handle, column + 2, row, data); } /* @@ -6845,10 +8098,10 @@ * row: Zero based row of data being set. * data: Pointer to the data to be added. */ -void API dw_filesystem_change_file(HWND handle, int row, char *filename, unsigned long icon) -{ - dw_container_change_item(handle, 0, row, (void *)&icon); - dw_container_change_item(handle, 1, row, (void *)&filename); +void API dw_filesystem_change_file(HWND handle, int row, char *filename, HICN icon) +{ + dw_container_change_item(handle, 0, row, (void *)&icon); + dw_container_change_item(handle, 1, row, (void *)&filename); } /* @@ -6860,10 +8113,10 @@ * row: Zero based row of data being set. * data: Pointer to the data to be added. */ -void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon) -{ - dw_container_set_item(handle, pointer, 0, row, (void *)&icon); - dw_container_set_item(handle, pointer, 1, row, (void *)&filename); +void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, HICN icon) +{ + dw_container_set_item(handle, pointer, 0, row, (void *)&icon); + dw_container_set_item(handle, pointer, 1, row, (void *)&filename); } /* @@ -6877,7 +8130,7 @@ */ void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data) { - dw_container_set_item(handle, pointer, column + 2, row, data); + dw_container_set_item(handle, pointer, column + 2, row, data); } /* @@ -6888,26 +8141,26 @@ */ int API dw_container_get_column_type(HWND handle, int column) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); - ULONG *flags = blah ? blah->data : 0; - int rc; - - if(!flags) - return 0; - - if(flags[column] & DW_CFA_BITMAPORICON) - rc = DW_CFA_BITMAPORICON; - else if(flags[column] & DW_CFA_STRING) - rc = DW_CFA_STRING; - else if(flags[column] & DW_CFA_ULONG) - rc = DW_CFA_ULONG; - else if(flags[column] & DW_CFA_DATE) - rc = DW_CFA_DATE; - else if(flags[column] & DW_CFA_TIME) - rc = DW_CFA_TIME; - else - rc = 0; - return rc; + WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); + ULONG *flags = blah ? blah->data : 0; + int rc; + + if(!flags) + return 0; + + if(flags[column] & DW_CFA_BITMAPORICON) + rc = DW_CFA_BITMAPORICON; + else if(flags[column] & DW_CFA_STRING) + rc = DW_CFA_STRING; + else if(flags[column] & DW_CFA_ULONG) + rc = DW_CFA_ULONG; + else if(flags[column] & DW_CFA_DATE) + rc = DW_CFA_DATE; + else if(flags[column] & DW_CFA_TIME) + rc = DW_CFA_TIME; + else + rc = 0; + return rc; } /* @@ -6918,7 +8171,21 @@ */ int API dw_filesystem_get_column_type(HWND handle, int column) { - return dw_container_get_column_type( handle, column + 2 ); + return dw_container_get_column_type( handle, column + 2 ); +} + +/* + * Sets the alternating row colors for container window (widget) handle. + * Parameters: + * handle: The window (widget) handle. + * oddcolor: Odd row background color in DW_RGB format or a default color index. + * evencolor: Even row background color in DW_RGB format or a default color index. + * DW_RGB_TRANSPARENT will disable coloring rows. + * DW_CLR_DEFAULT will use the system default alternating row colors. + */ +void API dw_container_set_stripe(HWND handle, unsigned long oddcolor, unsigned long evencolor) +{ + /* Don't think this is possible on OS/2 */ } /* @@ -6930,9 +8197,9 @@ */ void API dw_container_set_column_width(HWND handle, int column, int width) { - handle = handle; /* keep compiler happy */ - column = column; /* keep compiler happy */ - width = width; /* keep compiler happy */ + handle = handle; /* keep compiler happy */ + column = column; /* keep compiler happy */ + width = width; /* keep compiler happy */ } /* @@ -6944,29 +8211,76 @@ */ void API dw_container_set_row_title(void *pointer, int row, char *title) { - ContainerInfo *ci = (ContainerInfo *)pointer; - PRECORDCORE temp; - int z, currentcount; - CNRINFO cnr; - - if(!ci) - return; - - temp = (PRECORDCORE)ci->data; - - z = 0; - - if(!_dw_send_msg(ci->handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0)) - return; - - currentcount = cnr.cRecords; - - for(z=0;z<(row-currentcount);z++) - temp = temp->preccNextRecord; - - temp->pszIcon = title; - temp->pszName = title; - temp->pszText = title; + ContainerInfo *ci = (ContainerInfo *)pointer; + PRECORDCORE temp; + int z, currentcount; + CNRINFO cnr; + + if(!ci) + return; + + temp = (PRECORDCORE)ci->data; + + z = 0; + + if(!_dw_send_msg(ci->handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0)) + return; + + currentcount = cnr.cRecords; + + for(z=0;z<(row-currentcount);z++) + temp = temp->preccNextRecord; + + temp->pszIcon = (PSZ)title; + temp->pszName = (PSZ)title; + temp->pszText = (PSZ)title; +} + +/* + * Changes the title of a row already inserted in the container. + * Parameters: + * handle: Handle to the container window (widget). + * row: Zero based row of data being set. + * title: String title of the item. + */ +void API dw_container_change_row_title(HWND handle, int row, char *title) +{ + PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + int count = 0; + + while(pCore) + { + if(count == row) + { + pCore->pszIcon = (PSZ)title; + pCore->pszName = (PSZ)title; + pCore->pszText = (PSZ)title; + + WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED)); + return; + } + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + count++; + } +} + +/* Internal function to get the first item with given flags */ +PRECORDCORE _dw_container_start(HWND handle, unsigned long flags) +{ + PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + + if(pCore) + { + while(pCore) + { + if(pCore->flRecordAttr & flags) + { + return pCore; + } + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + } + } + return NULL; } /* @@ -6978,22 +8292,34 @@ */ void API dw_container_insert(HWND handle, void *pointer, int rowcount) { - RECORDINSERT recin; - ContainerInfo *ci = (ContainerInfo *)pointer; - - if(!ci) - return; - - recin.cb = sizeof(RECORDINSERT); - recin.pRecordOrder = (PRECORDCORE)CMA_END; - recin.pRecordParent = NULL; - recin.zOrder = CMA_TOP; - recin.fInvalidateRecord = TRUE; - recin.cRecordsInsert = rowcount; - - _dw_send_msg(handle, CM_INSERTRECORD, MPFROMP(ci->data), MPFROMP(&recin), 0); - - free(ci); + RECORDINSERT recin; + ContainerInfo *ci = (ContainerInfo *)pointer; + PRECORDCORE pCore; + + if(!ci) + return; + + recin.cb = sizeof(RECORDINSERT); + recin.pRecordOrder = (PRECORDCORE)CMA_END; + recin.pRecordParent = NULL; + recin.zOrder = CMA_TOP; + recin.fInvalidateRecord = TRUE; + recin.cRecordsInsert = rowcount; + + _dw_send_msg(handle, CM_INSERTRECORD, MPFROMP(ci->data), MPFROMP(&recin), 0); + + free(ci); + + if((pCore = _dw_container_start(handle, CRA_CURSORED))) + { + NOTIFYRECORDEMPHASIS pre; + + pre.pRecord = pCore; + pre.fEmphasisMask = CRA_CURSORED; + pre.hwndCnr = handle; + _run_event(handle, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre); + pre.pRecord->flRecordAttr |= CRA_CURSORED; + } } /* @@ -7004,30 +8330,30 @@ */ void API dw_container_clear(HWND handle, int redraw) { - PCNRITEM pCore; - int container = (int)dw_window_get_data(handle, "_dw_container"); - - if(hwndEmph == handle) - _clear_emphasis(); - - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); - - while(pCore) - { - if(container) - _dw_container_free_strings(handle, (PRECORDCORE)pCore); - else - { - /* Free icon text */ - if(pCore->rc.pszIcon) - { - free(pCore->rc.pszIcon); - pCore->rc.pszIcon = 0; - } - } - pCore = (PCNRITEM)pCore->rc.preccNextRecord;/*WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));*/ - } - _dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, (redraw ? CMA_INVALIDATE : 0) | CMA_FREE), -1); + PCNRITEM pCore; + int container = (int)dw_window_get_data(handle, "_dw_container"); + + if(hwndEmph == handle) + _clear_emphasis(); + + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + + while(pCore) + { + if(container) + _dw_container_free_strings(handle, (PRECORDCORE)pCore); + else + { + /* Free icon text */ + if(pCore->rc.pszIcon) + { + free(pCore->rc.pszIcon); + pCore->rc.pszIcon = 0; + } + } + pCore = (PCNRITEM)pCore->rc.preccNextRecord;/*WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));*/ + } + _dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, (redraw ? CMA_INVALIDATE : 0) | CMA_FREE), -1); } /* @@ -7038,21 +8364,21 @@ */ void API dw_container_delete(HWND handle, int rowcount) { - RECORDCORE *last, **prc = malloc(sizeof(RECORDCORE *) * rowcount); - int current = 1; - - prc[0] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); - - while(last && current < rowcount) - { - _dw_container_free_strings(handle, last); - prc[current] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)last, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); - current++; - } - - _dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)prc, MPFROM2SHORT(current, CMA_INVALIDATE | CMA_FREE), -1); - - free(prc); + RECORDCORE *last, **prc = malloc(sizeof(RECORDCORE *) * rowcount); + int current = 1; + + prc[0] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + + while(last && current < rowcount) + { + _dw_container_free_strings(handle, last); + prc[current] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)last, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + current++; + } + + _dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)prc, MPFROM2SHORT(current, CMA_INVALIDATE | CMA_FREE), -1); + + free(prc); } /* @@ -7065,16 +8391,16 @@ */ void API dw_container_scroll(HWND handle, int direction, long rows) { - rows = rows; /* keep compiler happy */ - switch(direction) - { - case DW_SCROLL_TOP: - WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(-10000000)); + rows = rows; /* keep compiler happy */ + switch(direction) + { + case DW_SCROLL_TOP: + WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(-10000000)); break; - case DW_SCROLL_BOTTOM: - WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(10000000)); - break; - } + case DW_SCROLL_BOTTOM: + WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(10000000)); + break; + } } /* @@ -7087,29 +8413,29 @@ */ char * API dw_container_query_start(HWND handle, unsigned long flags) { - PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); - - if(pCore) - { - if(flags) - { - while(pCore) - { - if(pCore->flRecordAttr & flags) - { - dw_window_set_data(handle, "_dw_pcore", (void *)pCore); - return pCore->pszIcon; - } - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); - } - } - else - { - dw_window_set_data(handle, "_dw_pcore", (void *)pCore); - return pCore->pszIcon; - } - } - return NULL; + PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + + if(pCore) + { + if(flags) + { + while(pCore) + { + if(pCore->flRecordAttr & flags) + { + dw_window_set_data(handle, "_dw_pcore", (void *)pCore); + return (char *)pCore->pszIcon; + } + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + } + } + else + { + dw_window_set_data(handle, "_dw_pcore", (void *)pCore); + return (char *)pCore->pszIcon; + } + } + return NULL; } /* @@ -7122,31 +8448,31 @@ */ char * API dw_container_query_next(HWND handle, unsigned long flags) { - PRECORDCORE pCore = (PRECORDCORE)dw_window_get_data(handle, "_dw_pcore"); - - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); - - if(pCore) - { - if(flags) - { - while(pCore) - { - if(pCore->flRecordAttr & flags) - { - dw_window_set_data(handle, "_dw_pcore", (void *)pCore); - return pCore->pszIcon; - } - - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); - } - } - else - { - dw_window_set_data(handle, "_dw_pcore", (void *)pCore); - return pCore->pszIcon; - } - } + PRECORDCORE pCore = (PRECORDCORE)dw_window_get_data(handle, "_dw_pcore"); + + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + + if(pCore) + { + if(flags) + { + while(pCore) + { + if(pCore->flRecordAttr & flags) + { + dw_window_set_data(handle, "_dw_pcore", (void *)pCore); + return (char *)pCore->pszIcon; + } + + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + } + } + else + { + dw_window_set_data(handle, "_dw_pcore", (void *)pCore); + return (char *)pCore->pszIcon; + } + } return NULL; } @@ -7158,34 +8484,35 @@ */ void API dw_container_cursor(HWND handle, char *text) { - RECTL viewport, item; - PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); - - while(pCore) - { - if((char *)pCore->pszIcon == text) - { - QUERYRECORDRECT qrr; - int scrollpixels = 0, midway; - - qrr.cb = sizeof(QUERYRECORDRECT); - qrr.pRecord = pCore; - qrr.fRightSplitWindow = 0; - qrr.fsExtent = CMA_TEXT; - - WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(TRUE, CRA_CURSORED)); - WinSendMsg(handle, CM_QUERYVIEWPORTRECT, (MPARAM)&viewport, MPFROM2SHORT(CMA_WORKSPACE, FALSE)); - WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr); - - midway = (viewport.yTop - viewport.yBottom)/2; - scrollpixels = viewport.yTop - (item.yTop + midway); - - WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(scrollpixels)); - return; - } - - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); - } + RECTL viewport, item; + PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + int textcomp = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_textcomp")); + + while(pCore) + { + if((textcomp && pCore->pszIcon && strcmp((char *)pCore->pszIcon, text) == 0) || (!textcomp && (char *)pCore->pszIcon == text)) + { + QUERYRECORDRECT qrr; + int scrollpixels = 0, midway; + + qrr.cb = sizeof(QUERYRECORDRECT); + qrr.pRecord = pCore; + qrr.fRightSplitWindow = 0; + qrr.fsExtent = CMA_TEXT; + + WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(TRUE, CRA_CURSORED)); + WinSendMsg(handle, CM_QUERYVIEWPORTRECT, (MPARAM)&viewport, MPFROM2SHORT(CMA_WORKSPACE, FALSE)); + WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr); + + midway = (viewport.yTop - viewport.yBottom)/2; + scrollpixels = viewport.yTop - (item.yTop + midway); + + WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(scrollpixels)); + return; + } + + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + } } /* @@ -7196,17 +8523,18 @@ */ void API dw_container_delete_row(HWND handle, char *text) { - PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); - - while(pCore) - { - if((char *)pCore->pszIcon == text) - { - WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_FREE | CMA_INVALIDATE)); - return; - } - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); - } + PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + int textcomp = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_textcomp")); + + while(pCore) + { + if((textcomp && pCore->pszIcon && strcmp((char *)pCore->pszIcon, text) == 0) || (!textcomp && (char *)pCore->pszIcon == text)) + { + WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_FREE | CMA_INVALIDATE)); + return; + } + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + } } /* @@ -7216,44 +8544,44 @@ */ void API dw_container_optimize(HWND handle) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); - RECTL item; - PRECORDCORE pCore = NULL; - int max = 0; - - if(blah && !blah->flags) - return; - - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); - while(pCore) - { - QUERYRECORDRECT qrr; - int vector; - - qrr.cb = sizeof(QUERYRECORDRECT); - qrr.pRecord = pCore; - qrr.fRightSplitWindow = 0; - qrr.fsExtent = CMA_TEXT; - - WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr); - - vector = item.xRight - item.xLeft; - - if(vector > max) - max = vector; - - pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); - } - - if(max) - { - CNRINFO cnri; - - cnri.cb = sizeof(CNRINFO); - cnri.xVertSplitbar = max; - - WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_XVERTSPLITBAR)); - } + WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER); + RECTL item; + PRECORDCORE pCore = NULL; + int max = 0; + + if(blah && !blah->flags) + return; + + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); + while(pCore) + { + QUERYRECORDRECT qrr; + int vector; + + qrr.cb = sizeof(QUERYRECORDRECT); + qrr.pRecord = pCore; + qrr.fRightSplitWindow = 0; + qrr.fsExtent = CMA_TEXT; + + WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr); + + vector = item.xRight - item.xLeft; + + if(vector > max) + max = vector; + + pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); + } + + if(max) + { + CNRINFO cnri; + + cnri.cb = sizeof(CNRINFO); + cnri.xVertSplitbar = max; + + WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_XVERTSPLITBAR)); + } } /* @@ -7263,12 +8591,15 @@ * icon: Icon handle to display in the taskbar. * bubbletext: Text to show when the mouse is above the icon. */ -void API dw_taskbar_insert(HWND handle, unsigned long icon, char *bubbletext) -{ - handle = handle; - icon = icon; - bubbletext = bubbletext; - /* TODO */ +void API dw_taskbar_insert(HWND handle, HICN icon, char *bubbletext) +{ + /* Make sure we have our server */ + if(!hwndTrayServer) + return; + + WinSendMsg(hwndApp, WM_SETICON, (MPARAM)icon, 0); + hwndTaskBar = handle; + WinPostMsg(hwndTrayServer, WM_USER+1, (MPARAM)hwndApp, (MPARAM)icon); } /* @@ -7277,11 +8608,14 @@ * handle: Window handle that was used with dw_taskbar_insert(). * icon: Icon handle that was used with dw_taskbar_insert(). */ -void API dw_taskbar_delete(HWND handle, unsigned long icon) -{ - handle = handle; - icon = icon; - /* TODO */ +void API dw_taskbar_delete(HWND handle, HICN icon) +{ + /* Make sure we have our server */ + if(!hwndTrayServer) + return; + + WinPostMsg(hwndTrayServer, WM_USER+2, (MPARAM)hwndApp, (MPARAM)0); + hwndTaskBar = NULLHANDLE; } /* @@ -7293,19 +8627,19 @@ */ HWND API dw_render_new(unsigned long id) { - HWND hwndframe = WinCreateWindow(HWND_OBJECT, - WC_FRAME, - NULL, - WS_VISIBLE | - FS_NOBYTEALIGN, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - WinSubclassWindow(hwndframe, _RendProc); - return hwndframe; + HWND hwndframe = WinCreateWindow(HWND_OBJECT, + WC_FRAME, + NULL, + WS_VISIBLE | + FS_NOBYTEALIGN, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + WinSubclassWindow(hwndframe, _RendProc); + return hwndframe; } /* Sets the current foreground drawing color. @@ -7316,7 +8650,7 @@ */ void API dw_color_foreground_set(unsigned long value) { - _foreground = value; + _foreground = value; } /* Sets the current background drawing color. @@ -7327,39 +8661,39 @@ */ void API dw_color_background_set(unsigned long value) { - _background = value; + _background = value; } int DWSIGNAL _dw_color_cancel_func(HWND window, void *data) { - DWDialog *dwwait = (DWDialog *)data; - HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex"); - void *val; - - window = (HWND)dwwait->data; - val = dw_window_get_data(window, "_dw_val"); - - dw_mutex_lock(mtx); - dw_mutex_close(mtx); - dw_window_destroy(window); - dw_dialog_dismiss((DWDialog *)data, val); - return FALSE; + DWDialog *dwwait = (DWDialog *)data; + HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex"); + void *val; + + window = (HWND)dwwait->data; + val = dw_window_get_data(window, "_dw_val"); + + dw_mutex_lock(mtx); + dw_mutex_close(mtx); + dw_window_destroy(window); + dw_dialog_dismiss((DWDialog *)data, val); + return FALSE; } int DWSIGNAL _dw_color_ok_func(HWND window, void *data) { - DWDialog *dwwait = (DWDialog *)data; - HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex"); - unsigned long val; - - window = (HWND)dwwait->data; - val = _dw_color_spin_get(window); - - dw_mutex_lock(mtx); - dw_mutex_close(mtx); - dw_window_destroy(window); - dw_dialog_dismiss((DWDialog *)data, (void *)val); - return FALSE; + DWDialog *dwwait = (DWDialog *)data; + HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex"); + unsigned long val; + + window = (HWND)dwwait->data; + val = _dw_color_spin_get(window); + + dw_mutex_lock(mtx); + dw_mutex_close(mtx); + dw_window_destroy(window); + dw_dialog_dismiss((DWDialog *)data, (void *)val); + return FALSE; } /* Allows the user to choose a color using the system's color chooser dialog. @@ -7370,122 +8704,122 @@ */ unsigned long API dw_color_choose(unsigned long value) { - HWND window, hbox, vbox, col, button, text; - DWDialog *dwwait; - HMTX mtx = dw_mutex_new(); - - window = dw_window_new( HWND_DESKTOP, "Choose Color", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU); - - vbox = dw_box_new(DW_VERT, 5); - - dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0); - - hbox = dw_box_new(DW_HORZ, 0); - - dw_box_pack_start(vbox, hbox, 0, 0, FALSE, FALSE, 0); - dw_window_set_style(hbox, 0, WS_CLIPCHILDREN); - - col = WinCreateWindow(vbox, "ColorSelectClass", "", WS_VISIBLE | WS_GROUP, 0, 0, 390, 300, vbox, HWND_TOP, 266, NULL,NULL); - dw_box_pack_start(hbox, col, 390, 300, FALSE, FALSE, 0); - - dw_window_set_data(hbox, "_dw_window", (void *)window); - dw_window_set_data(window, "_dw_mutex", (void *)mtx); - dw_window_set_data(window, "_dw_col", (void *)col); - dw_window_set_data(window, "_dw_val", (void *)value); - - hbox = dw_box_new(DW_HORZ, 0); - dw_window_set_data(hbox, "_dw_window", (void *)window); - - dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0); - - text = dw_text_new("Red:", 0); - dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER); - dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3); - - button = dw_spinbutton_new("", 1001L); - dw_spinbutton_set_limits(button, 255, 0); - dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3); - WinSetOwner(button, hbox); - dw_window_set_data(window, "_dw_red_spin", (void *)button); - - text = dw_text_new("Green:", 0); - dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER); - dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3); - - button = dw_spinbutton_new("", 1002L); - dw_spinbutton_set_limits(button, 255, 0); - dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3); - WinSetOwner(button, hbox); - dw_window_set_data(window, "_dw_green_spin", (void *)button); - - text = dw_text_new("Blue:", 0); - dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER); - dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3); - - button = dw_spinbutton_new("", 1003L); - dw_spinbutton_set_limits(button, 255, 0); - dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3); - WinSetOwner(button, hbox); - dw_window_set_data(window, "_dw_blue_spin", (void *)button); - - hbox = dw_box_new(DW_HORZ, 0); - - dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0); - dw_box_pack_start(hbox, 0, 100, 1, TRUE, FALSE, 0); - - button = dw_button_new("Ok", 1001L); - dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); - - dwwait = dw_dialog_new((void *)window); - - dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_ok_func), (void *)dwwait); - - button = dw_button_new("Cancel", 1002L); - dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); - - dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait); - dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait); - - dw_window_set_size(window, 400, 400); - - _dw_col_set(col, value); - _dw_color_spin_set(window, value); - - dw_window_show(window); - - return (unsigned long)dw_dialog_wait(dwwait); + HWND window, hbox, vbox, col, button, text; + DWDialog *dwwait; + HMTX mtx = dw_mutex_new(); + + window = dw_window_new( HWND_DESKTOP, "Choose Color", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU); + + vbox = dw_box_new(DW_VERT, 5); + + dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0); + + hbox = dw_box_new(DW_HORZ, 0); + + dw_box_pack_start(vbox, hbox, 0, 0, FALSE, FALSE, 0); + dw_window_set_style(hbox, 0, WS_CLIPCHILDREN); + + col = WinCreateWindow(vbox, (PSZ)"ColorSelectClass", NULL, WS_VISIBLE | WS_GROUP, 0, 0, 390, 300, vbox, HWND_TOP, 266, NULL,NULL); + dw_box_pack_start(hbox, col, 390, 300, FALSE, FALSE, 0); + + dw_window_set_data(hbox, "_dw_window", (void *)window); + dw_window_set_data(window, "_dw_mutex", (void *)mtx); + dw_window_set_data(window, "_dw_col", (void *)col); + dw_window_set_data(window, "_dw_val", (void *)value); + + hbox = dw_box_new(DW_HORZ, 0); + dw_window_set_data(hbox, "_dw_window", (void *)window); + + dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0); + + text = dw_text_new("Red:", 0); + dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER); + dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3); + + button = dw_spinbutton_new("", 1001L); + dw_spinbutton_set_limits(button, 255, 0); + dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3); + WinSetOwner(button, hbox); + dw_window_set_data(window, "_dw_red_spin", (void *)button); + + text = dw_text_new("Green:", 0); + dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER); + dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3); + + button = dw_spinbutton_new("", 1002L); + dw_spinbutton_set_limits(button, 255, 0); + dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3); + WinSetOwner(button, hbox); + dw_window_set_data(window, "_dw_green_spin", (void *)button); + + text = dw_text_new("Blue:", 0); + dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER); + dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3); + + button = dw_spinbutton_new("", 1003L); + dw_spinbutton_set_limits(button, 255, 0); + dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3); + WinSetOwner(button, hbox); + dw_window_set_data(window, "_dw_blue_spin", (void *)button); + + hbox = dw_box_new(DW_HORZ, 0); + + dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0); + dw_box_pack_start(hbox, 0, 100, 1, TRUE, FALSE, 0); + + button = dw_button_new("Ok", 1001L); + dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); + + dwwait = dw_dialog_new((void *)window); + + dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_ok_func), (void *)dwwait); + + button = dw_button_new("Cancel", 1002L); + dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); + + dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait); + dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait); + + dw_window_set_size(window, 400, 400); + + _dw_col_set(col, value); + _dw_color_spin_set(window, value); + + dw_window_show(window); + + return (unsigned long)dw_dialog_wait(dwwait); } HPS _set_hps(HPS hps) { - LONG alTable[2]; - - alTable[0] = DW_RED_VALUE(_foreground) << 16 | DW_GREEN_VALUE(_foreground) << 8 | DW_BLUE_VALUE(_foreground); - alTable[1] = DW_RED_VALUE(_background) << 16 | DW_GREEN_VALUE(_background) << 8 | DW_BLUE_VALUE(_background); - - GpiCreateLogColorTable(hps, - LCOL_RESET, - LCOLF_CONSECRGB, - 16, - 2, - alTable); - if(_foreground & DW_RGB_COLOR) - GpiSetColor(hps, 16); - else - GpiSetColor(hps, _internal_color(_foreground)); - if(_background & DW_RGB_COLOR) - GpiSetBackColor(hps, 17); - else - GpiSetBackColor(hps, _internal_color(_background)); - return hps; + LONG alTable[2]; + + alTable[0] = DW_RED_VALUE(_foreground) << 16 | DW_GREEN_VALUE(_foreground) << 8 | DW_BLUE_VALUE(_foreground); + alTable[1] = DW_RED_VALUE(_background) << 16 | DW_GREEN_VALUE(_background) << 8 | DW_BLUE_VALUE(_background); + + GpiCreateLogColorTable(hps, + LCOL_RESET, + LCOLF_CONSECRGB, + 16, + 2, + alTable); + if(_foreground & DW_RGB_COLOR) + GpiSetColor(hps, 16); + else + GpiSetColor(hps, _internal_color(_foreground)); + if(_background & DW_RGB_COLOR) + GpiSetBackColor(hps, 17); + else + GpiSetBackColor(hps, _internal_color(_background)); + return hps; } HPS _set_colors(HWND handle) { - HPS hps = WinGetPS(handle); - - _set_hps(hps); - return hps; + HPS hps = WinGetPS(handle); + + _set_hps(hps); + return hps; } /* Draw a point on a window (preferably a render window). @@ -7497,29 +8831,29 @@ */ void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) { - HPS hps; - int height; - POINTL ptl; - - if(handle) - { - hps = _set_colors(handle); + HPS hps; + int height; + POINTL ptl; + + if(handle) + { + hps = _set_colors(handle); height = _get_height(handle); - } - else if(pixmap) - { - hps = _set_hps(pixmap->hps); - height = pixmap->height; - } - else - return; - - ptl.x = x; - ptl.y = height - y - 1; - - GpiSetPel(hps, &ptl); - if(!pixmap) - WinReleasePS(hps); + } + else if(pixmap) + { + hps = _set_hps(pixmap->hps); + height = pixmap->height; + } + else + return; + + ptl.x = x; + ptl.y = height - y - 1; + + GpiSetPel(hps, &ptl); + if(!pixmap) + WinReleasePS(hps); } /* Draw a line on a window (preferably a render window). @@ -7533,56 +8867,56 @@ */ void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2) { - HPS hps; - int height; - POINTL ptl[2]; - - if(handle) - { - hps = _set_colors(handle); + HPS hps; + int height; + POINTL ptl[2]; + + if(handle) + { + hps = _set_colors(handle); height = _get_height(handle); - } - else if(pixmap) - { - hps = _set_hps(pixmap->hps); - height = pixmap->height; - } - else - return; - - ptl[0].x = x1; - ptl[0].y = height - y1 - 1; - ptl[1].x = x2; - ptl[1].y = height - y2 - 1; - - GpiMove(hps, &ptl[0]); - GpiLine(hps, &ptl[1]); - - if(!pixmap) - WinReleasePS(hps); + } + else if(pixmap) + { + hps = _set_hps(pixmap->hps); + height = pixmap->height; + } + else + return; + + ptl[0].x = x1; + ptl[0].y = height - y1 - 1; + ptl[1].x = x2; + ptl[1].y = height - y2 - 1; + + GpiMove(hps, &ptl[0]); + GpiLine(hps, &ptl[1]); + + if(!pixmap) + WinReleasePS(hps); } void _CopyFontSettings(HPS hpsSrc, HPS hpsDst) { - FONTMETRICS fm; - FATTRS fat; - SIZEF sizf; - - GpiQueryFontMetrics(hpsSrc, sizeof(FONTMETRICS), &fm); - - memset(&fat, 0, sizeof(fat)); - - fat.usRecordLength = sizeof(FATTRS); - fat.lMatch = fm.lMatch; - strcpy(fat.szFacename, fm.szFacename); - - GpiCreateLogFont(hpsDst, 0, 1L, &fat); - GpiSetCharSet(hpsDst, 1L); - - sizf.cx = MAKEFIXED(fm.lEmInc,0); - sizf.cy = MAKEFIXED(fm.lMaxBaselineExt,0); - GpiSetCharBox(hpsDst, &sizf ); + FONTMETRICS fm; + FATTRS fat; + SIZEF sizf; + + GpiQueryFontMetrics(hpsSrc, sizeof(FONTMETRICS), &fm); + + memset(&fat, 0, sizeof(fat)); + + fat.usRecordLength = sizeof(FATTRS); + fat.lMatch = fm.lMatch; + strcpy(fat.szFacename, fm.szFacename); + + GpiCreateLogFont(hpsDst, 0, 1L, &fat); + GpiSetCharSet(hpsDst, 1L); + + sizf.cx = MAKEFIXED(fm.lEmInc,0); + sizf.cy = MAKEFIXED(fm.lMaxBaselineExt,0); + GpiSetCharBox(hpsDst, &sizf ); } /* Draw text on a window (preferably a render window). @@ -7595,51 +8929,51 @@ */ void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text) { - HPS hps; - int z, height; - RECTL rcl; - char fontname[128]; - POINTL aptl[TXTBOX_COUNT]; - - if(handle) - { - hps = _set_colors(handle); - height = _get_height(handle); - _GetPPFont(handle, fontname); - } - else if(pixmap) - { - HPS pixmaphps = WinGetPS(pixmap->handle); - - hps = _set_hps(pixmap->hps); - height = pixmap->height; - _GetPPFont(pixmap->handle, fontname); - _CopyFontSettings(pixmaphps, hps); - WinReleasePS(pixmaphps); - } - else - return; - - for(z=0;z<strlen(fontname);z++) - { - if(fontname[z]=='.') - break; - } - - GpiQueryTextBox(hps, strlen(text), text, TXTBOX_COUNT, aptl); - - rcl.xLeft = x; - rcl.yTop = height - y; - rcl.yBottom = rcl.yTop - (aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y); - rcl.xRight = rcl.xLeft + (aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x); - - if(_background == DW_CLR_DEFAULT) - WinDrawText(hps, -1, text, &rcl, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS); - else - WinDrawText(hps, -1, text, &rcl, _internal_color(_foreground), _internal_color(_background), DT_VCENTER | DT_LEFT | DT_ERASERECT); - - if(!pixmap) - WinReleasePS(hps); + HPS hps; + int z, height; + RECTL rcl; + char fontname[128]; + POINTL aptl[TXTBOX_COUNT]; + + if(handle) + { + hps = _set_colors(handle); + height = _get_height(handle); + _GetPPFont(handle, fontname); + } + else if(pixmap) + { + HPS pixmaphps = WinGetPS(pixmap->font ? pixmap->font : pixmap->handle); + + hps = _set_hps(pixmap->hps); + height = pixmap->height; + _GetPPFont(pixmap->font ? pixmap->font : pixmap->handle, fontname); + _CopyFontSettings(pixmaphps, hps); + WinReleasePS(pixmaphps); + } + else + return; + + for(z=0;z<strlen(fontname);z++) + { + if(fontname[z]=='.') + break; + } + + GpiQueryTextBox(hps, strlen(text), (PCH)text, TXTBOX_COUNT, aptl); + + rcl.xLeft = x; + rcl.yTop = height - y; + rcl.yBottom = rcl.yTop - (aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y); + rcl.xRight = rcl.xLeft + (aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x); + + if(_background == DW_CLR_DEFAULT) + WinDrawText(hps, -1, (PCH)text, &rcl, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS); + else + WinDrawText(hps, -1, (PCH)text, &rcl, _internal_color(_foreground), _internal_color(_background), DT_VCENTER | DT_LEFT | DT_ERASERECT); + + if(!pixmap) + WinReleasePS(hps); } /* Query the width and height of a text string. @@ -7652,75 +8986,227 @@ */ void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height) { - HPS hps; - POINTL aptl[TXTBOX_COUNT]; - - if(handle) - { - hps = _set_colors(handle); - } - else if(pixmap) - { - HPS pixmaphps = WinGetPS(pixmap->handle); - - hps = _set_hps(pixmap->hps); - _CopyFontSettings(pixmaphps, hps); - WinReleasePS(pixmaphps); - } - else - return; - - GpiQueryTextBox(hps, strlen(text), text, TXTBOX_COUNT, aptl); - - if(width) - *width = aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x; - - if(height) - *height = aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y; - - if(!pixmap) - WinReleasePS(hps); + HPS hps; + POINTL aptl[TXTBOX_COUNT]; + + if(handle) + { + hps = _set_colors(handle); + } + else if(pixmap) + { + HPS pixmaphps = WinGetPS(pixmap->font ? pixmap->font : pixmap->handle); + + hps = _set_hps(pixmap->hps); + _CopyFontSettings(pixmaphps, hps); + WinReleasePS(pixmaphps); + } + else + return; + + GpiQueryTextBox(hps, strlen(text), (PCH)text, TXTBOX_COUNT, aptl); + + if(width) + *width = aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x; + + if(height) + *height = aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y; + + if(!pixmap) + WinReleasePS(hps); +} + +/* Draw a polygon on a window (preferably a render window). + * Parameters: + * handle: Handle to the window. + * pixmap: Handle to the pixmap. (choose only one of these) + * flags: DW_DRAW_FILL (1) to fill the polygon or DW_DRAW_DEFAULT (0). + * x: X coordinate. + * y: Y coordinate. + * width: Width of rectangle. + * height: Height of rectangle. + */ +void API dw_draw_polygon( HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y ) +{ + HPS hps; + int thisheight; + POINTL *pptl; + POINTL start; + int i; + + if(handle) + { + hps = _set_colors(handle); + thisheight = _get_height(handle); + } + else if(pixmap) + { + hps = _set_hps(pixmap->hps); + thisheight = pixmap->height; + } + else + return; + if ( npoints == 0 ) + return; + pptl = (POINTL *)malloc(sizeof(POINTL)*npoints); + if ( pptl == NULL ) + return; + /* + * For a filled polygon we need to start an area + */ + if ( flags & DW_DRAW_FILL ) + GpiBeginArea( hps, 0L ); + if ( npoints ) + { + /* + * Move to the first point of the polygon + */ + start.x = x[0]; + start.y = thisheight - y[0] - 1; + GpiMove( hps, &start ); + /* + * Convert the remainder of the x and y points + */ + for ( i = 1; i < npoints; i++ ) + { + pptl[i-1].x = x[i]; + pptl[i-1].y = thisheight - y[i] - 1; + } + GpiPolyLine( hps, npoints-1, pptl ); + + if ( flags & DW_DRAW_FILL ) + GpiEndArea( hps ); + } + if ( !pixmap ) + WinReleasePS(hps); + free( pptl ); } /* Draw a rectangle on a window (preferably a render window). * Parameters: * handle: Handle to the window. * pixmap: Handle to the pixmap. (choose only one of these) - * fill: Fill box TRUE or FALSE. + * flags: DW_DRAW_FILL (1) to fill the box or DW_DRAW_DEFAULT (0). * x: X coordinate. * y: Y coordinate. * width: Width of rectangle. * height: Height of rectangle. */ -void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height) -{ - HPS hps; - int thisheight; - POINTL ptl[2]; - - if(handle) - { - hps = _set_colors(handle); +void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height) +{ + HPS hps; + int thisheight; + POINTL ptl[2]; + + if(handle) + { + hps = _set_colors(handle); thisheight = _get_height(handle); - } - else if(pixmap) - { - hps = _set_hps(pixmap->hps); - thisheight = pixmap->height; - } - else - return; - - ptl[0].x = x; - ptl[0].y = thisheight - y - 1; - ptl[1].x = x + width - 1; - ptl[1].y = thisheight - y - height; - - GpiMove(hps, &ptl[0]); - GpiBox(hps, fill ? DRO_OUTLINEFILL : DRO_OUTLINE, &ptl[1], 0, 0); - - if(!pixmap) - WinReleasePS(hps); + } + else if(pixmap) + { + hps = _set_hps(pixmap->hps); + thisheight = pixmap->height; + } + else + return; + + ptl[0].x = x; + ptl[0].y = thisheight - y - 1; + ptl[1].x = x + width - 1; + ptl[1].y = thisheight - y - height; + + GpiMove(hps, &ptl[0]); + GpiBox(hps, (flags & DW_DRAW_FILL) ? DRO_OUTLINEFILL : DRO_OUTLINE, &ptl[1], 0, 0); + + if(!pixmap) + WinReleasePS(hps); +} + +/* VisualAge doesn't seem to have this */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* Draw an arc on a window (preferably a render window). + * Parameters: + * handle: Handle to the window. + * pixmap: Handle to the pixmap. (choose only one of these) + * flags: DW_DRAW_FILL (1) to fill the arc or DW_DRAW_DEFAULT (0). + * DW_DRAW_FULL will draw a complete circle/elipse. + * xorigin: X coordinate of center of arc. + * yorigin: Y coordinate of center of arc. + * x1: X coordinate of first segment of arc. + * y1: Y coordinate of first segment of arc. + * x2: X coordinate of second segment of arc. + * y2: Y coordinate of second segment of arc. + */ +void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) +{ + HPS hps; + int thisheight; + ARCPARAMS ap = { 1, 1, 0, 0 }; + POINTL pts[2]; + double r, a1, a2, a; + + if(handle) + { + hps = _set_colors(handle); + thisheight = _get_height(handle); + } + else if(pixmap) + { + hps = _set_hps(pixmap->hps); + thisheight = pixmap->height; + } + else + return; + + /* Handle full circle/ellipse */ + if(flags & DW_DRAW_FULL) + { + pts[0].x = xorigin; + pts[0].y = thisheight - yorigin - 1; + GpiMove(hps, pts); + ap.lP = (x2 - x1)/2; + ap.lQ = (y2 - y1)/2; + /* Setup the arc info on the presentation space */ + GpiSetArcParams(hps, &ap); + GpiFullArc(hps, (flags & DW_DRAW_FILL) ? DRO_OUTLINEFILL : DRO_OUTLINE, MAKEFIXED(1, 1)); + } + else + { + /* For a filled arc we need to start an area */ + if(flags & DW_DRAW_FILL) + GpiBeginArea(hps, 0L); + + /* Setup the default arc info on the presentation space */ + GpiSetArcParams(hps, &ap); + pts[0].x = x1; + pts[0].y = thisheight - y1 - 1; + /* Move to the initial position */ + GpiMove(hps, pts); + /* Calculate the midpoint */ + r = 0.5 * (hypot((double)(y1 - yorigin), (double)(x1 - xorigin)) + + hypot((double)(y2 - yorigin), (double)(x2 - xorigin))); + a1 = atan2((double)(y1 - yorigin), (double)(x1 - xorigin)); + a2 = atan2((double)(y2 - yorigin), (double)(x2 - xorigin)); + if(a2 < a1) + a2 += M_PI * 2; + a = (a1 + a2) / 2.; + /* Prepare to draw */ + pts[0].x = (int)(xorigin + r * cos(a)); + pts[0].y = thisheight - (int)(yorigin + r * sin(a)) - 1; + pts[1].x = x2; + pts[1].y = thisheight - y2 - 1; + /* Actually draw the arc */ + GpiPointArc(hps, pts); + if(flags & DW_DRAW_FILL) + GpiEndArea(hps); + } + + if(!pixmap) + WinReleasePS(hps); } /* Call this after drawing to the screen to make sure @@ -7742,52 +9228,53 @@ */ HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth) { - BITMAPINFOHEADER bmih; - SIZEL sizl = { 0, 0 }; - HPIXMAP pixmap; - HDC hdc; - HPS hps; - ULONG ulFlags; + BITMAPINFOHEADER bmih; + SIZEL sizl = { 0, 0 }; + HPIXMAP pixmap; + HDC hdc; + HPS hps; + ULONG ulFlags; LONG cPlanes, cBitCount; - if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) - return NULL; - - hps = WinGetPS(handle); - - hdc = GpiQueryDevice(hps); - ulFlags = GpiQueryPS(hps, &sizl); - - pixmap->handle = handle; - pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc); - pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC); - - DevQueryCaps(hdc, CAPS_COLOR_PLANES , 1L, &cPlanes); - if (!depth) - { - DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &cBitCount); - depth = cBitCount; - } - - memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); - bmih.cbFix = sizeof(BITMAPINFOHEADER); - bmih.cx = (SHORT)width; - bmih.cy = (SHORT)height; - bmih.cPlanes = (SHORT)cPlanes; - bmih.cBitCount = (SHORT)depth; - - pixmap->width = width; pixmap->height = height; - - pixmap->hbm = GpiCreateBitmap(pixmap->hps, (PBITMAPINFOHEADER2)&bmih, 0L, NULL, NULL); - - GpiSetBitmap(pixmap->hps, pixmap->hbm); - - if (depth>8) - GpiCreateLogColorTable(pixmap->hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, NULL ); - - WinReleasePS(hps); - - return pixmap; + if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) + return NULL; + + hps = WinGetPS(handle); + + hdc = GpiQueryDevice(hps); + ulFlags = GpiQueryPS(hps, &sizl); + + pixmap->handle = handle; + pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc); + pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC); + + DevQueryCaps(hdc, CAPS_COLOR_PLANES , 1L, &cPlanes); + if (!depth) + { + DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &cBitCount); + depth = cBitCount; + } + + memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); + bmih.cbFix = sizeof(BITMAPINFOHEADER); + bmih.cx = (SHORT)width; + bmih.cy = (SHORT)height; + bmih.cPlanes = (SHORT)cPlanes; + bmih.cBitCount = (SHORT)depth; + + pixmap->width = width; pixmap->height = height; + pixmap->transcolor = DW_CLR_DEFAULT; + + pixmap->hbm = GpiCreateBitmap(pixmap->hps, (PBITMAPINFOHEADER2)&bmih, 0L, NULL, NULL); + + GpiSetBitmap(pixmap->hps, pixmap->hbm); + + if (depth>8) + GpiCreateLogColorTable(pixmap->hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, NULL ); + + WinReleasePS(hps); + + return pixmap; } /* @@ -7802,37 +9289,107 @@ */ HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename) { - HPIXMAP pixmap; - char *file = alloca(strlen(filename) + 5); - - if(!file || !(pixmap = calloc(1,sizeof(struct _hpixmap)))) - return NULL; - - strcpy(file, filename); - - /* check if we can read from this file (it exists and read permission) */ - if(access(file, 04) != 0) - { - /* Try with .bmp extention */ - strcat(file, ".bmp"); - if(access(file, 04) != 0) - { - free(pixmap); - return NULL; - } - } - - /* Try to load the bitmap from file */ - if(!_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height)) - { - free(pixmap); - return NULL; - } - - /* Success fill in other values */ - pixmap->handle = handle; - - return pixmap; + HPIXMAP pixmap; + char *file = alloca(strlen(filename) + 5); + + if ( !file || !(pixmap = calloc(1,sizeof(struct _hpixmap))) ) + return NULL; + + strcpy(file, filename); + + /* check if we can read from this file (it exists and read permission) */ + if ( access(file, 04) != 0 ) + { + /* Try with .bmp extention */ + strcat(file, ".bmp"); + if ( access(file, 04) != 0 ) + { + free(pixmap); + return NULL; + } + } + + /* Try to load the bitmap from file */ + if ( !_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height) ) + { + free(pixmap); + return NULL; + } + + /* Success fill in other values */ + pixmap->handle = handle; + pixmap->transcolor = DW_CLR_DEFAULT; + + return pixmap; +} + +/* + * Creates a pixmap from memory. + * Parameters: + * handle: Window handle the pixmap is associated with. + * data: Source of the image data + * (BMP on OS/2 or Windows, XPM on Unix) + * le: length of data + * Returns: + * A handle to a pixmap or NULL on failure. + */ +HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len) +{ + HPIXMAP pixmap; + char *file; + FILE *fp; + + if ( !(pixmap = calloc(1,sizeof(struct _hpixmap))) ) + return NULL; + + file = tmpnam( NULL ); + if ( file != NULL ) + { + fp = fopen( file, "wb" ); + if ( fp != NULL ) + { + fwrite( data, 1, len, fp ); + fclose( fp ); + if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */ + { + /* Try to load the bitmap from file */ + if ( !_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height) ) + { + free(pixmap); + return NULL; + } + } + else /* otherwise its assumed to be an ico */ + { + /* con't use ICO ? */ + unlink( file ); + return NULL; + } + } + else + { + unlink( file ); + return NULL; + } + unlink( file ); + } + + /* Success fill in other values */ + pixmap->handle = handle; + pixmap->transcolor = DW_CLR_DEFAULT; + + return pixmap; +} + +/* + * Creates a bitmap mask for rendering bitmaps with transparent backgrounds + */ +void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color ) +{ + if ( pixmap ) + { + pixmap->transcolor = _internal_color(color); + } } /* @@ -7845,35 +9402,59 @@ */ HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id) { - BITMAPINFOHEADER bmih; - SIZEL sizl = { 0, 0 }; - HPIXMAP pixmap; - HDC hdc; - HPS hps; - ULONG ulFlags; - - if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) - return NULL; - - hps = WinGetPS(handle); - - hdc = GpiQueryDevice(hps); - ulFlags = GpiQueryPS(hps, &sizl); - - pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc); - pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC); - - pixmap->hbm = GpiLoadBitmap(pixmap->hps, NULLHANDLE, id, 0, 0); - - GpiQueryBitmapParameters(pixmap->hbm, &bmih); - - GpiSetBitmap(pixmap->hps, pixmap->hbm); - - pixmap->width = bmih.cx; pixmap->height = bmih.cy; - - WinReleasePS(hps); - - return pixmap; + BITMAPINFOHEADER bmih; + SIZEL sizl = { 0, 0 }; + HPIXMAP pixmap; + HDC hdc; + HPS hps; + ULONG ulFlags; + + if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) + return NULL; + + hps = WinGetPS(handle); + + hdc = GpiQueryDevice(hps); + ulFlags = GpiQueryPS(hps, &sizl); + + pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc); + pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC); + + pixmap->hbm = GpiLoadBitmap(pixmap->hps, NULLHANDLE, id, 0, 0); + + GpiQueryBitmapParameters(pixmap->hbm, &bmih); + + GpiSetBitmap(pixmap->hps, pixmap->hbm); + + pixmap->width = bmih.cx; pixmap->height = bmih.cy; + pixmap->transcolor = DW_CLR_DEFAULT; + + WinReleasePS(hps); + + return pixmap; +} + +/* + * Sets the font used by a specified pixmap. + * Normally the pixmap font is obtained from the associated window handle. + * However this can be used to override that, or for pixmaps with no window. + * Parameters: + * pixmap: Handle to a pixmap returned by dw_pixmap_new() or + * passed to the application via a callback. + * fontname: Name and size of the font in the form "size.fontname" + * Returns: + * DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure. + */ +int API dw_pixmap_set_font(HPIXMAP pixmap, char *fontname) +{ + if(pixmap && fontname && *fontname) + { + if(!pixmap->font) + pixmap->font = WinCreateWindow(HWND_OBJECT, WC_FRAME, NULL, 0,0,0,1,1, NULLHANDLE, HWND_TOP,0, NULL, NULL); + WinSetPresParam(pixmap->font, PP_FONTNAMESIZE, strlen(fontname)+1, fontname); + return DW_ERROR_NONE; + } + return DW_ERROR_GENERAL; } /* @@ -7884,12 +9465,14 @@ */ void API dw_pixmap_destroy(HPIXMAP pixmap) { - GpiSetBitmap(pixmap->hps, NULLHANDLE); - GpiDeleteBitmap(pixmap->hbm); - GpiAssociate(pixmap->hps, NULLHANDLE); - GpiDestroyPS(pixmap->hps); - DevCloseDC(pixmap->hdc); - free(pixmap); + if(pixmap->font) + WinDestroyWindow(pixmap->font); + GpiSetBitmap(pixmap->hps, NULLHANDLE); + GpiDeleteBitmap(pixmap->hbm); + GpiAssociate(pixmap->hps, NULLHANDLE); + GpiDestroyPS(pixmap->hps); + DevCloseDC(pixmap->hdc); + free(pixmap); } /* @@ -7908,68 +9491,117 @@ */ void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc) { - HPS hpsdest; - HPS hpssrc; - POINTL ptl[4]; - int destheight, srcheight; - - if(dest) - { - hpsdest = WinGetPS(dest); - destheight = _get_height(dest); - } - else if(destp) - { - hpsdest = destp->hps; - destheight = destp->height; - } - else - return; - - if(src) - { - hpssrc = WinGetPS(src); - srcheight = _get_height(src); - } - else if(srcp) - { - hpssrc = srcp->hps; - srcheight = srcp->height; - } - else - { - if(!destp) - WinReleasePS(hpsdest); - return; - } - - ptl[0].x = xdest; - ptl[0].y = (destheight - ydest) - height; - ptl[1].x = ptl[0].x + width; - ptl[1].y = destheight - ydest; - ptl[2].x = xsrc; - ptl[2].y = srcheight - (ysrc + height); - ptl[3].x = ptl[2].x + width; - ptl[3].y = ptl[2].y + height; - - GpiBitBlt(hpsdest, hpssrc, 4, ptl, ROP_SRCCOPY, BBO_IGNORE); - - if(!destp) - WinReleasePS(hpsdest); - if(!srcp) - WinReleasePS(hpssrc); + dw_pixmap_stretch_bitblt(dest, destp, xdest, ydest, width, height, src, srcp, xsrc, ysrc, -1, -1); +} + +/* + * Copies from one surface to another allowing for stretching. + * Parameters: + * dest: Destination window handle. + * destp: Destination pixmap. (choose only one). + * xdest: X coordinate of destination. + * ydest: Y coordinate of destination. + * width: Width of the target area. + * height: Height of the target area. + * src: Source window handle. + * srcp: Source pixmap. (choose only one). + * xsrc: X coordinate of source. + * ysrc: Y coordinate of source. + * srcwidth: Width of area to copy. + * srcheight: Height of area to copy. + * Returns: + * DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure. + */ +int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight) +{ + HPS hpsdest; + HPS hpssrc; + POINTL ptl[4]; + int dheight, sheight; + int count = 3; + + /* Do some sanity checks */ + if((srcheight == -1 || srcwidth == -1) && srcheight != srcwidth) + return DW_ERROR_GENERAL; + + if(dest) + { + hpsdest = WinGetPS(dest); + dheight = _get_height(dest); + } + else if(destp) + { + hpsdest = destp->hps; + dheight = destp->height; + } + else + return DW_ERROR_GENERAL; + + if(src) + { + hpssrc = WinGetPS(src); + sheight = _get_height(src); + } + else if(srcp) + { + hpssrc = srcp->hps; + sheight = srcp->height; + } + else + { + if(!destp) + WinReleasePS(hpsdest); + return DW_ERROR_GENERAL; + } + + ptl[0].x = xdest; + ptl[0].y = dheight - (ydest + height); + ptl[1].x = xdest + width; + ptl[1].y = dheight - ydest; + ptl[2].x = xsrc; + ptl[2].y = sheight - (ysrc + (srcheight != -1 ? srcheight : height)); + if(srcwidth != -1 && srcheight != -1) + { + count = 4; + ptl[3].x = xsrc + srcwidth; + ptl[3].y = sheight - ysrc; + } + + /* Handle transparency if requested */ + if(srcp && srcp->transcolor != DW_CLR_DEFAULT) + { + IMAGEBUNDLE newIb, oldIb; + /* Transparent color is put into the background color */ + GpiSetBackColor(hpsdest, srcp->transcolor); + GpiQueryAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, (PBUNDLE)&oldIb); + newIb.usBackMixMode = BM_SRCTRANSPARENT; + GpiSetAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, 0, (PBUNDLE)&newIb); + GpiBitBlt(hpsdest, hpssrc, count, ptl, ROP_SRCCOPY, BBO_IGNORE); + GpiSetAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, 0, (PBUNDLE)&oldIb); + } + else + { + /* Otherwise use the regular BitBlt call */ + GpiBitBlt(hpsdest, hpssrc, count, ptl, ROP_SRCCOPY, BBO_IGNORE); + } + + if(!destp) + WinReleasePS(hpsdest); + if(!srcp) + WinReleasePS(hpssrc); + return DW_ERROR_NONE; } /* Run DosBeep() in a separate thread so it doesn't block */ void _beepthread(void *data) { - int *info = (int *)data; - - if(data) - { - DosBeep(info[0], info[1]); - free(data); - } + int *info = (int *)data; + + if(data) + { + DosBeep(info[0], info[1]); + free(data); + } } /* @@ -7980,15 +9612,15 @@ */ void API dw_beep(int freq, int dur) { - int *info = malloc(sizeof(int) * 2); - - if(info) - { - info[0] = freq; - info[1] = dur; - - _beginthread(_beepthread, NULL, 100, (void *)info); - } + int *info = malloc(sizeof(int) * 2); + + if(info) + { + info[0] = freq; + info[1] = dur; + + _beginthread(_beepthread, NULL, 100, (void *)info); + } } /* Open a shared library and return a handle. @@ -7999,9 +9631,9 @@ */ int API dw_module_load(char *name, HMOD *handle) { - char objnamebuf[300] = ""; - - return DosLoadModule(objnamebuf, sizeof(objnamebuf), name, handle); + char objnamebuf[300] = ""; + + return DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)name, handle); } /* Queries the address of a symbol within open handle. @@ -8013,7 +9645,7 @@ */ int API dw_module_symbol(HMOD handle, char *name, void**func) { - return DosQueryProcAddr(handle, 0, name, (PFN*)func); + return DosQueryProcAddr(handle, 0, (PSZ)name, (PFN*)func); } /* Frees the shared library previously opened. @@ -8022,8 +9654,8 @@ */ int API dw_module_close(HMOD handle) { - DosFreeModule(handle); - return 0; + DosFreeModule(handle); + return 0; } /* @@ -8031,10 +9663,10 @@ */ HMTX API dw_mutex_new(void) { - HMTX mutex; - - DosCreateMutexSem(NULL, &mutex, 0, FALSE); - return mutex; + HMTX mutex; + + DosCreateMutexSem(NULL, &mutex, 0, FALSE); + return mutex; } /* @@ -8044,7 +9676,7 @@ */ void API dw_mutex_close(HMTX mutex) { - DosCloseMutexSem(mutex); + DosCloseMutexSem(mutex); } /* @@ -8056,18 +9688,32 @@ */ void API dw_mutex_lock(HMTX mutex) { - if(_dwtid == dw_thread_id()) - { - int rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN); - - while(rc == ERROR_TIMEOUT) - { - dw_main_sleep(10); - rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN); - } - } + if(_dwtid == dw_thread_id()) + { + int rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN); + + while(rc == ERROR_TIMEOUT) + { + dw_main_sleep(10); + rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN); + } + } else - DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT); + DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT); +} + +/* + * Tries to gain access to the semaphore. + * Parameters: + * mutex: The handle to the mutex returned by dw_mutex_new(). + * Returns: + * DW_ERROR_NONE on success, DW_ERROR_TIMEOUT if it is already locked. + */ +int API dw_mutex_trylock(HMTX mutex) +{ + if(DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) + return DW_ERROR_NONE; + return DW_ERROR_TIMEOUT; } /* @@ -8077,7 +9723,7 @@ */ void API dw_mutex_unlock(HMTX mutex) { - DosReleaseMutexSem(mutex); + DosReleaseMutexSem(mutex); } /* @@ -8085,12 +9731,12 @@ */ HEV API dw_event_new(void) { - HEV blah; - - if(DosCreateEventSem (NULL, &blah, 0L, FALSE)) - return 0; - - return blah; + HEV blah; + + if(DosCreateEventSem (NULL, &blah, 0L, FALSE)) + return 0; + + return blah; } /* @@ -8100,11 +9746,11 @@ */ int API dw_event_reset(HEV eve) { - ULONG count; - - if(DosResetEventSem(eve, &count)) - return FALSE; - return TRUE; + ULONG count; + + if(DosResetEventSem(eve, &count)) + return DW_ERROR_GENERAL; + return DW_ERROR_NONE; } /* @@ -8115,9 +9761,9 @@ */ int API dw_event_post(HEV eve) { - if(DosPostEventSem(eve)) - return FALSE; - return TRUE; + if(DosPostEventSem(eve)) + return DW_ERROR_GENERAL; + return DW_ERROR_NONE; } @@ -8129,12 +9775,12 @@ */ int API dw_event_wait(HEV eve, unsigned long timeout) { - int rc = DosWaitEventSem(eve, timeout); - if(!rc) - return 1; - if(rc == ERROR_TIMEOUT) - return -1; - return 0; + int rc = DosWaitEventSem(eve, timeout); + if(!rc) + return DW_ERROR_NONE; + if(rc == ERROR_TIMEOUT) + return DW_ERROR_TIMEOUT; + return DW_ERROR_GENERAL; } /* @@ -8144,9 +9790,9 @@ */ int API dw_event_close(HEV *eve) { - if(!eve || ~DosCloseEventSem(*eve)) - return FALSE; - return TRUE; + if(!eve || ~DosCloseEventSem(*eve)) + return DW_ERROR_GENERAL; + return DW_ERROR_NONE; } /* Create a named event semaphore which can be @@ -8158,19 +9804,19 @@ */ HEV API dw_named_event_new(char *name) { - char *semname = malloc(strlen(name)+8); - HEV ev = 0; - - if(!semname) - return 0; - - strcpy(semname, "\\sem32\\"); - strcat(semname, name); - - DosCreateEventSem(semname, &ev, 0L, FALSE); - - free(semname); - return ev; + char *semname = malloc(strlen(name)+8); + HEV ev = 0; + + if(!semname) + return 0; + + strcpy(semname, "\\sem32\\"); + strcat(semname, name); + + DosCreateEventSem((PSZ)semname, &ev, 0L, FALSE); + + free(semname); + return ev; } /* Open an already existing named event semaphore. @@ -8181,19 +9827,19 @@ */ HEV API dw_named_event_get(char *name) { - char *semname = malloc(strlen(name)+8); - HEV ev; - - if(!semname) - return 0; - - strcpy(semname, "\\sem32\\"); - strcat(semname, name); - - DosOpenEventSem(semname, &ev); - - free(semname); - return ev; + char *semname = malloc(strlen(name)+8); + HEV ev; + + if(!semname) + return 0; + + strcpy(semname, "\\sem32\\"); + strcat(semname, name); + + DosOpenEventSem((PSZ)semname, &ev); + + free(semname); + return ev; } /* Resets the event semaphore so threads who call wait @@ -8204,9 +9850,9 @@ */ int API dw_named_event_reset(HEV eve) { - ULONG count; - - return DosResetEventSem(eve, &count); + ULONG count; + + return DosResetEventSem(eve, &count); } /* Sets the posted state of an event semaphore, any threads @@ -8217,7 +9863,7 @@ */ int API dw_named_event_post(HEV eve) { - return DosPostEventSem(eve); + return DosPostEventSem(eve); } @@ -8231,26 +9877,26 @@ */ int API dw_named_event_wait(HEV eve, unsigned long timeout) { - int rc; - - rc = DosWaitEventSem(eve, timeout); - switch (rc) - { - case ERROR_INVALID_HANDLE: - rc = DW_ERROR_NON_INIT; - break; - case ERROR_NOT_ENOUGH_MEMORY: - rc = DW_ERROR_NO_MEM; - break; - case ERROR_INTERRUPT: - rc = DW_ERROR_INTERRUPT; - break; - case ERROR_TIMEOUT: - rc = DW_ERROR_TIMEOUT; - break; - } - - return rc; + int rc; + + rc = DosWaitEventSem(eve, timeout); + switch (rc) + { + case ERROR_INVALID_HANDLE: + rc = DW_ERROR_NON_INIT; + break; + case ERROR_NOT_ENOUGH_MEMORY: + rc = DW_ERROR_NO_MEM; + break; + case ERROR_INTERRUPT: + rc = DW_ERROR_INTERRUPT; + break; + case ERROR_TIMEOUT: + rc = DW_ERROR_TIMEOUT; + break; + } + + return rc; } /* Release this semaphore, if there are no more open @@ -8261,21 +9907,21 @@ */ int API dw_named_event_close(HEV eve) { - int rc; - - rc = DosCloseEventSem(eve); - switch (rc) - { - case ERROR_INVALID_HANDLE: - rc = DW_ERROR_NON_INIT; - break; - - case ERROR_SEM_BUSY: - rc = DW_ERROR_INTERRUPT; - break; - } - - return rc; + int rc; + + rc = DosCloseEventSem(eve); + switch (rc) + { + case ERROR_INVALID_HANDLE: + rc = DW_ERROR_NON_INIT; + break; + + case ERROR_SEM_BUSY: + rc = DW_ERROR_INTERRUPT; + break; + } + + return rc; } /* @@ -8288,14 +9934,14 @@ */ HSHM API dw_named_memory_new(void **dest, int size, char *name) { - char namebuf[1024]; - - sprintf(namebuf, "\\sharemem\\%s", name); - - if(DosAllocSharedMem((void *)dest, namebuf, size, PAG_COMMIT | PAG_WRITE | PAG_READ) != NO_ERROR) - return 0; - - return 1; + char namebuf[1024]; + + sprintf(namebuf, "\\sharemem\\%s", name); + + if(DosAllocSharedMem((void *)dest, (PSZ)namebuf, size, PAG_COMMIT | PAG_WRITE | PAG_READ) != NO_ERROR) + return 0; + + return 1; } /* @@ -8307,15 +9953,15 @@ */ HSHM API dw_named_memory_get(void **dest, int size, char *name) { - char namebuf[1024]; - - size = size; - sprintf(namebuf, "\\sharemem\\%s", name); - - if(DosGetNamedSharedMem((void *)dest, namebuf, PAG_READ | PAG_WRITE) != NO_ERROR) - return 0; - - return 1; + char namebuf[1024]; + + size = size; + sprintf(namebuf, "\\sharemem\\%s", name); + + if(DosGetNamedSharedMem((void *)dest, (PSZ)namebuf, PAG_READ | PAG_WRITE) != NO_ERROR) + return 0; + + return 1; } /* @@ -8326,11 +9972,11 @@ */ int API dw_named_memory_free(HSHM handle, void *ptr) { - handle = handle; - - if(DosFreeMem(ptr) != NO_ERROR) - return -1; - return 0; + handle = handle; + + if(DosFreeMem(ptr) != NO_ERROR) + return -1; + return 0; } /* @@ -8338,18 +9984,18 @@ */ void _dwthreadstart(void *data) { - HAB thishab = WinInitialize(0); - HMQ thishmq = WinCreateMsgQueue(dwhab, 0); - void (* API threadfunc)(void *) = NULL; - void **tmp = (void **)data; - - threadfunc = (void (*)(void *))tmp[0]; - threadfunc(tmp[1]); - - free(tmp); - - WinDestroyMsgQueue(thishmq); - WinTerminate(thishab); + HAB thishab = WinInitialize(0); + HMQ thishmq = WinCreateMsgQueue(dwhab, 0); + void (* API threadfunc)(void *) = NULL; + void **tmp = (void **)data; + + threadfunc = (void (* API)(void *))tmp[0]; + threadfunc(tmp[1]); + + free(tmp); + + WinDestroyMsgQueue(thishmq); + WinTerminate(thishab); } /* @@ -8361,12 +10007,12 @@ */ DWTID API dw_thread_new(void *func, void *data, int stack) { - void **tmp = malloc(sizeof(void *) * 2); - - tmp[0] = func; - tmp[1] = data; - - return (DWTID)_beginthread((void (*)(void *))_dwthreadstart, NULL, stack, (void *)tmp); + void **tmp = malloc(sizeof(void *) * 2); + + tmp[0] = func; + tmp[1] = data; + + return (DWTID)_beginthread((void (*)(void *))_dwthreadstart, NULL, stack, (void *)tmp); } /* @@ -8374,7 +10020,7 @@ */ void API dw_thread_end(void) { - _endthread(); + _endthread(); } /* @@ -8382,7 +10028,7 @@ */ DWTID API dw_thread_id(void) { - return (DWTID)_threadid; + return (DWTID)_threadid; } /* @@ -8392,17 +10038,17 @@ */ void API dw_exit(int exitcode) { - /* Destroy the menu message window */ - dw_window_destroy(hwndApp); - - /* In case we are in a signal handler, don't - * try to free memory that could possibly be - * free()'d by the runtime already. - */ - Root = NULL; - - DosFreeModule(wpconfig); - exit(exitcode); + /* Destroy the menu message window */ + dw_window_destroy(hwndApp); + + /* In case we are in a signal handler, don't + * try to free memory that could possibly be + * free()'d by the runtime already. + */ + Root = NULL; + + DosFreeModule(wpconfig); + exit(exitcode); } /* @@ -8416,34 +10062,34 @@ */ HWND API dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id) { - HWND tmp = WinCreateWindow(HWND_OBJECT, - SplitbarClassName, - NULL, - WS_VISIBLE | WS_CLIPCHILDREN, - 0,0,2000,1000, - NULLHANDLE, - HWND_TOP, - id, - NULL, - NULL); - if(tmp) - { - HWND tmpbox = dw_box_new(DW_VERT, 0); + HWND tmp = WinCreateWindow(HWND_OBJECT, + (PSZ)SplitbarClassName, + NULL, + WS_VISIBLE | WS_CLIPCHILDREN, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + if(tmp) + { + HWND tmpbox = dw_box_new(DW_VERT, 0); float *percent = malloc(sizeof(float)); - dw_box_pack_start(tmpbox, topleft, 1, 1, TRUE, TRUE, 0); - WinSetParent(tmpbox, tmp, FALSE); - dw_window_set_data(tmp, "_dw_topleft", (void *)tmpbox); - - tmpbox = dw_box_new(DW_VERT, 0); - dw_box_pack_start(tmpbox, bottomright, 1, 1, TRUE, TRUE, 0); - WinSetParent(tmpbox, tmp, FALSE); - *percent = 50.0; - dw_window_set_data(tmp, "_dw_bottomright", (void *)tmpbox); - dw_window_set_data(tmp, "_dw_percent", (void *)percent); - dw_window_set_data(tmp, "_dw_type", (void *)type); - } - return tmp; + dw_box_pack_start(tmpbox, topleft, 1, 1, TRUE, TRUE, 0); + WinSetParent(tmpbox, tmp, FALSE); + dw_window_set_data(tmp, "_dw_topleft", (void *)tmpbox); + + tmpbox = dw_box_new(DW_VERT, 0); + dw_box_pack_start(tmpbox, bottomright, 1, 1, TRUE, TRUE, 0); + WinSetParent(tmpbox, tmp, FALSE); + *percent = 50.0; + dw_window_set_data(tmp, "_dw_bottomright", (void *)tmpbox); + dw_window_set_data(tmp, "_dw_percent", (void *)percent); + dw_window_set_data(tmp, "_dw_type", (void *)type); + } + return tmp; } /* @@ -8453,16 +10099,16 @@ */ void API dw_splitbar_set(HWND handle, float percent) { - float *mypercent = (float *)dw_window_get_data(handle, "_dw_percent"); - int type = (int)dw_window_get_data(handle, "_dw_type"); + float *mypercent = (float *)dw_window_get_data(handle, "_dw_percent"); + int type = (int)dw_window_get_data(handle, "_dw_type"); unsigned long width, height; - if(mypercent) - *mypercent = percent; - - dw_window_get_pos_size(handle, NULL, NULL, &width, &height); - - _handle_splitbar_resize(handle, percent, type, width, height); + if(mypercent) + *mypercent = percent; + + dw_window_get_pos_size(handle, NULL, NULL, &width, &height); + + _handle_splitbar_resize(handle, percent, type, width, height); } /* @@ -8472,197 +10118,97 @@ */ float API dw_splitbar_get(HWND handle) { - float *percent = (float *)dw_window_get_data(handle, "_dw_percent"); - - if(percent) - return *percent; - return 0.0; -} - -/* - * Pack windows (widgets) into a box from the start (or top). - * Parameters: - * box: Window handle of the box to be packed into. - * item: Window handle of the item to be back. - * width: Width in pixels of the item or -1 to be self determined. - * height: Height in pixels of the item or -1 to be self determined. - * hsize: TRUE if the window (widget) should expand horizontally to fill space given. - * vsize: TRUE if the window (widget) should expand vertically to fill space given. - * pad: Number of pixels of padding around the item. - */ -void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) -{ - char *funcname = "dw_box_pack_start()"; - - /* - * If you try and pack an item into itself VERY bad things can happen; like at least an - * infinite loop on GTK! Lets be safe! - */ - if(box == item) - { - dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); - return; - } - - if(WinWindowFromID(box, FID_CLIENT)) - { - box = WinWindowFromID(box, FID_CLIENT); - hsize = TRUE; - vsize = TRUE; - } - _dw_box_pack_start(box, item, width, height, hsize, vsize, pad, funcname); -} - -void _dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname) -{ - Box *thisbox = WinQueryWindowPtr(box, QWP_USER); - - if(thisbox) - { - int z; - Item *tmpitem, *thisitem = thisbox->items; - char tmpbuf[100]; - HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box"); - - tmpitem = malloc(sizeof(Item)*(thisbox->count+1)); - - for(z=0;z<thisbox->count;z++) - { - tmpitem[z] = thisitem[z]; - } - - WinQueryClassName(item, 99, tmpbuf); - - if(vsize && !height) - height = 1; - if(hsize && !width) - width = 1; - - if(strncmp(tmpbuf, "#1", 3)==0) - tmpitem[thisbox->count].type = TYPEBOX; - else - { - if ( width == 0 && hsize == FALSE ) - dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); - if ( height == 0 && vsize == FALSE ) - dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); - - tmpitem[thisbox->count].type = TYPEITEM; - } - - tmpitem[thisbox->count].hwnd = item; - tmpitem[thisbox->count].origwidth = tmpitem[thisbox->count].width = width; - tmpitem[thisbox->count].origheight = tmpitem[thisbox->count].height = height; - tmpitem[thisbox->count].pad = pad; - if(hsize) - tmpitem[thisbox->count].hsize = SIZEEXPAND; - else - tmpitem[thisbox->count].hsize = SIZESTATIC; - - if(vsize) - tmpitem[thisbox->count].vsize = SIZEEXPAND; - else - tmpitem[thisbox->count].vsize = SIZESTATIC; - - thisbox->items = tmpitem; - - if(thisbox->count) - free(thisitem); - - thisbox->count++; - - /* Don't set the ownership if it's an entryfield or spinbutton */ - WinQueryClassName(item, 99, tmpbuf); - if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0) - WinSetOwner(item, box); - WinSetParent(frame ? frame : item, box, FALSE); - } + float *percent = (float *)dw_window_get_data(handle, "_dw_percent"); + + if(percent) + return *percent; + return 0.0; } /* The following two functions graciously contributed by Peter Nielsen. */ static ULONG _ParseBuildLevel (char* pchBuffer, ULONG ulSize) { - char* pchStart = pchBuffer; - char* pchEnd = pchStart + ulSize - 2; - - while (pchEnd >= pchStart) - { - if ((pchEnd[0] == '#') && (pchEnd[1] == '@')) - { - *pchEnd-- = '\0'; - while (pchEnd >= pchStart) - { - if ((pchEnd[0] == '@') && (pchEnd[1] == '#')) - { - ULONG ulMajor = 0; - ULONG ulMinor = 0; - - char* pch = pchEnd + 2; - while (!isdigit ((int)*pch) && *pch) - pch++; - - while (isdigit ((int)*pch)) - ulMajor = ulMajor * 10 + *pch++ - '0'; - - if (*pch == '.') - { - while (isdigit ((int)*++pch)) - ulMinor = ulMinor * 10 + *pch - '0'; - } - return ((ulMajor << 16) | ulMinor); - } - pchEnd--; - } - } - pchEnd--; - } - return (0); + char* pchStart = pchBuffer; + char* pchEnd = pchStart + ulSize - 2; + + while (pchEnd >= pchStart) + { + if ((pchEnd[0] == '#') && (pchEnd[1] == '@')) + { + *pchEnd-- = '\0'; + while (pchEnd >= pchStart) + { + if ((pchEnd[0] == '@') && (pchEnd[1] == '#')) + { + ULONG ulMajor = 0; + ULONG ulMinor = 0; + + char* pch = pchEnd + 2; + while (!isdigit ((int)*pch) && *pch) + pch++; + + while (isdigit ((int)*pch)) + ulMajor = ulMajor * 10 + *pch++ - '0'; + + if (*pch == '.') + { + while (isdigit ((int)*++pch)) + ulMinor = ulMinor * 10 + *pch - '0'; + } + return ((ulMajor << 16) | ulMinor); + } + pchEnd--; + } + } + pchEnd--; + } + return (0); } ULONG _GetSystemBuildLevel(void) { - /* The build level info is normally available in the end of the OS2KRNL file. However, this is not the case in some beta versions of OS/2. - * We first try to find the info in the 256 last bytes of the file. If that fails, we load the entire file and search it completely. - */ - ULONG ulBootDrive = 0; - ULONG ulBuild = 0; - if (DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ulBootDrive)) == NO_ERROR) - { - char achFileName[11] = "C:\\OS2KRNL"; - HFILE hfile; - ULONG ulResult; + /* The build level info is normally available in the end of the OS2KRNL file. However, this is not the case in some beta versions of OS/2. + * We first try to find the info in the 256 last bytes of the file. If that fails, we load the entire file and search it completely. + */ + ULONG ulBootDrive = 0; + ULONG ulBuild = 0; + if (DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ulBootDrive)) == NO_ERROR) + { + char achFileName[11] = "C:\\OS2KRNL"; + HFILE hfile; + ULONG ulResult; achFileName[0] = (char)('A'+ulBootDrive-1); - if (DosOpen (achFileName, &hfile, &ulResult, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL) == NO_ERROR) - { - ULONG ulFileSize = 0; - if (DosSetFilePtr (hfile, 0, FILE_END, &ulFileSize) == NO_ERROR) - { - const ULONG ulFirstTry = min (256, ulFileSize); - if (DosSetFilePtr (hfile, -(LONG)ulFirstTry, FILE_END, &ulResult) == NO_ERROR) - { - char *pchBuffer = malloc(ulFirstTry); - if (DosRead (hfile, pchBuffer, ulFirstTry, &ulResult) == NO_ERROR) - { - ulBuild = _ParseBuildLevel (pchBuffer, ulFirstTry); - if (ulBuild == 0) - { - if (DosSetFilePtr (hfile, 0, FILE_BEGIN, &ulResult) == NO_ERROR) - { - free(pchBuffer); - pchBuffer = malloc(ulFileSize); - - if (DosRead (hfile, pchBuffer, ulFileSize, &ulResult) == NO_ERROR) - ulBuild = _ParseBuildLevel (pchBuffer, ulFileSize); - } - } - } - free(pchBuffer); - } - } - DosClose (hfile); - } - } - return (ulBuild); + if (DosOpen ((PSZ)achFileName, &hfile, &ulResult, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL) == NO_ERROR) + { + ULONG ulFileSize = 0; + if (DosSetFilePtr (hfile, 0, FILE_END, &ulFileSize) == NO_ERROR) + { + const ULONG ulFirstTry = min (256, ulFileSize); + if (DosSetFilePtr (hfile, -(LONG)ulFirstTry, FILE_END, &ulResult) == NO_ERROR) + { + char *pchBuffer = malloc(ulFirstTry); + if (DosRead (hfile, pchBuffer, ulFirstTry, &ulResult) == NO_ERROR) + { + ulBuild = _ParseBuildLevel (pchBuffer, ulFirstTry); + if (ulBuild == 0) + { + if (DosSetFilePtr (hfile, 0, FILE_BEGIN, &ulResult) == NO_ERROR) + { + free(pchBuffer); + pchBuffer = malloc(ulFileSize); + + if (DosRead (hfile, pchBuffer, ulFileSize, &ulResult) == NO_ERROR) + ulBuild = _ParseBuildLevel (pchBuffer, ulFileSize); + } + } + } + free(pchBuffer); + } + } + DosClose (hfile); + } + } + return (ulBuild); } /* @@ -8673,15 +10219,15 @@ */ void API dw_window_default(HWND window, HWND defaultitem) { - Box *thisbox = NULL; - HWND box; - - box = WinWindowFromID(window, FID_CLIENT); - if(box) - thisbox = WinQueryWindowPtr(box, QWP_USER); - - if(thisbox) - thisbox->defaultitem = defaultitem; + Box *thisbox = NULL; + HWND box; + + box = WinWindowFromID(window, FID_CLIENT); + if(box) + thisbox = WinQueryWindowPtr(box, QWP_USER); + + if(thisbox) + thisbox->defaultitem = defaultitem; } /* @@ -8692,10 +10238,65 @@ */ void API dw_window_click_default(HWND window, HWND next) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER); - - if(blah) - blah->clickdefault = next; + WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER); + + if(blah) + blah->clickdefault = next; +} + +/* + * Gets the contents of the default clipboard as text. + * Parameters: + * None. + * Returns: + * Pointer to an allocated string of text or NULL if clipboard empty or contents could not + * be converted to text. + */ +char *dw_clipboard_get_text() +{ + APIRET rc; + char *retbuf = NULL; + ULONG fmtInfo; + + WinOpenClipbrd(dwhab); + + rc = WinQueryClipbrdFmtInfo(dwhab, CF_TEXT, &fmtInfo); + if (rc) /* Text data in clipboard */ + { + PSZ pszClipText = (PSZ)WinQueryClipbrdData(dwhab, CF_TEXT); /* Query data handle */ + retbuf = strdup((char *)pszClipText); + } + WinCloseClipbrd(dwhab); + return retbuf; +} + +/* + * Sets the contents of the default clipboard to the supplied text. + * Parameters: + * Text. + */ +void dw_clipboard_set_text( char *str, int len ) +{ + APIRET rc; + static PVOID shared; + + WinOpenClipbrd(dwhab); /* Open clipboard */ + WinEmptyClipbrd(dwhab); /* Empty clipboard */ + + /* Ok, clipboard wants giveable unnamed shared memory */ + + shared = NULL; + rc = DosAllocSharedMem(&shared, NULL, len, OBJ_GIVEABLE | PAG_COMMIT | PAG_READ | PAG_WRITE); + + if (rc == 0) + { + memcpy(shared, str, len); + + WinSetClipbrdData(dwhab, (ULONG)shared, CF_TEXT, CFI_POINTER); + } + + WinCloseClipbrd(dwhab); /* Close clipboard */ + return; } /* @@ -8705,198 +10306,202 @@ */ void API dw_environment_query(DWEnv *env) { - ULONG Build; - - if(!env) - return; - - /* The default is OS/2 2.0 */ - strcpy(env->osName,"OS/2"); - env->MajorVersion = 2; - env->MinorVersion = 0; - - Build = _GetSystemBuildLevel(); - env->MinorBuild = Build & 0xFFFF; - env->MajorBuild = Build >> 16; - - if (aulBuffer[0] == 20) - { - int i = (unsigned int)aulBuffer[1]; - if (i > 20) - { - strcpy(env->osName,"Warp"); - env->MajorVersion = (int)i/10; - env->MinorVersion = i-(((int)i/10)*10); - } - else if (i == 10) - env->MinorVersion = 1; - } - strcpy(env->buildDate, __DATE__); - strcpy(env->buildTime, __TIME__); - env->DWMajorVersion = DW_MAJOR_VERSION; - env->DWMinorVersion = DW_MINOR_VERSION; - env->DWSubVersion = DW_SUB_VERSION; + ULONG Build; + + if(!env) + return; + + /* The default is OS/2 2.0 */ + strcpy(env->osName,"OS/2"); + env->MajorVersion = 2; + env->MinorVersion = 0; + + Build = _GetSystemBuildLevel(); + env->MinorBuild = Build & 0xFFFF; + env->MajorBuild = Build >> 16; + + if (aulBuffer[0] == 20) + { + int i = (unsigned int)aulBuffer[1]; + if (i > 20) + { + strcpy(env->osName,"Warp"); + env->MajorVersion = (int)i/10; + env->MinorVersion = i-(((int)i/10)*10); + } + else if (i == 10) + env->MinorVersion = 1; + } + strcpy(env->buildDate, __DATE__); + strcpy(env->buildTime, __TIME__); + env->DWMajorVersion = DW_MAJOR_VERSION; + env->DWMinorVersion = DW_MINOR_VERSION; +#ifdef VER_REV + env->DWSubVersion = VER_REV; +#else + env->DWSubVersion = DW_SUB_VERSION; +#endif } /* The next few functions are support functions for the OS/2 folder browser */ void _populate_directory(HWND tree, HTREEITEM parent, char *path) { - FILEFINDBUF3 ffbuf; - HTREEITEM item; - ULONG count = 1; - HDIR hdir = HDIR_CREATE; - - if(DosFindFirst(path, &hdir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED | MUST_HAVE_DIRECTORY, - &ffbuf, sizeof(FILEFINDBUF3), &count, FIL_STANDARD) == NO_ERROR) - { - while(DosFindNext(hdir, &ffbuf, sizeof(FILEFINDBUF3), &count) == NO_ERROR) - { - if(strcmp(ffbuf.achName, ".") && strcmp(ffbuf.achName, "..")) - { - int len = strlen(path); - char *folder = malloc(len + ffbuf.cchName + 2); - HTREEITEM tempitem; - - strcpy(folder, path); - strcpy(&folder[len-1], ffbuf.achName); - - item = dw_tree_insert(tree, ffbuf.achName, WinLoadFileIcon(folder, TRUE), parent, (void *)parent); - tempitem = dw_tree_insert(tree, "", 0, item, 0); - dw_tree_item_set_data(tree, item, (void *)tempitem); - } - } - DosFindClose(hdir); - } -} - -void _populate_tree_thread(void *data) -{ - HWND window = (HWND)data, tree = (HWND)dw_window_get_data(window, "_dw_tree"); - HMTX mtx = (HMTX)dw_window_get_data(window, "_dw_mutex"); - int drive; - HTREEITEM items[26]; - FSINFO volinfo; - - DosError(FERR_DISABLEHARDERR); - - dw_mutex_lock(mtx); - for(drive=0;drive<26;drive++) - { - if(DosQueryFSInfo(drive+1, FSIL_VOLSER,(PVOID)&volinfo, sizeof(FSINFO)) == NO_ERROR) - { - char folder[5] = "C:\\", name[9] = "Drive C:"; - HTREEITEM tempitem; - - folder[0] = name[6] = 'A' + drive; - - items[drive] = dw_tree_insert(tree, name, WinLoadFileIcon(folder, TRUE), NULL, 0); - tempitem = dw_tree_insert(tree, "", 0, items[drive], 0); - dw_tree_item_set_data(tree, items[drive], (void *)tempitem); - } - else - items[drive] = 0; - } - dw_mutex_unlock(mtx); - - DosError(FERR_ENABLEHARDERR); + FILEFINDBUF3 ffbuf; + HTREEITEM item; + ULONG count = 1; + HDIR hdir = HDIR_CREATE; + + if(DosFindFirst((PSZ)path, &hdir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED | MUST_HAVE_DIRECTORY, + &ffbuf, sizeof(FILEFINDBUF3), &count, FIL_STANDARD) == NO_ERROR) + { + while(DosFindNext(hdir, &ffbuf, sizeof(FILEFINDBUF3), &count) == NO_ERROR) + { + if(strcmp(ffbuf.achName, ".") && strcmp(ffbuf.achName, "..")) + { + int len = strlen(path); + char *folder = malloc(len + ffbuf.cchName + 2); + HTREEITEM tempitem; + + strcpy(folder, path); + strcpy(&folder[len-1], ffbuf.achName); + + item = dw_tree_insert(tree, ffbuf.achName, WinLoadFileIcon((PSZ)folder, TRUE), parent, (void *)parent); + tempitem = dw_tree_insert(tree, "", 0, item, 0); + dw_tree_item_set_data(tree, item, (void *)tempitem); + } + } + DosFindClose(hdir); + } +} + +void API _populate_tree_thread(void *data) +{ + HWND window = (HWND)data, tree = (HWND)dw_window_get_data(window, "_dw_tree"); + HMTX mtx = (HMTX)dw_window_get_data(window, "_dw_mutex"); + int drive; + HTREEITEM items[26]; + FSINFO volinfo; + + DosError(FERR_DISABLEHARDERR); + + dw_mutex_lock(mtx); + for(drive=0;drive<26;drive++) + { + if(DosQueryFSInfo(drive+1, FSIL_VOLSER,(PVOID)&volinfo, sizeof(FSINFO)) == NO_ERROR) + { + char folder[5] = "C:\\", name[9] = "Drive C:"; + HTREEITEM tempitem; + + folder[0] = name[6] = 'A' + drive; + + items[drive] = dw_tree_insert(tree, name, WinLoadFileIcon((PSZ)folder, TRUE), NULL, 0); + tempitem = dw_tree_insert(tree, "", 0, items[drive], 0); + dw_tree_item_set_data(tree, items[drive], (void *)tempitem); + } + else + items[drive] = 0; + } + dw_mutex_unlock(mtx); + + DosError(FERR_ENABLEHARDERR); } int DWSIGNAL _dw_ok_func(HWND window, void *data) { - DWDialog *dwwait = (DWDialog *)data; - HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex"); - void *treedata; - - window = window; - if(!dwwait) - return FALSE; - - dw_mutex_lock(mtx); - treedata = dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected"); - dw_mutex_close(mtx); - dw_window_destroy((HWND)dwwait->data); - dw_dialog_dismiss((DWDialog *)data, treedata); - return FALSE; + DWDialog *dwwait = (DWDialog *)data; + HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex"); + void *treedata; + + window = window; + if(!dwwait) + return FALSE; + + dw_mutex_lock(mtx); + treedata = dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected"); + dw_mutex_close(mtx); + dw_window_destroy((HWND)dwwait->data); + dw_dialog_dismiss((DWDialog *)data, treedata); + return FALSE; } int DWSIGNAL _dw_cancel_func(HWND window, void *data) { - DWDialog *dwwait = (DWDialog *)data; - HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex"); - - window = window; - if(!dwwait) - return FALSE; - - dw_mutex_lock(mtx); - dw_mutex_close(mtx); - dw_window_destroy((HWND)dwwait->data); - dw_dialog_dismiss((DWDialog *)data, NULL); - return FALSE; + DWDialog *dwwait = (DWDialog *)data; + HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex"); + + window = window; + if(!dwwait) + return FALSE; + + dw_mutex_lock(mtx); + dw_mutex_close(mtx); + dw_window_destroy((HWND)dwwait->data); + dw_dialog_dismiss((DWDialog *)data, NULL); + return FALSE; } char *_tree_folder(HWND tree, HTREEITEM item) { - char *folder=strdup(""); - HTREEITEM parent = item; - - while(parent) - { - char *temp, *text = dw_tree_get_title(tree, parent); - - if(text) - { - if(strncmp(text, "Drive ", 6) == 0) - text = &text[6]; - - temp = malloc(strlen(text) + strlen(folder) + 3); - strcpy(temp, text); - strcat(temp, "\\"); - strcat(temp, folder); - free(folder); - folder = temp; - } - parent = dw_tree_get_parent(tree, parent); - } - return folder; + char *folder=strdup(""); + HTREEITEM parent = item; + + while(parent) + { + char *temp, *text = dw_tree_get_title(tree, parent); + + if(text) + { + if(strncmp(text, "Drive ", 6) == 0) + text = &text[6]; + + temp = malloc(strlen(text) + strlen(folder) + 3); + strcpy(temp, text); + strcat(temp, "\\"); + strcat(temp, folder); + free(folder); + folder = temp; + } + parent = dw_tree_get_parent(tree, parent); + } + return folder; } int DWSIGNAL _item_select(HWND window, HTREEITEM item, char *text, void *data, void *itemdata) { - DWDialog *dwwait = (DWDialog *)data; - char *treedata = (char *)dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected"); - - text = text; itemdata = itemdata; - if(treedata) - free(treedata); - - treedata = _tree_folder(window, item); - dw_window_set_data((HWND)dwwait->data, "_dw_tree_selected", (void *)treedata); - - return FALSE; + DWDialog *dwwait = (DWDialog *)data; + char *treedata = (char *)dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected"); + + text = text; itemdata = itemdata; + if(treedata) + free(treedata); + + treedata = _tree_folder(window, item); + dw_window_set_data((HWND)dwwait->data, "_dw_tree_selected", (void *)treedata); + + return FALSE; } int DWSIGNAL _tree_expand(HWND window, HTREEITEM item, void *data) { - HTREEITEM tempitem = (HTREEITEM)dw_tree_item_get_data(window, item); - - data = data; - if(tempitem) - { - char *folder = _tree_folder(window, item); - - dw_tree_item_set_data(window, item, 0); - dw_tree_item_delete(window, tempitem); - - if(*folder) - { - strcat(folder, "*"); - _populate_directory(window, item, folder); - } - free(folder); - } - - return FALSE; + HTREEITEM tempitem = (HTREEITEM)dw_tree_item_get_data(window, item); + + data = data; + if(tempitem) + { + char *folder = _tree_folder(window, item); + + dw_tree_item_set_data(window, item, 0); + dw_tree_item_delete(window, tempitem); + + if(*folder) + { + strcat(folder, "*"); + _populate_directory(window, item, folder); + } + free(folder); + } + + return FALSE; } /* @@ -8913,110 +10518,131 @@ */ char * API dw_file_browse(char *title, char *defpath, char *ext, int flags) { - if(flags == DW_DIRECTORY_OPEN) - { - HWND window, hbox, vbox, tree, button; - DWDialog *dwwait; - HMTX mtx = dw_mutex_new(); - - window = dw_window_new( HWND_DESKTOP, title, FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX); - - vbox = dw_box_new(DW_VERT, 5); - - dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0); - - tree = dw_tree_new(60); - - dw_box_pack_start(vbox, tree, 1, 1, TRUE, TRUE, 0); - dw_window_set_data(window, "_dw_mutex", (void *)mtx); - dw_window_set_data(window, "_dw_tree", (void *)tree); - - hbox = dw_box_new(DW_HORZ, 0); - - dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0); - - dwwait = dw_dialog_new((void *)window); - - dw_signal_connect(tree, DW_SIGNAL_ITEM_SELECT, DW_SIGNAL_FUNC(_item_select), (void *)dwwait); - dw_signal_connect(tree, DW_SIGNAL_TREE_EXPAND, DW_SIGNAL_FUNC(_tree_expand), (void *)dwwait); - - button = dw_button_new("Ok", 1001L); - dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); - dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_ok_func), (void *)dwwait); - - button = dw_button_new("Cancel", 1002L); - dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); - dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait); - dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait); - - dw_window_set_size(window, 225, 300); - dw_window_show(window); - - dw_thread_new((void *)_populate_tree_thread, (void *)window, 0xff); - return (char *)dw_dialog_wait(dwwait); - } - else - { - FILEDLG fild; - HWND hwndFile; - int len; - - if(defpath) - strcpy(fild.szFullFile, defpath); - else - strcpy(fild.szFullFile, ""); - - len = strlen(fild.szFullFile); - - if(len) - { - if(fild.szFullFile[len-1] != '\\') - strcat(fild.szFullFile, "\\"); - } - strcat(fild.szFullFile, "*"); - - if(ext) - { - strcat(fild.szFullFile, "."); - strcat(fild.szFullFile, ext); - } - - memset(&fild, 0, sizeof(FILEDLG)); - fild.cbSize = sizeof(FILEDLG); - fild.fl = FDS_CENTER | FDS_OPEN_DIALOG; - fild.pszTitle = title; - fild.pszOKButton = ((flags & DW_FILE_SAVE) ? "Save" : "Open"); - fild.pfnDlgProc = (PFNWP)WinDefFileDlgProc; - - hwndFile = WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fild); - if(hwndFile) - { - switch(fild.lReturn) - { - case DID_OK: - return strdup(fild.szFullFile); - case DID_CANCEL: - return NULL; - } - } - } - return NULL; + if(flags == DW_DIRECTORY_OPEN) + { + HWND window, hbox, vbox, tree, button; + DWDialog *dwwait; + HMTX mtx = dw_mutex_new(); + + window = dw_window_new( HWND_DESKTOP, title, FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX); + + vbox = dw_box_new(DW_VERT, 5); + + dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0); + + tree = dw_tree_new(60); + + dw_box_pack_start(vbox, tree, 1, 1, TRUE, TRUE, 0); + dw_window_set_data(window, "_dw_mutex", (void *)mtx); + dw_window_set_data(window, "_dw_tree", (void *)tree); + + hbox = dw_box_new(DW_HORZ, 0); + + dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0); + + dwwait = dw_dialog_new((void *)window); + + dw_signal_connect(tree, DW_SIGNAL_ITEM_SELECT, DW_SIGNAL_FUNC(_item_select), (void *)dwwait); + dw_signal_connect(tree, DW_SIGNAL_TREE_EXPAND, DW_SIGNAL_FUNC(_tree_expand), (void *)dwwait); + + button = dw_button_new("Ok", 1001L); + dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); + dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_ok_func), (void *)dwwait); + + button = dw_button_new("Cancel", 1002L); + dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); + dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait); + dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait); + + dw_window_set_size(window, 225, 300); + dw_window_show(window); + + dw_thread_new((void *)_populate_tree_thread, (void *)window, 0xff); + return (char *)dw_dialog_wait(dwwait); + } + else + { + FILEDLG fild = { 0 }; + HWND hwndFile; + int len; + struct stat buf; + + if(defpath) + { + if(DosQueryPathInfo((PSZ)defpath, FIL_QUERYFULLNAME, fild.szFullFile, sizeof(fild.szFullFile))) + strcpy(fild.szFullFile, defpath); + }; + + len = strlen(fild.szFullFile); + + /* If we have a defpath */ + if(len) + { + /* Check to see if it exists */ + if(stat(fild.szFullFile, &buf) == 0) + { + /* If it is a directory... make sure there is a trailing \ */ + if(buf.st_mode & S_IFDIR) + { + if(fild.szFullFile[len-1] != '\\') + strcat(fild.szFullFile, "\\"); + /* Set len to 0 so the wildcard gets added below */ + len = 0; + } + } + } + + /* If we need a wildcard (defpath isn't a file) */ + if(!len) + { + /* Add a * to get all files... */ + strcat(fild.szFullFile, "*"); + + /* If an extension was requested... */ + if(ext) + { + /* Limit the results further */ + strcat(fild.szFullFile, "."); + strcat(fild.szFullFile, ext); + } + } + + /* Setup the structure */ + fild.cbSize = sizeof(FILEDLG); + fild.fl = FDS_CENTER | FDS_OPEN_DIALOG; + fild.pszTitle = (PSZ)title; + fild.pszOKButton = (PSZ)((flags & DW_FILE_SAVE) ? "Save" : "Open"); + fild.pfnDlgProc = (PFNWP)WinDefFileDlgProc; + + hwndFile = WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fild); + if(hwndFile) + { + switch(fild.lReturn) + { + case DID_OK: + return strdup(fild.szFullFile); + case DID_CANCEL: + return NULL; + } + } + } + return NULL; } /* Internal function to set drive and directory */ int _SetPath(char *path) { #ifndef __WATCOMC__ - if(strlen(path) > 2) - { - if(path[1] == ':') - { - char drive = toupper(path[0]); - _chdrive((drive - 'A')+1); - } - } + if(strlen(path) > 2) + { + if(path[1] == ':') + { + char drive = toupper(path[0]); + _chdrive((drive - 'A')+1); + } + } #endif - return chdir(path); + return chdir(path); } /* @@ -9030,8 +10656,8 @@ */ int API dw_exec(char *program, int type, char **params) { - type = type; /* keep compiler happy */ - return spawnvp(P_NOWAIT, program, (const char **)params); + type = type; /* keep compiler happy */ + return spawnvp(P_NOWAIT, program, (char * const *)params); } /* @@ -9041,58 +10667,465 @@ */ int API dw_browse(char *url) { - char *execargs[3], browser[1024], *olddir, *newurl = NULL; - int len, ret; - - olddir = _getcwd(NULL, 1024); - - PrfQueryProfileString(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", - "DefaultWorkingDir", NULL, browser, 1024); - - if(browser[0]) - _SetPath(browser); - - PrfQueryProfileString(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", - "DefaultBrowserExe", NULL, browser, 1024); - - len = strlen(browser) - strlen("explore.exe"); - - execargs[0] = browser; - execargs[1] = url; - execargs[2] = NULL; - - /* Special case for Web Explorer, it requires file:/// instead - * of file:// so I am handling it here. - */ - if(len > 0) - { - if(stricmp(&browser[len], "explore.exe") == 0 && stricmp(url, "file://") == 0) - { - int newlen, z; - newurl = malloc(strlen(url) + 2); - sprintf(newurl, "file:///%s", &url[7]); - newlen = strlen(newurl); - for(z=8;z<(newlen-8);z++) - { - if(newurl[z] == '|') - newurl[z] = ':'; - if(newurl[z] == '/') - newurl[z] = '\\'; - } - execargs[1] = newurl; - } - } - - ret = dw_exec(browser, DW_EXEC_GUI, execargs); - - if(olddir) - { - _SetPath(olddir); - free(olddir); - } - if(newurl) - free(newurl); - return ret; + char *execargs[3], browser[1024], *olddir, *newurl = NULL; + int len, ret; + + olddir = _getcwd(NULL, 1024); + + PrfQueryProfileString(HINI_USERPROFILE, (PSZ)"WPURLDEFAULTSETTINGS", + (PSZ)"DefaultWorkingDir", NULL, (PSZ)browser, 1024); + + if(browser[0]) + _SetPath(browser); + + PrfQueryProfileString(HINI_USERPROFILE, (PSZ)"WPURLDEFAULTSETTINGS", + (PSZ)"DefaultBrowserExe", NULL, (PSZ)browser, 1024); + + len = strlen(browser) - strlen("explore.exe"); + + execargs[0] = browser; + execargs[1] = url; + execargs[2] = NULL; + + /* Special case for Web Explorer, it requires file:/// instead + * of file:// so I am handling it here. + */ + if(len > 0) + { + if(stricmp(&browser[len], "explore.exe") == 0 && stricmp(url, "file://") == 0) + { + int newlen, z; + newurl = malloc(strlen(url) + 2); + sprintf(newurl, "file:///%s", &url[7]); + newlen = strlen(newurl); + for(z=8;z<(newlen-8);z++) + { + if(newurl[z] == '|') + newurl[z] = ':'; + if(newurl[z] == '/') + newurl[z] = '\\'; + } + execargs[1] = newurl; + } + } + + ret = dw_exec(browser, DW_EXEC_GUI, execargs); + + if(olddir) + { + _SetPath(olddir); + free(olddir); + } + if(newurl) + free(newurl); + return ret; +} + +/* + * Causes the embedded HTML widget to take action. + * Parameters: + * handle: Handle to the window. + * action: One of the DW_HTML_* constants. + */ +void API dw_html_action(HWND handle, int action) +{ + handle = handle; + action = action; +} + +/* + * Render raw HTML code in the embedded HTML widget.. + * Parameters: + * handle: Handle to the window. + * string: String buffer containt HTML code to + * be rendered. + * Returns: + * 0 on success. + */ +int API dw_html_raw(HWND handle, char *string) +{ + handle = handle; + string = string; + return -1; +} + +/* + * Render file or web page in the embedded HTML widget.. + * Parameters: + * handle: Handle to the window. + * url: Universal Resource Locator of the web or + * file object to be rendered. + * Returns: + * 0 on success. + */ +int API dw_html_url(HWND handle, char *url) +{ + handle = handle; + url = url; + return -1; +} + +/* + * Create a new HTML window (widget) to be packed. + * Not available under OS/2, eCS + * Parameters: + * text: The default text to be in the entryfield widget. + * id: An ID to be used with dw_window_from_id() or 0L. + */ +HWND API dw_html_new(unsigned long id) +{ + id = id; + dw_debug("HTML widget not available; OS/2 currently does not support it.\n"); + return 0; +} + +typedef struct _dwprint +{ + HDC hdc; + char *printername; + int (* API drawfunc)(HPRINT, HPIXMAP, int, void *); + void *drawdata; + unsigned long flags; + unsigned int startpage, endpage; + char *jobname; +} DWPrint; + +/* Internal functions to handle the print dialog */ +int DWSIGNAL _dw_printer_cancel_func(HWND window, void *data) +{ + DWPrint *print = (DWPrint *)data; + DWDialog *dwwait = (DWDialog *)print->printername; + + window = (HWND)dwwait->data; + + dw_window_destroy(window); + dw_dialog_dismiss(dwwait, NULL); + return FALSE; +} + +int DWSIGNAL _dw_printer_ok_func(HWND window, void *data) +{ + DWPrint *print = (DWPrint *)data; + DWDialog *dwwait = (DWDialog *)print->printername; + HWND printerlist, startspin, endspin; + char *result = NULL; + + window = (HWND)dwwait->data; + printerlist = (HWND)dw_window_get_data(window, "_dw_list"); + startspin = (HWND)dw_window_get_data(window, "_dw_start_spin"); + endspin = (HWND)dw_window_get_data(window, "_dw_end_spin"); + if(printerlist) + { + char printername[32] = ""; + int selected = dw_listbox_selected(printerlist); + + /* Get the name of the selected printer */ + if(selected != DW_ERROR_UNKNOWN) + { + dw_listbox_get_text(printerlist, selected, printername, 32); + if(printername[0]) + print->printername = result = strdup(printername); + } + /* Get the start and end positions */ + print->startpage = (unsigned int)dw_spinbutton_get_pos(startspin); + print->endpage = (unsigned int)dw_spinbutton_get_pos(endspin); + + /* If the start is bigger than end... swap them */ + if(print->startpage > print->endpage) + { + print->endpage = print->startpage; + print->startpage = (unsigned int)dw_spinbutton_get_pos(endspin); + } + } + + dw_window_destroy(window); + dw_dialog_dismiss(dwwait, (void *)result); + return FALSE; +} + +/* Borrowed functions which should probably be rewritten */ +BOOL _ExtractLogAddress(char * LogAddress, char * DetailStr) +{ + char *p; + + p = DetailStr; + while(*p++ != ';'); /* Gets to first ';' and one char beyond */ + while(*p++ != ';'); /* Gets to second ';' and one char beyond */ + while(*p != ';') *LogAddress++ = *p++; + *LogAddress = '\0'; + return TRUE; +} + +BOOL _ExtractDriverName(char * DriverName, char * DetailStr) +{ + char *p; + + p = DetailStr; + while(*p++ != ';'); /* Gets to first ';' and one char beyond */ + while(*p != '.' && *p != ';' && *p != ',') + *DriverName++ = *p++; + *DriverName = '\0'; + return TRUE; +} + +/* EMX Doesn't seem to define this? */ +#ifndef NERR_BufTooSmall +#define NERR_BufTooSmall 2123 +#endif + +/* + * Creates a new print object. + * Parameters: + * jobname: Name of the print job to show in the queue. + * flags: Flags to initially configure the print object. + * pages: Number of pages to print. + * drawfunc: The pointer to the function to be used as the callback. + * drawdata: User data to be passed to the handler function. + * Returns: + * A handle to the print object or NULL on failure. + */ +HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata) +{ + char printername[32], tmpbuf[20]; + HWND window, hbox, vbox, printerlist, button, text; + DWDialog *dwwait; + DWPrint *print; + PVOID pBuf = NULL; + ULONG fsType = SPL_PR_QUEUE; + ULONG cbBuf, cRes, cTotal, cbNeeded; + SPLERR splerr = 0 ; + PPRINTERINFO pRes ; /* Check the default printer for now... want a printer list in the future */ + int cb = PrfQueryProfileString(HINI_PROFILE, (PSZ)"PM_SPOOLER", (PSZ)"PRINTER", (PSZ)"", printername, 32); + + if(!drawfunc || !(print = calloc(1, sizeof(DWPrint)))) + return NULL; + + print->drawfunc = drawfunc; + print->drawdata = drawdata; + print->jobname = jobname ? jobname : "Dynamic Windows Print Job"; + print->startpage = 1; + print->endpage = pages; + print->flags = flags; + + /* Check to see how much space we need for the printer list */ + splerr = SplEnumPrinter(NULL, 0, fsType, NULL, 0, &cRes, &cTotal, &cbNeeded ,NULL); + + if(splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall) + { + /* Allocate memory for the buffer using the count of bytes that were returned in cbNeeded. */ + DosAllocMem(&pBuf, cbNeeded, PAG_READ|PAG_WRITE|PAG_COMMIT); + + /* Set count of bytes in buffer to value used to allocate buffer. */ + cbBuf = cbNeeded; + + /* Call function again with the correct buffer size. */ + splerr = SplEnumPrinter(NULL, 0, fsType, pBuf, cbBuf, &cRes, &cTotal, &cbNeeded, NULL); + } + + /* Make sure we got a valid result */ + if(cb > 2) + printername[cb-2] = '\0'; + else + printername[0] = '\0'; + + /* If we didnt' get a printer list or default printer abort */ + if(!cRes && !printername[0]) + { + /* Show an error and return failure */ + dw_messagebox("Printing", DW_MB_ERROR | DW_MB_OK, "No printers detected."); + free(print); + return NULL; + } + + /* Create the print dialog */ + window = dw_window_new(HWND_DESKTOP, "Choose Printer", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU); + + vbox = dw_box_new(DW_VERT, 5); + + dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0); + + printerlist = dw_listbox_new(0, FALSE); + dw_box_pack_start(vbox, printerlist, 1, 1, TRUE, TRUE, 0); + + /* If there are any returned structures in the buffer... */ + if(pBuf && cRes) + { + int count = 0; + + pRes = (PPRINTERINFO)pBuf ; + while(cRes--) + { + dw_listbox_append(printerlist, (char *)pRes[cRes].pszPrintDestinationName); + /* If this is the default printer... select it by default */ + if(strcmp((char *)pRes[cRes].pszPrintDestinationName, printername) == 0) + dw_listbox_select(printerlist, count, TRUE); + count++; + } + } + else + { + /* Otherwise just add the default */ + dw_listbox_append(printerlist, printername); + dw_listbox_select(printerlist, 0, TRUE); + } + + /* Free any unneeded memory */ + if(pBuf) + DosFreeMem(pBuf); + + dw_window_set_data(window, "_dw_list", (void *)printerlist); + + /* Start spinbutton */ + hbox = dw_box_new(DW_HORZ, 0); + + dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0); + + text = dw_text_new("Start page:", 0); + dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER); + dw_box_pack_start(hbox, text, 70, 20, FALSE, FALSE, 3); + + button = dw_spinbutton_new("1", 0); + dw_spinbutton_set_limits(button, 1, pages); + dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3); + dw_window_set_data(window, "_dw_start_spin", (void *)button); + + /* End spinbutton */ + hbox = dw_box_new(DW_HORZ, 0); + + dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0); + + text = dw_text_new("End page:", 0); + dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER); + dw_box_pack_start(hbox, text, 70, 20, FALSE, FALSE, 3); + + sprintf(tmpbuf, "%d", pages); + button = dw_spinbutton_new(tmpbuf, 0); + dw_spinbutton_set_limits(button, 1, pages); + dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3); + dw_window_set_data(window, "_dw_end_spin", (void *)button); + + /* Ok and Cancel buttons */ + hbox = dw_box_new(DW_HORZ, 0); + + dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0); + dw_box_pack_start(hbox, 0, 100, 1, TRUE, FALSE, 0); + + button = dw_button_new("Ok", 0); + dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); + + dwwait = dw_dialog_new((void *)window); + /* Save it temporarily there until we need it */ + print->printername = (char *)dwwait; + + dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_printer_ok_func), (void *)print); + + button = dw_button_new("Cancel", 0); + dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3); + + dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_printer_cancel_func), (void *)print); + dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_printer_cancel_func), (void *)print); + + dw_window_set_size(window, 300, 400); + + dw_window_show(window); + + print->printername = dw_dialog_wait(dwwait); + + /* The user picked a printer */ + if(print->printername) + { + char PrintDetails[256]; + char DriverName[32]; + char LogAddress[32]; + DEVOPENSTRUC dop; + + /* Get the printer information string */ + cb = PrfQueryProfileString(HINI_PROFILE, (PSZ)"PM_SPOOLER_PRINTER", (PSZ)print->printername, (PSZ)"", PrintDetails, 256); + _ExtractLogAddress(LogAddress, PrintDetails); + _ExtractDriverName(DriverName, PrintDetails); + dop.pszDriverName = (PSZ)DriverName; + dop.pszLogAddress = (PSZ)LogAddress; + dop.pdriv = NULL; + dop.pszDataType = (PSZ)"PM_Q_STD"; + /* Attempt to open a device context and return a handle to it */ + print->hdc = DevOpenDC(dwhab, OD_QUEUED, (PSZ)"*", 4L, (PDEVOPENDATA) &dop, (HDC)NULL); + if(print->hdc) + return print; + } + /* The user canceled */ + if(print->printername) + free(print->printername); + free(print); + return NULL; +} + +/* + * Runs the print job, causing the draw page callbacks to fire. + * Parameters: + * print: Handle to the print object returned by dw_print_new(). + * flags: Flags to run the print job. + * Returns: + * DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success. + */ +int API dw_print_run(HPRINT print, unsigned long flags) +{ + DWPrint *p = print; + HPIXMAP pixmap; + int x, result = DW_ERROR_UNKNOWN; + SIZEL sizl = { 0, 0 }; + + if(!p) + return result; + + if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) + return result; + + /* Start the job */ + DevEscape(p->hdc, DEVESC_STARTDOC, strlen(p->jobname), (PBYTE)p->jobname, NULL, NULL); + + pixmap->font = WinCreateWindow(HWND_OBJECT, WC_FRAME, NULL, 0,0,0,1,1, NULLHANDLE, HWND_TOP,0, NULL, NULL); + pixmap->hdc = p->hdc; + pixmap->hps = GpiCreatePS(dwhab, p->hdc, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC); + pixmap->transcolor = DW_RGB_TRANSPARENT; + pixmap->width = sizl.cx; + pixmap->height = sizl.cy; + dw_pixmap_set_font(pixmap, DefaultFont); + + /* Cycle through each page */ + for(x=p->startpage-1; x<p->endpage && p->drawfunc; x++) + { + p->drawfunc(print, pixmap, x, p->drawdata); + /* Next page */ + DevEscape(p->hdc, DEVESC_NEWFRAME, 0, NULL, NULL, NULL); + } + /* Determine the completion code */ + if(p->drawfunc) + { + result = DW_ERROR_NONE; + /* Signal that we are done */ + DevEscape(p->hdc, DEVESC_ENDDOC, 0, NULL, NULL, NULL); + } + else + DevEscape(p->hdc, DEVESC_ABORTDOC, 0, NULL, NULL, NULL); + /* Free memory */ + dw_pixmap_destroy(pixmap); + if(p->printername) + free(p->printername); + free(p); + return result; +} + +/* + * Cancels the print job, typically called from a draw page callback. + * Parameters: + * print: Handle to the print object returned by dw_print_new(). + */ +void API dw_print_cancel(HPRINT print) +{ + DWPrint *p = print; + + if(p) + p->drawfunc = NULL; } /* @@ -9102,18 +11135,18 @@ */ char * API dw_user_dir(void) { - static char _user_dir[1024] = ""; - - if(!_user_dir[0]) - { - char *home = getenv("HOME"); - - if(home) - strcpy(_user_dir, home); - else - strcpy(_user_dir, "C:\\"); - } - return _user_dir; + static char _user_dir[1024] = ""; + + if(!_user_dir[0]) + { + char *home = getenv("HOME"); + + if(home) + strcpy(_user_dir, home); + else + strcpy(_user_dir, "C:\\"); + } + return _user_dir; } /* @@ -9125,7 +11158,7 @@ */ void API dw_window_function(HWND handle, void *function, void *data) { - WinSendMsg(handle, WM_USER, (MPARAM)function, (MPARAM)data); + WinSendMsg(handle, WM_USER, (MPARAM)function, (MPARAM)data); } /* Functions for managing the user data lists that are associated with @@ -9134,92 +11167,90 @@ */ UserData *_find_userdata(UserData **root, char *varname) { - UserData *tmp = *root; - - while(tmp) - { - if(stricmp(tmp->varname, varname) == 0) - return tmp; - tmp = tmp->next; - } - return NULL; + UserData *tmp = *root; + + while(tmp) + { + if(stricmp(tmp->varname, varname) == 0) + return tmp; + tmp = tmp->next; + } + return NULL; } int _new_userdata(UserData **root, char *varname, void *data) { - UserData *new = _find_userdata(root, varname); - - if(new) - { - new->data = data; - return TRUE; - } - else - { - new = malloc(sizeof(UserData)); - if(new) - { - new->varname = strdup(varname); - new->data = data; - - new->next = NULL; - - if (!*root) - *root = new; - else - { - UserData *prev = NULL, *tmp = *root; - while(tmp) - { - prev = tmp; - tmp = tmp->next; - } - if(prev) - prev->next = new; - else - *root = new; - } - return TRUE; - } - } - return FALSE; + UserData *new = _find_userdata(root, varname); + + if(new) + { + new->data = data; + return TRUE; + } + else + { + new = malloc(sizeof(UserData)); + if(new) + { + new->varname = strdup(varname); + new->data = data; + + new->next = NULL; + + if (!*root) + *root = new; + else + { + UserData *prev = *root, *tmp = prev->next; + + while(tmp) + { + prev = tmp; + tmp = tmp->next; + } + prev->next = new; + } + return TRUE; + } + } + return FALSE; } int _remove_userdata(UserData **root, char *varname, int all) { - UserData *prev = NULL, *tmp = *root; - - while(tmp) - { - if(all || stricmp(tmp->varname, varname) == 0) - { - if(!prev) - { - *root = tmp->next; - free(tmp->varname); - free(tmp); - if(!all) - return 0; - tmp = *root; - } - else - { - /* If all is true we should - * never get here. - */ - prev->next = tmp->next; - free(tmp->varname); - free(tmp); - return 0; - } - } - else - { - prev = tmp; - tmp = tmp->next; - } - } - return 0; + UserData *prev = NULL, *tmp = *root; + + while(tmp) + { + if(all || stricmp(tmp->varname, varname) == 0) + { + if(!prev) + { + *root = tmp->next; + free(tmp->varname); + free(tmp); + if(!all) + return 0; + tmp = *root; + } + else + { + /* If all is true we should + * never get here. + */ + prev->next = tmp->next; + free(tmp->varname); + free(tmp); + return 0; + } + } + else + { + prev = tmp; + tmp = tmp->next; + } + } + return 0; } /* @@ -9231,26 +11262,26 @@ */ void API dw_window_set_data(HWND window, char *dataname, void *data) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER); - - if(!blah) - { - if(!dataname) - return; - - blah = calloc(1, sizeof(WindowData)); - WinSetWindowPtr(window, QWP_USER, blah); - } - - if(data) - _new_userdata(&(blah->root), dataname, data); - else - { - if(dataname) - _remove_userdata(&(blah->root), dataname, FALSE); - else - _remove_userdata(&(blah->root), NULL, TRUE); - } + WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER); + + if(!blah) + { + if(!dataname) + return; + + blah = calloc(1, sizeof(WindowData)); + WinSetWindowPtr(window, QWP_USER, blah); + } + + if(data) + _new_userdata(&(blah->root), dataname, data); + else + { + if(dataname) + _remove_userdata(&(blah->root), dataname, FALSE); + else + _remove_userdata(&(blah->root), NULL, TRUE); + } } /* @@ -9262,15 +11293,15 @@ */ void * API dw_window_get_data(HWND window, char *dataname) { - WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER); - - if(blah && blah->root && dataname) - { - UserData *ud = _find_userdata(&(blah->root), dataname); - if(ud) - return ud->data; - } - return NULL; + WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER); + + if(blah && blah->root && dataname) + { + UserData *ud = _find_userdata(&(blah->root), dataname); + if(ud) + return ud->data; + } + return NULL; } /* @@ -9284,17 +11315,17 @@ */ int API dw_timer_connect(int interval, void *sigfunc, void *data) { - if(sigfunc) - { - int timerid = WinStartTimer(dwhab, NULLHANDLE, 0, interval); - - if(timerid) - { - _new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, data); - return timerid; - } - } - return 0; + if(sigfunc) + { + int timerid = WinStartTimer(dwhab, NULLHANDLE, 0, interval); + + if(timerid) + { + _new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, data); + return timerid; + } + } + return 0; } /* @@ -9304,37 +11335,37 @@ */ void API dw_timer_disconnect(int id) { - SignalHandler *prev = NULL, *tmp = Root; - - /* 0 is an invalid timer ID */ - if(!id) - return; - - WinStopTimer(dwhab, NULLHANDLE, id); - - while(tmp) - { - if(tmp->id == id) - { - if(prev) - { - prev->next = tmp->next; - free(tmp); - tmp = prev->next; - } - else - { - Root = tmp->next; - free(tmp); - tmp = Root; - } - } - else - { - prev = tmp; - tmp = tmp->next; - } - } + SignalHandler *prev = NULL, *tmp = Root; + + /* 0 is an invalid timer ID */ + if(!id) + return; + + WinStopTimer(dwhab, NULLHANDLE, id); + + while(tmp) + { + if(tmp->id == id) + { + if(prev) + { + prev->next = tmp->next; + free(tmp); + tmp = prev->next; + } + else + { + Root = tmp->next; + free(tmp); + tmp = Root; + } + } + else + { + prev = tmp; + tmp = tmp->next; + } + } } /* @@ -9347,36 +11378,33 @@ */ void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) { - ULONG message = 0, id = 0; - - if(window && signame && sigfunc) - { - if((message = _findsigmessage(signame)) != 0) - { - /* Handle special case of the menu item */ - if(message == WM_COMMAND && window < 65536) - { - char buffer[15]; - HWND owner; - - sprintf(buffer, "_dw_id%d", (int)window); - owner = (HWND)dw_window_get_data(hwndApp, buffer); - - if(owner) - { - id = window; - window = owner; - dw_window_set_data(hwndApp, buffer, 0); - } - else - { - /* If it is a popup menu clear all entries */ - dw_signal_disconnect_by_window(window); - } - } - _new_signal(message, window, id, sigfunc, data); - } - } + ULONG message = 0, id = 0; + + if(window && signame && sigfunc) + { + if((message = _findsigmessage(signame)) != 0) + { + /* Handle special case of the menu item */ + if(message == WM_COMMAND && window < 65536) + { + char buffer[15]; + HWND owner; + + sprintf(buffer, "_dw_id%d", (int)window); + owner = (HWND)dw_window_get_data(hwndApp, buffer); + + /* Make sure there are no dupes from popups */ + dw_signal_disconnect_by_window(window); + + if(owner) + { + id = window; + window = owner; + } + } + _new_signal(message, window, id, sigfunc, data); + } + } } /* @@ -9386,35 +11414,35 @@ */ void API dw_signal_disconnect_by_name(HWND window, char *signame) { - SignalHandler *prev = NULL, *tmp = Root; - ULONG message; - - if(!window || !signame || (message = _findsigmessage(signame)) == 0) - return; - - while(tmp) - { - if(tmp->window == window && tmp->message == message) - { - if(prev) - { - prev->next = tmp->next; - free(tmp); - tmp = prev->next; - } - else - { - Root = tmp->next; - free(tmp); - tmp = Root; - } - } - else - { - prev = tmp; - tmp = tmp->next; - } - } + SignalHandler *prev = NULL, *tmp = Root; + ULONG message; + + if(!window || !signame || (message = _findsigmessage(signame)) == 0) + return; + + while(tmp) + { + if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->message == message) + { + if(prev) + { + prev->next = tmp->next; + free(tmp); + tmp = prev->next; + } + else + { + Root = tmp->next; + free(tmp); + tmp = Root; + } + } + else + { + prev = tmp; + tmp = tmp->next; + } + } } /* @@ -9424,31 +11452,31 @@ */ void API dw_signal_disconnect_by_window(HWND window) { - SignalHandler *prev = NULL, *tmp = Root; - - while(tmp) - { - if(tmp->window == window) - { - if(prev) - { - prev->next = tmp->next; - free(tmp); - tmp = prev->next; - } - else - { - Root = tmp->next; - free(tmp); - tmp = Root; - } - } - else - { - prev = tmp; - tmp = tmp->next; - } - } + SignalHandler *prev = NULL, *tmp = Root; + + while(tmp) + { + if((window < 65536 && tmp->id == window) || tmp->window == window) + { + if(prev) + { + prev->next = tmp->next; + free(tmp); + tmp = prev->next; + } + else + { + Root = tmp->next; + free(tmp); + tmp = Root; + } + } + else + { + prev = tmp; + tmp = tmp->next; + } + } } /* @@ -9459,31 +11487,99 @@ */ void API dw_signal_disconnect_by_data(HWND window, void *data) { - SignalHandler *prev = NULL, *tmp = Root; - - while(tmp) - { - if(tmp->window == window && tmp->data == data) - { - if(prev) - { - prev->next = tmp->next; - free(tmp); - tmp = prev->next; - } - else - { - Root = tmp->next; - free(tmp); - tmp = Root; - } - } - else - { - prev = tmp; - tmp = tmp->next; - } - } -} - - + SignalHandler *prev = NULL, *tmp = Root; + + while(tmp) + { + if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->data == data) + { + if(prev) + { + prev->next = tmp->next; + free(tmp); + tmp = prev->next; + } + else + { + Root = tmp->next; + free(tmp); + tmp = Root; + } + } + else + { + prev = tmp; + tmp = tmp->next; + } + } +} + +/* + * Create a new calendar window (widget) to be packed. + * Parameters: + * id: An ID to be used with dw_window_from_id() or 0L. + * Returns: + * Handle to the created calendar or NULL on error. + */ +HWND API dw_calendar_new(ULONG id) +{ + WindowData *blah = calloc(sizeof(WindowData), 1); + DATETIME dt; + HWND tmp = WinCreateWindow(HWND_OBJECT, + WC_STATIC, + NULL, + WS_VISIBLE | SS_TEXT, + 0,0,2000,1000, + NULLHANDLE, + HWND_TOP, + id, + NULL, + NULL); + blah->oldproc = WinSubclassWindow(tmp, _calendarproc); + WinSetWindowPtr(tmp, QWP_USER, blah); + dw_window_set_font(tmp, DefaultFont); + if(!DosGetDateTime(&dt)) + dw_calendar_set_date(tmp, dt.year, dt.month, dt.day); + return tmp; +} + +/* + * Sets the current date of a calendar. + * Parameters: + * handle: The handle to the calendar returned by dw_calendar_new(). + * year, month, day: To set the calendar to display. + */ +void API dw_calendar_set_date( HWND window, unsigned int year, unsigned int month, unsigned int day ) +{ + /* Need to be 0 based */ + if(year > 0) + year--; + if(month > 0) + month--; + if(day > 0) + day--; + + dw_window_set_data(window, "_dw_year", DW_INT_TO_POINTER(year)); + dw_window_set_data(window, "_dw_month", DW_INT_TO_POINTER(month)); + dw_window_set_data(window, "_dw_day", DW_INT_TO_POINTER(day)); + /* Make it redraw */ + WinPostMsg(window, WM_PAINT, 0, 0); +} + +/* + * Gets the year, month and day set in the calendar widget. + * Parameters: + * handle: The handle to the calendar returned by dw_calendar_new(). + * year: Variable to store the year or NULL. + * month: Variable to store the month or NULL. + * day: Variable to store the day or NULL. + */ +void API dw_calendar_get_date( HWND window, unsigned int *year, unsigned int *month, unsigned int *day ) +{ + if(year) + *year = DW_POINTER_TO_UINT(dw_window_get_data(window, "_dw_year")) + 1; + if(month) + *month = DW_POINTER_TO_UINT(dw_window_get_data(window, "_dw_month")) + 1; + if(day) + *day = DW_POINTER_TO_UINT(dw_window_get_data(window, "_dw_day")) + 1; +}
--- a/dw.h Fri Feb 18 02:50:18 2011 -0600 +++ b/dw.h Thu Nov 24 03:45:48 2011 -0600 @@ -1,13 +1,14 @@ -/* $Id: dw.h,v 1.1 2005/05/09 19:21:08 nuke Exp $ */ +/* $Id: dw.h 1377 2011-11-22 20:46:37Z bsmith $ */ #ifndef _H_DW #define _H_DW /* Dynamic Windows version numbers */ -#define DW_MAJOR_VERSION 0 -#define DW_MINOR_VERSION 9 +#define DW_MAJOR_VERSION 2 +#define DW_MINOR_VERSION 2 #define DW_SUB_VERSION 0 +#if !defined(__PHOTON__) /* These corespond to the entries in the color * arrays in the Win32 dw.c, they are also the * same as DOS ANSI colors. @@ -29,6 +30,7 @@ #define DW_CLR_CYAN 14 #define DW_CLR_WHITE 15 #define DW_CLR_DEFAULT 16 +#endif /* Signal handler defines */ #define DW_SIGNAL_CONFIGURE "configure_event" @@ -49,7 +51,20 @@ #define DW_SIGNAL_COLUMN_CLICK "click-column" #define DW_SIGNAL_TREE_EXPAND "tree-expand" -#if defined(__OS2__) || defined(__WIN32__) || defined(__MAC__) || defined(WINNT) || defined(__EMX__) +/* status of menu items */ +#define DW_MIS_ENABLED 1 +#define DW_MIS_DISABLED (1 << 1) +#define DW_MIS_CHECKED (1 << 2) +#define DW_MIS_UNCHECKED (1 << 3) + +/* ensure we can build the Gtk port with MingW on Windows */ +#if defined(DW_USE_GTK) && defined(__MINGW32__) +# ifndef GDK_WINDOWING_WIN32 +# define GDK_WINDOWING_WIN32 +# endif +#endif + +#if defined(__OS2__) || (defined(__WIN32__) && !defined(GDK_WINDOWING_WIN32)) || defined(__MAC__) || (defined(WINNT) && !defined(GDK_WINDOWING_WIN32)) || defined(__EMX__) /* OS/2, Windows or MacOS */ #if (defined(__IBMC__) || defined(_System)) && !defined(API) @@ -68,9 +83,9 @@ typedef struct _user_data { - struct _user_data *next; - void *data; - char *varname; + struct _user_data *next; + void *data; + char *varname; } UserData; /* OS/2 Specific section */ @@ -101,6 +116,7 @@ #define FCF_CLOSEBUTTON 0x04000000L #endif +#define DW_FCF_CLOSEBUTTON 0 #define DW_FCF_TITLEBAR FCF_TITLEBAR #define DW_FCF_SYSMENU (FCF_SYSMENU | FCF_CLOSEBUTTON) #define DW_FCF_MENU FCF_MENU @@ -147,6 +163,9 @@ #define DW_POINTER_DEFAULT 0 #define DW_POINTER_ARROW SPTR_ARROW #define DW_POINTER_CLOCK SPTR_WAIT +#define DW_POINTER_QUESTION SPTR_ICONQUESTION + +#define DW_BS_NOBORDER BS_NOBORDER #define DW_OS2_NEW_WINDOW 1 @@ -204,19 +223,20 @@ #define VK_RMENU VK_MENU typedef struct _window_data { - PFNWP oldproc; - UserData *root; - HWND clickdefault; - ULONG flags; - void *data; + PFNWP oldproc; + UserData *root; + HWND clickdefault; + ULONG flags; + void *data; } WindowData; typedef struct _hpixmap { - unsigned long width, height; - HDC hdc; - HPS hps; - HBITMAP hbm; - HWND handle; + unsigned long width, height; + HDC hdc; + HPS hps; + HBITMAP hbm; + HWND handle, font; + unsigned long transcolor; } *HPIXMAP; typedef void *HTREEITEM; @@ -224,6 +244,7 @@ typedef HMODULE HMOD; typedef unsigned short UWORD; typedef unsigned long HSHM; +typedef unsigned long HICN; extern HAB dwhab; extern HMQ dwhmq; @@ -231,10 +252,21 @@ #if defined(__MAC__) /* MacOS specific section */ -#include <Carbon/Carbon.h> +#include <pthread.h> +#include <dlfcn.h> -typedef ControlRef HWND; -typedef ThreadID DWTID; +/* Unfortunately using Cocoa we can't include + * Cocoa.h from C code, so we have to instead + * use opaque types and use the values from + * Cocoa.h in the header here directly without + * using the symbolic names. + */ + +#define TRUE 1 +#define FALSE 0 + +typedef void *HWND; +typedef void *HSHM; typedef unsigned long ULONG; typedef long LONG; typedef unsigned short USHORT; @@ -245,44 +277,65 @@ typedef char CHAR; typedef unsigned UINT; typedef int INT; -typedef void *HMTX; -typedef void *HEV; -typedef void *HSHM; -typedef void *HMOD; -typedef void *HPIXMAP; +typedef pthread_mutex_t *HMTX; +typedef struct _dw_unix_event { + pthread_mutex_t mutex; + pthread_cond_t event; + pthread_t thread; + int alive; + int posted; +} *HEV; +typedef pthread_t DWTID; +typedef void * HMOD; +struct _dw_unix_shm { + int fd; + char *path; + int sid; + int size; +}; typedef void *HTREEITEM; -typedef MenuRef HMENUI; +typedef void *HMENUI; +typedef void *HICN; typedef struct _window_data { - UserData *root; - HWND clickdefault; - ULONG flags; - void *data; + UserData *root; + HWND clickdefault; + ULONG flags; + void *data; } WindowData; -#define DW_DT_LEFT 0 +typedef struct _hpixmap { + unsigned long width, height; + void *image, *font; + HWND handle; +} *HPIXMAP; + +void _dw_pool_drain(void); + +#define DW_DT_LEFT 0 /* NSLeftTextAlignment */ #define DW_DT_QUERYEXTENT 0 #define DW_DT_UNDERSCORE 0 #define DW_DT_STRIKEOUT 0 #define DW_DT_TEXTATTRS 0 #define DW_DT_EXTERNALLEADING 0 -#define DW_DT_CENTER 0 -#define DW_DT_RIGHT 0 +#define DW_DT_CENTER 2 /* NSCenterTextAlignment */ +#define DW_DT_RIGHT 1 /* NSRightTextAlignment */ #define DW_DT_TOP 0 -#define DW_DT_VCENTER 0 +#define DW_DT_VCENTER (1 << 10) #define DW_DT_BOTTOM 0 #define DW_DT_HALFTONE 0 #define DW_DT_MNEMONIC 0 #define DW_DT_WORDBREAK 0 #define DW_DT_ERASERECT 0 -#define DW_FCF_TITLEBAR 0 -#define DW_FCF_SYSMENU kWindowCloseBoxAttribute +#define DW_FCF_CLOSEBUTTON (1 << 1) /* NSClosableWindowMask */ +#define DW_FCF_TITLEBAR (1 << 0) /* NSTitledWindowMask */ +#define DW_FCF_SYSMENU (1 << 1) /* NSClosableWindowMask */ #define DW_FCF_MENU 0 -#define DW_FCF_SIZEBORDER (kWindowResizableAttribute|kWindowLiveResizeAttribute) -#define DW_FCF_MINBUTTON kWindowCollapseBoxAttribute -#define DW_FCF_MAXBUTTON kWindowFullZoomAttribute -#define DW_FCF_MINMAX (kWindowCollapseBoxAttribute|kWindowFullZoomAttribute) +#define DW_FCF_SIZEBORDER (1 << 3) /* NSResizableWindowMask */ +#define DW_FCF_MINBUTTON (1 << 2) /* NSMiniaturizableWindowMask */ +#define DW_FCF_MAXBUTTON 0 +#define DW_FCF_MINMAX (1 << 2) /* NSMiniaturizableWindowMask */ #define DW_FCF_VERTSCROLL 0 #define DW_FCF_HORZSCROLL 0 #define DW_FCF_DLGBORDER 0 @@ -292,7 +345,7 @@ #define DW_FCF_NOBYTEALIGN 0 #define DW_FCF_NOMOVEWITHOWNER 0 #define DW_FCF_SYSMODAL 0 -#define DW_FCF_HIDEBUTTON kWindowCollapseAttribute +#define DW_FCF_HIDEBUTTON 0 #define DW_FCF_HIDEMAX 0 #define DW_FCF_AUTOICON 0 #define DW_FCF_MAXIMIZE 0 @@ -317,13 +370,16 @@ #define DW_LIT_NONE -1 -#define DW_MLE_CASESENSITIVE MLFSEARCH_CASESENSITIVE +#define DW_MLE_CASESENSITIVE 2 /* NSLiteralSearch */ + +#define DW_BS_NOBORDER 1 #define DW_POINTER_DEFAULT 0 -#define DW_POINTER_ARROW 0 -#define DW_POINTER_CLOCK watchCursor +#define DW_POINTER_ARROW 1 +#define DW_POINTER_CLOCK 2 +#define DW_POINTER_QUESTION 3 -#define HWND_DESKTOP ((HWND)0) +#define HWND_DESKTOP ((HWND)0) /* flag values for dw_messagebox() */ #define DW_MB_OK (1 << 1) @@ -336,7 +392,90 @@ #define DW_MB_INFORMATION (1 << 12) #define DW_MB_QUESTION (1 << 13) +/* Virtual Key Codes */ +#define VK_LBUTTON 0xFF10 /* TODO */ +#define VK_RBUTTON 0xFF11 /* TODO */ +#define VK_CANCEL 0xFF12 /* TODO */ +#define VK_MBUTTON 0xFF13 /* TODO */ +#define VK_BACK 0x7F +#define VK_TAB 0x09 +#define VK_CLEAR 71 +#define VK_RETURN 13 +#define VK_MENU 0xF735 /* NSMenuFunctionKey */ +#define VK_PAUSE 0xF730 /* NSPauseFunctionKey */ +#define VK_CAPITAL 57 +#define VK_ESCAPE 0x1B +#define VK_SPACE ' ' +#define VK_PRIOR 0xF72C /* NSPageUpFunctionKey */ +#define VK_NEXT 0xF72D /* NSPageDownFunctionKey */ +#define VK_END 0xF72B /* NSEndFunctionKey */ +#define VK_HOME 0xF729 /* NSHomeFunctionKey */ +#define VK_LEFT 0xF702 /* NSLeftArrowFunctionKey */ +#define VK_UP 0xF700 /* NSUpArrowFunctionKey */ +#define VK_RIGHT 0xF703 /* NSRightArrowFunctionKey */ +#define VK_DOWN 0xF701 /* NSDownArrowFunctionKey */ +#define VK_SELECT 0xF741 /* NSSelectFunctionKey */ +#define VK_PRINT 0xF738 /* NSPrintFunctionKey */ +#define VK_EXECUTE 0xF742 /* NSExecuteFunctionKey */ +#define VK_SNAPSHOT 0xF72E /* NSPrintScreenFunctionKey */ +#define VK_INSERT 0xF727 /* NSInsertFunctionKey */ +#define VK_DELETE 0xF728 /* NSDeleteFunctionKey */ +#define VK_HELP 0xF746 /* NSHelpFunctionKey */ +#define VK_LWIN 55 +#define VK_RWIN 0xFF14 /* TODO */ +#define VK_NUMPAD0 82 +#define VK_NUMPAD1 83 +#define VK_NUMPAD2 84 +#define VK_NUMPAD3 85 +#define VK_NUMPAD4 86 +#define VK_NUMPAD5 87 +#define VK_NUMPAD6 88 +#define VK_NUMPAD7 89 +#define VK_NUMPAD8 91 +#define VK_NUMPAD9 92 +#define VK_MULTIPLY 67 +#define VK_ADD 69 +#define VK_SEPARATOR 0xFF15 /* TODO */ +#define VK_SUBTRACT 78 +#define VK_DECIMAL 65 +#define VK_DIVIDE 75 +#define VK_F1 0xF704 /* NSF1FunctionKey */ +#define VK_F2 0xF705 /* NSF2FunctionKey */ +#define VK_F3 0xF706 /* NSF3FunctionKey */ +#define VK_F4 0xF707 /* NSF4FunctionKey */ +#define VK_F5 0xF708 /* NSF5FunctionKey */ +#define VK_F6 0xF709 /* NSF6FunctionKey */ +#define VK_F7 0xF70A /* NSF7FunctionKey */ +#define VK_F8 0xF70B /* NSF8FunctionKey */ +#define VK_F9 0xF70C /* NSF9FunctionKey */ +#define VK_F10 0xF70D /* NSF10FunctionKey */ +#define VK_F11 0xF70E /* NSF11FunctionKey */ +#define VK_F12 0xF70F /* NSF12FunctionKey */ +#define VK_F13 0xF710 /* NSF13FunctionKey */ +#define VK_F14 0xF711 /* NSF14FunctionKey */ +#define VK_F15 0xF712 /* NSF15FunctionKey */ +#define VK_F16 0xF713 /* NSF16FunctionKey */ +#define VK_F17 0xF714 /* NSF17FunctionKey */ +#define VK_F18 0xF715 /* NSF18FunctionKey */ +#define VK_F19 0xF716 /* NSF19FunctionKey */ +#define VK_F20 0xF717 /* NSF20FunctionKey */ +#define VK_F21 0xF718 /* NSF21FunctionKey */ +#define VK_F22 0xF719 /* NSF22FunctionKey */ +#define VK_F23 0xF71A /* NSF23FunctionKey */ +#define VK_F24 0xF71B /* NSF24FunctionKey */ +#define VK_NUMLOCK 0xFF16 /* TODO */ +#define VK_SCROLL 0xF72F /* NSScrollLockFunctionKey */ +#define VK_LSHIFT 56 +#define VK_RSHIFT 60 +#define VK_LCONTROL 59 +#define VK_RCONTROL 62 +#define VK_LMENU 0xF735 /* NSMenuFunctionKey */ +#define VK_RMENU 0xF735 /* NSMenuFunctionKey */ +/* Key Modifiers */ +#define KC_CTRL (1 << 18) /* NSControlKeyMask */ +#define KC_SHIFT (1 << 17) /* NSShiftKeyMask */ +#define KC_ALT (1 << 19) /* NSAlternateKeyMask */ #endif /* Windows specific section */ @@ -372,6 +511,7 @@ #define DW_DT_WORDBREAK 0 #define DW_DT_ERASERECT 0 +#define DW_FCF_CLOSEBUTTON 0 #define DW_FCF_TITLEBAR WS_CAPTION #define DW_FCF_SYSMENU WS_SYSMENU #define DW_FCF_MENU 0 @@ -389,7 +529,7 @@ #define DW_FCF_NOMOVEWITHOWNER 0 #define DW_FCF_SYSMODAL 0 #define DW_FCF_HIDEBUTTON WS_MINIMIZEBOX -#define DW_FCF_HIDEMAX 0 +#define DW_FCF_HIDEMAX (WS_MINIMIZEBOX|WS_MAXIMIZEBOX) #define DW_FCF_AUTOICON 0 #define DW_FCF_MAXIMIZE WS_MAXIMIZE #define DW_FCF_MINIMIZE WS_MINIMIZE @@ -415,9 +555,12 @@ #define DW_MLE_CASESENSITIVE 1 +#define DW_BS_NOBORDER BS_FLAT + #define DW_POINTER_DEFAULT 0 #define DW_POINTER_ARROW 32512 #define DW_POINTER_CLOCK 32514 +#define DW_POINTER_QUESTION 32651 /* flag values for dw_messagebox() */ #define DW_MB_OK MB_OK @@ -447,120 +590,392 @@ #define ClassName "dynamicwindows" #define SplitbarClassName "dwsplitbar" #define ObjectClassName "dwobjectclass" +#define BrowserClassName "dwbrowserclass" +#define ScrollClassName "dwscrollclass" #define DefaultFont NULL typedef struct _color { - int fore; - int back; - HWND combo, buddy; - int user; - int vcenter; - HWND clickdefault; - HBRUSH hbrush; - HFONT hfont; - char fontname[128]; - WNDPROC pOldProc; - UserData *root; + int fore; + int back; + HWND combo, buddy; + int user; + int vcenter; + HWND clickdefault; + HBRUSH hbrush; + HFONT hfont; + char fontname[128]; + WNDPROC pOldProc; + UserData *root; } ColorInfo; typedef struct _notebookpage { - ColorInfo cinfo; - TC_ITEM item; - HWND hwnd; - int realid; + ColorInfo cinfo; + TC_ITEM item; + HWND hwnd; + int realid; } NotebookPage; typedef HANDLE HMTX; typedef HANDLE HEV; typedef HANDLE HMOD; typedef HANDLE HSHM; +typedef HANDLE HICN; typedef struct _container { - ColorInfo cinfo; - ULONG *flags; - WNDPROC pOldProc; - ULONG columns; + ColorInfo cinfo; + ULONG *flags; + ULONG columns; + COLORREF odd, even; } ContainerInfo; typedef struct _hpixmap { - unsigned long width, height; - HBITMAP hbm; - HDC hdc; - HWND handle; - void *bits; + unsigned long width, height; + HBITMAP hbm; + HDC hdc; + unsigned long transcolor; + HWND handle; + void *bits; + unsigned long depth; + HFONT font; } *HPIXMAP; typedef HWND HMENUI; #endif typedef struct _item { - /* Item type - Box or Item */ - int type; - /* Handle to Frame or Window */ - HWND hwnd; - /* Width and Height of static size */ - int width, height, origwidth, origheight; - /* Size Type - Static or Expand */ - int hsize, vsize; - /* Padding */ - int pad; - /* Ratio of current item */ - float xratio, yratio; + /* Item type - Box or Item */ + int type; + /* Handle to Frame or Window */ + HWND hwnd; + /* Width and Height of static size */ + int width, height, origwidth, origheight; + /* Size Type - Static or Expand */ + int hsize, vsize; + /* Padding */ + int pad; + /* Ratio of current item */ + float xratio, yratio; } Item; typedef struct _box { #if defined(__WIN32__) || defined(WINNT) - ColorInfo cinfo; + ColorInfo cinfo; #elif defined(__OS2__) || defined(__EMX__) - PFNWP oldproc; - UserData *root; - HWND hwndtitle, hwnd; - int titlebar; + PFNWP oldproc; + UserData *root; + HWND hwndtitle, hwnd; + int titlebar; #endif - /* Number of items in the box */ - int count; - /* Box type - horizontal or vertical */ - int type; - /* Padding */ - int pad, parentpad, grouppadx, grouppady; - /* Groupbox */ - HWND grouphwnd; - /* Default item */ - HWND defaultitem; - /* Used as temporary storage in the calculation stage */ - int upx, upy, minheight, minwidth; - /* Ratio in this box */ - float xratio, yratio, parentxratio, parentyratio; - /* Used for calculating individual item ratios */ - int width, height; - /* Any combinations of flags describing the box */ - unsigned long flags; - /* Array of item structures */ - struct _item *items; + /* Number of items in the box */ + int count; + /* Box type - horizontal or vertical */ + int type; + /* Padding */ + int pad, parentpad, grouppadx, grouppady; + /* Groupbox */ + HWND grouphwnd; + /* Default item */ + HWND defaultitem; + /* Used as temporary storage in the calculation stage */ + int upx, upy, minheight, minwidth; + /* Ratio in this box */ + float xratio, yratio, parentxratio, parentyratio; + /* Used for calculating individual item ratios */ + int width, height; + /* Any combinations of flags describing the box */ + unsigned long flags; + /* Array of item structures */ + struct _item *items; } Box; typedef struct _bubblebutton { #if defined(__WIN32__) || defined(WINNT) - ColorInfo cinfo; - int checkbox; - WNDPROC pOldProc; + ColorInfo cinfo; + int checkbox; + WNDPROC pOldProc; #endif #if defined(__OS2__) || defined(__EMX__) - PFNWP pOldProc; - UserData *root; + PFNWP pOldProc; + UserData *root; + unsigned long id; + char bubbletext[BUBBLE_HELP_MAX]; #endif - unsigned long id; - char bubbletext[BUBBLE_HELP_MAX]; } BubbleButton; +#elif defined(__PHOTON__) +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/utsname.h> +/* Photon specific section */ +#include <Pt.h> +#include <Ph.h> +/* which image formats supported */ +#define PX_IMAGE_MODULES +#define PX_GIF_SUPPORT +#define PX_JPG_SUPPORT +#define PX_BMP_SUPPORT +#define PX_PND_SUPPORT +#include <photon/PxImage.h> + +#define TRUE 1 +#define FALSE 0 + +typedef PtWidget_t *pPtWidget_t; +typedef pPtWidget_t HWND; + +typedef unsigned long ULONG; +typedef long LONG; +typedef unsigned short USHORT; +typedef short SHORT; +typedef unsigned short UWORD; +typedef short WORD ; +typedef unsigned char UCHAR; +typedef char CHAR; +typedef unsigned UINT; +typedef int INT; +typedef void *HMTX; +typedef void *HEV; +typedef void *HSHM; +typedef void *HMOD; +typedef PtTreeItem_t *HTREEITEM; +typedef HWND HMENUI; +typedef int DWTID; +typedef unsigned long HICN; + +typedef struct _user_data +{ + struct _user_data *next; + void *data; + char *varname; +} UserData; + +typedef struct _window_data { + UserData *root; + HWND clickdefault; + ULONG flags; + void *data; +} WindowData; + +typedef struct _hpixmap { + unsigned long width, height; + /* ?? *pixmap; */ + HWND handle; +} *HPIXMAP; + +/* colors matching Photon Graphics colors */ +#define DW_CLR_BLACK Pg_BLACK +#define DW_CLR_DARKRED Pg_DRED +#define DW_CLR_DARKGREEN Pg_DGREEN +#define DW_CLR_BROWN Pg_BROWN +#define DW_CLR_DARKBLUE Pg_DBLUE +#define DW_CLR_DARKPINK Pg_PURPLE +#define DW_CLR_DARKCYAN Pg_DCYAN +#define DW_CLR_PALEGRAY Pg_GRAY +#define DW_CLR_DARKGRAY Pg_MGRAY +#define DW_CLR_RED Pg_RED +#define DW_CLR_GREEN Pg_GREEN +#define DW_CLR_YELLOW Pg_YELLOW +#define DW_CLR_BLUE Pg_BLUE +#define DW_CLR_PINK Pg_MAGENTA +#define DW_CLR_CYAN Pg_CYAN +#define DW_CLR_WHITE Pg_WHITE +#define DW_CLR_DEFAULT Pg_GRAY +/* color manipulation macros */ +#define DW_RGB_COLOR (0xF0000000) +#define DW_RGB_TRANSPARENT (0x0F000000) +#define DW_RGB_MASK (0x00FFFFFF) +#define DW_RED_MASK (0x00FF0000) +#define DW_GREEN_MASK (0x0000FF00) +#define DW_BLUE_MASK (0x000000FF) +#define DW_RED_VALUE(a) PgRedValue(a) +#define DW_GREEN_VALUE(a) PgGreenValue(a) +#define DW_BLUE_VALUE(a) PgBluValue(a) +#define DW_RGB(a, b, c) PgRGB( a, b, c ) + +#define DW_DT_LEFT 0 +#define DW_DT_QUERYEXTENT 0 +#define DW_DT_UNDERSCORE 0 +#define DW_DT_STRIKEOUT 0 +#define DW_DT_TEXTATTRS 0 +#define DW_DT_EXTERNALLEADING 0 +#define DW_DT_CENTER 0 +#define DW_DT_RIGHT 0 +#define DW_DT_TOP 0 +#define DW_DT_VCENTER 0 +#define DW_DT_BOTTOM 0 +#define DW_DT_HALFTONE 0 +#define DW_DT_MNEMONIC 0 +#define DW_DT_WORDBREAK 0 +#define DW_DT_ERASERECT 0 + +#define DW_FCF_CLOSEBUTTON Ph_WM_RENDER_CLOSE +#define DW_FCF_TITLEBAR Ph_WM_RENDER_TITLE +#define DW_FCF_SYSMENU 0 +#define DW_FCF_MENU Ph_WM_RENDER_MENU +#define DW_FCF_SIZEBORDER Ph_WM_RENDER_RESIZE +#define DW_FCF_MINBUTTON Ph_WM_RENDER_MIN +#define DW_FCF_MAXBUTTON Ph_WM_RENDER_MAX +#define DW_FCF_MINMAX (Ph_WM_RENDER_MIN|Ph_WM_RENDER_MAX) +#define DW_FCF_VERTSCROLL 0 +#define DW_FCF_HORZSCROLL 0 +#define DW_FCF_DLGBORDER 0 +#define DW_FCF_BORDER Ph_WM_RENDER_BORDER +#define DW_FCF_SHELLPOSITION 0 +#define DW_FCF_TASKLIST 0 +#define DW_FCF_NOBYTEALIGN 0 +#define DW_FCF_NOMOVEWITHOWNER 0 +#define DW_FCF_SYSMODAL 0 +#define DW_FCF_HIDEBUTTON 0 +#define DW_FCF_HIDEMAX 0 +#define DW_FCF_AUTOICON (Ph_WM_RENDER_ASICON | ~Ph_WM_RENDER_ASAPP) +#define DW_FCF_MAXIMIZE 0 +#define DW_FCF_MINIMIZE 0 + +#define DW_CFA_BITMAPORICON 1 +#define DW_CFA_STRING (1 << 1) +#define DW_CFA_ULONG (1 << 2) +#define DW_CFA_TIME (1 << 3) +#define DW_CFA_DATE (1 << 4) +#define DW_CFA_CENTER (1 << 5) +#define DW_CFA_LEFT (1 << 6) +#define DW_CFA_RIGHT (1 << 7) +#define DW_CFA_STRINGANDICON (1 << 8) +#define DW_CFA_HORZSEPARATOR 0 +#define DW_CFA_SEPARATOR 0 + +#define DW_CRA_SELECTED 1 +#define DW_CRA_CURSORED (1 << 1) + +#define DW_LS_MULTIPLESEL 1 + +#define DW_LIT_NONE -1 + +#ifdef MLFSEARCH_CASESENSITIVE +# define DW_MLE_CASESENSITIVE MLFSEARCH_CASESENSITIVE +#else +# define DW_MLE_CASESENSITIVE 0 +#endif + +#define DW_BS_NOBORDER 1 + +#define DW_POINTER_DEFAULT 0 +#define DW_POINTER_ARROW 0 +#define DW_POINTER_CLOCK 0 +#define DW_POINTER_QUESTION 0 + +#define HWND_DESKTOP ((HWND)0) + +/* flag values for dw_messagebox() */ +#define DW_MB_OK (1 << 1) +#define DW_MB_OKCANCEL (1 << 2) +#define DW_MB_YESNO (1 << 3) +#define DW_MB_YESNOCANCEL (1 << 4) + +#define DW_MB_WARNING (1 << 10) +#define DW_MB_ERROR (1 << 11) +#define DW_MB_INFORMATION (1 << 12) +#define DW_MB_QUESTION (1 << 13) + +/* Virtual Key Codes */ +#define VK_LBUTTON 0 +#define VK_RBUTTON 0 +#define VK_CANCEL 0 +#define VK_MBUTTON 0 +#define VK_BACK 0 +#define VK_TAB 0 +#define VK_CLEAR 0 +#define VK_RETURN 0 +#define VK_MENU 0 +#define VK_PAUSE 0 +#define VK_CAPITAL 0 +#define VK_ESCAPE 0 +#define VK_SPACE 0 +#define VK_PRIOR 0 +#define VK_NEXT 0 +#define VK_END 0 +#define VK_HOME 0 +#define VK_LEFT 0 +#define VK_UP 0 +#define VK_RIGHT 0 +#define VK_DOWN 0 +#define VK_SELECT 0 +#define VK_PRINT 0 +#define VK_EXECUTE 0 +#define VK_SNAPSHOT 0 +#define VK_INSERT 0 +#define VK_DELETE 0 +#define VK_HELP 0 +#define VK_LWIN 0 +#define VK_RWIN 0 +#define VK_NUMPAD0 0 +#define VK_NUMPAD1 0 +#define VK_NUMPAD2 0 +#define VK_NUMPAD3 0 +#define VK_NUMPAD4 0 +#define VK_NUMPAD5 0 +#define VK_NUMPAD6 0 +#define VK_NUMPAD7 0 +#define VK_NUMPAD8 0 +#define VK_NUMPAD9 0 +#define VK_MULTIPLY 0 +#define VK_ADD 0 +#define VK_SEPARATOR 0 +#define VK_SUBTRACT 0 +#define VK_DECIMAL 0 +#define VK_DIVIDE 0 +#define VK_F1 0 +#define VK_F2 0 +#define VK_F3 0 +#define VK_F4 0 +#define VK_F5 0 +#define VK_F6 0 +#define VK_F7 0 +#define VK_F8 0 +#define VK_F9 0 +#define VK_F10 0 +#define VK_F11 0 +#define VK_F12 0 +#define VK_F13 0 +#define VK_F14 0 +#define VK_F15 0 +#define VK_F16 0 +#define VK_F17 0 +#define VK_F18 0 +#define VK_F19 0 +#define VK_F20 0 +#define VK_F21 0 +#define VK_F22 0 +#define VK_F23 0 +#define VK_F24 0 +#define VK_NUMLOCK 0 +#define VK_SCROLL 0 +#define VK_LSHIFT 0 +#define VK_RSHIFT 0 +#define VK_LCONTROL 0 +#define VK_RCONTROL 0 +#define VK_LMENU 0 +#define VK_RMENU 0 + +/* Key Modifiers */ +#define KC_CTRL (1) +#define KC_SHIFT (1 << 1) +#define KC_ALT (1 << 2) + #else /* GTK Specific section */ #include <gtk/gtk.h> -#include <gdk/gdkx.h> +#ifdef GDK_WINDOWING_X11 +# include <gdk/gdkx.h> +#else +# include <gdk/gdk.h> +#endif #include <gdk/gdkprivate.h> #include <gdk/gdkkeysyms.h> #include <pthread.h> -#include <dlfcn.h> +#if !defined(GDK_WINDOWING_WIN32) +# include <dlfcn.h> +#endif #define DW_DT_LEFT 1 #define DW_DT_UNDERSCORE (1 << 1) @@ -601,6 +1016,7 @@ #define DW_FCF_AUTOICON (1 << 18) #define DW_FCF_MAXIMIZE (1 << 19) #define DW_FCF_MINIMIZE (1 << 20) +#define DW_FCF_CLOSEBUTTON (1 << 21) #define DW_CFA_BITMAPORICON 1 #define DW_CFA_STRING (1 << 1) @@ -623,9 +1039,12 @@ #define DW_MLE_CASESENSITIVE 1 +#define DW_BS_NOBORDER 1 + #define DW_POINTER_DEFAULT 0 #define DW_POINTER_ARROW GDK_TOP_LEFT_ARROW #define DW_POINTER_CLOCK GDK_WATCH +#define DW_POINTER_QUESTION GDK_QUESTION_ARROW #define HWND_DESKTOP ((HWND)0) @@ -641,6 +1060,87 @@ #define DW_MB_QUESTION (1 << 13) /* Virtual Key Codes */ +#if GTK_MAJOR_VERSION > 2 +#define VK_LBUTTON GDK_KEY_Pointer_Button1 +#define VK_RBUTTON GDK_KEY_Pointer_Button3 +#define VK_CANCEL GDK_KEY_Cancel +#define VK_MBUTTON GDK_KEY_Pointer_Button2 +#define VK_BACK GDK_KEY_BackSpace +#define VK_TAB GDK_KEY_Tab +#define VK_CLEAR GDK_KEY_Clear +#define VK_RETURN GDK_KEY_Return +#define VK_MENU GDK_KEY_Menu +#define VK_PAUSE GDK_KEY_Pause +#define VK_CAPITAL GDK_KEY_Caps_Lock +#define VK_ESCAPE GDK_KEY_Escape +#define VK_SPACE GDK_KEY_space +#define VK_PRIOR GDK_KEY_Page_Up +#define VK_NEXT GDK_KEY_Page_Down +#define VK_END GDK_KEY_End +#define VK_HOME GDK_KEY_Home +#define VK_LEFT GDK_KEY_Left +#define VK_UP GDK_KEY_Up +#define VK_RIGHT GDK_KEY_Right +#define VK_DOWN GDK_KEY_Down +#define VK_SELECT GDK_KEY_Select +#define VK_PRINT GDK_KEY_Sys_Req +#define VK_EXECUTE GDK_KEY_Execute +#define VK_SNAPSHOT GDK_KEY_Print +#define VK_INSERT GDK_KEY_Insert +#define VK_DELETE GDK_KEY_Delete +#define VK_HELP GDK_KEY_Help +#define VK_LWIN GDK_KEY_Super_L +#define VK_RWIN GDK_KEY_Super_R +#define VK_NUMPAD0 GDK_KEY_KP_0 +#define VK_NUMPAD1 GDK_KEY_KP_1 +#define VK_NUMPAD2 GDK_KEY_KP_2 +#define VK_NUMPAD3 GDK_KEY_KP_3 +#define VK_NUMPAD4 GDK_KEY_KP_4 +#define VK_NUMPAD5 GDK_KEY_KP_5 +#define VK_NUMPAD6 GDK_KEY_KP_6 +#define VK_NUMPAD7 GDK_KEY_KP_7 +#define VK_NUMPAD8 GDK_KEY_KP_8 +#define VK_NUMPAD9 GDK_KEY_KP_9 +#define VK_MULTIPLY GDK_KEY_KP_Multiply +#define VK_ADD GDK_KEY_KP_Add +#define VK_SEPARATOR GDK_KEY_KP_Separator +#define VK_SUBTRACT GDK_KEY_KP_Subtract +#define VK_DECIMAL GDK_KEY_KP_Decimal +#define VK_DIVIDE GDK_KEY_KP_Divide +#define VK_F1 GDK_KEY_F1 +#define VK_F2 GDK_KEY_F2 +#define VK_F3 GDK_KEY_F3 +#define VK_F4 GDK_KEY_F4 +#define VK_F5 GDK_KEY_F5 +#define VK_F6 GDK_KEY_F6 +#define VK_F7 GDK_KEY_F7 +#define VK_F8 GDK_KEY_F8 +#define VK_F9 GDK_KEY_F9 +#define VK_F10 GDK_KEY_F10 +#define VK_F11 GDK_KEY_F11 +#define VK_F12 GDK_KEY_F12 +#define VK_F13 GDK_KEY_F13 +#define VK_F14 GDK_KEY_F14 +#define VK_F15 GDK_KEY_F15 +#define VK_F16 GDK_KEY_F16 +#define VK_F17 GDK_KEY_F17 +#define VK_F18 GDK_KEY_F18 +#define VK_F19 GDK_KEY_F19 +#define VK_F20 GDK_KEY_F20 +#define VK_F21 GDK_KEY_F21 +#define VK_F22 GDK_KEY_F22 +#define VK_F23 GDK_KEY_F23 +#define VK_F24 GDK_KEY_F24 +#define VK_NUMLOCK GDK_KEY_Num_Lock +#define VK_SCROLL GDK_KEY_Scroll_Lock +#define VK_LSHIFT GDK_KEY_Shift_L +#define VK_RSHIFT GDK_KEY_Shift_R +#define VK_LCONTROL GDK_KEY_Control_L +#define VK_RCONTROL GDK_KEY_Control_R +#define VK_LMENU GDK_KEY_Menu +#define VK_RMENU GDK_KEY_Menu + +#else #define VK_LBUTTON GDK_Pointer_Button1 #define VK_RBUTTON GDK_Pointer_Button3 #define VK_CANCEL GDK_Cancel @@ -719,6 +1219,7 @@ #define VK_RCONTROL GDK_Control_R #define VK_LMENU GDK_Menu #define VK_RMENU GDK_Menu +#endif /* Key Modifiers */ #define KC_CTRL GDK_CONTROL_MASK @@ -740,34 +1241,45 @@ typedef int INT; typedef pthread_mutex_t *HMTX; typedef struct _dw_unix_event { - pthread_mutex_t mutex; - pthread_cond_t event; - pthread_t thread; - int alive; - int posted; + pthread_mutex_t mutex; + pthread_cond_t event; + pthread_t thread; + int alive; + int posted; } *HEV; typedef pthread_t DWTID; typedef void * HMOD; struct _dw_unix_shm { - int fd; - char *path; - int sid; - int size; + int fd; + char *path; + int sid; + int size; }; typedef struct _hpixmap { - unsigned long width, height; - GdkPixmap *pixmap; - HWND handle; + unsigned long width, height; + HWND handle; + char *font; +#if GTK_MAJOR_VERSION > 1 + GdkPixbuf *pixbuf; /* the actual image */ +#endif +#if GTK_MAJOR_VERSION > 2 + cairo_surface_t *image; /* Going to have dual storage for now */ +#else + GdkPixmap *pixmap; /* the actual image */ + GdkBitmap *bitmap; /* if not null, the image mask representing the transparency mask */ + void *image; /* Opaque handle to a cairo_surface_t for printing */ +#endif } *HPIXMAP; typedef GtkWidget *HMENUI; typedef void *HTREEITEM; typedef void *HSHM; +typedef void *HICN; typedef struct _resource_struct { - long resource_max, *resource_id; - char **resource_data; + long resource_max, *resource_id; + char **resource_data; } DWResources; #if !defined(DW_RESOURCES) || defined(BUILD_DLL) @@ -781,48 +1293,50 @@ #if !defined(__OS2__) && !defined(__EMX__) typedef struct _CDATE { - UCHAR day; - UCHAR month; - USHORT year; + UCHAR day; + UCHAR month; + USHORT year; } CDATE; typedef CDATE *PCDATE; typedef struct _CTIME { - UCHAR hours; - UCHAR minutes; - UCHAR seconds; - UCHAR ucReserved; + UCHAR hours; + UCHAR minutes; + UCHAR seconds; + UCHAR ucReserved; } CTIME; typedef CTIME *PCTIME; #endif -#if defined(__OS2__) || defined(__WIN32__) || defined(WINNT) || defined(__EMX__) +#if defined(__OS2__) || (defined(__WIN32__) && !defined(GDK_WINDOWING_WIN32)) || (defined(WINNT) && !defined(GDK_WINDOWING_WIN32)) || defined(__EMX__) typedef unsigned long DWTID; #endif typedef struct _dwenv { - /* Operating System Name and DW Build Date/Time */ - char osName[30], buildDate[30], buildTime[30]; - /* Versions and builds */ - short MajorVersion, MinorVersion, MajorBuild, MinorBuild; - /* Dynamic Window version */ - short DWMajorVersion, DWMinorVersion, DWSubVersion; + /* Operating System Name and DW Build Date/Time */ + char osName[30], buildDate[30], buildTime[30]; + /* Versions and builds */ + short MajorVersion, MinorVersion, MajorBuild, MinorBuild; + /* Dynamic Window version */ + short DWMajorVersion, DWMinorVersion, DWSubVersion; } DWEnv; typedef struct _dwexpose { - int x, y; - int width, height; + int x, y; + int width, height; } DWExpose; typedef struct _dwdialog { - HEV eve; - int done; - int method; - void *data, *result; + HEV eve; + int done; + int method; + void *data, *result; } DWDialog; +typedef void *HPRINT; + #define DW_SIGNAL_FUNC(a) ((void *)a) #define DW_DESKTOP HWND_DESKTOP @@ -842,6 +1356,8 @@ #define DW_HORZ 0 #define DW_VERT 1 +#define DW_TIMEOUT_INFINITE ((unsigned long)-1) + /* Obsolete, should disappear sometime */ #define BOXHORZ DW_HORZ #define BOXVERT DW_VERT @@ -860,6 +1376,7 @@ #define DW_PIXMAP_WIDTH(x) (x ? x->width : 0) #define DW_PIXMAP_HEIGHT(x) (x ? x->height : 0) +#if !defined(__PHOTON__) #define DW_RGB_COLOR (0xF0000000) #define DW_RGB_TRANSPARENT (0x0F000000) #define DW_RGB_MASK (0x00FFFFFF) @@ -869,10 +1386,15 @@ #define DW_RED_VALUE(a) (a & DW_RED_MASK) #define DW_GREEN_VALUE(a) ((a & DW_GREEN_MASK) >> 8) #define DW_BLUE_VALUE(a) ((a & DW_BLUE_MASK) >> 16) -#define DW_RGB(a, b, c) (0xF0000000 | a | b << 8 | c << 16) +#define DW_RGB(a, b, c) (0xF0000000 | (a) | (b) << 8 | (c) << 16) +#endif #define DW_MENU_SEPARATOR "" #define DW_NOMENU 0 +#define DW_MENU_AUTO 0 +#define DW_MENU_POPUP (unsigned long)-1 + +#define DW_PERCENT_INDETERMINATE ((unsigned int)-1) /* Return value error codes */ #define DW_ERROR_NONE 0 @@ -881,6 +1403,39 @@ #define DW_ERROR_NON_INIT 3 #define DW_ERROR_NO_MEM 4 #define DW_ERROR_INTERRUPT 5 +#define DW_ERROR_UNKNOWN -1 + +/* Embedded HTML actions */ +#define DW_HTML_GOBACK 0 +#define DW_HTML_GOFORWARD 1 +#define DW_HTML_GOHOME 2 +#define DW_HTML_SEARCH 3 +#define DW_HTML_RELOAD 4 +#define DW_HTML_STOP 5 +#define DW_HTML_PRINT 6 + +/* Drawing flags... used for Arc currently */ +#define DW_DRAW_DEFAULT 0 +#define DW_DRAW_FILL 1 +#define DW_DRAW_FULL (1 << 1) + + +/* Macro for casting resource IDs to HICN */ +#define DW_RESOURCE(a) (a < 65536 ? (HICN)a : (HICN)0) + +#include <limits.h> +/* Macros for converting from INT/UINT to and from POINTER without compiler warnings */ +#if LONG_MAX > INT_MAX +#define DW_INT_TO_POINTER(a) ((void *)(long)a) +#define DW_POINTER_TO_INT(a) ((int)(long)a) +#define DW_UINT_TO_POINTER(a) ((void *)(unsigned long)a) +#define DW_POINTER_TO_UINT(a) ((unsigned int)(unsigned long)a) +#else +#define DW_INT_TO_POINTER(a) ((void *)a) +#define DW_POINTER_TO_INT(a) ((int)a) +#define DW_UINT_TO_POINTER(a) ((void *)a) +#define DW_POINTER_TO_UINT(a) ((unsigned int)a) +#endif #ifndef API #define API @@ -905,6 +1460,7 @@ /* Public function prototypes */ void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad); void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad); +void API dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad); #if !defined(__OS2__) && !defined(__WIN32__) && !defined(__EMX__) && !defined(__MAC__) int API dw_int_init(DWResources *res, int newthread, int *argc, char **argv[]); #define dw_init(a, b, c) dw_int_init(&_resources, a, &b, &c) @@ -923,14 +1479,19 @@ int API dw_window_destroy(HWND handle); void API dw_window_redraw(HWND handle); int API dw_window_set_font(HWND handle, char *fontname); +char * API dw_window_get_font(HWND handle); int API dw_window_set_color(HWND handle, unsigned long fore, unsigned long back); HWND API dw_window_new(HWND hwndOwner, char *title, unsigned long flStyle); HWND API dw_box_new(int type, int pad); +HWND API dw_scrollbox_new(int type, int pad); +int API dw_scrollbox_get_pos( HWND handle, int orient ); +int API dw_scrollbox_get_range( HWND handle, int orient ); HWND API dw_groupbox_new(int type, int pad, char *title); HWND API dw_mdi_new(unsigned long id); HWND API dw_bitmap_new(unsigned long id); HWND API dw_bitmapbutton_new(char *text, unsigned long id); HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename); +HWND API dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *str, int len); HWND API dw_container_new(unsigned long id, int multi); HWND API dw_tree_new(unsigned long id); HWND API dw_text_new(char *text, unsigned long id); @@ -948,6 +1509,7 @@ HWND API dw_checkbox_new(char *text, unsigned long id); HWND API dw_listbox_new(unsigned long id, int multi); void API dw_listbox_append(HWND handle, char *text); +void API dw_listbox_insert(HWND handle, char *text, int pos); void API dw_listbox_list_append(HWND handle, char **text, int count); void API dw_listbox_clear(HWND handle); int API dw_listbox_count(HWND handle); @@ -956,7 +1518,7 @@ void API dw_listbox_delete(HWND handle, int index); void API dw_listbox_get_text(HWND handle, unsigned int index, char *buffer, unsigned int length); void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer); -unsigned int API dw_listbox_selected(HWND handle); +int API dw_listbox_selected(HWND handle); int API dw_listbox_selected_multi(HWND handle, int where); void API dw_percent_set_pos(HWND handle, unsigned int position); unsigned int API dw_slider_get_pos(HWND handle); @@ -964,13 +1526,14 @@ unsigned int API dw_scrollbar_get_pos(HWND handle); void API dw_scrollbar_set_pos(HWND handle, unsigned int position); void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible); -void API dw_window_set_pos(HWND handle, unsigned long x, unsigned long y); +void API dw_window_set_pos(HWND handle, long x, long y); void API dw_window_set_size(HWND handle, unsigned long width, unsigned long height); -void API dw_window_set_pos_size(HWND handle, unsigned long x, unsigned long y, unsigned long width, unsigned long height); -void API dw_window_get_pos_size(HWND handle, unsigned long *x, unsigned long *y, unsigned long *width, unsigned long *height); +void API dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height); +void API dw_window_get_pos_size(HWND handle, long *x, long *y, unsigned long *width, unsigned long *height); void API dw_window_set_style(HWND handle, unsigned long style, unsigned long mask); -void API dw_window_set_icon(HWND handle, unsigned long id); +void API dw_window_set_icon(HWND handle, HICN icon); void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename); +void API dw_window_set_bitmap_from_data(HWND handle, unsigned long id, char *data, int len); char * API dw_window_get_text(HWND handle); void API dw_window_set_text(HWND handle, char *text); int API dw_window_set_border(HWND handle, int border); @@ -1000,11 +1563,11 @@ long API dw_spinbutton_get_pos(HWND handle); int API dw_checkbox_get(HWND handle); void API dw_checkbox_set(HWND handle, int value); -HTREEITEM API dw_tree_insert(HWND handle, char *title, unsigned long icon, HTREEITEM parent, void *itemdata); -HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, unsigned long icon, HTREEITEM parent, void *itemdata); +HTREEITEM API dw_tree_insert(HWND handle, char *title, HICN icon, HTREEITEM parent, void *itemdata); +HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, HICN icon, HTREEITEM parent, void *itemdata); void API dw_tree_clear(HWND handle); void API dw_tree_item_delete(HWND handle, HTREEITEM item); -void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, unsigned long icon); +void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon); void API dw_tree_item_expand(HWND handle, HTREEITEM item); void API dw_tree_item_collapse(HWND handle, HTREEITEM item); void API dw_tree_item_select(HWND handle, HTREEITEM item); @@ -1013,14 +1576,18 @@ char * API dw_tree_get_title(HWND handle, HTREEITEM item); HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item); int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator); -unsigned long API dw_icon_load(unsigned long module, unsigned long id); -unsigned long API dw_icon_load_from_file(char *filename); -void API dw_icon_free(unsigned long handle); +HICN API dw_icon_load(unsigned long module, unsigned long id); +HICN API dw_icon_load_from_file(char *filename); +HICN API dw_icon_load_from_data(char *data, int len); +void API dw_icon_free(HICN handle); void * API dw_container_alloc(HWND handle, int rowcount); void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data); void API dw_container_change_item(HWND handle, int column, int row, void *data); void API dw_container_set_column_width(HWND handle, int column, int width); void API dw_container_set_row_title(void *pointer, int row, char *title); +void API dw_container_change_row_title(HWND handle, int row, char *title); +#define dw_container_set_row_data(a, b, c) dw_container_set_row_title(a, b, (char *)c) +#define dw_container_change_row_data(a, b, c) dw_container_change_row_title(a, b, (char *)c) void API dw_container_insert(HWND handle, void *pointer, int rowcount); void API dw_container_clear(HWND handle, int redraw); void API dw_container_delete(HWND handle, int rowcount); @@ -1030,15 +1597,16 @@ void API dw_container_cursor(HWND handle, char *text); void API dw_container_delete_row(HWND handle, char *text); void API dw_container_optimize(HWND handle); +void API dw_container_set_stripe(HWND handle, unsigned long oddcolor, unsigned long evencolor); int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count); void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data); -void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon); +void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, HICN icon); void API dw_filesystem_change_item(HWND handle, int column, int row, void *data); -void API dw_filesystem_change_file(HWND handle, int row, char *filename, unsigned long icon); +void API dw_filesystem_change_file(HWND handle, int row, char *filename, HICN icon); int API dw_container_get_column_type(HWND handle, int column); int API dw_filesystem_get_column_type(HWND handle, int column); -void API dw_taskbar_insert(HWND handle, unsigned long icon, char *bubbletext); -void API dw_taskbar_delete(HWND handle, unsigned long icon); +void API dw_taskbar_insert(HWND handle, HICN icon, char *bubbletext); +void API dw_taskbar_delete(HWND handle, HICN icon); int API dw_screen_width(void); int API dw_screen_height(void); unsigned long API dw_color_depth_get(void); @@ -1056,7 +1624,9 @@ HMENUI API dw_menu_new(unsigned long id); HMENUI API dw_menubar_new(HWND location); HWND API dw_menu_append_item(HMENUI menu, char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu); +int API dw_menu_delete_item(HMENUI menu, unsigned long id); void API dw_menu_item_set_check(HMENUI menu, unsigned long id, int check); +void API dw_menu_item_set_state( HMENUI menux, unsigned long id, unsigned long state); void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y); void API dw_menu_destroy(HMENUI *menu); void API dw_pointer_query_pos(long *x, long *y); @@ -1066,6 +1636,7 @@ HMTX API dw_mutex_new(void); void API dw_mutex_close(HMTX mutex); void API dw_mutex_lock(HMTX mutex); +int API dw_mutex_trylock(HMTX mutex); void API dw_mutex_unlock(HMTX mutex); HEV API dw_event_new(void); int API dw_event_reset(HEV eve); @@ -1080,18 +1651,27 @@ void API dw_color_foreground_set(unsigned long value); void API dw_color_background_set(unsigned long value); unsigned long API dw_color_choose(unsigned long value); +char * API dw_font_choose(char *currfont); void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y); void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2); void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height); +void API dw_draw_polygon(HWND handle, HPIXMAP pixmap, int fill, int npoints, int *x, int *y); +void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2); void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text); void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height); +void API dw_font_set_default(char *fontname); void API dw_flush(void); void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc); +int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight); HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth); HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename); +HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len); HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id); +void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color ); +int API dw_pixmap_set_font(HPIXMAP pixmap, char *fontname); void API dw_pixmap_destroy(HPIXMAP pixmap); void API dw_beep(int freq, int dur); +void API dw_debug(char *format, ...); int API dw_messagebox(char *title, int flags, char *format, ...); void API dw_environment_query(DWEnv *env); int API dw_exec(char *program, int type, char **params); @@ -1121,5 +1701,17 @@ HSHM API dw_named_memory_new(void **dest, int size, char *name); HSHM API dw_named_memory_get(void **dest, int size, char *name); int API dw_named_memory_free(HSHM handle, void *ptr); +void API dw_html_action(HWND hwnd, int action); +int API dw_html_raw(HWND hwnd, char *string); +int API dw_html_url(HWND hwnd, char *url); +HWND API dw_html_new(unsigned long id); +char * API dw_clipboard_get_text(void); +void API dw_clipboard_set_text( char *str, int len ); +HWND API dw_calendar_new(unsigned long id); +void API dw_calendar_set_date( HWND window, unsigned int year, unsigned int month, unsigned int day ); +void API dw_calendar_get_date( HWND window, unsigned int *year, unsigned int *month, unsigned int *day ); +HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata); +int API dw_print_run(HPRINT print, unsigned long flags); +void API dw_print_cancel(HPRINT print); #endif
--- a/filter_plug.h Fri Feb 18 02:50:18 2011 -0600 +++ b/filter_plug.h Thu Nov 24 03:45:48 2011 -0600 @@ -1,23 +1,42 @@ -#if __cplusplus +#ifndef PM123_FILTER_PLUG_H +#define PM123_FILTER_PLUG_H + +#include "format.h" + +#ifdef __cplusplus extern "C" { #endif -typedef struct { - int size; +#pragma pack(4) + +#define PARAMS_SIZE_1 24 /* size of the FILTER_PARAMS structure prior PM123 1.32 */ +#define PARAMS_SIZE_2 32 /* size of the FILTER_PARAMS structure since PM123 1.32 */ + +typedef struct _FILTER_PARAMS +{ + int size; - /* specify a function which the filter should use for output */ - int (* _System output_play_samples)(void *a, FORMAT_INFO *format, char *buf, int len, int posmarker); - void *a; /* only to be used with the precedent function */ - int audio_buffersize; + /* specify a function which the filter should use for output */ + int (DLLENTRYP output_play_samples)( void* a, FORMAT_INFO* format, char* buf, int len, int posmarker ); + void* a; /* only to be used with the precedent function */ + int audio_buffersize; + + /* error message function the filter plug-in should use */ + void (DLLENTRYP error_display)( char* ); - /* error message function the filter plug-in should use */ - void (* _System error_display)(char *); + /* info message function the filter plug-in should use */ + /* this information is always displayed to the user right away */ + void (DLLENTRYP info_display)( char* ); + + /* added since PM123 1.32 */ + int (DLLENTRYP pm123_getstring)( int index, int subindex, int bufsize, char* buf ); + void (DLLENTRYP pm123_control)( int index, void* param ); } FILTER_PARAMS; /* returns 0 -> ok */ -ULONG _System filter_init(void **f, FILTER_PARAMS *params); -BOOL _System filter_uninit(void *f); +ULONG DLLENTRY filter_init ( void** f, FILTER_PARAMS* params ); +BOOL DLLENTRY filter_uninit( void* f ); /* Notice it is the same parameters as output_play_samples() */ @@ -25,9 +44,11 @@ /* a filter plug-in or directly in an output plug-in */ /* BUT you will have to pass void *a from above to the next */ /* stage which will be either a filter or output */ -int _System filter_play_samples(void *f, FORMAT_INFO *format, char *buf,int len, int posmarker); +int DLLENTRY filter_play_samples( void* f, FORMAT_INFO* format, char* buf, int len, int posmarker ); +#pragma pack() -#if __cplusplus +#ifdef __cplusplus } #endif +#endif /* PM123_FILTER_PLUG_H */
--- a/format.h Fri Feb 18 02:50:18 2011 -0600 +++ b/format.h Thu Nov 24 03:45:48 2011 -0600 @@ -1,22 +1,47 @@ -/* AFAIK, all of those also have BitsPerSample as format specific */ -#define WAVE_FORMAT_PCM 0x0001 -#define WAVE_FORMAT_ADPCM 0x0002 -#define WAVE_FORMAT_ALAW 0x0006 -#define WAVE_FORMAT_MULAW 0x0007 -#define WAVE_FORMAT_OKI_ADPCM 0x0010 -#define WAVE_FORMAT_DIGISTD 0x0015 -#define WAVE_FORMAT_DIGIFIX 0x0016 -#define IBM_FORMAT_MULAW 0x0101 -#define IBM_FORMAT_ALAW 0x0102 -#define IBM_FORMAT_ADPCM 0x0103 +#ifndef PM123_FORMAT_H +#define PM123_FORMAT_H + +#include "config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(4) -typedef struct +#define WM_PLAYSTOP (WM_USER + 69) +#define WM_PLAYERROR (WM_USER + 100) +#define WM_SEEKSTOP (WM_USER + 666) +#define WM_METADATA (WM_USER + 42) +#define WM_CHANGEBR (WM_USER + 43) +#define WM_OUTPUT_OUTOFDATA (WM_USER + 667) +#define WM_PLUGIN_CONTROL (WM_USER + 668) /* Plugin notify message */ + +/* + * WM_PLUGIN_CONTROL + * LONGFROMMP(mp1) = notify code + * LONGFROMMP(mp2) = additional information + * + * Notify codes: +*/ + +#define PN_TEXTCHANGED 1 /* Display text changed */ + +#define WAVE_FORMAT_PCM 0x0001 + +typedef struct _FORMAT_INFO { int size; - int samplerate; int channels; int bits; - int format; // PCM = 1 + int format; /* WAVE_FORMAT_PCM = 1 */ + } FORMAT_INFO; +#pragma pack() + +#ifdef __cplusplus +} +#endif +#endif /* PM123_FORMAT_H */
--- a/nuclear.c Fri Feb 18 02:50:18 2011 -0600 +++ b/nuclear.c Thu Nov 24 03:45:48 2011 -0600 @@ -15,8 +15,11 @@ #include <stdio.h> #include <math.h> #include <stdlib.h> + +#include "config.h" #include "format.h" #include "decoder_plug.h" +#include "visual_plug.h" #include "plugin.h" #define FULL_CLEAR @@ -25,9 +28,9 @@ #define strcasecmp stricmp -PLUGIN_PROCS procs; -int (* _System specana_init)(int setnumsamples); -int (* _System specana_dobands)(float bands[]); +VISPLUGININIT plug; +static ULONG (DLLENTRYP decoderPlayingSamples)( FORMAT_INFO *info, char *buf, int len ); +static BOOL (DLLENTRYP decoderPlaying)( void ); void DiveInit(void); void DiveShutdown(void); @@ -70,7 +73,7 @@ HDC hdcClient; HPS hpsDive; -int _System plugin_query(PPLUGIN_QUERYPARAM param) +void DLLENTRY plugin_query(PPLUGIN_QUERYPARAM param) { param->type = PLUGIN_VISUAL; /* Identify the plugin as visual */ @@ -82,8 +85,6 @@ param->configurable = TRUE; /* Toggles plugin configurability via PM123 Properties dialog */ - - return 0; } /* Write the nuclear.ini file with all of the current settings */ @@ -321,7 +322,7 @@ /* Find the ideal number of bars (bands) for our analyzer */ while(bands < wantedsamples) { - bands = specana_init(z); + bands = init_bands(z); z++; if(z < 1 || z > 4097) { @@ -381,7 +382,7 @@ update_analyzer(handles); } -int _System plugin_configure(HWND hwnd, HMODULE module) +void DLLENTRY plugin_configure(HWND hwnd, HMODULE module) { HWND entrywindow, mainbox, vbox, cancelbutton, okbutton, buttonbox, applybutton, xbox, stext, winbox, groupbox, notebook, @@ -619,7 +620,7 @@ return 0; } -int _System plugin_deinit(int unload) +int DLLENTRY plugin_deinit(void) { if(usedive) DiveShutdown(); @@ -741,7 +742,7 @@ float scale; HPS hps = WinGetPS(hwnd); - max = specana_dobands(current); + max = do_bands(); if(boost) scale = (float)max/(cy*boostval); @@ -996,7 +997,7 @@ int z, max; float scale; - max = specana_dobands(current); + max = do_bands(); if(boost) scale = (float)max/(cy*boostval); @@ -1145,7 +1146,7 @@ break; case WM_TIMER: - if(procs.decoder_playing()) + if(decoderPlaying()) { if(usedive) DiveRender(hwnd); @@ -1224,7 +1225,7 @@ return WinDefWindowProc (hwnd, msg, mp1, mp2); } -HWND _System vis_init(PVISPLUGININIT initdata) +HWND DLLENTRY vis_init(PVISPLUGININIT initdata) { int z = 1, wantedsamples; SIZEL sizl; @@ -1258,9 +1259,9 @@ hwndPM123 = initdata->hwnd; /* Save copies of the function pointers for our use */ - memcpy(&procs, initdata->procs, sizeof(PLUGIN_PROCS)); - specana_init = initdata->procs->specana_init; - specana_dobands = initdata->procs->specana_dobands; + memcpy(&plug, initdata, sizeof( VISPLUGININIT)); + decoderPlayingSamples = initdata->procs->output_playing_samples; + decoderPlaying = initdata->procs->decoder_playing; cx = initdata->cx; cy = initdata->cy; @@ -1274,7 +1275,7 @@ /* Find the ideal number of bars (bands) for our analyzer */ while(bands < wantedsamples) { - bands = specana_init(z); + bands = init_bands(z); z++; if(z < 1 || z > 4097) {
--- a/output_plug.h Fri Feb 18 02:50:18 2011 -0600 +++ b/output_plug.h Thu Nov 24 03:45:48 2011 -0600 @@ -1,56 +1,94 @@ +#ifndef PM123_OUTPUT_PLUG_H +#define PM123_OUTPUT_PLUG_H -#define WM_PLAYERROR WM_USER+100 -#define WM_OUTPUT_OUTOFDATA WM_USER+667 +#include "format.h" +#include "decoder_plug.h" -ULONG _System output_init(void **a); -ULONG _System output_uninit(void *a); +#ifdef __cplusplus +extern "C" { +#endif -#define OUTPUT_OPEN 1 // may not be necessary! +#pragma pack(4) + +ULONG DLLENTRY output_init ( void** a ); +ULONG DLLENTRY output_uninit( void* a ); + +#define OUTPUT_OPEN 1 /* may not be necessary! */ #define OUTPUT_CLOSE 2 #define OUTPUT_VOLUME 3 #define OUTPUT_PAUSE 4 #define OUTPUT_SETUP 5 #define OUTPUT_TRASH_BUFFERS 6 -#define OUTPUT_NOBUFFERMODE 7 +#define OUTPUT_NOBUFFERMODE 7 /* obsolete, don't used anymore */ -typedef struct +#define OUTPUT_SIZE_1 76 /* size of the OUTPUT_PARAMS structure prior PM123 1.32 */ +#define OUTPUT_SIZE_2 80 /* size of the OUTPUT_PARAMS structure since PM123 1.32 */ +#define OUTPUT_SIZE_3 84 /* size of the OUTPUT_PARAMS structure since PM123 1.33 */ + +typedef struct _OUTPUT_PARAMS { - int size; + /* --- see OUTPUT_SIZE definitions */ + int size; /* --- OUTPUT_SETUP */ - FORMAT_INFO formatinfo; + FORMAT_INFO formatinfo; - int buffersize; + int buffersize; + + unsigned short boostclass, normalclass; + signed short boostdelta, normaldelta; - unsigned short boostclass, normalclass; - signed short boostdelta, normaldelta; + void (DLLENTRYP error_display)( char* ); - void (* _System error_display)(char *); + /* info message function the output plug-in should use */ + /* this information is always displayed to the user right away */ + void (DLLENTRYP info_display)( char* ); - HWND hwnd; // commodity for PM interface, sends a few messages to this handle + HWND hwnd; /* commodity for PM interface, sends a few messages to this handle. */ /* --- OUTPUT_VOLUME */ - char volume; - float amplifier; + unsigned char volume; + float amplifier; /* --- OUTPUT_PAUSE */ - BOOL pause; - - /* --- OUTPUT_NOBUFFERMODE */ - - BOOL nobuffermode; + BOOL pause; + BOOL unused1; /* obsolete, must be NULL */ /* --- OUTPUT_TRASH_BUFFERS */ - ULONG temp_playingpos; // used until new buffers come in + ULONG temp_playingpos; /* used until new buffers come in */ + + /* --- OUTPUT_OPEN */ + + char* filename; /* filename, URL or track now being played, + useful for disk output */ + + /* --- OUTPUT_SETUP */ + + BOOL always_hungry; /* *OUTPUT* the output plug-in imposes no time restraint + it is always WM_OUTPUT_OUTOFDATA */ + + DECODER_INFO* info; /* added since PM123 1.32 */ + + /* Added since PM123 1.33. Output plug-in should call this + function for sound equalization. */ + + int (DLLENTRYP equalize_samples)( FORMAT_INFO*, char* buf, int len ); } OUTPUT_PARAMS; -ULONG _System output_command(void *a, ULONG msg, OUTPUT_PARAMS *info); + +ULONG DLLENTRY output_command( void* a, ULONG msg, OUTPUT_PARAMS* info ); +ULONG DLLENTRY output_playing_samples( void* a, FORMAT_INFO* info, char* buf, int len ); +int DLLENTRY output_play_samples( void* a, FORMAT_INFO* format, char* buf, int len, int posmarker ); +ULONG DLLENTRY output_playing_pos( void* a ); +BOOL DLLENTRY output_playing_data( void* a ); -ULONG _System output_playing_samples(void *a, FORMAT_INFO *info, char *buf, int len); -int _System output_play_samples(void *a, FORMAT_INFO *format, char *buf,int len, int posmarker); -ULONG _System output_playing_pos(void *a); -BOOL _System output_playing_data(void *a); +#pragma pack() + +#ifdef __cplusplus +} +#endif +#endif /* PM123_OUTPUT_PLUG_H */
--- a/plugin.h Fri Feb 18 02:50:18 2011 -0600 +++ b/plugin.h Thu Nov 24 03:45:48 2011 -0600 @@ -1,9 +1,7 @@ +#ifndef PM123_PLUGIN_H +#define PM123_PLUGIN_H -/* - PM123 Plugin Definitions - Copyright (C) 1998 Taneli Lepp„ <rosmo@kalja.com> - Samuel Audet <guardia@cam.org> -*/ +#include "format.h" #define PLUGIN_NULL 0x000 #define PLUGIN_VISUAL 0x001 @@ -11,82 +9,61 @@ #define PLUGIN_DECODER 0x004 #define PLUGIN_OUTPUT 0x008 -/* see decoder_plug.h and output_plug.h for more information - on some of these functions */ -typedef struct { - ULONG (* _System output_playing_samples)(FORMAT_INFO *info, char *buf, int len); - BOOL (* _System decoder_playing)(); - ULONG (* _System output_playing_pos)(); - ULONG (* _System decoder_status)(); - ULONG (* _System decoder_command)(ULONG msg, DECODER_PARAMS *params); - /* name is the DLL filename of the decoder that can play that file */ - ULONG (* _System decoder_fileinfo)(char *filename, DECODER_INFO *info, char *name); +#define PLUGIN_OK 0 +#define PLUGIN_UNSUPPORTED 1 +#define PLUGIN_NO_READ 100 +#define PLUGIN_NO_PLAY 200 +#define PLUGIN_GO_ALREADY 101 +#define PLUGIN_GO_FAILED 102 +#define PLUGIN_FAILED -1 +#define PLUGIN_NO_USABLE -2 + +#ifdef __cplusplus +extern "C" { +#endif - PFN specana_init; - /* int specana_init(int setnumsamples); - Returns the number of bands in return (setnumsamples/2+1). - */ - PFN specana_dobands; - /* - int specana_dobands(float bands[]); - Returns the max value. - */ - PFN pm123_getstring; - PFN pm123_control; +#pragma pack(4) - /* name is the DLL filename of the decoder that can play that track */ - ULONG (* _System decoder_trackinfo)(char *drive, int track, DECODER_INFO *info, char *name); - ULONG (* _System decoder_cdinfo)(char *drive, DECODER_CDINFO *info); - ULONG (* _System decoder_length)(); +typedef struct _PLUGIN_QUERYPARAM +{ + int type; /* null, visual, filter, input. values can be ORed */ + char* author; /* Author of the plugin */ + char* desc; /* Description of the plugin */ + int configurable; /* Is the plugin configurable */ -} PLUGIN_PROCS, *PPLUGIN_PROCS; +} PLUGIN_QUERYPARAM, *PPLUGIN_QUERYPARAM; + +void DLLENTRY plugin_query( PLUGIN_QUERYPARAM* param ); +void DLLENTRY plugin_configure( HWND hwnd, HMODULE module ); + +#pragma pack() /* - int pm123_getstring(int index, int subindex, int bufsize, char *buf) - - index - which string (see STR_* defines below) - subindex - not currently used - bufsize - bytes in buf - buf - buffer for the string -*/ + * int pm123_getstring( int index, int subindex, int bufsize, char* buf ) + * + * index - which string (see STR_* defines below) + * subindex - not currently used + * bufsize - bytes in buf + * buf - buffer for the string + */ #define STR_NULL 0 #define STR_VERSION 1 /* PM123 version */ -#define STR_DISPLAY_TEXT 2 /* Display text */ +#define STR_DISPLAY_TEXT 2 /* Displayed text */ #define STR_FILENAME 3 /* Currently loaded file */ +#define STR_DISPLAY_TAG 4 /* Displayed song info */ +#define STR_DISPLAY_INFO 5 /* Displayed tech info */ /* - int pm123_control(int index, void *param); - - index - operation - param - parameter for the operation -*/ -#define CONTROL_NEXTMODE 1 /* Next display mode */ - -typedef struct { - int x, y, cx, cy; /* Input */ - HWND hwnd; /* Input/Output */ - PPLUGIN_PROCS procs; /* Input */ - int id; /* Input */ - char *param; /* Input */ - HAB hab; /* Input */ -} VISPLUGININIT, *PVISPLUGININIT; + * int pm123_control( int index, void* param ); + * + * index - operation + * param - parameter for the operation + */ -typedef struct -{ - int type; /* null, visual, filter, input. values can be ORred */ - char *author; /* Author of the plugin */ - char *desc; /* Description of the plugin */ - int configurable; /* Is the plugin configurable */ -} PLUGIN_QUERYPARAM, *PPLUGIN_QUERYPARAM; - +#define CONTROL_NEXTMODE 1 /* Next display mode */ -/* Plugin notify message */ -#define WM_PLUGIN_CONTROL (WM_USER + 666) -/* - WM_PLUGIN_CONTROL - LONGFROMMP(mp1) = notify code - LONGFROMMP(mp2) = additional information -*/ -/* Notify codes */ -#define PN_TEXTCHANGED 1 /* Display text changed */ +#ifdef __cplusplus +} +#endif +#endif /* PM123_PLUGIN_H */