/* 
   PXKWindow.m

   NSWindow for GNUstep GUI X/DPS Backend.

   Copyright (C) 1996 Free Software Foundation, Inc.

   Author:  Pascal Forget <pascal@wsc.com>
   Date: February 1996
   
   This file is part of the GNUstep GUI X/DPS Backend.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
   
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   If you are interested in a warranty or support for this source code,
   contact Scott Christley <scottc@net-community.com> for more information.
   
   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ 

#include <gnustep/xdps/PXKWindow.h>
#include <gnustep/xdps/PXKView.h>

//
// Backend structure for PXKWindow
//
typedef struct _PXKWindow_struct
{
  Window xWindow;
} PXKWindow_struct;

#define XWINDOW (((PXKWindow_struct *)be_wind_reserved)->xWindow)

@implementation PXKWindow

- (void)close;
{
    if (window_num > -1 ) {
#if 0
	if ((delegate == nil) ||
	    (((BOOL)[delegate respondsToSelector:
			      @selector(windowWillClose:)]) &&
	     
	     ((BOOL)[(id)delegate windowWillClose:self])))
	{
	    closeWindow(window_num);
	}
#else
	closeWindow(window_num);
#endif
    }
    visible = NO;
}

- (id)initWithContentRect:(NSRect)contentRect
		styleMask:(unsigned int)aStyle
		  backing:(NSBackingStoreType)bufferingType
		    defer:(BOOL)flag
		   screen:aScreen;
{
  // Allocate the back-end structure
  be_wind_reserved = malloc(sizeof(PXKWindow_struct));
  XWINDOW = 0;

  [super initWithContentRect:contentRect styleMask:aStyle
	 backing:bufferingType defer:flag screen:aScreen];

  NSLog(@"PXKWindow default initializer\n");

  XWINDOW = createXWindow(contentRect);
  frame_view = [[NSView alloc] initWithFrame:contentRect];
  [frame_view addSubview:content_view];

#ifdef TRANSPARENCY
  [content_view setOpaque:YES];
#endif

  [frame_view viewWillMoveToWindow:self];

  NSLog(@"PXKWindow end of default initializer\n");
  return self;
}

- (void)dealloc;
{
  // Destroy the X Window
  if (XWINDOW)
    {
      XDestroyWindow(pxkDisplay, XWINDOW);
      XWINDOW = 0;
    }

  // Release the back-end structure
  free(be_wind_reserved);

  [super dealloc];
}

- (void)setTitle:(NSString *)aString
{
  XTextProperty windowName;
  char *newTitle;

  [super setTitle: aString];

  if ((window_title) && (XWINDOW))
    {
      newTitle = (char *)malloc([window_title length] + 1);
      strcpy(newTitle, [window_title cString]);
      XStringListToTextProperty(&newTitle, 1, &windowName);
      XSetWMName(pxkDisplay, XWINDOW, &windowName);
      XSetWMIconName(pxkDisplay, XWINDOW, &windowName);
      free(newTitle);
    }
}

- (void)display;
{
#if 0    
    pxkDebugMsg("displayXWindow");
#endif
    XFlush(pxkDisplay);
    XMapWindow(pxkDisplay, XWINDOW);
#if 0    
    XClearWindow(pxkDisplay, XWINDOW);
#endif
    
    XMapSubwindows(pxkDisplay, XWINDOW);    /* I'm not sure that's necessary */
    XFlush(pxkDisplay);    
    XMapWindow(pxkDisplay, XWINDOW);
#if 0
    XClearWindow(pxkDisplay, XWINDOW);
#endif
    XMapSubwindows(pxkDisplay, XWINDOW);    /* I'm not sure that's necessary */
    XFlush(pxkDisplay);

    visible = YES;
}

- (void)mouseDown:(NSEvent *)theEvent;
{
    NSView *hit = [content_view hitTest:[theEvent locationInWindow]];
    
    if (hit == nil) {
    	[self noResponderFor:@selector(mouseDown:)];
	return;
    } else {
	if (([self isKeyWindow] == YES) || 
	    ([hit acceptsFirstMouse:theEvent] == YES))
	{
	    [hit mouseDown:theEvent];
	}
    }
}

- (void)rightMouseDown:(NSEvent *)theEvent;
{
    NSView *hit = [content_view hitTest:[theEvent locationInWindow]];
    
    if (hit == nil) {
    	[self noResponderFor:@selector(rightMouseDown:)];
	return;
    } else {
	if (([self isKeyWindow] == YES) || 
	    ([hit acceptsFirstMouse:theEvent] == YES))
	{
	    [hit rightMouseDown:theEvent];
	}
    }    
}

- (void)setContentSize:(NSSize)aSize;
{

#if 0    
    _contentRect.size = aSize;
    
    if (content_view == nil) {
	content_view = [[NSView alloc] initWithFrame:_contentRect];
    }

    [content_view setFrameSize:aSize];
#endif    
}

- (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
{
    NSSize aSize;
    frame = frameRect;
    
    setWindowFrame(window_num, frame);

    aSize = frameRect.size;
    
    aSize.height -= 21.0; /* Title bar is always there in this release */

    [self setContentSize:aSize];
    
    if (flag == YES) {
	[self display];
    }
}

- (void)setFrameOrigin:(NSPoint)aPoint;
{
    frame.origin = aPoint;
    setWindowFrameOrigin(window_num, aPoint);
}

- (void)setFrameTopLeftPoint:(NSPoint)aPoint;
{
    frame.origin.x = aPoint.x;
    frame.origin.y = aPoint.y - frame.size.height;
    setWindowFrameOrigin(window_num, aPoint);
}

- (void)sendEvent:(NSEvent *)theEvent
{
  NSLog(@"PXKWindow -sendEvent:\n");
  NSLog(@"Window frame %f %f %f %f\n", frame.origin.x, frame.origin.y,
	frame.size.width, frame.size.height);

  [super sendEvent: theEvent];
}

//
// GNUstep backend methods
//
- (void)captureMouse:sender
{
  int ret = XGrabPointer(pxkDisplay, [self xWindow], True,
			 PointerMotionMask,
			 GrabModeAsync, GrabModeAsync, 
			 None, None, CurrentTime);

  if (ret != GrabSuccess)
    NSLog(@"Failed to grab pointer\n");
  else
    NSLog(@"Grabbed pointer\n");
}

- (void)releaseMouse:sender
{
  XUngrabPointer(pxkDisplay, CurrentTime);
}

@end

//
// Methods for XWindows implementation
//
@implementation PXKWindow (GNUstepXDPS)

- (Window)xWindow
{
  return XWINDOW;
}

- (void)setFrameFromXFrame:(NSRect)rect
{
  NSRect bounds;

  frame = rect;

  // Determine the size of our content rect
  bounds.origin = NSZeroPoint;
  bounds.size = frame.size;

  // Inform our content view
  [content_view setFrame:bounds];
}

@end
