Checkin for Caz (without pain, even!) which adds rudimentary DrawBitmap support
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7223 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8af87c1dcc
commit
da08bdd09d
@ -38,6 +38,210 @@
|
||||
// handled by the public drawing functions.
|
||||
// Add clipping and make sure public functions have Lock & Unlock.
|
||||
|
||||
struct integer_rect
|
||||
{
|
||||
int32 x;
|
||||
int32 y;
|
||||
int32 w;
|
||||
int32 h;
|
||||
};
|
||||
|
||||
struct integer_scaling_info
|
||||
{
|
||||
int32 k;
|
||||
};
|
||||
|
||||
static inline void BRect_to_integer_rect(BRect source_rect, integer_rect &dest_rect)
|
||||
{
|
||||
dest_rect.x = (int32)source_rect.left;
|
||||
dest_rect.y = (int32)source_rect.top;
|
||||
dest_rect.w = (int32)(source_rect.right - source_rect.left) + 1;
|
||||
dest_rect.h = (int32)(source_rect.bottom - source_rect.top) + 1;
|
||||
}
|
||||
|
||||
static inline integer_rect BRect_to_integer_rect(BRect source_rect)
|
||||
{
|
||||
integer_rect dest_rect;
|
||||
dest_rect.x = (int32)source_rect.left;
|
||||
dest_rect.y = (int32)source_rect.top;
|
||||
dest_rect.w = (int32)(source_rect.right - source_rect.left) + 1;
|
||||
dest_rect.h = (int32)(source_rect.bottom - source_rect.top) + 1;
|
||||
return dest_rect;
|
||||
}
|
||||
|
||||
class Blitter
|
||||
{
|
||||
public:
|
||||
Blitter();
|
||||
void draw_8_to_8(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
void draw_8_to_16(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
void draw_8_to_32(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
|
||||
void draw_16_to_8(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
void draw_16_to_16(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
void draw_16_to_32(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
|
||||
void draw_32_to_8(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
void draw_32_to_16(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
void draw_32_to_32(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
|
||||
void draw_none(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor) {}
|
||||
void Draw(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
|
||||
void Select(int32 source_bits_per_pixel, int32 dest_bits_per_pixel);
|
||||
|
||||
drawing_mode GetDrawMode() const { return mode; }
|
||||
void SetDrawMode(drawing_mode draw_mode) { mode = draw_mode; }
|
||||
|
||||
private:
|
||||
void (Blitter::*DrawFunc)(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor);
|
||||
drawing_mode mode;
|
||||
};
|
||||
|
||||
static Blitter blitter;
|
||||
|
||||
Blitter::Blitter()
|
||||
{
|
||||
DrawFunc = &Blitter::draw_none;
|
||||
}
|
||||
|
||||
void Blitter::draw_8_to_8(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
uint8 *s = (uint8 *)src;
|
||||
uint8 *d = (uint8 *)dst;
|
||||
|
||||
while(width--)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Blitter::draw_8_to_16(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
uint8 *s = (uint8 *)src;
|
||||
uint16 *d = (uint16 *)dst;
|
||||
|
||||
while(width--)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Blitter::draw_8_to_32(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
uint8 *s = (uint8 *)src;
|
||||
uint32 *d = (uint32 *)dst;
|
||||
|
||||
while(width--)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Blitter::draw_16_to_8(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
uint16 *s = (uint16 *)src;
|
||||
uint8 *d = (uint8 *)dst;
|
||||
|
||||
while(width--)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Blitter::draw_16_to_16(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
uint16 *s = (uint16 *)src;
|
||||
uint16 *d = (uint16 *)dst;
|
||||
|
||||
while(width--)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Blitter::draw_16_to_32(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
uint16 *s = (uint16 *)src;
|
||||
uint32 *d = (uint32 *)dst;
|
||||
|
||||
while(width--)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Blitter::draw_32_to_8(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
uint32 *s = (uint32 *)src;
|
||||
uint8 *d = (uint8 *)dst;
|
||||
|
||||
while(width--)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Blitter::draw_32_to_16(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
uint32 *s = (uint32 *)src;
|
||||
uint16 *d = (uint16 *)dst;
|
||||
|
||||
while(width--)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Blitter::draw_32_to_32(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
uint32 *s = (uint32 *)src;
|
||||
uint32 *d = (uint32 *)dst;
|
||||
|
||||
while(width--)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Blitter::Draw(uint8 *src, uint8 *dst, int32 width, int32 xscale_position, int32 xscale_factor)
|
||||
{
|
||||
(this->*DrawFunc)(src, dst, width, xscale_position, xscale_factor);
|
||||
}
|
||||
|
||||
void Blitter::Select(int32 source_bits_per_pixel, int32 dest_bits_per_pixel)
|
||||
{
|
||||
if(source_bits_per_pixel == 8 && dest_bits_per_pixel == 8)
|
||||
DrawFunc = &Blitter::draw_8_to_8;
|
||||
else if(source_bits_per_pixel == 8 && dest_bits_per_pixel == 16)
|
||||
DrawFunc = &Blitter::draw_8_to_16;
|
||||
else if(source_bits_per_pixel == 8 && dest_bits_per_pixel == 32)
|
||||
DrawFunc = &Blitter::draw_8_to_32;
|
||||
else if(source_bits_per_pixel == 16 && dest_bits_per_pixel == 16)
|
||||
DrawFunc = &Blitter::draw_16_to_16;
|
||||
else if(source_bits_per_pixel == 16 && dest_bits_per_pixel == 8)
|
||||
DrawFunc = &Blitter::draw_16_to_8;
|
||||
else if(source_bits_per_pixel == 16 && dest_bits_per_pixel == 32)
|
||||
DrawFunc = &Blitter::draw_16_to_32;
|
||||
else if(source_bits_per_pixel == 32 && dest_bits_per_pixel == 32)
|
||||
DrawFunc = &Blitter::draw_32_to_32;
|
||||
else if(source_bits_per_pixel == 32 && dest_bits_per_pixel == 16)
|
||||
DrawFunc = &Blitter::draw_32_to_16;
|
||||
else if(source_bits_per_pixel == 32 && dest_bits_per_pixel == 8)
|
||||
DrawFunc = &Blitter::draw_32_to_8;
|
||||
else
|
||||
DrawFunc = &Blitter::draw_none;
|
||||
}
|
||||
|
||||
LineCalc::LineCalc()
|
||||
{
|
||||
}
|
||||
@ -304,14 +508,169 @@ void DisplayDriver::CopyRegion(BRegion *src, const BPoint &lefttop)
|
||||
|
||||
/*!
|
||||
\brief Called for all BView::DrawBitmap calls
|
||||
\param region Destination rects in screen coordinates
|
||||
\param bmp Bitmap to be drawn. It will always be non-NULL and valid. The color
|
||||
space is not guaranteed to match.
|
||||
\param src Source rectangle
|
||||
\param dest Destination rectangle. Source will be scaled to fit if not the same size.
|
||||
\param d Data structure containing any other data necessary for the call. Always non-NULL.
|
||||
*/
|
||||
|
||||
void DisplayDriver::DrawBitmap(BRegion *region, ServerBitmap *bitmap, const BRect &source, const BRect &dest, const DrawData *d)
|
||||
{
|
||||
Lock();
|
||||
|
||||
FBBitmap frameBuffer;
|
||||
FBBitmap *bmp = &frameBuffer;
|
||||
|
||||
blitter.Select(32, 32);
|
||||
|
||||
if(!AcquireBuffer(&frameBuffer))
|
||||
{
|
||||
debugger("ERROR: Couldn't acquire framebuffer in DrawBitmap()\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 colorspace_size = (bitmap->BitsPerPixel() + 7) / 8;
|
||||
|
||||
int32 count = region->CountRects();
|
||||
|
||||
BRect bitmaprect(bitmap->Bounds());
|
||||
BRect sourcerect(source);
|
||||
|
||||
BRect destrect(dest);
|
||||
destrect.right *= d->scale;
|
||||
destrect.bottom *= d->scale;
|
||||
|
||||
if(sourcerect.left < 0) sourcerect.left = 0;
|
||||
if(sourcerect.top < 0) sourcerect.top = 0;
|
||||
|
||||
if(sourcerect.Width() > bitmaprect.Width())
|
||||
sourcerect.right = bitmaprect.left + bitmaprect.Width();
|
||||
|
||||
if(sourcerect.Height() > bitmaprect.Height())
|
||||
sourcerect.bottom = bitmaprect.top + bitmaprect.Height();
|
||||
|
||||
int32 sourcewidth = (int32)sourcerect.Width() + 1;
|
||||
int32 sourceheight = (int32)sourcerect.Height() + 1;
|
||||
|
||||
int32 destwidth = (int32)destrect.Width() + 1;
|
||||
int32 destheight = (int32)destrect.Height() + 1;
|
||||
|
||||
int32 xscale_factor = (sourcewidth << 16) / destwidth;
|
||||
int32 yscale_factor = (sourceheight << 16) / destheight;
|
||||
|
||||
uint8 *src_bits = (uint8 *)bitmap->Bits();
|
||||
uint8 *dest_bits = (uint8*)bmp->Bits();
|
||||
|
||||
int32 src_row = bitmap->BytesPerRow();
|
||||
int32 dest_row = bmp->BytesPerRow();
|
||||
|
||||
src_bits += uint32((sourcerect.top * src_row) + (sourcerect.left * colorspace_size));
|
||||
|
||||
integer_rect src_integer_rectangle = BRect_to_integer_rect(sourcerect);
|
||||
integer_rect dst_integer_rectangle = BRect_to_integer_rect(destrect);
|
||||
|
||||
int32 xscale_position = 0, yscale_position = 0, clipped_xscale_position = 0;
|
||||
|
||||
for(int32 c = 0; c < count; c++)
|
||||
{
|
||||
integer_rect screen_integer_rect = BRect_to_integer_rect(region->RectAt(c));
|
||||
integer_rect src_integer_rect = src_integer_rectangle;
|
||||
integer_rect dst_integer_rect = dst_integer_rectangle;
|
||||
|
||||
xscale_position = 0, yscale_position = 0, clipped_xscale_position = 0;
|
||||
|
||||
if(dst_integer_rect.x < screen_integer_rect.x)
|
||||
{
|
||||
dst_integer_rect.x -= screen_integer_rect.x;
|
||||
dst_integer_rect.w += dst_integer_rect.x;
|
||||
src_integer_rect.x -= dst_integer_rect.x;
|
||||
dst_integer_rect.x = screen_integer_rect.x;
|
||||
}
|
||||
|
||||
if(dst_integer_rect.y < screen_integer_rect.y)
|
||||
{
|
||||
dst_integer_rect.y -= screen_integer_rect.y;
|
||||
dst_integer_rect.h += dst_integer_rect.y;
|
||||
src_integer_rect.y -= dst_integer_rect.y;
|
||||
dst_integer_rect.y = screen_integer_rect.y;
|
||||
}
|
||||
|
||||
if(dst_integer_rect.w > screen_integer_rect.w)
|
||||
dst_integer_rect.w = screen_integer_rect.w;
|
||||
|
||||
if(dst_integer_rect.h > screen_integer_rect.h)
|
||||
dst_integer_rect.h = screen_integer_rect.h;
|
||||
|
||||
if(src_integer_rect.x > src_integer_rectangle.x)
|
||||
{
|
||||
int32 x_scale_pixel_multiply = src_integer_rect.x - src_integer_rectangle.x;
|
||||
clipped_xscale_position = xscale_factor * x_scale_pixel_multiply;
|
||||
}
|
||||
|
||||
if(src_integer_rect.y > src_integer_rectangle.y)
|
||||
{
|
||||
int32 y_scale_pixel_multiply = src_integer_rect.y - src_integer_rectangle.y;
|
||||
yscale_position = yscale_factor * y_scale_pixel_multiply;
|
||||
}
|
||||
|
||||
if(dst_integer_rect.w > 0 && dst_integer_rect.h > 0)
|
||||
{
|
||||
uint8 *src_data = src_bits;
|
||||
uint8 *dst_data = (uint8 *)dest_bits + dst_integer_rect.y * dest_row + dst_integer_rect.x * colorspace_size;
|
||||
|
||||
while(dst_integer_rect.h--)
|
||||
{
|
||||
xscale_position = clipped_xscale_position;
|
||||
uint8 *s = (uint8 *)((uint8 *)src_data + (yscale_position >> 16) * src_row);
|
||||
uint8 *d = (uint8 *)((uint8 *)dst_data);
|
||||
|
||||
blitter.Draw(s, d, dst_integer_rect.w, xscale_position, xscale_factor);
|
||||
#if 0
|
||||
for(int32 x = 0; x < dst_integer_rect.w; x++)
|
||||
{
|
||||
*d++ = s[xscale_position >> 16];
|
||||
xscale_position += xscale_factor;
|
||||
}
|
||||
#endif
|
||||
dst_data += dest_row;
|
||||
yscale_position += yscale_factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseBuffer();
|
||||
Unlock();
|
||||
Invalidate(destrect);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Called for all BView::DrawBitmap calls
|
||||
\param bmp Bitmap to be drawn. It will always be non-NULL and valid. The color
|
||||
space is not guaranteed to match.
|
||||
\param src Source rectangle
|
||||
\param dest Destination rectangle. Source will be scaled to fit if not the same size.
|
||||
\param d Data structure containing any other data necessary for the call. Always non-NULL.
|
||||
*/
|
||||
|
||||
void DisplayDriver::DrawBitmap(ServerBitmap *bmp, const BRect &src, const BRect &dest, const DrawData *d)
|
||||
{
|
||||
Lock();
|
||||
|
||||
FBBitmap frameBuffer;
|
||||
FBBitmap *fbmp = &frameBuffer;
|
||||
|
||||
if(!AcquireBuffer(&frameBuffer))
|
||||
{
|
||||
debugger("ERROR: Couldn't acquire framebuffer in DrawBitmap()\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ReleaseBuffer();
|
||||
Unlock();
|
||||
|
||||
Invalidate(dest);
|
||||
}
|
||||
|
||||
void DisplayDriver::CopyRegionList(BList* list, BList* pList, int32 rCount, BRegion* clipReg)
|
||||
|
@ -574,6 +574,7 @@ void ServerApp::_DispatchMessage(PortMessage *msg)
|
||||
|
||||
if(sbmp)
|
||||
{
|
||||
fBitmapList->AddItem(sbmp);
|
||||
PortLink replylink(replyport);
|
||||
replylink.SetOpCode(SERVER_TRUE);
|
||||
replylink.Attach<int32>(sbmp->Token());
|
||||
@ -607,7 +608,7 @@ void ServerApp::_DispatchMessage(PortMessage *msg)
|
||||
msg->Read<int32>(&bmp_id);
|
||||
msg->Read<int32>(&replyport);
|
||||
|
||||
ServerBitmap *sbmp=_FindBitmap(bmp_id);
|
||||
ServerBitmap *sbmp=FindBitmap(bmp_id);
|
||||
if(sbmp)
|
||||
{
|
||||
STRACE(("ServerApp %s: Deleting Bitmap %ld\n",fSignature.String(),bmp_id));
|
||||
@ -920,7 +921,7 @@ void ServerApp::_DispatchMessage(PortMessage *msg)
|
||||
\param token ID token of the bitmap to find
|
||||
\return The bitmap having that ID or NULL if not found
|
||||
*/
|
||||
ServerBitmap *ServerApp::_FindBitmap(int32 token)
|
||||
ServerBitmap *ServerApp::FindBitmap(int32 token)
|
||||
{
|
||||
ServerBitmap *temp;
|
||||
for(int32 i=0; i<fBitmapList->CountItems();i++)
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
|
||||
void SendMessageToClient( const BMessage* msg ) const;
|
||||
void SetAppCursor(void);
|
||||
ServerBitmap *FindBitmap(int32 token);
|
||||
|
||||
team_id ClientTeamID();
|
||||
|
||||
|
@ -705,6 +705,93 @@ void ServerWindow::DispatchMessage(int32 code)
|
||||
switch(code)
|
||||
{
|
||||
//--------- BView Messages -----------------
|
||||
case AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT:
|
||||
{
|
||||
int32 bitmapToken;
|
||||
BPoint point;
|
||||
|
||||
fSession->ReadInt32(&bitmapToken);
|
||||
fSession->ReadPoint(&point);
|
||||
|
||||
ServerBitmap *sbmp = fServerApp->FindBitmap(bitmapToken);
|
||||
if(sbmp)
|
||||
{
|
||||
BRect src, dst;
|
||||
BRegion region;
|
||||
|
||||
src = sbmp->Bounds();
|
||||
dst = cl->_parent->ConvertFromParent(cl->_full.Frame());
|
||||
region = cl->_parent->ConvertFromParent(&(cl->_full));
|
||||
dst.OffsetBy(point);
|
||||
|
||||
cl->fDriver->DrawBitmap(®ion, sbmp, src, dst, cl->_layerdata);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_DRAW_BITMAP_ASYNC_AT_POINT:
|
||||
{
|
||||
int32 bitmapToken;
|
||||
BPoint point;
|
||||
|
||||
fSession->ReadInt32(&bitmapToken);
|
||||
fSession->ReadPoint(&point);
|
||||
|
||||
ServerBitmap *sbmp = fServerApp->FindBitmap(bitmapToken);
|
||||
if(sbmp)
|
||||
{
|
||||
BRect src, dst;
|
||||
BRegion region;
|
||||
|
||||
src = sbmp->Bounds();
|
||||
dst = cl->_parent->ConvertFromParent(cl->_full.Frame());
|
||||
region = cl->_parent->ConvertFromParent(&(cl->_full));
|
||||
dst.OffsetBy(point);
|
||||
|
||||
cl->fDriver->DrawBitmap(®ion, sbmp, src, dst, cl->_layerdata);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_DRAW_BITMAP_SYNC_IN_RECT:
|
||||
{
|
||||
int32 bitmapToken;
|
||||
BRect srcRect, dstRect;
|
||||
|
||||
fSession->ReadInt32(&bitmapToken);
|
||||
fSession->ReadRect(&dstRect);
|
||||
fSession->ReadRect(&srcRect);
|
||||
|
||||
ServerBitmap *sbmp = fServerApp->FindBitmap(bitmapToken);
|
||||
if(sbmp)
|
||||
{
|
||||
//cl->fDriver->DrawBitmap(®ion, sbmp, srcRect, dstRect, cl->_layerdata);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_DRAW_BITMAP_ASYNC_IN_RECT:
|
||||
{
|
||||
int32 bitmapToken;
|
||||
BRect srcRect, dstRect;
|
||||
|
||||
fSession->ReadInt32(&bitmapToken);
|
||||
fSession->ReadRect(&dstRect);
|
||||
fSession->ReadRect(&srcRect);
|
||||
|
||||
ServerBitmap *sbmp = fServerApp->FindBitmap(bitmapToken);
|
||||
if(sbmp)
|
||||
{
|
||||
BRegion region;
|
||||
BRect dst;
|
||||
region = cl->_parent->ConvertFromParent(&(cl->_full));
|
||||
dst = cl->_parent->ConvertFromParent(cl->_full.Frame());
|
||||
dstRect.OffsetBy(dst.left, dst.top);
|
||||
|
||||
cl->fDriver->DrawBitmap(®ion, sbmp, srcRect, dstRect, cl->_layerdata);
|
||||
//printf("%d %d %d %d %d %d %d %d %d %d\n", (int)cl->_boundsLeftTop.x, (int)cl->_boundsLeftTop.y,
|
||||
// (int)cl->_frame.left, (int)cl->_frame.top, (int)cl->_frame.right, (int)cl->_frame.bottom,
|
||||
// (int)cl->_parent->_frame.left, (int)cl->_parent->_frame.top, (int)cl->_parent->_frame.right, (int)cl->_parent->_frame.bottom);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AS_SET_CURRENT_LAYER:
|
||||
{
|
||||
int32 token;
|
||||
@ -2095,7 +2182,7 @@ printf("Deleting window...\n");
|
||||
}
|
||||
default:
|
||||
{
|
||||
STRACE(("ServerWindow %s: got a message to dispatch\n",win->Title()));
|
||||
//STRACE(("ServerWindow %s: got a message to dispatch\n",win->Title()));
|
||||
win->DispatchMessage(code);
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user