/*
 * widgproc.c --
 *
 * Copyright (c) 1994 Software Research Associates, Inc.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Software Research Associates not be
 * used in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.  Software Research
 * Associates makes no representations about the suitability of this software
 * for any purpose.  It is provided "as is" without express or implied
 * warranty.
 */

#include "xlibInt.h" 

extern XSetWindowAttributes defAttrs;
extern XWindowChanges defChanges;

/*
 *----------------------------------------------------------------------
 * RegisterWidgetClass --
 *
 *	Register the window type "Widget" and sets its window
 *	procedure
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	None
 *----------------------------------------------------------------------
 */
void
RegisterWidgetClass(HINSTANCE hInstance)
{
    WNDCLASS wndclass;

    wndclass.style	   = CS_HREDRAW  | CS_VREDRAW;
    wndclass.lpfnWndProc   = WidgetProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 64;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon	   = LoadIcon(0, IDI_APPLICATION);
    wndclass.hCursor       = NULL;
    wndclass.hbrBackground = NULL;
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = "Widget";

    RegisterClass(&wndclass);
}

/* 
 *----------------------------------------------------------------------
 *
 * DeleteProperty --
 * 
 *	Callback function for EnumProp.
 *
 *----------------------------------------------------------------------
 */
static BOOL CALLBACK
DeleteProperty(HWND hwnd, LPCSTR lpsz, HANDLE hData)	
{
    RemoveProp(hwnd, lpsz);
    GlobalFree(hData);
    return 1;
}

/*
 *----------------------------------------------------------------------
 * WidgetProc --
 *
 *	Process Windows messages for an individual widget here.
 *	Toplevel Windows messages do not pass through here.  If
 *	the message cannot be handled here, it is passed on to the
 *	Windows libraries.
 *
 * Side Effects:
 *	Depends on the message.  For some messages, the structure
 *	associated the window may be modified.  This structure
 *	maintains info about its width, height, and position.
 *======================================================================
 */
LRESULT CALLBACK
WidgetProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HGLOBAL hXSWAttrs, hXWChanges;
    XSetWindowAttributes *pXSWAttrs;
    XWindowChanges *pXWChanges;
    HGLOBAL hwp;
    WINDOWPOS *lpwp;
    HCURSOR hcs;
    BOOLEAN flag;

    switch(message) {
    case WM_CREATE:
    	hXSWAttrs = GlobalAlloc(GHND, sizeof(XSetWindowAttributes));
	pXSWAttrs = (XSetWindowAttributes *) GlobalLock(hXSWAttrs);
	memcpy(pXSWAttrs, &defAttrs, sizeof(XSetWindowAttributes));
	GlobalUnlock(hXSWAttrs);

	hXWChanges = GlobalAlloc(GHND, sizeof(XWindowChanges));
	pXWChanges = (XWindowChanges *) GlobalLock(hXWChanges);
	memcpy(pXWChanges, &defChanges, sizeof(XWindowChanges));
	GlobalUnlock(hXWChanges);

    	SetWindowLong(hwnd, XSWA_OFFSET, (LONG) hXSWAttrs);
	SetWindowLong(hwnd, XWCH_OFFSET, (LONG) hXWChanges);

	PostMessage(hwnd, CREATENOTIFY,  wParam, lParam); 
	return 0;

    case WM_ACTIVATE:
    	PostMessage(hwnd, EXPOSE, 0, 0L);
	return 0;

    case WM_SETFOCUS:
	PostMessage(hwnd, FOCUSIN, wParam, 0L); 
	return 0;
	
    case WM_KILLFOCUS:
	PostMessage(hwnd, FOCUSOUT, wParam, 0L); 
	return 0;

    case WM_WINDOWPOSCHANGED:
    	hwp = GlobalAlloc(LHND, sizeof(WINDOWPOS));
	lpwp = (WINDOWPOS *) GlobalLock(hwp);
	memcpy(lpwp, (WINDOWPOS *)lParam, sizeof(WINDOWPOS));

	hXWChanges = (HGLOBAL) GetWindowLong(hwnd, XWCH_OFFSET);
	pXWChanges = (XWindowChanges *) GlobalLock(hXWChanges);
	GlobalUnlock(hXWChanges);

	if (lpwp->flags & SWP_NOMOVE) {
	     lpwp->x = pXWChanges->x;
	     lpwp->y = pXWChanges->y;
	} else {
	     pXWChanges->x = lpwp->x;
	     pXWChanges->y = lpwp->y;
	}
	if (lpwp->flags & SWP_NOSIZE) {
	     lpwp->cx = pXWChanges->width;
	     lpwp->cy = pXWChanges->height;
	} else {
	     pXWChanges->width = lpwp->cx;
	     pXWChanges->height = lpwp->cy;
	}

	GlobalUnlock(hwp);
	PostMessage(hwnd, CONFIGURENOTIFY, (WPARAM) hwp, XOpenDisplay(NULL)->request); 
	return 0;

    case WM_MOUSEMOVE: 
	hcs = (HGLOBAL) GetWindowLong(hwnd, HCCS_OFFSET);
    	if (hcs == NULL) {
	    hcs = FindCursor(hwnd);
	}
	SetCursor(hcs);				    
	return 0;

    case WM_DESTROY: 
    	GlobalFree((HGLOBAL) GetWindowLong(hwnd, XSWA_OFFSET));
	GlobalFree((HGLOBAL) GetWindowLong(hwnd, XWCH_OFFSET));
	EnumProps(hwnd, DeleteProperty);
	return 0;

    case WM_PAINT:
	return 0;


    case TKW_SELECTIONSAVE:
	/* This message gets posted by TbSetClipboard() in tkwinutil.c */
        flag = 1;
	return 0;

    case WM_DESTROYCLIPBOARD:
	if (flag) {
	    flag = 0;
	} else {
	    PostMessage(hwnd, SELECTIONCLEAR, wParam, 0L);
	}
	return 0; 

    }
    DefWindowProc(hwnd, message, wParam, lParam);
}

			
