/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
#include "window/wmanager.hh"
#include "error/error.hh"
#include "window/style.hh"
#include "error/error.hh"
#include "window/win_evt.hh"
i4_color i4_window_manager_class::i4_read_color_from_resource(char *resource)
{
i4_const_str::iterator i=i4gets(resource).begin();
i4_color red=i.read_number();
i4_color grn=i.read_number();
i4_color blue=i.read_number();
return i4_pal_man.convert_32_to( (red<<16)|(grn<<8)|(blue),
&local_image->get_pal()->source);
}
void i4_window_manager_class::set_background_color(w32 color)
{
background_color=color;
}
void i4_window_manager_class::parent_draw(i4_draw_context_class &context)
{
i4_rect_list_class child_clip(&context.clip,0,0);
child_clip.intersect_list(&undrawn_area); // intersect clipped area with area that needs to be drawn
child_clip.swap(&context.clip); // make this the display's new clip list
local_image->clear(background_color,context); // clear out this area
child_clip.swap(&context.clip); // restore the display's clip list
}
void i4_window_manager_class::root_draw() // called by application
{
// i4_draw_context_class c(0,0,639,439);
// display->get_screen()->clear(0, c);
i4_parent_window_class::draw(*display->get_context());
display->flush(); // tell the display to page-flip or copy-dirty rects
}
// a window manager does not actually get associated with anything until prepare_for_mode
i4_window_manager_class::i4_window_manager_class() : i4_parent_window_class(0,0)
{
drag_drop.active=i4_F;
display=0;
devices_present=0;
style=0;
default_cursor=0;
background_color=0;
no_cursor_installed=i4_T;
key_modifiers_pressed=0;
}
i4_window_manager_class::~i4_window_manager_class()
{
cleanup_old_mode();
}
void i4_window_manager_class::receive_event(i4_event *ev)
{
if (ev->type()==i4_event::WINDOW_MESSAGE)
{
CAST_PTR(cc,i4_window_change_cursor_class,ev);
if (cc->sub_type==i4_window_message_class::CHANGE_CURSOR)
{
if (cc->cursor)
{
display->set_mouse_shape(cc->cursor);
no_cursor_installed=i4_F;
}
else if (default_cursor) // make sure we have default cursor first
display->set_mouse_shape(default_cursor);
}
else if (cc->sub_type==i4_window_message_class::REQUEST_DRAG_DROP_START)
{
CAST_PTR(drag, i4_window_request_drag_drop_start_class, ev);
drag_drop.active=i4_T;
drag_drop.reference_id=drag->reference_id;
drag_drop.further_info=drag->further_info;
drag_drop.originator=drag->from();
if (drag->drag_cursor)
display->set_mouse_shape(drag->drag_cursor);
}
else if (cc->sub_type==i4_window_message_class::REQUEST_DRAG_DROP_END)
{
i4_error("fixme");
// drag_drop.active=i4_F;
// if (default_cursor)
// display->set_mouse_shape(default_cursor);
// i4_window_class *prev_from=drag_frop
// i4_window_got_drop_class drop(drag_drop.originator,
// drag_drop.reference_id,
// drag_drop.further_info);
// i4_parent_window_class::receive_event(&drop);
}
else if (cc->sub_type==i4_window_message_class::REQUEST_MOUSE_GRAB)
{
CAST_PTR(grab,i4_window_request_mouse_grab_class,ev);
i4_parent_window_class::receive_event(ev);
}
else if (cc->sub_type==i4_window_message_class::REQUEST_MOUSE_UNGRAB)
{
CAST_PTR(ungrab,i4_window_request_mouse_ungrab_class,ev);
i4_parent_window_class::receive_event(ev);
ungrab->return_result=i4_T;
}
else i4_parent_window_class::receive_event(ev);
} else if (ev->type()==i4_event::DISPLAY_CHANGE)
{
i4_image_class *im=display->get_screen();
private_resize(im->width(),im->height()); // in case the resolution changed
reparent(im,0); // grab the new image
}
else
{
switch (ev->type())
{
case i4_event::KEY_PRESS :
key_modifiers_pressed=((i4_key_press_event_class *)ev)->modifiers;
break;
case i4_event::KEY_RELEASE :
key_modifiers_pressed=((i4_key_release_event_class *)ev)->modifiers;
break;
case i4_event::MOUSE_BUTTON_DOWN :
case i4_event::MOUSE_BUTTON_UP :
{
CAST_PTR(bev, i4_mouse_button_event_class,ev);
if (bev->time.milli_diff(bev->last_time)time_hint->double_click)
bev->double_click=i4_T;
} break;
}
i4_parent_window_class::receive_event(ev);
}
if (drag_drop.active && ev->type()==i4_event::MOUSE_MOVE)
{
CAST_PTR(mouse_move, i4_mouse_move_event_class, ev);
i4_window_drag_drop_move_class move(drag_drop.originator,
mouse_move->x,
mouse_move->y,
drag_drop.reference_id,
drag_drop.further_info);
i4_parent_window_class::receive_event(&move);
}
}
void i4_window_manager_class::set_default_cursor(i4_cursor_class *cursor)
{
if (default_cursor)
delete default_cursor;
default_cursor=cursor->copy();
if (no_cursor_installed)
display->set_mouse_shape(cursor);
}
i4_graphical_style_class *i4_window_manager_class::get_style()
{
return style;
}
void i4_window_manager_class::prepare_for_mode(i4_display_class *display,
i4_display_class::mode *mode)
{
cleanup_old_mode();
i4_window_manager_class::display=display;
const i4_const_str s=i4gets("window_manager",i4_F);
if (!s.null())
{
char buf[100];
i4_const_str::iterator i=s.begin();
i.read_ascii(buf,100);
style=i4_style_man.find_style(buf);
}
else style=0;
if (!style)
style=i4_style_man.first_style();
if (!style)
i4_error("No window styles installed");
i4_image_class *im=display->get_screen();
resize(im->width(),im->height());
reparent(im,0);
style->prepare_for_mode(local_image->get_pal(), mode);
i4_kernel.request_events(this,
i4_device_class::FLAG_MOUSE_BUTTON_UP|
i4_device_class::FLAG_MOUSE_BUTTON_DOWN|
i4_device_class::FLAG_MOUSE_MOVE|
i4_device_class::FLAG_KEY_PRESS|
i4_device_class::FLAG_KEY_RELEASE|
i4_device_class::FLAG_DISPLAY_CHANGE|
i4_device_class::FLAG_DRAG_DROP_EVENTS|
i4_device_class::FLAG_IDLE);
default_cursor=style->cursor_hint->normal_cursor()->copy();
display->set_mouse_shape(default_cursor);
i4_const_str::iterator col=i4gets("root_background_color").begin();
w32 r=col.read_number();
w32 g=col.read_number();
w32 b=col.read_number();
background_color=i4_pal_man.convert_32_to( (r<<16)|(g<<8)|(b),
&local_image->get_pal()->source);
}
void i4_window_manager_class::cleanup_old_mode()
{
if (style) // has a previous mode been used?
{
i4_kernel.unrequest_events(this,
i4_device_class::FLAG_MOUSE_BUTTON_UP|
i4_device_class::FLAG_MOUSE_BUTTON_DOWN|
i4_device_class::FLAG_MOUSE_MOVE|
i4_device_class::FLAG_KEY_PRESS|
i4_device_class::FLAG_KEY_RELEASE|
i4_device_class::FLAG_DISPLAY_CHANGE |
i4_device_class::FLAG_DRAG_DROP_EVENTS|
i4_device_class::FLAG_IDLE
);
if (default_cursor)
{
delete default_cursor;
default_cursor=0;
no_cursor_installed=i4_T;
}
}
}