[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [MiNT] XaAES 1.55 + NetSurf
- To: mint@lists.fishpool.fi
- Subject: Re: [MiNT] XaAES 1.55 + NetSurf
- From: "Helmut Karlowski" <helmut.karlowski@ish.de>
- Date: Thu, 28 Mar 2013 02:20:42 +0100
- In-reply-to: <e7c4c70cf907533ad427523bc375eab2-EhVcX1lFRQVaRwYcDTpQCEFddQZLVF5dQUNBAjBeX15ZVF0WWlpoBVc6XFxZRUEAWVJbQg==-webmailer2@server06.webmailer.hosteurope.de>
- List-help: <mailto:ecartis@lists.fishpool.fi?Subject=help>
- List-id: <mint.lists.fishpool.fi>
- List-owner: <mailto:tjhukkan@fishpool.fi>
- List-post: <mailto:mint@lists.fishpool.fi>
- List-subscribe: <mailto:mint-request@lists.fishpool.fi?Subject=subscribe>
- List-unsubscribe: <mailto:mint-request@lists.fishpool.fi?Subject=unsubscribe>
- References: <1a2bc1b0313889dc18489decbddd2c3b-EhVcX1lFRQVaRwYcDTpQCEFddQZLVF5dQUNBAjBeX15ZVF0WXl9/H1RUWTBeQkMGXlxRQl9V-webmailer2@server02.webmailer.hosteurope.de> <52f3d2826a772c5b4b06dfa093d62a7f-EhVcX1lFRQVaRwYcDTpQCEFddQZLVF5dQUNBAjBYWEJGUFEWXFloA1VTMl5cR0EAX19eQFg=-webmailer2@server06.webmailer.hosteurope.de> <op.wuhyjes3ofd6j1@nebbiolo> <1791863.aaK6fzoqOT@chertsey> <08afba233ce6847e01607a6d6ee96fdb-EhVcX1lFRQVaRwYcDTpQCEFddQZLVF5dQUNBAjBeX15ZVF0WWlpoBVc6XFxZRUcHWltfRw==-webmailer2@server02.webmailer.hosteurope.de> <d791c38954ade8f9b5bc912755026421-EhVcX1lFRQVaRwYcDTpQCEFddQZLVF5dQUNBAjBYWEJGUFEWXFloA1VTMl5cR0EAV19ZSVs=-webmailer2@server06.webmailer.hosteurope.de> <eaab616427395c36fe43345756276068-EhVcX1lFRQVaRwYcDTpQCEFddQZLVF5dQUNBAjBeX15ZVF0WWlpoBVc6XFxZRUYGX11QQQ==-webmailer2@server01.webmailer.hosteurope.de> <op.wulf0lxsofd6j1@nebbiolo> <45acc2a5b70dc211cef4ee87c4294a8e-EhVcX1lFRQVaRwYcDTpQCEFddQZLVF5dQUNBAjBeX15ZVF0WWlpoBVc6XFxZRUEAXF9aRQ==-webmailer2@server06.webmailer.hosteurope.de> <op.wummgybfofd6j1@nebbiolo> <e7c4c70cf907533ad427523bc375eab2-EhVcX1lFRQVaRwYcDTpQCEFddQZLVF5dQUNBAjBeX15ZVF0WWlpoBVc6XFxZRUEAWVJbQg==-webmailer2@server06.webmailer.hosteurope.de>
- Sender: mint-bounce@lists.fishpool.fi
- User-agent: Opera Mail/12.14 (Win32)
Ole, 28.03.2013 00:27:02:
But after updating the mint kernel (because xaaes complained about the
kernel version...) I only get into an reboot loop... (the version error
went away, but xaaes causes a reboot right after displaying the xaaes
logo).
Set loglvl=1 and post the xa_boot.log. The root_window is opened at
k_init.c#1040, open_window in c_window.c#1581, you might debug it yourself
now :)
Attached is c_window.c with some DBG inside.
BTW: I changed the protection in fvdi from super to global, and now
netsurf does not crash anymore and runs ok as well as sysinfo :-/
hm, that makes sense... but how is this related to xaaes 1.55 on
coldfire ;) ?
Not at all.
I guess the memory-protection error has nothing to do with the crash on
coldfire
then...
No. I ran it this way for years and it was wrong ;)
--
Helmut Karlowski
/*
* $Id: c_window.c,v 1.147.2.44 2013/03/24 10:25:41 hek Exp $
*
* XaAES - XaAES Ain't the AES (c) 1992 - 1998 C.Graham
* 1999 - 2003 H.Robbers
* 2004 F.Naumann & O.Skancke
*
* A multitasking AES replacement for FreeMiNT
*
* This file is part of XaAES.
*
* XaAES is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* XaAES 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XaAES; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "c_window.h"
#include "xa_global.h"
#include "app_man.h"
#include "taskman.h"
#include "desktop.h"
#include "k_main.h"
#include "k_mouse.h"
#include "menuwidg.h"
#include "draw_obj.h"
#include "rectlist.h"
#include "scrlobjc.h"
#include "widgets.h"
#include "xa_bubble.h"
#include "xa_graf.h"
#include "xa_wind.h"
#include "mint/signal.h"
STATIC struct xa_window *pull_wind_to_top(enum locks lock, struct xa_window *w);
STATIC void fitin_root(RECT *r);
STATIC void set_and_update_window(struct xa_window *wind, bool blit, bool only_wa, RECT *new);
/*
* Window Stack Management Functions
*/
//static void draw_window(enum locks lock, struct xa_window *wind);
/* HR:
* I hated the kind of runaway behaviour (return wind_handle++)
* So here is my solution:
* Window handle bit array (used to generate unique window handles)
* As this fills up, there may be a problem if a user opens
* more than MAX_WINDOWS windows concurrently :-)
*/
static unsigned long
btst(unsigned long word, unsigned int bit)
{
unsigned long mask = 1UL << bit;
return (word & mask);
}
static void
bclr(unsigned long *word, unsigned int bit)
{
unsigned long mask = 1UL << bit;
*word &= ~mask;
}
static void
bset(unsigned long *word, unsigned int bit)
{
unsigned long mask = 1UL << bit;
*word |= mask;
}
static unsigned long wind_handle[MAX_WINDOWS / LBITS];
static const unsigned int words = MAX_WINDOWS / LBITS;
static int
new_wind_handle(void)
{
unsigned int word;
unsigned int l;
for (word = 0; word < words; word++)
if (wind_handle[word] != 0xffffffffUL)
break;
#if XXX
assert(word < words);
#endif
l = 0;
while (btst(wind_handle[word], l))
l++;
bset(wind_handle+word, l);
return word * LBITS + l;
}
static void
free_wind_handle(int h)
{
unsigned int word = h / LBITS;
bclr(wind_handle+word, h % LBITS);
}
void
clear_wind_handles(void)
{
unsigned int f;
for (f = 0; f < words; f++)
wind_handle[f] = 0;
}
/*
* Go through and check that all windows belonging to this client are
* closed and deleted
*/
/* HR: This is an exemple of the use of the lock system.
* The function can be called by both server and client.
*
* If called by the server, lock will be preset to winlist,
* resulting in no locking (not needed).
*
* If called by the signal handler, it is unclear, so the
* lock is applied. (doesnt harm).
*/
static void
rw(enum locks lock, struct xa_window *wl, struct xa_client *client)
{
struct xa_window *nwl;
while (wl)
{
DIAGS(("-- RW: %lx, next=%lx, prev=%lx",
wl, wl->next, wl->prev));
nwl = wl->next;
if (wl != root_window && wl != menu_window)
{
if (!client || wl->owner == client)
{
if ((wl->window_status & XAWS_OPEN))
{
DIAGS(("-- RW: closing %lx, client=%lx", wl, client));
close_window(lock, wl);
}
DIAGS(("-- RW: deleting %lx", wl));
delete_window(lock, wl);
}
}
#if GENERATE_DIAGS
else
DIAGS((" -- RW: skipping root window"));
#endif
wl = nwl;
}
}
void
remove_windows(enum locks lock, struct xa_client *client)
{
DIAG((D_wind,client,"remove_windows on open_windows list for %s", c_owner(client)));
if( !client )
return;
rw(lock, window_list, client);
DIAG((D_wind,client,"remove_windows on closed_windows list for %s", c_owner(client)));
rw(lock, S.closed_windows.first, client);
}
void
remove_all_windows(enum locks lock, struct xa_client *client)
{
DIAG((D_wind, client,"remove_all_windows for %s", c_owner(client)));
if( !client )
return;
remove_windows(lock, client);
DIAG((D_wind, client, "remove_all_windows on open_nlwindows for %s", c_owner(client)));
rw(lock, S.open_nlwindows.first, client);
DIAG((D_wind, client, "remove_all_windows on closed_nlwindows for %s", c_owner(client)));
rw(lock, S.closed_nlwindows.first, client);
rw(lock, S.calc_windows.first, client);
}
inline static void
calc_shade_height(struct xa_window *wind)
{
if (wind->active_widgets & (CLOSER|NAME|MOVER|ICONIFIER|FULLER))
{
RECT t;
t = w2f(&wind->rbd, &wind->widgets[XAW_TITLE].r, false);
if( t.h < 6 )
t.h = 6;
wind->sh = t.h + wind->y_shadow;
if (wind->frame > 0)
wind->sh += (wind->frame << 1);
}
}
STATIC void
clear_wind_rectlist(struct xa_window *wind)
{
DIAGS(("clear_wind_rectlist: on %d of %s", wind->handle, wind->owner->name));
free_rectlist_entry(&wind->rect_list);
free_rectlist_entry(&wind->rect_opt);
free_rectlist_entry(&wind->rect_toolbar);
}
/*
* Find first free position for iconification.
* Uses the RECT at wind->t.
*/
RECT
free_icon_pos(enum locks lock, struct xa_window *ignore)
{
RECT ic, r;
int i = 0;
for (;;)
{
struct xa_window *w = window_list;
ic = iconify_grid(i++);
// display("icgrid %d/%d/%d/%d", ic);
/* find first unused position. */
while (w)
{
if (w != ignore && (is_iconified(w) || (w->window_status & XAWS_CHGICONIF)))
{
r = ic;
if (w->t.x == r.x && w->t.y == r.y)
/* position occupied; advance with next position in grid. */
break;
}
w = w->next;
if (w == root_window)
{
w = NULL;
break;
}
}
if (!w)
/* position not in list of iconified windows, so it is free. */
break;
}
return ic;
}
static void
move_ctxdep_widgets(struct xa_window *wind)
{
if (wind->active_widgets & TOOLBAR)
rp_2_ap_cs(wind, get_widget(wind, XAW_TOOLBAR), NULL);
if (wind->active_widgets & XaMENU)
{
rp_2_ap_cs(wind, get_widget(wind, XAW_MENU), NULL);
}
}
XA_WIND_ATTR
hide_move(struct options *o)
{
XA_WIND_ATTR kind = 0;
if (!o->xa_nohide)
kind |= HIDE;
if (!o->xa_nomove)
kind |= MOVER;
return kind;
}
void
set_winrect(struct xa_window *wind, RECT *wr, const RECT *new)
{
RECT r;
if (wind->opts & XAWO_WCOWORK)
r = w2f(&wind->delta, new, true);
else
r = *new;
fitin_root(&r);
*wr = r;
}
/* return 0 if true
* 1 if too high
* 2 if too left
* 3 if both
*/
short
inside_root(RECT *r, bool noleft)
{
short ret = 0;
if( !cfg.leave_top_border )
{
short min = 0;
if (cfg.menu_bar && cfg.menu_layout == 0 && cfg.menu_ontop == 0)
{
min = get_menu_height();
}
if (r->y < min )
{
r->y = min;
ret = 1;
}
}
if (noleft && r->x < root_window->wa.x)
{
r->x = root_window->wa.x;
ret |= 2;
}
return ret;
}
STATIC void
fitin_root(RECT *r)
{
RECT *w = &root_window->wa;
if (r->x < w->x)
r->x = w->x;
if (r->y < w->y)
r->y = w->y;
if (r->w > w->w)
r->w = w->w;
if (r->h > w->h)
r->h = w->h;
}
void
inside_minmax(RECT *r, struct xa_window *wind)
{
bool um = (wind->active_widgets & USE_MAX);
if (!is_iconified(wind))
{
if (um && wind->max.w && r->w > wind->max.w)
r->w = wind->max.w;
if (wind->min.w && r->w < wind->min.w)
r->w = wind->min.w;
if (um && wind->max.h && r->h > wind->max.h)
r->h = wind->max.h;
if (wind->min.h && r->h < wind->min.h)
r->h = wind->min.h;
}
}
#if GENERATE_DIAGS
static char *stacks[] =
{
"HUH!!",
"Open windows",
"Closed windows",
"Open nlwindows",
"Closed nlwindows",
"Deleted windows",
"hidden windows",
"calc_windows",
};
#endif
STATIC void
wi_remove(struct win_base *b, struct xa_window *w, bool chkfocus)
{
#if GENERATE_DIAGS
int stack = 0;
if (b == &S.open_windows)
stack = 1;
else if (b == &S.closed_windows)
stack = 2;
else if (b == &S.open_nlwindows)
stack = 3;
else if (b == &S.closed_nlwindows)
stack = 4;
else if (b == &S.deleted_windows)
stack = 5;
else if (b == &S.hidden_windows)
stack = 6;
else if (b == &S.calc_windows)
stack = 7;
DIAGA(("wi_put_first: on stack %s", stacks[stack]));
#endif
if (w->prev)
w->prev->next = w->next;
if (w->next)
w->next->prev = w->prev;
if (w == b->first)
b->first = w->next;
if (w == b->last)
b->last = w->prev;
w->next = NULL;
w->prev = NULL;
if (b->top == w)
{
w->window_status &= ~XAWS_FIRST;
b->top = b->first;
if (b->top)
b->first->window_status |= XAWS_FIRST;
DIAGA(("wi_remove: remove top %d of %s, newtop %d of %s",
w->handle, w->owner->name,
b->top ? b->top->handle : -2,
b->top ? b->top->owner->name : "no more winds"));
}
if (chkfocus && w == S.focus) {
DIAGA(("wi_remove: remove focus %d of %s", w->handle, w->owner->name));
S.focus = NULL;
}
}
STATIC void
wi_put_first(struct win_base *b, struct xa_window *w)
{
struct xa_window **wind;
#if GENERATE_DIAGS
int stack = 0;
if (b == &S.open_windows)
stack = 1;
else if (b == &S.closed_windows)
stack = 2;
else if (b == &S.open_nlwindows)
stack = 3;
else if (b == &S.closed_nlwindows)
stack = 4;
else if (b == &S.deleted_windows)
stack = 5;
else if (b == &S.hidden_windows)
stack = 6;
else if (b == &S.calc_windows)
stack = 7;
DIAGA(("wi_put_first: on stack %s", stacks[stack]));
#endif
wind = &b->first;
if (!(w->window_status & XAWS_FLOAT))
{
while (*wind)
{
if (!((*wind)->window_status & XAWS_FLOAT) || *wind == root_window)
break;
wind = &((*wind)->next);
}
}
if (*wind)
{
w->next = *wind;
w->prev = (*wind)->prev;
(*wind)->prev = w;
}
else
{
if (b->first)
{
w->prev = b->last;
b->last->next = w;
}
else
w->prev = NULL;
b->last = w;
w->next = NULL;
}
*wind = w;
if (b->top) {
DIAGA(("wi_put_first: detopped %d of %s", b->top->handle, b->top->owner->name));
b->top->window_status &= ~XAWS_FIRST;
}
b->top = w;
DIAGA(("wi_put_first: new top %d of %s", w->handle, w->owner->name));
w->window_status |= XAWS_FIRST;
}
extern bool diags_always;
/* This a special version of put last; it puts w just befor last. */
static void
wi_put_blast(struct win_base *b, struct xa_window *w, bool top, bool belowroot)
{
struct xa_window **wind;
#if GENERATE_DIAGS
int stack = 0;
if (b == &S.open_windows)
stack = 1;
else if (b == &S.closed_windows)
stack = 2;
else if (b == &S.open_nlwindows)
stack = 3;
else if (b == &S.closed_nlwindows)
stack = 4;
else if (b == &S.deleted_windows)
stack = 5;
else if (b == &S.hidden_windows)
stack = 6;
else if (b == &S.calc_windows)
stack = 7;
DIAGA(("wi_put_first: on stack %s", stacks[stack]));
#endif
wind = &b->last;
if (belowroot)
{
wind = &b->last;
(*wind)->next = w;
w->next = NULL;
w->prev = *wind;
*wind = w;
return;
}
wind = b->root ? &(b->root->prev) : &b->last;
while (*wind)
{
if ( *wind != root_window &&
( (!top && (w->window_status & XAWS_SINK)) || !((*wind)->window_status & XAWS_SINK))
)
break;
wind = &((*wind)->prev);
}
if (*wind)
{
w->next = (*wind)->next;
(*wind)->next = w;
w->prev = *wind;
if (w->next)
w->next->prev = w;
else
b->last = w;
}
else
{
if ((w->next = b->first))
w->next->prev = w;
else
b->last = w;
w->prev = NULL;
b->first = w;
}
if (top || !b->top)
{
if (b->top && b->top != w) {
b->top->window_status &= ~XAWS_FIRST;
DIAGA(("wi_put_blast: detopped %d of %s", b->top->handle, b->top->owner->name));
}
b->top = w;
w->window_status |= XAWS_FIRST;
DIAGA(("wi_put_blast: new top %d of %s", b->top->handle, b->top->owner->name));
}
}
void
wi_move_first(struct win_base *b, struct xa_window *w)
{
DIAGA(("wi_move_first: %d of %s", w->handle, w->owner->name));
wi_remove(b, w, false);
if (!(w->window_status & XAWS_SINK))
wi_put_first(b, w);
else
wi_put_blast(b, w, true, false);
DIAGA(("wi_move_first: !"));
}
STATIC void
wi_move_blast(struct win_base *b, struct xa_window *w)
{
DIAGA(("wi_move_blast: %d of %s", w->handle, w->owner->name));
wi_remove(b, w, false);
if ((w->window_status & XAWS_FLOAT))
wi_put_first(b, w);
else
wi_put_blast(b, w, false, false);
DIAGA(("wi_move_blast: !"));
}
STATIC void
wi_move_belowroot(struct win_base *b, struct xa_window *w)
{
DIAGA(("wi_move_belowroot: %d of %s", w->handle, w->owner->name));
wi_remove(b, w, false);
wi_put_blast(b, w, false, true);
DIAGA(("wi_move_belowroot: !"));
}
/*
* XXX - Ozk:
* Note that the window is not actually hidden until client calls
* wind_set(WF_CURRXYWH), but we mark it hidden internally right now,
* and it will be skipped in various other places, like rectangle
* building, immediately.
*/
void
hide_window(enum locks lock, struct xa_window *wind)
{
if (!is_hidden(wind))
{
RECT r = wind->rc;
r.x = root_window->rc.x + root_window->rc.w + 16;
r.y = root_window->rc.y + root_window->rc.h + 16;
wind->hx = wind->rc.x;
wind->hy = wind->rc.y;
if (wind->opts & XAWO_WCOWORK)
r = f2w(&wind->delta, &r, true);
send_moved(lock, wind, AMQ_NORM, &r);
wind->window_status |= XAWS_HIDDEN;
}
}
void
unhide_window(enum locks lock, struct xa_window *wind, bool check)
{
if (is_hidden(wind))
{
RECT r;
if (is_iconified(wind))
r = free_icon_pos(lock, wind);
else
{
r = wind->rc;
r.x = wind->hx;
r.y = wind->hy;
}
wind->t = r;
if (wind->opts & XAWO_WCOWORK)
r = f2w(&wind->delta, &r, true);
send_moved(lock, wind, AMQ_NORM, &r);
wind->window_status &= ~XAWS_HIDDEN;
if (any_hidden(lock, wind->owner, wind))
set_unhidden(lock, wind->owner);
}
}
static inline void
movewind_belowroot(struct xa_window *wind)
{
wi_move_belowroot(&S.open_windows, wind);
wind->window_status |= XAWS_BELOWROOT;
clear_wind_rectlist(wind);
}
void
hide_toolboxwindows(struct xa_client *client)
{
struct xa_window *wind = window_list, *nxt;
while (wind && wind != root_window)
{
nxt = wind->next;
if (wind->owner == client && (wind->window_status & XAWS_BINDFOCUS))
{
struct xa_window *wl = wind->next;
movewind_belowroot(wind);
// wi_move_belowroot(&S.open_windows, wind);
// wind->window_status |= XAWS_BELOWROOT;
// clear_wind_rectlist(wind);
update_windows_below(0, &wind->r, NULL, wl, NULL);
}
wind = nxt;
}
set_winmouse(-1, -1);
}
void
show_toolboxwindows(struct xa_client *client)
{
struct xa_window *wind = root_window->next, *nxt;
RECT clip;
while (wind)
{
nxt = wind->next;
if (wind->owner == client && (wind->window_status & XAWS_BELOWROOT))
{
wi_move_first(&S.open_windows, wind);
wind->window_status &= ~XAWS_BELOWROOT;
wind->window_status |= XAWS_SEMA;
}
wind = nxt;
}
wind = window_list;
while (wind && wind != root_window)
{
if (wind->window_status & XAWS_SEMA)
{
struct xa_rect_list *rl;
wind->window_status &= ~XAWS_SEMA;
make_rect_list(wind, true, RECT_SYS);
rl = wind->rect_list.start;
while (rl)
{
if (xa_rect_clip(&wind->r, &rl->r, &clip))
generate_redraws(0, wind, &clip, RDRW_ALL);
rl = rl->next;
}
update_windows_below(0, &wind->r, NULL, wind->next, NULL);
}
wind = wind->next;
}
set_winmouse(-1, -1);
}
/*
* ONLY call from from correct context
*/
void
set_window_title(struct xa_window *wind, const char *title, bool redraw)
{
char *dst = wind->wname;
XA_WIDGET *widg;
if (title)
{
int i;
for (i = 0; i < (sizeof(wind->wname)-1) && (*dst++ = *title++); i++)
;
}
*dst = '\0';
widg = get_widget(wind, XAW_TITLE);
widg->stuff = wind->wname;
DIAG((D_wind, wind->owner, " - %s", wind->wname));
/* redraw if necessary */
if (redraw && (wind->active_widgets & NAME) && ((wind->window_status & (XAWS_OPEN|XAWS_HIDDEN)) == XAWS_OPEN))
{
RECT clip;
rp_2_ap(wind, widg, &clip);
display_window(0, 45, wind, &clip);
}
add_window_to_tasklist( wind, title );
}
void
get_window_title(struct xa_window *wind, char *dst)
{
if (dst)
{
char *src = wind->wname;
strcpy(dst, src);
}
}
/*
* ONLY call from from correct context
*/
void
set_window_info(struct xa_window *wind, const char *info, bool redraw)
{
char *dst = wind->winfo;
XA_WIDGET *widg;
if (info)
{
int i;
for (i = 0; i < (sizeof(wind->winfo)-1) && (*dst++ = *info++); i++)
;
}
*dst = '\0';
widg = get_widget(wind, XAW_INFO);
widg->stuff = wind->winfo;
DIAG((D_wind, wind->owner, " - %s", wind->winfo));
if (redraw && (wind->active_widgets & INFO) && (wind->window_status & (XAWS_OPEN|XAWS_SHADED|XAWS_ICONIFIED|XAWS_HIDDEN)) == XAWS_OPEN)
{
RECT clip;
rp_2_ap(wind, widg, &clip);
display_window(0, 46, wind, &clip);
}
}
void
get_window_info(struct xa_window *wind, char *dst)
{
if (dst)
{
char *src = wind->winfo;
strcpy(dst, src);
}
}
#if INCLUDE_UNUSED
STATIC void
send_ontop(enum locks lock)
{
struct xa_window *top = TOP_WINDOW;
struct xa_client *client = top->owner;
if (!client->fmd.wind)
{
if (top->send_message)
top->send_message(lock, top, NULL, AMQ_NORM, QMF_CHKDUP,
WM_ONTOP, 0, 0, top->handle,
0, 0, 0, 0);
}
}
#endif
void
send_topped(enum locks lock, struct xa_window *wind)
{
struct xa_client *client = wind->owner;
if (wind->send_message && (!client->fmd.wind || client->fmd.wind == wind))
wind->send_message(lock, wind, NULL, AMQ_NORM, QMF_CHKDUP,
WM_TOPPED, 0, 0, wind->handle,
0, 0, 0, 0);
}
void
send_bottomed(enum locks lock, struct xa_window *wind)
{
struct xa_client *client = wind->owner;
if (wind->send_message && (!client->fmd.wind || client->fmd.wind == wind))
wind->send_message(lock, wind, NULL, AMQ_NORM, QMF_CHKDUP,
WM_BOTTOMED, 0, 0, wind->handle,
0, 0, 0, 0);
}
void
send_moved(enum locks lock, struct xa_window *wind, short amq, RECT *r)
{
if (wind->send_message)
{
C.move_block = 2;
wind->send_message(lock, wind, NULL, amq, QMF_CHKDUP,
WM_MOVED, 0, 0, wind->handle,
r->x, r->y, r->w, r->h);
}
}
#define WIND_WMIN 64
#define WIND_HMIN 64
void
send_sized(enum locks lock, struct xa_window *wind, short amq, RECT *r)
{
if (!(wind->window_status & XAWS_SHADED))
{
if (wind->send_message)
{
if( r->w < WIND_WMIN )
r->w = WIND_WMIN;
if( r->h < WIND_HMIN )
r->h = WIND_HMIN;
C.move_block = 2;
wind->send_message(lock, wind, NULL, amq, QMF_CHKDUP,
WM_SIZED, 0,0, wind->handle,
r->x, r->y, r->w, r->h);
}
}
}
void
send_reposed(enum locks lock, struct xa_window *wind, short amq, RECT *r)
{
if (wind->send_message)
{
C.move_block = 2;
wind->send_message(lock, wind, NULL, amq, QMF_CHKDUP,
WM_REPOSED, 0,0, wind->handle,
r->x, r->y, r->w, r->h);
}
}
STATIC void
send_redraw(enum locks lock, struct xa_window *wind, RECT *r)
{
if (!(wind->window_status & (XAWS_SHADED|XAWS_HIDDEN)) && wind->send_message)
{
wind->send_message(lock, wind, NULL, AMQ_REDRAW, QMF_CHKDUP,
WM_REDRAW, 0,0, wind->handle,
r->x, r->y, r->w, r->h);
}
}
void
send_vslid(enum locks lock, struct xa_window *wind, short offs)
{
if (wind->send_message)
{
wind->send_message(lock, wind, NULL, AMQ_NORM, QMF_CHKDUP,
WM_VSLID, 0,0, wind->handle,
offs, 0,0,0);
}
}
void
send_hslid(enum locks lock, struct xa_window *wind, short offs)
{
if (wind->send_message)
{
wind->send_message(lock, wind, NULL, AMQ_NORM, QMF_CHKDUP,
WM_HSLID, 0,0, wind->handle,
offs, 0,0,0);
}
}
void
send_closed(enum locks lock, struct xa_window *wind)
{
if (wind->send_message)
{
wind->send_message(lock, wind, NULL, AMQ_NORM, QMF_CHKDUP,
WM_CLOSED, 0, 0, wind->handle,
0,0,0,0);
}
}
void close_window_menu(Tab *tab);
void
setwin_untopped(enum locks lock, struct xa_window *wind, bool snd_untopped)
{
struct xa_client *client = wind->owner;
if( wind != root_window && wind->tool && ((XA_WIDGET *)wind->tool)->m.r.xaw_idx == XAW_MENU )
{
Tab *tab = TAB_LIST_START;
if( tab && tab->wind == wind )
{
close_window_menu( tab );
nap(100);
}
}
if (snd_untopped && wind->send_message && (!client->fmd.wind || client->fmd.wind == wind))
wind->send_message(lock, wind, NULL, AMQ_NORM, QMF_CHKDUP,
WM_UNTOPPED, 0, 0, wind->handle,
0, 0, 0, 0);
}
void
setwin_ontop(enum locks lock, struct xa_window *wind, bool snd_ontop)
{
struct xa_client *client = wind->owner;
if (!client->fmd.wind || (wind == client->fmd.wind))
{
if (wind != root_window && snd_ontop && wind->send_message)
wind->send_message(lock, wind, NULL, AMQ_NORM, QMF_CHKDUP,
WM_ONTOP, 0, 0, wind->handle,
0, 0, 0, 0);
}
}
void
send_iredraw(enum locks lock, struct xa_window *wind, short xaw, RECT *r)
{
if (wind == root_window)
{
if (get_desktop()->owner == C.Aes) {
display_window(lock, 0, wind, r);
} else if (r) {
send_app_message(lock, wind, get_desktop()->owner, AMQ_IREDRAW, QMF_NORM,
WM_REDRAW, xaw, ((long)wind) >> 16, ((long)wind) & 0xffff,
r->x, r->y, r->w, r->h);
} else {
send_app_message(lock, wind, get_desktop()->owner, AMQ_IREDRAW, QMF_NORM,
WM_REDRAW, xaw, ((long)wind) >> 16, ((long)wind) & 0xffff,
0,0,0,0);
}
}
else
{
if (r)
{
if (!is_inside(r, &wind->rwa))
{
send_app_message(lock, wind, NULL, AMQ_IREDRAW, QMF_NORM,
WM_REDRAW, xaw, ((long)wind) >> 16, ((long)wind) & 0xffff,
r->x, r->y, r->w, r->h);
}
}
else
{
send_app_message(lock, wind, NULL, AMQ_IREDRAW, QMF_NORM,
WM_REDRAW, xaw, ((long)wind) >> 16, ((long)wind) & 0xffff,
0,0,0,0);
}
}
}
void
generate_redraws(enum locks lock, struct xa_window *wind, RECT *r, short flags)
{
RECT b;
DIAGS(("generate_redraws: on %d of %s", wind->handle, wind->owner->name));
if ((wind->window_status & (XAWS_OPEN|XAWS_HIDDEN)) == XAWS_OPEN)
{
if (wind != root_window && r && (flags & RDRW_WA) && !is_shaded(wind))
{
struct xa_widget *widg;
if (xa_rect_clip(&wind->rwa, r, &b))
{
send_redraw(lock, wind, &b);
}
if ((widg = usertoolbar_installed(wind)) )
{
if (xa_rect_clip(&widg->ar, r, &b))
{
send_app_message(lock, wind, NULL, AMQ_IREDRAW, QMF_NORM,
WM_REDRAW, widg->m.r.xaw_idx, ((long)wind) >> 16, ((long)wind) & 0xffff,
b.x, b.y, b.w, b.h);
}
}
}
if ((flags & RDRW_EXT))
{
send_iredraw(lock, wind, 0, r);
}
}
DIAGS(("generate_redraws: !"));
}
static void
remove_from_iredraw_queue(enum locks lock, struct xa_window *wind)
{
struct xa_aesmsg_list **msg, *free;
msg = &wind->owner->irdrw_msg;
while (*msg)
{
if ((*msg)->message.irdrw.ptr == wind)
{
free = *msg;
*msg = (*msg)->next;
kfree(free);
kick_mousemove_timeout();
}
else
msg = &(*msg)->next;
}
}
void
iconify_window(enum locks lock, struct xa_window *wind, RECT *r)
{
if ((r->w == -1 && r->h == -1) || (!r->w && !r->h) || (r->y + r->h + cfg.icnfy_b_y != screen.r.h))
*r = free_icon_pos(lock, NULL);
move_window(lock, wind, true, XAWS_ICONIFIED, r->x, r->y, r->w, r->h);
wind->window_status &= ~XAWS_CHGICONIF;
}
void
uniconify_window(enum locks lock, struct xa_window *wind, RECT *r)
{
move_window(lock, wind, true, ~XAWS_ICONIFIED, r->x, r->y, r->w, r->h);
wind->window_status &= ~XAWS_CHGICONIF;
/* reinstall the menu - maybe theres a better place for this */
if( wind->active_widgets & XaMENU )
{
XA_WIDGET *widg = get_widget( wind, XAW_MENU );
if( widg && widg->stuff )
set_menu_widget( wind, wind->owner, widg->stuff );
}
/*
* re-install toolbar to achieve correct vslider
*/
if( (wind->active_widgets & TOOLBAR) && (wind->active_widgets & VSLIDE) )
{
XA_WIDGET *widg = get_widget( wind, XAW_TOOLBAR );
AESPB pb;
short intin[8], intout[8];
intin[0] = wind->handle;
intin[1] = WF_TOOLBAR;
ptr_to_shorts( ((XA_TREE*)widg->stuff)->tree, intin + 2 );
pb.intin = intin;
pb.intout = intout;
/* install toolbar */
XA_wind_set( lock, wind->owner, &pb );
}
set_reiconify_timeout(lock);
}
void _cdecl
top_window(enum locks lock, bool snd_untopped, bool snd_ontop, struct xa_window *w)
{
DIAG((D_wind, NULL, "top_window %d for %s", w->handle, w == root_window ? get_desktop()->owner->proc_name : w->owner->proc_name));
if (w == NULL || w == root_window || (S.focus == w) )
return;
if (w->nolist)
{
setnew_focus(w, NULL, false, snd_ontop, false);
}
else
{
#if WITH_BBL_HELP
if( w != bgem_window && !(w->dial == (created_for_ALERT | created_for_AES)) )
{
if( !C.boot_focus )
xa_bubble( 0, bbl_close_bubble1, 0, 2 );
}
#endif
pull_wind_to_top(lock, w);
setnew_focus(w, NULL, true, snd_untopped, snd_ontop);
}
set_winmouse(-1, -1);
}
void _cdecl
bottom_window(enum locks lock, bool snd_untopped, bool snd_ontop, struct xa_window *w)
{
bool was_top = (is_topped(w) ? true : false);
struct xa_window *wl = w->next, *new_focus;
DIAG((D_wind, w->owner, "bottom_window %d", w->handle));
if (w == w->owner->fmd.wind && w->dial == created_for_FMD_START)
return; // modal dialog
if (w == root_window || wl == root_window)
/* Don't do anything if already bottom */
return;
if (w->nolist)
unset_focus(w);
else
{
/* Send it to the back */
send_wind_to_bottom(lock, w);
if (was_top)
{
if (!(TOP_WINDOW->window_status & XAWS_NOFOCUS))
new_focus = TOP_WINDOW;
else
{
new_focus = window_list;
while (new_focus && new_focus != root_window)
{
if (!(new_focus->window_status & XAWS_NOFOCUS))
break;
new_focus = new_focus->next;
}
}
setnew_focus(new_focus, w, true, snd_untopped, snd_ontop);
}
DIAG((D_wind, w->owner, " - menu_owner %s, w_list_owner %s",
t_owner(get_menu()), w_owner(window_list)));
update_windows_below(lock, &w->r, NULL, wl, w);
}
}
STATIC XA_WIND_ATTR
fix_wind_kind(XA_WIND_ATTR tp)
{
/* avoid confusion: if only 1 specified, give both (fail safe!) */
if (tp & (UPARROW|DNARROW))
tp |= UPARROW|DNARROW|UPARROW1;
else
tp &= ~UPARROW1;
if (tp & (LFARROW|RTARROW))
tp |= LFARROW|RTARROW|LFARROW1;
else
tp &= ~LFARROW1;
/* cant hide a window that cannot be moved. */
if (!(tp & MOVER))
tp &= ~HIDE;
/* temporary until solved. */
if (tp & MENUBAR)
tp |= XaMENU;
return tp;
}
/*
* Create a window
*
* introduced pid -1 for temporary windows created basicly only to be able to do
* calc_work_area and center.
*
* needed a dynamiccally sized frame
*
* ? what if older prgs set HOTCLOSEBOX which is in fact MENUBAR ?
*/
struct xa_window * _cdecl
create_window(
enum locks lock,
SendMessage *message_handler,
DoWinMesag *message_doer,
struct xa_client *client,
bool nolist,
XA_WIND_ATTR tp,
WINDOW_TYPE dial,
int frame,
bool thinwork,
const RECT R,
const RECT *max,
RECT *remember)
{
struct xa_window *w;
struct xa_widget_theme *wtheme;
RECT r;
r = R;
#if GENERATE_DIAGS
if (max)
{
DIAG((D_wind, client, "create_window for %s: r:%d,%d/%d,%d max:%d,%d/%d,%d",
c_owner(client), r.x,r.y,r.w,r.h,max->x,max->y,max->w,max->h));
}
else
{
DIAG((D_wind, client, "create_window for %s: r:%d,%d/%d,%d no max",
c_owner(client), r.x,r.y,r.w,r.h));
}
#endif
w = kmalloc(sizeof(*w));
if (!w) /* Unable to allocate memory for window? */
return NULL;
init_client_widget_theme(client);
if (!(wtheme = client->widget_theme))
{
kfree(w);
return NULL;
}
bzero(w, sizeof(*w));
{
int i;
for (i = 0; i < XA_MAX_WIDGETS; i++)
w->widgets[i].wind = w;
}
w->vdi_settings = client->vdi_settings;
w->min.h = w->min.w = WIND_WMIN;
tp = fix_wind_kind(tp);
w->requested_widgets = tp;
/* implement maximum rectangle (needed for at least TosWin2) */
// w->max = max ? *max : root_window->wa;
if (tp & (UPARROW|DNARROW|LFARROW|RTARROW))
{
w->min.x = w->min.y = -1;
w->min.w = 6 * 16; //cfg.widg_w;
w->min.h = 7 * 16; //cfg.widg_h;
}
else
w->min.w = w->min.h = 0;
if (tp & (MENUBAR))
w->min.h += 20;
if (tp & (INFO))
w->min.h += 10;
w->rc = w->r = w->pr = r;
{
long opts = client->options.wind_opts;
if (client->options.naes_ff)
opts |= XAWO_FULLREDRAW;
w->opts = opts;
}
// w->widget_theme = client->widget_theme;
if (dial & created_for_ALERT)
{
w->class = WINCLASS_ALERT;
w->active_theme = client->widget_theme->alert;
w->window_status |= XAWS_FLOAT;
}
else if (dial & created_for_POPUP)
{
w->class = WINCLASS_POPUP;
w->active_theme = client->widget_theme->popup;
w->window_status |= XAWS_FLOAT|XAWS_NOFOCUS;
}
else if (dial & created_for_SLIST)
{
w->class = WINCLASS_SLIST;
w->active_theme = client->widget_theme->slist;
w->window_status |= XAWS_NOFOCUS;
}
else
{
w->class = WINCLASS_CLIENT;
w->active_theme = client->widget_theme->client;
}
w->active_theme->links++;
(*client->xmwt->new_color_theme)(client->wtheme_handle, w->class, &w->ontop_cols, &w->untop_cols);
w->colours = w->ontop_cols;
w->wheel_mode = client->options.wheel_mode;
w->frame = frame;
w->thinwork = MONO ? true : thinwork;
w->owner = client;
w->handle = -1;
w->nolist = nolist;
w->dial = dial;
w->send_message = message_handler;
w->do_message = message_doer;
get_widget(w, XAW_TITLE)->stuff = client->name;
/*if (dial & created_for_POPUP)
{
w->x_shadow = 1;
w->y_shadow = 1;
}
else
*/
{
w->x_shadow = 1; //2;
w->y_shadow = 1; //2;
}
w->wa_frame = true;
// if (w->frame > 0)
// tp |= BORDER;
if (nolist)
{
if (!(w->dial & (created_for_SLIST | created_for_CALC)))
wi_put_first(&S.closed_nlwindows, w);
/* Attach the appropriate widgets to the window */
DIAGS((" -- nolist window"));
standard_widgets(w, tp, false);
}
else
{
tp &= ~STORE_BACK;
w->handle = new_wind_handle();
DIAG((D_wind, client, " allocated handle = %d", w->handle));
wi_put_first(&S.closed_windows, w);
DIAG((D_wind,client," inserted in closed_windows list"));
/* Attach the appropriate widgets to the window */
standard_widgets(w, tp, false);
#if INCLUDE_UNUSED
/* If STORE_BACK extended attribute is used, window preserves its own background */
if (tp & STORE_BACK)
{
DIAG((D_wind,client," allocating background storage buffer"));
/* XXX the store back code is not failsafe if kmalloc fail */
w->background = kmalloc(calc_back(&r, screen.planes));
assert(w->background);
}
else
#endif
w->background = NULL;
}
calc_work_area(w);
if (max)
{
if (w->opts & XAWO_WCOWORK)
{
w->max = w2f(&w->delta, max, true);
}
else
{
w->max = *max;
}
fitin_root(&w->max);
}
else
w->max = root_window->wa;
calc_shade_height(w);
#if 0
if (tp & (CLOSER|NAME|MOVER|ICONIFIER|FULLER))
{
RECT t;
t = w2f(&w->rbd, &w->widgets[XAW_TITLE].r, true);
w->sh = t.h + w->y_shadow;
}
#endif
if (remember)
*remember = w->r;
return w;
}
void
change_window_attribs(enum locks lock,
struct xa_client *client,
struct xa_window *w,
XA_WIND_ATTR tp,
bool r_is_wa,
bool insideroot,
short noleft,
RECT r, RECT *remember)
{
XA_WIND_ATTR old_tp = w->active_widgets;
DIAG((D_wind, client, "change_window_attribs for %s: r:%d,%d/%d,%d no max",
c_owner(client), r.x,r.y,r.w,r.h));
tp = fix_wind_kind(tp);
standard_widgets(w, tp, false);
if (r_is_wa)
{
w->r = calc_window(lock, client, WC_BORDER,
tp, w->dial,
client->options.thinframe,
client->options.thinwork,
*(RECT *)&r);
}
else
w->r = r;
if (insideroot)
{
bool nl;
switch (noleft)
{
case 1:
nl = false; break;
case 2:
nl = true; break;
case 0:
default:
nl = w->owner->options.noleft;
break;
}
inside_root(&w->r, nl);
}
w->rc = w->r;
if ((w->window_status & XAWS_SHADED))
w->r.h = w->sh;
calc_work_area(w);
clear_wind_rectlist(w);
/* If STORE_BACK extended attribute is used, window preserves its own background */
if (!(tp & STORE_BACK))
{
if ((old_tp & STORE_BACK) && w->background)
{
DIAG((D_wind,client," allocating background storage buffer"));
kfree(w->background);
w->background = NULL;
}
}
else if (!(old_tp & STORE_BACK) && !w->background)
{
/* XXX the store back code is not failsafe if kmalloc fail */
w->background = kmalloc(calc_back(&r, screen.planes));
assert(w->background);
}
calc_shade_height(w);
/*
* Now standard widgets are set and workarea of window
* is recalculated.
* Its time to do non-standard things depending on correct
* workarea coordinates now.
*/
{
struct widget_tree *wt;
if ((wt = get_widget(w, XAW_TOOLBAR)->stuff))
{
set_toolbar_coords(w, NULL);
if (wt->tree && client->p == get_curproc())
{
wt->tree->ob_x = w->wa.x;
wt->tree->ob_y = w->wa.y;
if (!wt->zen)
{
wt->tree->ob_x += wt->ox;
wt->tree->ob_y += wt->oy;
}
}
}
}
if (remember)
*remember = w->r;
}
void remove_window_widgets(enum locks lock, int full)
{
struct xa_window *wind = TOP_WINDOW;
if( wind && !(wind->window_status & XAWS_ICONIFIED) )
{
XA_WIND_ATTR active_widgets;
if( !(wind->window_status & XAWS_RM_WDG) )
{
wind->save_widgets = wind->active_widgets;
active_widgets = 0; // todo: uninstall menu/toolbar
wind->window_status |= XAWS_RM_WDG;
if( full )
{
wind->ro = wind->r;
wind->r = screen.r;
}
}
else
{
wind->window_status &= ~XAWS_RM_WDG;
active_widgets = wind->save_widgets; // todo: re-install menu/toolbar
if( full )
wind->r = wind->ro;
}
change_window_attribs(lock, wind->owner, wind, active_widgets, false, false, 0, wind->r, NULL);
if( full )
{
wind->send_message(lock, wind, NULL, AMQ_REDRAW, QMF_CHKDUP,
WM_SIZED, 0, 0, wind->handle, wind->r.x, wind->r.y, wind->r.w, wind->r.h);
}
if( memcmp( &wind->r, &screen.r, sizeof(RECT) ) )
{
update_windows_below(lock, &screen.r, NULL, window_list, NULL);
}
}
}
int _cdecl
open_window(enum locks lock, struct xa_window *wind, RECT r)
{
struct xa_window *wl = window_list;
RECT clip, our_win;
int ignorefocus = 0;
DIAG((D_wind, wind->owner, "open_window %d for %s to %d/%d,%d/%d status %lx",
wind->handle, c_owner(wind->owner), r.x,r.y,r.w,r.h, wind->window_status));
DBG((0, "open_window %d for %s to %d/%d,%d/%d status %lx,focus=%s,nolist=%d",wind->handle, wind->owner->name, r.x,r.y,r.w,r.h, wind->window_status, S.focus? S.focus->wname:"", wind->nolist));
if (C.redraws) {
yield();
}
if ((wind->window_status & XAWS_OPEN))
{
/* The window is already open, no need to do anything */
DIAGS(("WARNING: Attempt to open window when it was already open"));
set_active_client(lock, wind->owner);
swap_menu(lock|desk, wind->owner, NULL, SWAPM_DESK); // | SWAPM_TOPW);
return 0;
}
if (wind->nolist || (wind->dial & created_for_SLIST))
{
DIAGS(("open_window: nolist window - SLIST wind? %s",
(wind->dial & created_for_SLIST) ? "yes":"no"));
if (wind != root_window && !(wind->dial & (created_for_POPUP | created_for_SLIST)))
{
inside_root(&r, wind->owner->options.noleft);
inside_minmax(&r, wind);
}
wind->rc = wind->r = r;
calc_work_area(wind);
if ((wind->window_status & XAWS_SHADED))
wind->r.h = wind->sh;
wind->window_status |= XAWS_OPEN;
make_rect_list(wind, true, RECT_SYS);
if (wind->active_widgets & STORE_BACK)
{
(*xa_vdiapi->form_save)(0, wind->r, &(wind->background));
}
if (!(wind->dial & created_for_POPUP))
move_ctxdep_widgets(wind);
if (!(wind->dial & created_for_SLIST))
{
wi_remove(&S.closed_nlwindows, wind, false);
wi_put_first(&S.open_nlwindows, wind);
if (!(wind->active_widgets & STORE_BACK))
{
our_win = wind->r;
wl = wind->next;
if (!wl)
wl = window_list;
while (wl)
{
clip = wl->r;
if (xa_rc_intersect(our_win, &clip))
make_rect_list(wl, true, RECT_SYS);
if (!wl->next && wl->nolist)
wl = window_list;
else
wl = wl->next;
if (wl == root_window)
break;
}
}
if (!(wind->window_status & XAWS_NOFOCUS))
wind->colours = wind->untop_cols;
generate_redraws(lock, wind, &wind->r, RDRW_ALL);
}
/* dont open unlisted windows */
return 1;
}
wi_remove(&S.closed_windows, wind, false);
if( (wind->window_status & XAWS_NOFOCUS))
ignorefocus = 1;
else if( (C.boot_focus && wind->owner->p != C.boot_focus))
ignorefocus = 2;
#if WITH_BBL_HELP
DBG((0,"open_window:%s:wind=%lx, bgem_window=%lx, handle=%d, dial=%x,boot_focus=%lx", wind->wname, wind, bgem_window, wind->handle, wind->dial, C.boot_focus ));
if( wind != bgem_window && wind->handle >= 0 && !ignorefocus
&& !(wind->dial && (created_for_ALERT | created_for_AES | created_for_WDIAL)) )
{
xa_bubble( 0, bbl_close_bubble1, 0, 3 );
}
#endif
if (wind != root_window && (wind->window_status & XAWS_BINDFOCUS) && get_app_infront() != wind->owner)
{
wi_put_blast(&S.open_windows, wind, false, true);
wind->window_status |= XAWS_BELOWROOT;
}
else {
wi_put_first(&S.open_windows, wind);
}
/* New top window - change the cursor to this client's choice */
xa_graf_mouse(wind->owner->mouse, wind->owner->mouse_form, wind->owner, false);
if (is_iconified(wind))
{
if (wind != root_window && !(wind->dial & created_for_POPUP))
inside_root(&r, wind->owner->options.noleft);
if (r.w != -1 && r.h != -1)
wind->rc = wind->r = r;
if ((wind->window_status & XAWS_SHADED))
wind->r.h = wind->sh;
}
else
{
/* Change the window coords */
if (wind != root_window && !(wind->dial & created_for_POPUP))
{
inside_root(&r, wind->owner->options.noleft);
//inside_minmax(&r, wind);
}
wind->rc = wind->r = r;
if ((wind->window_status & XAWS_SHADED))
{
wind->r.h = wind->sh;
if (wind->send_message) {
wind->send_message(lock, wind, NULL, AMQ_CRITICAL, QMF_CHKDUP,
WM_SHADED, 0,0, wind->handle, 0,0,0,0);
}
}
}
wind->window_status |= XAWS_OPEN;
calc_work_area(wind);
DBG((0,"open_window:ignorefocus=%d,wind=%s:%s", ignorefocus, wind->wname, wind->owner->name));
if (!ignorefocus && wl && (wl == root_window || wl->owner != wind->owner || !is_infront(wind->owner)))
{
DIAG((D_appl, NULL, "open_window: Change infront app from %s to %s",
wl->owner->name, wind->owner->name));
set_active_client(lock, wind->owner);
swap_menu(lock|desk, wind->owner, NULL, SWAPM_DESK );
}
make_rect_list(wind, true, RECT_SYS);
/*
* Context dependant widgets must always follow the window
* movements
*/
move_ctxdep_widgets(wind);
/* Is this a 'preserve own background' window? */
if (wind->active_widgets & STORE_BACK)
{
if (!(wind->window_status & XAWS_BELOWROOT))
{
(*xa_vdiapi->form_save)(0, wind->r, &(wind->background));
/* This is enough, it is only for TOOLBAR windows. */
generate_redraws(lock, wind, &wind->r, RDRW_ALL);
}
}
else if (!(wind->window_status & XAWS_BELOWROOT))
{
struct xa_rect_list *rl;
wind->colours = wind->untop_cols;
our_win = wind->r;
wl = wind->next;
while (wl)
{
clip = wl->r;
if (xa_rc_intersect(our_win, &clip))
make_rect_list(wl, true, RECT_SYS);
if (wl == root_window)
break;
wl = wl->next;
}
if( !C.boot_focus )
setnew_focus(wind, S.focus, true, true, false);
/* avoid second redraw (see setnew_focus) */
if( wind->dial != created_for_FMD_START )
{
/* Display the window using clipping rectangles from the rectangle list */
rl = wind->rect_list.start;
while (rl)
{
if (xa_rect_clip(&wind->r, &rl->r, &clip)) {
generate_redraws(lock, wind, &clip/*&wind->r*/, RDRW_ALL);
}
rl = rl->next;
}
}
if( C.boot_focus )
{
if( ignorefocus == 0 )
top_window(lock, true, true, wind);
else if( ignorefocus == 2 && wind->send_message )
wind->send_message(lock, wind, NULL, AMQ_NORM, QMF_CHKDUP, WM_UNTOPPED, 0, 0, wind->handle, 0,0,0,0);
}
}
else
{
setnew_focus(wind, S.focus, true, true, false);
}
DIAG((D_wind, wind->owner, "open_window %d for %s exit with 1",
wind->handle, c_owner(wind->owner)));
set_winmouse(-1, -1);
add_window_to_tasklist( wind, NULL );
DBG((0,"open_window %d: return 1", wind->handle));
return 1;
}
bool clip_off_menu( RECT *cl )
{
short d = get_menu_height() - cl->y;
if( cl->h <= d )
return true;
cl->y = get_menu_height();
cl->h -= d;
return false;
}
void
draw_window(enum locks lock, struct xa_window *wind, const RECT *clip)
{
struct xa_vdi_settings *v = wind->vdi_settings;
RECT cl = *clip;
DIAG((D_wind, wind->owner, "draw_window %d for %s to %d/%d,%d/%d",
wind->handle, w_owner(wind),
wind->r.x, wind->r.y, wind->r.w, wind->r.h));
if (!(wind->window_status & XAWS_OPEN) || (wind->dial & created_for_MENUBAR) )
{
DIAG((D_wind, wind->owner, "Dwindow %d for %s not open",
wind->handle, w_owner(wind)));
return;
}
/* is window below menubar? (better should change rectlists?) */
if( wind->handle >= 0 && cfg.menu_layout == 0 && cfg.menu_bar && cl.y < get_menu_height() )
{
if( clip_off_menu( &cl ) )
return;
}
(*v->api->set_clip)(v, &cl);
(*v->api->l_color)(v, G_BLACK);
hidem();
/* Dont waste precious CRT glass */
if (wind != root_window)
{
(*v->api->f_color)(v, objc_rend.dial_colours.bg_col);
(*v->api->f_interior)(v, FIS_SOLID);
if (wind->draw_waframe)
(*wind->draw_waframe)(wind, clip);
if (wind->frame >= 0 && (wind->x_shadow || wind->y_shadow))
{
//shadow_object(0, OS_SHADOWED, &cl, G_BLACK, wind->shadow/2); //SHADOW_OFFSET/2);
shadow_area(v, 0, OS_SHADOWED, &wind->r, G_BLACK, wind->x_shadow, wind->y_shadow);
}
}
/* If the window has an auto-redraw function, call it
* do this before the widgets. (some programs supply x=0, y=0)
*/
/* XXX - Ozk: Extremely not good if draw_window() is to be context indipendant!!!
*/
if (wind->redraw)
{
wind->redraw(lock, wind);
}
{
int f;
WINDOW_STATUS status = wind->window_status;
XA_WIDGET *widg;
RECT r;
if (wind->draw_canvas)
{
(*wind->draw_canvas)(wind, &wind->outer, &wind->inner, clip);
}
for (f = 0; f < XA_MAX_WIDGETS; f++)
{
widg = get_widget(wind, f);
// if (f == XAW_TOOLBAR && wind != root_window && !(wind->dial & created_for_SLIST))
// display("toolbar statusmask %x, properties %x, draw %lx",
// widg->m.statusmask, widg->m.properties, widg->m.r.draw);
if ( (wind != root_window && f == XAW_TOOLBAR) ||
(widg->m.properties & WIP_NOTEXT) ||
(f == XAW_MENU && wind == root_window))
{
continue;
}
if ( !(status & widg->m.statusmask) )
{
if( wdg_is_inst(widg) )
{
DIAG((D_wind, wind->owner, "draw_window %d: display widget %d (func=%lx)",
wind->handle, f, widg->m.r.draw));
if (widg->m.properties & WIP_WACLIP)
{
if (xa_rect_clip(clip, &wind->wa, &r))
{
(*v->api->set_clip)(v, &r);
//if (f == XAW_TOOLBAR) display("drawing toolbar (waclip) for %s,w=%d", wind->owner->name, wind->wa.w);
(*widg->m.r.draw)(wind, widg, &r);
(*v->api->set_clip)(v, clip);
}
}
else
{
//if (f == XAW_TOOLBAR) display("drawing toolbar for %s", wind->owner->name);
widg->m.r.draw(wind, widg, clip );
}
}
else if( f == XAW_MENU && widg->r.w && widg->r.h ) /* draw a bar to avoid transparence */
{
(*v->api->gbar)(v, 0, &widg->ar);
}
//else if( wind->wname[0] )
// BLOG((0,"%s: widget %d not installed", wind->wname, f ));
}
}
}
showm();
DIAG((D_wind, wind->owner, "draw_window %d for %s exit ok",
wind->handle, w_owner(wind)));
}
struct xa_window *
find_window(enum locks lock, short x, short y, short flags)
{
struct xa_window *w = NULL;
if (flags & FNDW_NOLIST)
{
w = nolist_list;
while (w)
{
if (!(w->owner->status & CS_EXITING) && m_inside(x, y, &w->r))
{
return w;
}
w = w->next;
}
}
if (flags & FNDW_NORMAL)
{
w = window_list;
while (w)
{
if (!(w->owner->status & CS_EXITING) && m_inside(x, y, &w->r))
{
break;
}
if (w == root_window)
{
w = NULL;
break;
}
w = w->next;
}
}
return w;
}
struct xa_window *
get_wind_by_handle(enum locks lock, short h)
{
struct xa_window *w;
w = window_list;
while (w)
{
if (w->handle == h)
break;
w = w->next;
}
if (!w)
{
w = S.closed_windows.first;
while (w)
{
if (w->handle == h)
break;
w = w->next;
}
}
return w;
}
bool
wind_exist(enum locks lock, struct xa_window *wind)
{
struct xa_window *w;
w = window_list;
while (w)
{
if (w == wind)
break;
w = w->next;
}
if (!w)
{
w = S.closed_windows.first;
while (w)
{
if (w == wind)
break;
w = w->next;
}
}
return !!w;
}
/*
* Pull this window to the head of the window list
*/
STATIC struct xa_window *
pull_wind_to_top(enum locks lock, struct xa_window *w)
{
struct xa_window *wl, *below, *above;
RECT clip, r;
DIAG((D_wind, w->owner, "pull_wind_to_top %d for %s", w->handle, w_owner(w)));
if (w == root_window) /* just a safeguard */
{
make_rect_list(w, true, RECT_SYS);
}
else if (!(w->owner->status & CS_EXITING))
{
below = w->next;
above = w->prev;
r = w->r;
wi_move_first(&S.open_windows, w);
wl = window_list;
while (wl)
{
if (wl == w)
{
if (w->window_status & XAWS_BELOWROOT)
wl = root_window;
else
wl = above;
while (wl && wl != w)
{
clip = wl->r;
if (xa_rc_intersect(r, &clip))
make_rect_list(wl, true, RECT_SYS);
wl = wl->prev;
}
set_and_update_window(w, true, false, NULL);
break;
}
else if (wl == below)
{
while (wl)
{
clip = wl->r;
if (xa_rc_intersect(r, &clip))
make_rect_list(wl, true, RECT_SYS);
if (wl == w)
break;
wl = wl->next;
}
update_windows_below(lock, &r, NULL, below, w);
break;
}
wl = wl->next;
}
}
return w;
}
void _cdecl
send_wind_to_bottom(enum locks lock, struct xa_window *w)
{
struct xa_window *wl;
RECT r, clip;
if ( w->next == root_window /* Can't send to the bottom a window that's already there */
|| w == root_window /* just a safeguard */
|| !(w->window_status & XAWS_OPEN))
return;
wl = w->next;
r = w->r;
wi_move_blast(&S.open_windows, w);
while (wl)
{
clip = wl->r;
if (xa_rc_intersect(r, &clip))
make_rect_list(wl, true, RECT_SYS);
wl = wl->next;
}
make_rect_list(w, true, RECT_SYS);
}
static void redraw_menu_area(void)
{
RECT r = screen.r;
popout(TAB_LIST_START);
r.h = get_menu_height();
if( cfg.menu_layout || !cfg.menu_bar )
{
RECT rc = screen.r;
short mb = cfg.menu_bar;
cfg.menu_bar = 0;
if( mb )
{
rc.x = get_menu_widg()->r.w;
rc.w -= rc.x;
}
rc.h = r.h;
update_windows_below(0, &rc, &rc, window_list, NULL);
cfg.menu_bar = mb;
if( mb )
redraw_menu(0);
}
}
#if 0
static void print_rect_list( struct xa_window *wind )
{
struct xa_rect_list *rl = wind->rect_list.start;
int i;
BLOG((0, "print_rect_list:%s", wind->wname));
for( i = 0; rl; i++, rl = rl->next )
{
BLOG((0, "%2d:%d/%d/%d/%d", i, rl->r));
}
}
#endif
/*
* set point-size for main-menu
* adjust root-window-size
* also used to switch menubar on/off
*/
void set_standard_point(struct xa_client *client)
{
static int old_menu_bar = -1;
short w, h;
bool new_menu_sz = true;
struct xa_widget *xaw = get_menu_widg(), *xat = get_widget(root_window, XAW_TOOLBAR);
XA_TREE *wt = xat->stuff;
struct xa_vdi_settings *v = client->vdi_settings;
if( C.boot_focus && client->p != C.boot_focus)
return;
if( (cfg.menu_ontop && !menu_window) ) //|| !client->std_menu )
{
new_menu_sz = false;
}
#if 1
/* kludge: if < 1 set menu_bar=0, if != -1 set -standard_font_point */
if( cfg.menu_bar != 2 && client->options.standard_font_point < 0 )
{
client->options.standard_font_point = -client->options.standard_font_point;
if( client->options.standard_font_point == 1 )
client->options.standard_font_point = cfg.standard_font_point;
cfg.menu_bar = 0;
}
#endif
(*v->api->t_font)(client->vdi_settings, client->options.standard_font_point, cfg.font_id);
(*v->api->t_extent)(client->vdi_settings, "X", &w, &h );
screen.c_max_w = w;
screen.standard_font_point = client->options.standard_font_point;
if( new_menu_sz == true && cfg.menu_bar != 2 && cfg.menu_layout == 1 && client->std_menu )
{
xaw->r.w = xaw->ar.w = client->std_menu->area.w + 1;
//print_rect_list( root_window );
if( !cfg.menu_ontop )
redraw_menu_area();
}
if( h == screen.c_max_h && (cfg.menu_bar == 2 || (cfg.menu_bar == old_menu_bar && cfg.menu_layout == 0)) )
{
return;
}
old_menu_bar = cfg.menu_bar;
screen.standard_font_height = v->font_h;
screen.c_max_h = h;
if( new_menu_sz == true )
{
C.Aes->std_menu->tree->ob_height = h + 2;
xaw->r.h = xaw->ar.h = xat->r.h = xat->ar.h = h + 2;
if( cfg.menu_bar == 2 || (cfg.menu_bar == 1 && !cfg.menu_layout && !cfg.menu_ontop) )
{
root_window->wa.h = screen.r.h - xaw->r.h;
root_window->wa.y = xaw->r.h;
}
else
{
root_window->wa.h = screen.r.h;
root_window->wa.y = 0;
}
if( menu_window && cfg.menu_bar != 2 && cfg.menu_ontop && cfg.menu_bar )
{
menu_window->r.w = xaw->r.w;
menu_window->r.h = xaw->r.h;
if( menu_window->window_status & XAWS_OPEN)
{
move_window( 0, menu_window, true, 0, menu_window->r.x, menu_window->r.y, menu_window->r.w, menu_window->r.h );
redraw_menu_area();
}
}
//RECT rc = screen.r;
//update_windows_below(0, &rc, &rc, window_list, NULL);
root_window->rwa = root_window->wa;
if (get_desktop()->owner == C.Aes)
{
wt->tree->ob_height = root_window->wa.h;
wt->tree->ob_y = root_window->wa.y;
}
}
}
/*
* md=-2: off if was -1
* md=-1: on temp.
* else: set md
*/
void toggle_menu(enum locks lock, short md)
{
struct xa_client *client = menu_owner();
if( cfg.menu_bar == 2 )
return;
if( !client )
return;
if( md == -2 )
{
if( cfg.menu_bar == -1 )
md = 0;
else return;
}
if( md != -1 ){
if( cfg.menu_bar == md )
{
redraw_menu(lock);
return;
}
cfg.menu_bar = md;
}
else
if( ++cfg.menu_bar > 1 )
cfg.menu_bar = 0;
set_standard_point( client );
if( cfg.menu_bar )
{
#if WITH_BBL_HELP
xa_bubble( 0, bbl_close_bubble1, 0, 4 );
#endif
if( cfg.menu_ontop )
{
open_window(0, menu_window, menu_window->r );
}
redraw_menu(lock);
}
else
{
if( cfg.menu_ontop )
{
close_window(0, menu_window);
}
redraw_menu_area();
}
}
/*
* Change an open window's coordinates, updating rectangle lists as appropriate
*/
void _cdecl
move_window(enum locks lock, struct xa_window *wind, bool blit, WINDOW_STATUS newstate, short X, short Y, short W, short H)
{
IFDIAG(struct xa_client *client = wind->owner;)
RECT old, new;
DIAG((D_wind,client,"move_window(%s) %d for %s from %d/%d,%d/%d to %d/%d,%d,%d",
(wind->window_status & XAWS_OPEN) ? "open" : "closed",
wind->handle, c_owner(client), wind->r.x,wind->r.y,wind->r.w,wind->r.h, X,Y,W,H));
if (wind->owner->status & CS_EXITING)
return;
new.x = X;
new.y = Y;
new.w = W;
new.h = H;
old = wind->r;
if( BELOW_FOREIGN_MENU(old.y) )
{
blit = false;
}
if (!wind->nolist && C.redraws)
yield();
if (newstate != -1L)
{
blit = false;
if (newstate & XAWS_SEMA)
{
if (!(newstate & XAWS_ICONIFIED))
{
if (is_iconified(wind))
{
DIAGS(("move_window: Clear iconified"));
standard_widgets(wind, wind->save_widgets, true);
#if GENERATE_DIAGS
if ((wind->window_status & XAWS_SHADED))
{
DIAGS(("move_window: %d/%d/%d/%d - uniconify shaded window",
new));
}
#endif
}
}
#if GENERATE_DIAGS
if (!(newstate & XAWS_SHADED))
{
DIAGS(("move_window: clear shaded"));
}
#endif
if (newstate == ~XAWS_FULLED)
{
blit = false;
wind->pr = wind->rc;
DIAGS(("move_window: unFULLED"));
}
wind->window_status &= newstate;
}
else
{
if ((newstate & XAWS_ICONIFIED))
{
DIAGS(("move_window: set iconified"));
if (!is_iconified(wind))
{
wind->save_widgets = wind->active_widgets;
wind->save_delta = wind->delta;
wind->save_wadelta = wind->wadelta;
standard_widgets(wind, (wind->active_widgets & (NO_TOPPED)) | NAME|MOVER|ICONIFIER, true);
wind->ro = wind->rc;
}
}
#if GENERATE_DIAGS
if ((newstate & XAWS_SHADED))
{
DIAGS(("move_window: set shaded"));
}
#endif
if (newstate == XAWS_FULLED)
{
blit = false;
wind->pr = wind->rc;
DIAGS(("move_window: win is FULLED"));
}
wind->window_status |= newstate;
}
}
else
{
#if GENERATE_DIAGS
if ((wind->window_status & XAWS_SHADED))
{
DIAGS(("move_window: win is shaded"));
}
#endif
wind->pr = wind->rc;
}
inside_root(&new, wind->owner->options.noleft);
if( !cfg.menu_ontop && (cfg.menu_bar&1) && old.y != wind->r.y && old.y < get_menu_height() )
{
blit = false;
}
set_and_update_window(wind, blit, false, &new);
if ((wind->window_status & XAWS_OPEN) && !(wind->dial & created_for_SLIST) && !(wind->active_widgets & STORE_BACK))
{
struct xa_window *nxt = wind->nolist ? (wind->next ? wind->next : window_list) : wind->next;
update_windows_below(lock, &old, &new, nxt, NULL);
}
/*
* If moving the window did not result in any WM_REDRAWS
* being generated (C.move_block is set to 3 when WM_REDRAWS
* are added to a clients msg queue), we release move_block here
*/
if (!C.redraws && C.move_block != 3)
C.move_block = 0;
{
short y = old.y < new.y ? old.y : new.y;
if( !cfg.menu_ontop && cfg.menu_bar && y < get_menu_height() )
{
C.rdm = 1;
}
}
}
/*
* Close an open window and re-display any windows underneath it.
* Also places window in the closed_windows list but does NOT delete it
* - the window will still exist after this call.
*/
bool _cdecl
close_window(enum locks lock, struct xa_window *wind)
{
struct xa_window *wl, *w = NULL;
struct xa_client *client = wind->owner;
RECT r;
bool is_top, ignorefocus = false;
short dial;
if (wind == NULL)
{
DIAGS(("close_window: null window pointer"));
/* Invalid window handle, return error */
return false;
}
DIAG((D_wind, wind->owner, "close_window: %d (%s)",
wind->handle, (wind->window_status & XAWS_OPEN) ? "open" : "closed"));
if (!(wind->window_status & XAWS_OPEN))
return false;
if (wind == C.hover_wind)
{
#if WITH_BBL_HELP
//if( !C.boot_focus )
bubble_show(0); // cancel pending bubble
#endif
C.hover_wind = NULL;
C.hover_widg = NULL;
}
if( !C.shutdown )
add_window_to_tasklist( wind, (char *)-1);
if (!(wind->dial & (created_for_SLIST|created_for_CALC)))
cancel_winctxt_popup(lock, wind, NULL);
if (wind->nolist)
{
DIAGS(("close_window: nolist window %d, bkg=%lx",
wind->handle, wind->background));
cancel_do_winmesag(lock, wind);
if (!(wind->dial & created_for_SLIST))
{
if (!wind->next && wind->nolist)
{
wl = window_list;
}
else
{
wl = wind->next;
}
wi_remove(&S.open_nlwindows, wind, true);
wi_put_first(&S.closed_nlwindows, wind);
r = wind->r;
if (!(wind->active_widgets & STORE_BACK) && !C.shutdown )
update_windows_below(lock, &r, NULL, wl, NULL);
unset_focus(wind);
}
if ((wind->active_widgets & STORE_BACK))
{
(*xa_vdiapi->form_restore)(0, wind->r, &(wind->background));
}
clear_wind_rectlist(wind);
wind->window_status &= ~XAWS_OPEN;
remove_from_iredraw_queue(lock, wind);
return true;
}
is_top = is_topped(wind);
ignorefocus = (wind->window_status & XAWS_NOFOCUS) ? true : false;
wl = wind->next;
wi_remove(&S.open_windows, wind, true);
wi_put_first(&S.closed_windows, wind);
remove_from_iredraw_queue(lock, wind);
r = wind->r;
dial = wind->dial;
clear_wind_rectlist(wind);
/* Tag window as closed */
wind->window_status &= ~(XAWS_OPEN);
if (!(wind->window_status & XAWS_BELOWROOT))
{
if (!wl)
wl = window_list;
if( !C.shutdown )
update_windows_below(lock, &r, NULL, wl, NULL);
if (is_top)
{
if (wind->active_widgets & STORE_BACK)
{
(*xa_vdiapi->form_restore)(0, wind->r, &(wind->background));
return true;
}
w = window_list;
while (w && w != root_window)
{
if ((w->owner == client || (!(w->dial & created_for_AES) && (client == C.Hlp /*dial & created_for_AES*/)))
&& !(w->window_status & (XAWS_ICONIFIED|XAWS_HIDDEN|XAWS_NOFOCUS)))
{
if (w != TOP_WINDOW)
{
top_window(lock|winlist, true, true, w);
}
else
{
setnew_focus(w, NULL, true, true, true);
set_and_update_window(w, true, true, NULL);
}
wl = w->next;
break;
}
w = w->next;
}
if (w == root_window || (w->owner->status & CS_EXITING))
w = NULL;
}
if (!C.shutdown && !ignorefocus && TOP_WINDOW && is_top && !w
&& !(dial & (created_for_WDIAL|created_for_FORM_DO|created_for_FMD_START)) )
{
switch (client->options.clwtna)
{
case 0: /* Keep active client ontop */
{
break;
}
default:
case 1: /* Top app who owns window below closed one */
{
if ((w = TOP_WINDOW) && w != root_window)
{
do
{
if (!(w->window_status & (XAWS_ICONIFIED|XAWS_HIDDEN|XAWS_NOFOCUS)) && !(w->owner->status & CS_EXITING))
break;
} while ((w = w->next) && w != root_window);
}
if (w && w != root_window)
{
top_window(lock, true, true, w);
}
else if (w == root_window)
{
app_in_front(lock, desktop_owner(), true, true, true);
}
else
{
app_in_front(lock, previous_client(lock, 1), true, true, false);
}
break;
}
case 2: /* Top the client previously topped */
{
app_in_front(lock, previous_client(lock, 1), true, true, false);
break;
}
}
}
}
if( !C.shutdown )
set_winmouse(-1, -1);
return true;
}
static void
free_standard_widgets(struct xa_window *wind)
{
int i;
DIAGS(("free_standard_widgets: wind %d of %s", wind->handle, wind->owner->name));
for (i = 0; i < XA_MAX_WIDGETS; i++)
{
//DIAGS(("call remove_widget for widget %d", i));
remove_widget(0, wind, i);
}
DIAGS(("free_standard_widgets: !"));
}
static void
delete_window1(enum locks lock, struct xa_window *wind)
{
struct xa_client *client = wind->owner;
/* Ozk: I dont think this is really necessary here as it should
* should be done when closing the window..
*/
if (wind == C.hover_wind)
{
C.hover_wind = NULL;
C.hover_widg = NULL;
xa_graf_mouse(ARROW, NULL, NULL, false);
}
// cancel_do_winmesag(lock, wind);
if (!wind->nolist)
{
DIAG((D_wind, wind->owner, "delete_window1 %d for %s: open? %s",
wind->handle, w_owner(wind),
(wind->window_status & XAWS_OPEN) ? "yes" : "no"));
//assert(!(wind->window_status & XAWS_OPEN));
if( (wind->window_status & XAWS_OPEN) )
{
return; /* ?? */
}
/* Call the window destructor if any */
if (wind->destructor)
wind->destructor(lock|winlist, wind);
free_standard_widgets(wind);
free_wind_handle(wind->handle);
if (wind->background)
kfree(wind->background);
}
else
{
DIAGS(("delete_window1: nolist window %d, bgk=%lx", wind->handle, wind->background));
if (wind->destructor)
wind->destructor(lock, wind);
free_standard_widgets(wind);
if (wind->background)
kfree(wind->background);
}
clear_wind_rectlist(wind);
if (wind->widg_rows)
kfree(wind->widg_rows);
if (wind->ontop_cols)
{
(*client->xmwt->free_color_theme)(client->wtheme_handle, wind->ontop_cols);
}
if (wind->untop_cols)
{
(*client->xmwt->free_color_theme)(client->wtheme_handle, wind->untop_cols);
}
if (wind->active_theme) //wind->widget_theme && wind->widget_theme->active)
{
wind->active_theme->links--;
}
free_xa_data_list(&wind->xa_data);
kfree(wind);
}
static void
CE_delete_window(enum locks lock, struct c_event *ce, short cancel)
{
// if (!strnicmp(ce->client->proc_name, "gfa_xref", 8))
// display("CE_del_wind %lx", ce->ptr1);
/*
* Since the window in this event already have been removed from
* all stacks, we perform this deletion even when cancel flag is set
*/
//if (!cancel)
delete_window1(lock, ce->ptr1);
}
void _cdecl
delete_window(enum locks lock, struct xa_window *wind)
{
/* We must be sure it is in the correct list. */
if ((wind->window_status & XAWS_OPEN))
{
DIAG((D_wind, wind->owner, "delete_window %d: not closed", wind->handle));
/* open window, return error */
return;
}
if (wind->nolist)
{
if (wind->dial & created_for_CALC)
wi_remove(&S.calc_windows, wind, false);
else if (!(wind->dial & created_for_SLIST))
wi_remove(&S.closed_nlwindows, wind, false);
}
else
wi_remove(&S.closed_windows, wind, false);
if (!(wind->dial & (created_for_SLIST|created_for_CALC)))
{
cancel_winctxt_popup(lock, wind, NULL);
remove_from_iredraw_queue(lock, wind);
}
cancel_do_winmesag(lock, wind);
post_cevent(wind->owner, CE_delete_window, wind, NULL, 0,0, NULL, NULL);
//delete_window1(lock, wind);
}
void _cdecl
delayed_delete_window(enum locks lock, struct xa_window *wind)
{
DIAG((D_wind, wind->owner, "delayed_delete_window %d for %s: open? %s",
wind->handle, w_owner(wind),
(wind->window_status & XAWS_OPEN) ? "yes":"no" ));
/* We must be sure it is in the correct list. */
if ((wind->window_status & XAWS_OPEN))
{
DIAG((D_wind, wind->owner, "delayed_delete_window %d: not closed", wind->handle));
/* open window, return error */
return;
}
if (wind->nolist)
{
if (!(wind->dial & created_for_SLIST))
wi_remove(&S.closed_nlwindows, wind, false);
}
else
wi_remove(&S.closed_windows, wind, false);
if (!(wind->dial & (created_for_SLIST|created_for_CALC)))
{
cancel_winctxt_popup(lock, wind, NULL);
remove_from_iredraw_queue(lock, wind);
}
cancel_do_winmesag(lock, wind);
post_cevent(wind->owner, CE_delete_window, wind, NULL, 0,0, NULL, NULL);
//wi_put_first(&S.deleted_windows, wind);
}
void
do_delayed_delete_window(enum locks lock)
{
struct xa_window *wind = S.deleted_windows.first;
DIAGS(("do_delayed_delete_window"));
while (wind)
{
/* remove from list */
wi_remove(&S.deleted_windows, wind, false);
/* final delete */
if( wind == menu_window || wind == root_window )
BLOG((0,"do_delayed_delete_window:ERROR:wind=%s", wind == menu_window ? "menu-window" : "root-window" ));
else
delete_window1(lock, wind);
/* anything left? */
wind = S.deleted_windows.first;
}
}
/*
* Context dependant !!!
*
* which unused!
*/
void
display_window(enum locks lock, int which, struct xa_window *wind, RECT *clip)
{
if (!(wind->owner->status & CS_EXITING) && (wind->window_status & XAWS_OPEN))
{
{
struct xa_rect_list *rl;
RECT d;
rl = (wind->dial & created_for_SLIST) && wind->parent ? wind->parent->rect_list.start : wind->rect_list.start;
while (rl)
{
if (clip)
{
if (xa_rect_clip(clip, &rl->r, &d))
{
draw_window(lock, wind, &d);
}
}
else
{
draw_window(lock, wind, &rl->r);
}
rl = rl->next;
}
}
(*wind->vdi_settings->api->clear_clip)(wind->vdi_settings);
}
}
void
update_all_windows(enum locks lock, struct xa_window *wl)
{
while (wl)
{
if (wl != root_window && !(wl->owner->status & CS_EXITING) && (wl->window_status & XAWS_OPEN))
{
set_and_update_window(wl, true, false, NULL);
}
(*wl->vdi_settings->api->clear_clip)(wl->vdi_settings);
wl = wl->next;
}
}
/*
* Display a window that isn't on top, respecting clipping
* - Pass clip == NULL to redraw whole window, otherwise clip is a pointer to a GRECT that
* defines the clip rectangle.
*/
void
update_windows_below(enum locks lock, const RECT *old, RECT *new, struct xa_window *wl, struct xa_window *wend)
{
RECT clip;
enum locks wlock = lock | winlist;
DIAGS(("update_windows_below: ..."));
if (!wl)
return;
do
{
if (wend && wend == wl)
break;
if (!(wl->owner->status & CS_EXITING) && (wl->window_status & XAWS_OPEN))
{
/* Check for newly exposed windows */
if (xa_rect_clip(old, &wl->r, &clip))
{
struct xa_rect_list *rl;
RECT d;
make_rect_list(wl, true, RECT_SYS);
rl = wl->rect_list.start;
while (rl)
{
if (xa_rect_clip(&rl->r, &clip, &d))
{
generate_redraws(wlock, wl, &d, RDRW_ALL);
}
rl = rl->next;
}
/* if XaAES-window wait to avoid redraw-error */
if( wl->owner == C.Hlp )
yield();
}
else if (new)
{
/* Check for newly covered windows */
if (xa_rect_clip(new, &wl->r, &clip))
{
/* We don't need to send a redraw to
* these windows, we just have to update
* their rect lists */
make_rect_list(wl, true, RECT_SYS);
}
}
}
} while (wl != root_window && (wl = ((!wl->next && wl->nolist) ? window_list : wl->next)));
DIAGS(("update_windows_below: !"));
}
/*
* Typically called after client have been 'lagging',
* Redraw and send a FULL SET of WM_REDRAWS for all windows owned by
* the client going non-lagged.
* Context dependant!
*/
static int
get_lost_redraw_msg(struct xa_client *client, union msg_buf *buf)
{
struct xa_aesmsg_list *msg;
int rtn = 0;
msg = client->lost_rdrw_msg;
if (msg)
{
/* dequeue */
client->lost_rdrw_msg = msg->next;
/* write to client */
*buf = msg->message;
DIAG((D_m, NULL, "Got pending WM_REDRAW (%lx (wind=%d, %d/%d/%d/%d)) for %s",
msg, buf->m[3], *(RECT *)&buf->m[4], c_owner(client) ));
kfree(msg);
rtn = 1;
// kick_mousemove_timeout();
}
// else if (C.redraws)
// yield();
return rtn;
}
void
redraw_client_windows(enum locks lock, struct xa_client *client)
{
struct xa_window *wl;
struct xa_rect_list *rl;
union msg_buf buf;
bool makerl = true;
RECT r;
while (get_lost_redraw_msg(client, &buf))
{
if (get_desktop()->owner == client)
{
wl = root_window;
if (makerl) make_rect_list(wl, true, RECT_SYS);
rl = wl->rect_list.start;
while (rl)
{
if (xa_rect_clip(&rl->r, (RECT *)&buf.m[4], &r))
{
generate_redraws(lock, wl, &r, RDRW_ALL);
}
rl = rl->next;
}
}
wl = root_window->prev;
while (wl)
{
if (wl->owner == client && (wl->window_status & XAWS_OPEN))
{
if (makerl) make_rect_list(wl, true, RECT_SYS);
rl = wl->rect_list.start;
while (rl)
{
if (xa_rect_clip(&rl->r, (RECT *)&buf.m[4], &r))
{
generate_redraws(lock, wl, &r, RDRW_ALL);
}
rl = rl->next;
}
}
wl = wl->prev;
}
makerl = false;
}
}
RECT
w2f(RECT *d, const RECT *in, bool chkwh)
{
RECT r;
r.x = in->x - d->x; //(wind->rwa.x - wind->r.x);
r.y = in->y - d->y; //(wind->rwa.y - wind->r.y);
r.w = in->w + d->w; //(wind->r.w - wind->rwa.w);
r.h = in->h + d->h; //(wind->r.h - wind->rwa.h);
if (chkwh && (r.w <= 0 || r.h <= 0))
r.w = r.h = 0;
return r;
}
RECT
f2w(RECT *d, const RECT *in, bool chkwh)
{
RECT r;
r.x = in->x + d->x; //(wind->rwa.x - wind->r.x);
r.y = in->y + d->y; //(wind->rwa.y - wind->r.y);
r.w = in->w - d->w; //(wind->r.w - wind->rwa.w);
r.h = in->h - d->h; //(wind->r.h - wind->rwa.h);
if (chkwh && (r.w <= 0 || r.h <= 0))
r.w = r.h = 0;
return r;
}
/*
* Calculate window sizes
*
* HR: first intruduction of the use of a fake window (pid=-1) for calculations.
* (heavily used by multistrip, as an example.)
*/
#if 0
static void
Xpolate(RECT *r, RECT *o, RECT *i)
{
/* If you want to prove the maths here, draw two boxes one inside
* the other, then sit and think about it for a while...
* HR: very clever :-)
*/
r->x = 2 * o->x - i->x;
r->y = 2 * o->y - i->y;
r->w = 2 * o->w - i->w;
r->h = 2 * o->h - i->h;
}
#endif
static struct xa_wc_cache *
add_wcc_entry(struct xa_window *wind)
{
struct xa_wc_cache *new;
struct xa_client *client = wind->owner;
new = kmalloc(sizeof(*new));
if (new)
{
new->next = client->wcc;
client->wcc = new;
new->class = wind->class;
// new->wtheme_handle = themekey; //client->wtheme_handle;
new->tp = wind->requested_widgets;
new->delta = wind->delta;
new->wadelta = wind->wadelta;
}
return new;
}
void
delete_wc_cache(struct xa_wc_cache **wcc)
{
while (*wcc)
{
struct xa_wc_cache *n = *wcc;
*wcc = n->next;
kfree(n);
}
}
static struct xa_wc_cache *
lookup_wcc_entry(struct xa_client *client, short class, XA_WIND_ATTR tp)
{
struct xa_wc_cache *wcc = client->wcc;
while (wcc)
{
if (wcc->tp == tp && wcc->class == class) //client->wtheme_handle)
break;
wcc = wcc->next;
}
return wcc;
};
RECT
calc_window(enum locks lock, struct xa_client *client, int request, XA_WIND_ATTR tp, WINDOW_TYPE dial, int thinframe, bool thinwork, RECT r)
{
struct xa_window *w_temp;
struct xa_wc_cache *wcc;
short class;
RECT o;
DIAG((D_wind,client,"calc %s from %d/%d,%d/%d", request ? "work" : "border", r));
tp = fix_wind_kind(tp);
dial |= created_for_CALC;
if (dial & created_for_POPUP)
class = WINCLASS_POPUP;
else if (dial & created_for_ALERT)
class = WINCLASS_ALERT;
else
class = WINCLASS_CLIENT;
wcc = lookup_wcc_entry(client, class, tp);
if (!wcc)
{
w_temp = create_window(lock, NULL, NULL, client, true, tp, dial, thinframe, thinwork, r, 0,0);
wcc = add_wcc_entry(w_temp);
delete_window(lock, w_temp);
}
if (wcc)
{
switch (request)
{
case WC_BORDER:
{
o = w2f(&wcc->delta, &r, false);
break;
}
default:
{
o = f2w(&wcc->delta, &r, false);
break;
}
}
}
else
{
o = r;
}
return o;
}
/*
* two x-adjacend rects; y equal or outside wa: join
* when generating redraws
*
* cannot change window's rl (?)
*/
static bool join_redraws( short wlock, struct xa_window *wind, struct xa_rect_list *newrl, short flags )
{
short y11 = newrl->r.y, y12 = newrl->r.y + newrl->r.h, y21 = newrl->next->r.y, y22 = newrl->next->r.y + newrl->next->r.h,
x12 = newrl->r.x + newrl->r.w, x21 = newrl->next->r.x, x22 = newrl->next->r.x + newrl->next->r.w, x11 = newrl->r.x,
way1 = wind->wa.y, way2 = wind->wa.y + wind->wa.h;
/* two x-adjacend rects; y equal or outside wa: join */
if( (y11 == y21 || (y11 < way1 && y21 < way1)) && (y12 == y22 || (y12 >= way2 && y22 >= way2)) && (x21 == x12 || x22 == x11) )
{
RECT r;
r.y = y11 < y21 ? y11 : y21;
r.h = y12 > y22 ? y12 : y22;
r.h -= r.y;
r.x = x11 < x21 ? x11 : x21;
r.w = newrl->r.w + newrl->next->r.w;
generate_redraws(wlock, wind, &r, flags );
return true;
}
return false;
}
STATIC void
set_and_update_window(struct xa_window *wind, bool blit, bool only_wa, RECT *new)
{
short dir, resize, xmove, ymove, wlock = 0;
struct xa_rect_list *oldrl, *orl, *newrl, *brl, *prev, *next, *rrl, *nrl;
RECT bs, bd, old, wa, oldw;
DIAGS(("set_and_update_window:"));
old = wind->r;
oldw = wind->wa;
if (new)
{
wind->rc = wind->t = *new;
if ((wind->window_status & XAWS_SHADED))
{
new->h = wind->sh;
}
wind->r = *new;
calc_work_area(wind);
}
else
new = &wind->r;
wa = wind->wa;
xmove = new->x - old.x;
ymove = new->y - old.y;
resize = new->w != old.w || new->h != old.h ? 1 : 0;
#if WITH_BBL_HELP
if( !C.boot_focus )
bubble_show(0); // cancel pending bubble
#endif
if (xmove || ymove || resize)
{
/*
* Always update the true (actual) screen coordinates
* of the widgets that must be redrawn context
* dependantly
*/
move_ctxdep_widgets(wind);
/* XXX - This makes set_and_update_window() context dependant
* when moving windows!!
*/
//if (xmove || ymove)
{
XA_WIDGET *widg = get_widget(wind, XAW_TOOLBAR);
XA_TREE *wt = widg->stuff;
/* Temporary hack 070702 */
if (wt && wt->tree)
{
/* this moves the origin of the window -
objects (e.g.buttons) have to be moved by the client
*/
wt->tree->ob_x = wind->wa.x;
wt->tree->ob_y = wind->wa.y;
if (!wt->zen)
{
wt->tree->ob_x += wt->ox;
wt->tree->ob_y += wt->oy;
}
}
}
}
if (!(wind->window_status & XAWS_OPEN))
return;
#if 1
if ((wind->dial & created_for_SLIST))
return;
if ((wind->nolist && (wind->active_widgets & STORE_BACK))/* || (wind->dial & created_for_SLIST)*/)
{
if (xmove || ymove || resize)
{
if (wind->active_widgets & STORE_BACK)
(*xa_vdiapi->form_restore)(0, old, &(wind->background));
make_rect_list(wind, true, RECT_SYS);
if (wind->active_widgets & STORE_BACK)
{
(*xa_vdiapi->form_save)(0, wind->r, &(wind->background));
}
//if (!(wind->dial & created_for_SLIST)) // && !(wind->active_widgets & STORE_BACK))
{
generate_redraws(wlock, wind, (RECT *)&wind->r, !only_wa ? RDRW_ALL : RDRW_WA);
}
}
return;
}
#endif
oldrl = wind->rect_list.start;
wind->rect_list.start = wind->rect_list.next = NULL;
newrl = make_rect_list(wind, false, RECT_SYS);
wind->rect_list.start = newrl;
//blit = 1;
if (blit && oldrl && newrl)
{
//DIAGS(("old win=(%d/%d/%d/%d), new win=(%d/%d/%d/%d)",
// old, *new));
if (xmove || ymove)
{
if (ymove > 0)
dir = 1;
else
{
dir = 0;
ymove = -ymove;
}
if (xmove > 0)
{
dir |= 2;
}
else
xmove = -xmove;
}
else
dir = 4;
brl = NULL;
oldw.x -= old.x;
oldw.y -= old.y;
wa.x = wind->wa.x - new->x;
wa.y = wind->wa.y - new->y;
wa.w = wind->wa.w;
wa.h = wind->wa.h;
/* increase width of workarea by vslider-width if toolbar installed */
if( (wind->active_widgets & TOOLBAR) && (wind->active_widgets & VSLIDE) )
{
XA_WIDGET *widg = get_widget(wind, XAW_VSLIDE);
wa.w += widg->ar.w;
}
/*
* Convert to relative coords
*/
orl = oldrl;
prev = NULL;
while (orl)
{
orl->r.x -= old.x;
orl->r.y -= old.y;
if (resize)
{
if (!xa_rect_clip(&oldw, &orl->r, &orl->r))
{
if (prev)
prev->next = orl->next;
else
oldrl = orl->next;
nrl = orl;
orl = orl->next;
kfree(nrl);
//DIAGS(("kfree %lx (unused oldrl)", nrl));
}
else
{
prev = orl;
orl = orl->next;
}
}
else
orl = orl->next;
}
while (newrl)
{
bs.x = newrl->r.x - new->x;
bs.y = newrl->r.y - new->y;
bs.w = newrl->r.w;
bs.h = newrl->r.h;
if (resize)
{
if (!xa_rect_clip(&wa, &bs, &bs))
orl = NULL;
else
orl = oldrl;
}
else
orl = oldrl;
while (orl)
{
//DIAGS(("Check for common areas (newrl=%d/%d/%d/%d, oldrl=%d/%d/%d/%d)", bs, orl->r));
if (xa_rect_clip(&bs, &orl->r, &bd))
{
// if (dir == 3)
// display(" %04d/%04d/%04d/%04d", bd);
nrl = kmalloc(sizeof(*nrl));
assert(nrl);
//DIAGS(("kmalloc %lx (%ld bytes) blitrect", nrl, sizeof(*nrl)));
//DIAGS(("COMMON brl=%lx, nrl=%lx, brl->nxt=%lx", brl, nrl, brl ? (long)brl->next : 0xFACEDACE));
if (brl)
{
struct xa_rect_list *n, *p;
short ox2; // = bd.x + bd.w;
short oy2; // = bd.y + bd.h;
switch (dir)
{
case 0: // up/left
{
ox2 = bd.x + bd.w;
oy2 = bd.y + bd.h;
n = brl;
p = NULL;
while (n)
{
if ( (bd.x < n->r.x && ox2 <= n->r.x) ||
((n->r.x + n->r.w) > bd.x && oy2 <= n->r.y) )
{
if (p)
{
nrl->next = n;
p->next = nrl;
}
else
{
nrl->next = brl;
brl = nrl;
}
break;
}
p = n;
n = n->next;
}
if (!n)
{
p->next = nrl;
nrl->next = NULL;
}
break;
}
case 1: // down/left
{
ox2 = bd.x + bd.w;
n = brl;
p = NULL;
while (n)
{
if ( (bd.x < n->r.x && ox2 <= n->r.x) ||
((n->r.x + n->r.w) > bd.x && (n->r.y + n->r.h) <= bd.y) )
{
if (p)
{
nrl->next = n;
p->next = nrl;
}
else
{
nrl->next = brl;
brl = nrl;
}
break;
}
p = n;
n = n->next;
}
if (!n)
{
p->next = nrl;
nrl->next = NULL;
}
break;
}
case 2: // up/right
{
ox2 = bd.x + bd.w;
oy2 = bd.y + bd.h;
n = brl;
p = NULL;
while (n)
{
if ( (ox2 > (n->r.x + n->r.w) && bd.x >= (n->r.x + n->r.w)) ||
((n->r.x + n->r.w) < bd.x && oy2 <= n->r.y) )
{
if (p)
{
nrl->next = n;
p->next = nrl;
}
else
{
nrl->next = brl;
brl = nrl;
}
break;
}
p = n;
n = n->next;
}
if (!n)
{
p->next = nrl;
nrl->next = NULL;
}
break;
}
case 3: // down/right
{
oy2 = bd.y + bd.h;
n = brl;
p = NULL;
while (n)
{
if ( oy2 >= n->r.y &&
bd.x >= n->r.x
)
{
if (p)
{
nrl->next = n;
p->next = nrl;
}
else
{
nrl->next = brl;
brl = nrl;
}
break;
}
p = n;
n = n->next;
}
if (!n)
{
p->next = nrl;
nrl->next = NULL;
}
break;
}
case 4: // No sort - area is not moving
{
nrl->next = brl->next;
brl->next = nrl;
break;
}
}
}
else
{
brl = next = nrl;
brl->next = NULL;
}
nrl->r = bd;
//DIAGS(("save blitarea %d/%d/%d/%d", nrl->r));
}
orl = orl->next;
}
newrl = newrl->next;
}
/*
* Release previous rectangle list
*/
while (oldrl)
{
nrl = oldrl;
oldrl = oldrl->next;
//DIAGS(("freeing oldrl %lx", nrl));
kfree(nrl);
//DIAGS(("kfree %lx (rest of oldrl)", nrl));
}
if (brl)
{
/*
* Do the blitting first...
*/
if (xmove || ymove)
{
struct xa_rect_list *trl = 0;
nrl = brl;
hidem();
while (nrl)
{
/* first blit lower rect if two left, moving down and upper rect partly hidden by menubar (see build_rectlist - surely a hack ..) */
if( menu_window && cfg.menu_bar && (dir & 1) && nrl->r.y < menu_window->r.h )
if( nrl->next && !nrl->next->next && nrl->r.y + nrl->r.h == nrl->next->r.y && !trl )
{
trl = nrl;
nrl = nrl->next;
dir = 0;
}
bd = nrl->r;
bs.x = bd.x + new->x;
bs.y = bd.y + new->y;
bs.w = bd.w;
bs.h = bd.h;
bd.x += old.x;
bd.y += old.y;
//DIAGS(("Blitting from %d/%d/%d/%d to %d/%d/%d/%d (%lx, %lx)",
// bd, bs, brl, (long)brl->next));
(*xa_vdiapi->form_copy)(&bd, &bs);
if( trl )
{
if( nrl == trl )
{
nrl = 0; //nrl->next->next;
trl = 0;
}
nrl = trl;
}
else
nrl = nrl->next;
}
showm();
}
/*
* Calculate rectangles that need to be redrawn...
*/
newrl = wind->rect_list.start;
while (newrl)
{
nrl = kmalloc(sizeof(*nrl));
assert(nrl);
//DIAGS(("kmalloc %lx (%ld bytes)", nrl, sizeof(*nrl)));
nrl->next = NULL;
nrl->r.x = newrl->r.x - new->x;
nrl->r.y = newrl->r.y - new->y;
nrl->r.w = newrl->r.w;
nrl->r.h = newrl->r.h;
if (resize)
{
if (!xa_rect_clip(&wa, &nrl->r, &nrl->r))
{
kfree(nrl);
//DIAGS(("kfree %lx", nrl));
nrl = NULL;
}
}
orl = brl;
while (orl && nrl)
{
short w, h, flag;
short bx2 = orl->r.x + orl->r.w;
short by2 = orl->r.y + orl->r.h;
//DIAGS(("BLITRECT (orl=%lx, nxt=%lx)(nrl=%lx, nxt=%lx) %d/%d/%d/%d, x2/y2=%d/%d",
// orl, (long)orl->next, nrl, (long)nrl->next, orl->r, bx2, by2));
for (rrl = nrl, prev = NULL; rrl; rrl = next)
{
RECT our = rrl->r;
w = orl->r.x - rrl->r.x;
h = orl->r.y - rrl->r.y;
//DIAGS(("CLIPPING %d/%d/%d/%d, w/h=%d/%d", our, w, h));
//DIAGS(("rrl = %lx", rrl));
next = rrl->next;
if ( h < our.h &&
w < our.w &&
bx2 > our.x &&
by2 > our.y )
{
short nx2 = our.x + our.w;
short ny2 = our.y + our.h;
flag = 0;
if (orl->r.y > our.y)
{
rrl->r.x = our.x;
rrl->r.y = our.y;
rrl->r.w = our.w;
rrl->r.h = h;
our.y += h;
our.h -= h;
flag = 1;
//DIAGS((" -- 1. redraw part %d/%d/%d/%d, remain(blit) %d/%d/%d/%d",
// rrl->r, our));
}
if (orl->r.x > our.x)
{
if (flag)
{
prev = rrl;
rrl = kmalloc(sizeof(*rrl));
assert(rrl);
//DIAGS(("kmalloc %lx (%ld bytes)", rrl, sizeof(*rrl)));
rrl->next = prev->next;
prev->next = rrl;
//DIAGS((" -- 2. new (%lx)", rrl));
}
rrl->r.x = our.x;
rrl->r.y = our.y;
rrl->r.h = our.h;
rrl->r.w = w;
our.x += w;
our.w -= w;
flag = 1;
//DIAGS((" -- 2. redraw part %d/%d/%d/%d, remain(blit) %d/%d/%d/%d",
// rrl->r, our));
}
if (ny2 > by2)
{
if (flag)
{
prev = rrl;
rrl = kmalloc(sizeof(*rrl));
assert(rrl);
//DIAGS(("kmalloc %lx (%ld bytes)", rrl, sizeof(*rrl)));
rrl->next = prev->next;
prev->next = rrl;
//DIAGS((" -- 3. new (%lx)", rrl));
}
rrl->r.x = our.x;
rrl->r.y = by2;
rrl->r.w = our.w;
rrl->r.h = ny2 - by2;
our.h -= rrl->r.h;
flag = 1;
//DIAGS((" -- 3. redraw part %d/%d/%d/%d, remain(blit) %d/%d/%d/%d",
// rrl->r, our));
}
if (nx2 > bx2)
{
if (flag)
{
prev = rrl;
rrl = kmalloc(sizeof(*rrl));
assert(rrl);
//DIAGS(("kmalloc %lx (%ld bytes)", rrl, sizeof(*rrl)));
rrl->next = prev->next;
prev->next = rrl;
//DIAGS((" -- 4. new (%lx)", rrl));
}
rrl->r.x = bx2;
rrl->r.y = our.y;
rrl->r.w = nx2 - bx2;
rrl->r.h = our.h;
our.w -= rrl->r.w;
flag = 1;
//DIAGS((" -- 4. redraw part %d/%d/%d/%d, remain(blit) %d/%d/%d/%d",
// rrl->r, our));
}
if (!flag)
{
//DIAGS((" ALL BLIT (removed) nrl=%lx, rrl=%lx, prev=%lx, nxt=%lx, %d/%d/%d/%d",
// nrl, rrl, prev, (long)rrl->next, rrl->r));
if (nrl == rrl)
{
//if (prev == rrl)
// prev = NULL;
nrl = next;
}
else if (nrl->next == rrl)
nrl->next = next;
if (prev)
prev->next = next;
kfree(rrl);
//DIAGS(("kfree %lx", rrl));
}
else
prev = rrl;
}
else
{
//DIAGS((" -- ALL REDRAW %d/%d/%d/%d", rrl->r));
prev = rrl;
}
//DIAGS((" .. .. .."));
} /* for (rrl = nrl; rrl; rrl = next) */
//DIAGS(("FROM %lx to %lx", orl, (long)orl->next));
orl = orl->next;
} /* while (orl && nrl) */
//DIAGS(("DONE CLIPPING"));
/* only blitted: if window has a list-window inform list-window to move its widgets */
if( ! resize )
{
struct widget_tree *wt = get_widget(wind, XAW_TOOLBAR)->stuff;
#if 1
if( wt && wt->extra && (wt->flags & WTF_EXTRA_ISLIST) ) // &&
{
SCROLL_INFO *list = wt->extra;
while( list && list->wi )
{
struct xa_window *lwind = list->wi;
if( !(dir & 1) )
ymove = -ymove;
if( !(dir & 2) )
xmove = -xmove;
lwind->send_message(wlock, lwind, NULL, AMQ_NORM, QMF_CHKDUP,
WM_MOVED, 0,0, lwind->handle,
lwind->r.x + xmove, lwind->r.y + ymove, lwind->r.w, lwind->r.h);
list = list->next;
}
}
#endif
}
/*
* nrl is the first in a list of rectangles that needs
* to be redrawn
*/
while (nrl)
{
short flags;
nrl->r.x += new->x;
nrl->r.y += new->y;
//DIAGS(("redrawing area (%lx) %d/%d/%d/%d",
// nrl, nrl->r));
DIAGS(("redrawing area (%lx) %d/%d/%d/%d",nrl, nrl->r));
/*
* we only redraw window borders here if wind moves
*/
if( wind->window_status & XAWS_RESIZED )
{
flags = 0; /* redraw later */
}
else if (!resize && !only_wa)
{
flags = RDRW_ALL;
}
else
flags = RDRW_WA;
if( flags )
{
generate_redraws(wlock, wind, &nrl->r, flags);
}
orl = nrl;
nrl = nrl->next;
//DIAGS(("Freeing redrawed rect %lx", orl));
kfree(orl);
//DIAGS(("kfree %lx", orl));
}
newrl = newrl->next;
} /* while (newrl) */
/*
* free blitting list
*/
while (brl)
{
nrl = brl;
brl = brl->next;
//DIAGS(("Freeing blitrect %lx", nrl));
kfree(nrl);
//DIAGS(("kfree %lx", nrl));
}
/*
* If window was resized, redraw all window borders
*/
if (resize && !only_wa)
{
generate_redraws(wlock, wind, NULL, RDRW_EXT);
}
} /* if (brl) */
else
{
short flags = only_wa ? RDRW_WA : RDRW_ALL;
newrl = wind->rect_list.start;
while (newrl)
{
generate_redraws(wlock, wind, &newrl->r, flags);
newrl = newrl->next;
}
}
}
else if (newrl)
{
short flags = only_wa ? RDRW_WA : RDRW_ALL;
while (newrl)
{
bool joined = false;
if( newrl->next )
{
if( (joined = join_redraws( wlock, wind, newrl, flags )) )
newrl = newrl->next;
}
if( !joined )
generate_redraws(wlock, wind, &newrl->r, flags );
if( newrl )
newrl = newrl->next;
}
while (oldrl)
{
orl = oldrl;
oldrl = oldrl->next;
kfree(orl);
//DIAGS(("kfree %lx", orl));
}
}
DIAGS(("set_and_update_window: DONE!!!"));
}