Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libSDL
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PocketInsanity
libSDL
Commits
bf4cf189
Commit
bf4cf189
authored
Jul 27, 2011
by
Nathan Heisey
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved draw code to a separate thread
parent
350e15ee
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
104 additions
and
58 deletions
+104
-58
SDL_BApp.h
src/main/beos/SDL_BApp.h
+24
-13
SDL_BeApp.cc
src/main/beos/SDL_BeApp.cc
+1
-1
SDL_BWin.h
src/video/bwindow/SDL_BWin.h
+19
-8
SDL_bmodes.cc
src/video/bwindow/SDL_bmodes.cc
+59
-36
SDL_bmodes.h
src/video/bwindow/SDL_bmodes.h
+1
-0
No files found.
src/main/beos/SDL_BApp.h
View file @
bf4cf189
...
@@ -37,6 +37,7 @@ extern "C" {
...
@@ -37,6 +37,7 @@ extern "C" {
/* Local includes */
/* Local includes */
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_events_c.h"
#include "../../video/bwindow/SDL_bkeyboard.h"
#include "../../video/bwindow/SDL_bkeyboard.h"
#include "../../video/bwindow/SDL_bmodes.h"
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
@@ -167,7 +168,7 @@ public:
...
@@ -167,7 +168,7 @@ public:
int32
GetID
(
SDL_Window
*
win
)
{
int32
GetID
(
SDL_Window
*
win
)
{
int32
i
;
int32
i
;
for
(
i
=
0
;
i
<
_GetNumWindowSlots
();
++
i
)
{
for
(
i
=
0
;
i
<
_GetNumWindowSlots
();
++
i
)
{
if
(
_
GetSDLWindow
(
i
)
==
NULL
)
{
if
(
GetSDLWindow
(
i
)
==
NULL
)
{
_SetSDLWindow
(
win
,
i
);
_SetSDLWindow
(
win
,
i
);
return
i
;
return
i
;
}
}
...
@@ -189,6 +190,11 @@ public:
...
@@ -189,6 +190,11 @@ public:
there another way to do this? */
there another way to do this? */
void
ClearID
(
SDL_BWin
*
bwin
);
/* Defined in SDL_BeApp.cc */
void
ClearID
(
SDL_BWin
*
bwin
);
/* Defined in SDL_BeApp.cc */
SDL_Window
*
GetSDLWindow
(
int32
winID
)
{
return
window_map
[
winID
];
}
private
:
private
:
/* Event management */
/* Event management */
void
_HandleBasicWindowEvent
(
BMessage
*
msg
,
int32
sdlEventType
)
{
void
_HandleBasicWindowEvent
(
BMessage
*
msg
,
int32
sdlEventType
)
{
...
@@ -199,7 +205,7 @@ private:
...
@@ -199,7 +205,7 @@ private:
)
{
)
{
return
;
return
;
}
}
win
=
_
GetSDLWindow
(
winID
);
win
=
GetSDLWindow
(
winID
);
SDL_SendWindowEvent
(
win
,
sdlEventType
,
0
,
0
);
SDL_SendWindowEvent
(
win
,
sdlEventType
,
0
,
0
);
}
}
...
@@ -214,8 +220,11 @@ private:
...
@@ -214,8 +220,11 @@ private:
)
{
)
{
return
;
return
;
}
}
win
=
_
GetSDLWindow
(
winID
);
win
=
GetSDLWindow
(
winID
);
SDL_SendMouseMotion
(
win
,
0
,
x
,
y
);
SDL_SendMouseMotion
(
win
,
0
,
x
,
y
);
/* FIXME: Attempt at fixing rendering problems */
BE_UpdateWindowFramebuffer
(
NULL
,
win
,
NULL
,
-
1
);
}
}
void
_HandleMouseButton
(
BMessage
*
msg
)
{
void
_HandleMouseButton
(
BMessage
*
msg
)
{
...
@@ -229,7 +238,7 @@ private:
...
@@ -229,7 +238,7 @@ private:
)
{
)
{
return
;
return
;
}
}
win
=
_
GetSDLWindow
(
winID
);
win
=
GetSDLWindow
(
winID
);
SDL_SendMouseButton
(
win
,
state
,
button
);
SDL_SendMouseButton
(
win
,
state
,
button
);
}
}
...
@@ -244,7 +253,7 @@ private:
...
@@ -244,7 +253,7 @@ private:
)
{
)
{
return
;
return
;
}
}
win
=
_
GetSDLWindow
(
winID
);
win
=
GetSDLWindow
(
winID
);
SDL_SendMouseWheel
(
win
,
xTicks
,
yTicks
);
SDL_SendMouseWheel
(
win
,
xTicks
,
yTicks
);
}
}
...
@@ -275,7 +284,7 @@ private:
...
@@ -275,7 +284,7 @@ private:
)
{
)
{
return
;
return
;
}
}
win
=
_
GetSDLWindow
(
winID
);
win
=
GetSDLWindow
(
winID
);
if
(
bSetFocus
)
{
if
(
bSetFocus
)
{
SDL_SetMouseFocus
(
win
);
SDL_SetMouseFocus
(
win
);
}
else
if
(
SDL_GetMouseFocus
()
==
win
)
{
}
else
if
(
SDL_GetMouseFocus
()
==
win
)
{
...
@@ -294,7 +303,7 @@ private:
...
@@ -294,7 +303,7 @@ private:
)
{
)
{
return
;
return
;
}
}
win
=
_
GetSDLWindow
(
winID
);
win
=
GetSDLWindow
(
winID
);
if
(
bSetFocus
)
{
if
(
bSetFocus
)
{
SDL_SetKeyboardFocus
(
win
);
SDL_SetKeyboardFocus
(
win
);
}
else
if
(
SDL_GetKeyboardFocus
()
==
win
)
{
}
else
if
(
SDL_GetKeyboardFocus
()
==
win
)
{
...
@@ -315,8 +324,11 @@ private:
...
@@ -315,8 +324,11 @@ private:
)
{
)
{
return
;
return
;
}
}
win
=
_
GetSDLWindow
(
winID
);
win
=
GetSDLWindow
(
winID
);
SDL_SendWindowEvent
(
win
,
SDL_WINDOWEVENT_MOVED
,
xPos
,
yPos
);
SDL_SendWindowEvent
(
win
,
SDL_WINDOWEVENT_MOVED
,
xPos
,
yPos
);
/* FIXME: Attempt at fixing rendering problems */
BE_UpdateWindowFramebuffer
(
NULL
,
win
,
NULL
,
-
1
);
}
}
void
_HandleWindowResized
(
BMessage
*
msg
)
{
void
_HandleWindowResized
(
BMessage
*
msg
)
{
...
@@ -331,8 +343,11 @@ private:
...
@@ -331,8 +343,11 @@ private:
)
{
)
{
return
;
return
;
}
}
win
=
_
GetSDLWindow
(
winID
);
win
=
GetSDLWindow
(
winID
);
SDL_SendWindowEvent
(
win
,
SDL_WINDOWEVENT_RESIZED
,
w
,
h
);
SDL_SendWindowEvent
(
win
,
SDL_WINDOWEVENT_RESIZED
,
w
,
h
);
/* FIXME: Attempt at fixing rendering problems */
BE_UpdateWindowFramebuffer
(
NULL
,
win
,
NULL
,
-
1
);
}
}
bool
_GetWinID
(
BMessage
*
msg
,
int32
*
winID
)
{
bool
_GetWinID
(
BMessage
*
msg
,
int32
*
winID
)
{
...
@@ -342,10 +357,6 @@ private:
...
@@ -342,10 +357,6 @@ private:
/* Vector imitators */
/* Vector imitators */
SDL_Window
*
_GetSDLWindow
(
int32
winID
)
{
return
window_map
[
winID
];
}
void
_SetSDLWindow
(
SDL_Window
*
win
,
int32
winID
)
{
void
_SetSDLWindow
(
SDL_Window
*
win
,
int32
winID
)
{
window_map
[
winID
]
=
win
;
window_map
[
winID
]
=
win
;
}
}
...
...
src/main/beos/SDL_BeApp.cc
View file @
bf4cf189
...
@@ -126,7 +126,7 @@ SDL_QuitBeApp(void)
...
@@ -126,7 +126,7 @@ SDL_QuitBeApp(void)
void
SDL_BApp
::
ClearID
(
SDL_BWin
*
bwin
)
{
void
SDL_BApp
::
ClearID
(
SDL_BWin
*
bwin
)
{
_SetSDLWindow
(
NULL
,
bwin
->
GetID
());
_SetSDLWindow
(
NULL
,
bwin
->
GetID
());
int32
i
=
_GetNumWindowSlots
()
-
1
;
int32
i
=
_GetNumWindowSlots
()
-
1
;
while
(
i
>=
0
&&
_
GetSDLWindow
(
i
)
==
NULL
)
{
while
(
i
>=
0
&&
GetSDLWindow
(
i
)
==
NULL
)
{
_PopBackWindow
();
_PopBackWindow
();
--
i
;
--
i
;
}
}
...
...
src/video/bwindow/SDL_BWin.h
View file @
bf4cf189
...
@@ -76,9 +76,14 @@ class SDL_BWin:public BDirectWindow
...
@@ -76,9 +76,14 @@ class SDL_BWin:public BDirectWindow
/* Handle framebuffer stuff */
/* Handle framebuffer stuff */
_connected
=
_connection_disabled
=
false
;
_connected
=
_connection_disabled
=
false
;
_buffer_created
=
_buffer_dirty
=
false
;
_trash__window_buffer
=
false
;
_trash__window_buffer
=
false
;
_buffer_locker
=
new
BLocker
();
_buffer_locker
=
new
BLocker
();
_window_buffer
=
NULL
;
_window_buffer
=
NULL
;
_draw_thread_id
=
spawn_thread
(
BE_DrawThread
,
"drawing_thread"
,
B_NORMAL_PRIORITY
,
(
void
*
)
this
);
resume_thread
(
_draw_thread_id
);
// LockBuffer(); /* Unlocked by buffer initialization */
// LockBuffer(); /* Unlocked by buffer initialization */
}
}
...
@@ -86,6 +91,7 @@ class SDL_BWin:public BDirectWindow
...
@@ -86,6 +91,7 @@ class SDL_BWin:public BDirectWindow
{
{
Lock
();
Lock
();
_connection_disabled
=
true
;
_connection_disabled
=
true
;
int32
result
;
#if SDL_VIDEO_OPENGL
#if SDL_VIDEO_OPENGL
if
(
_SDL_GLView
)
{
if
(
_SDL_GLView
)
{
...
@@ -102,6 +108,7 @@ class SDL_BWin:public BDirectWindow
...
@@ -102,6 +108,7 @@ class SDL_BWin:public BDirectWindow
/* Clean up framebuffer stuff */
/* Clean up framebuffer stuff */
_buffer_locker
->
Lock
();
_buffer_locker
->
Lock
();
wait_for_thread
(
_draw_thread_id
,
&
result
);
free
(
_clips
);
free
(
_clips
);
delete
_buffer_locker
;
delete
_buffer_locker
;
}
}
...
@@ -382,8 +389,6 @@ class SDL_BWin:public BDirectWindow
...
@@ -382,8 +389,6 @@ class SDL_BWin:public BDirectWindow
/* Accessor methods */
/* Accessor methods */
bool
IsShown
()
{
return
_shown
;
}
bool
IsShown
()
{
return
_shown
;
}
int32
GetID
()
{
return
_id
;
}
int32
GetID
()
{
return
_id
;
}
void
LockBuffer
()
{
_buffer_locker
->
Lock
();
}
void
UnlockBuffer
()
{
_buffer_locker
->
Unlock
();
}
uint32
GetRowBytes
()
{
return
_row_bytes
;
}
uint32
GetRowBytes
()
{
return
_row_bytes
;
}
int32
GetFbX
()
{
return
_bounds
.
left
;
}
int32
GetFbX
()
{
return
_bounds
.
left
;
}
int32
GetFbY
()
{
return
_bounds
.
top
;
}
int32
GetFbY
()
{
return
_bounds
.
top
;
}
...
@@ -395,12 +400,18 @@ class SDL_BWin:public BDirectWindow
...
@@ -395,12 +400,18 @@ class SDL_BWin:public BDirectWindow
int32
GetNumClips
()
{
return
_num_clips
;
}
int32
GetNumClips
()
{
return
_num_clips
;
}
uint8
*
GetBufferPx
()
{
return
_bits
;
}
uint8
*
GetBufferPx
()
{
return
_bits
;
}
int32
GetBytesPerPx
()
{
return
_bytes_per_px
;
}
int32
GetBytesPerPx
()
{
return
_bytes_per_px
;
}
void
SetWindowFramebuffer
(
uint8
*
fb
)
{
_window_buffer
=
fb
;
}
uint8
*
GetWindowFramebuffer
()
{
return
_window_buffer
;
}
uint8
*
GetWindowFramebuffer
()
{
return
_window_buffer
;
}
bool
CanTrashWindowBuffer
()
{
return
_trash__window_buffer
;
}
bool
CanTrashWindowBuffer
()
{
return
_trash__window_buffer
;
}
bool
BufferExists
()
{
return
_buffer_created
;
}
bool
BufferIsDirty
()
{
return
_buffer_dirty
;
}
/* Setter methods */
/* Setter methods */
void
SetID
(
int32
id
)
{
_id
=
id
;
}
void
SetID
(
int32
id
)
{
_id
=
id
;
}
bool
SetBufferExists
(
bool
bufferExists
)
{
_buffer_created
=
bufferExists
;
}
void
SetWindowFramebuffer
(
uint8
*
fb
)
{
_window_buffer
=
fb
;
}
void
LockBuffer
()
{
_buffer_locker
->
Lock
();
}
void
UnlockBuffer
()
{
_buffer_locker
->
Unlock
();
}
void
SetBufferDirty
(
bool
bufferDirty
)
{
_buffer_dirty
=
bufferDirty
;
}
...
@@ -416,10 +427,6 @@ class SDL_BWin:public BDirectWindow
...
@@ -416,10 +427,6 @@ class SDL_BWin:public BDirectWindow
{
{
return
(
_the_view
);
return
(
_the_view
);
}
}
...
@@ -584,7 +591,10 @@ private:
...
@@ -584,7 +591,10 @@ private:
BRect
*
_prev_frame
;
/* Previous position and size of the window */
BRect
*
_prev_frame
;
/* Previous position and size of the window */
/* Framebuffer members */
/* Framebuffer members */
bool
_connected
,
_connection_disabled
;
bool
_connected
,
_connection_disabled
,
_buffer_created
,
_buffer_dirty
;
uint8
*
_bits
;
uint8
*
_bits
;
uint32
_row_bytes
;
uint32
_row_bytes
;
clipping_rect
_bounds
;
clipping_rect
_bounds
;
...
@@ -594,6 +604,7 @@ private:
...
@@ -594,6 +604,7 @@ private:
int32
_bytes_per_px
;
int32
_bytes_per_px
;
uint8
*
_window_buffer
;
/* A copy of the window buffer */
uint8
*
_window_buffer
;
/* A copy of the window buffer */
bool
_trash__window_buffer
;
bool
_trash__window_buffer
;
thread_id
_draw_thread_id
;
};
};
#endif
#endif
src/video/bwindow/SDL_bmodes.cc
View file @
bf4cf189
...
@@ -218,7 +218,7 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
...
@@ -218,7 +218,7 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
return
-
1
;
return
-
1
;
}
}
while
(
!
bwin
->
Connected
())
{
snooze
(
10
);
}
while
(
!
bwin
->
Connected
())
{
snooze
(
10
0
);
}
/* Make sure we have exclusive access to frame buffer data */
/* Make sure we have exclusive access to frame buffer data */
bwin
->
LockBuffer
();
bwin
->
LockBuffer
();
...
@@ -243,6 +243,7 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
...
@@ -243,6 +243,7 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
bwin
->
SetWindowFramebuffer
((
uint8
*
)(
*
pixels
));
bwin
->
SetWindowFramebuffer
((
uint8
*
)(
*
pixels
));
}
}
bwin
->
SetBufferExists
(
true
);
bwin
->
UnlockBuffer
();
bwin
->
UnlockBuffer
();
return
0
;
return
0
;
}
}
...
@@ -251,51 +252,72 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
...
@@ -251,51 +252,72 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
int
BE_UpdateWindowFramebuffer
(
_THIS
,
SDL_Window
*
window
,
int
BE_UpdateWindowFramebuffer
(
_THIS
,
SDL_Window
*
window
,
SDL_Rect
*
rects
,
int
numrects
)
{
SDL_Rect
*
rects
,
int
numrects
)
{
if
(
!
window
)
return
0
;
SDL_BWin
*
bwin
=
_ToBeWin
(
window
);
SDL_BWin
*
bwin
=
_ToBeWin
(
window
);
bwin
->
LockBuffer
();
bwin
->
SetBufferDirty
(
true
);
bwin
->
UnlockBuffer
();
return
0
;
}
int32
BE_DrawThread
(
void
*
data
)
{
SDL_BWin
*
bwin
=
(
SDL_BWin
*
)
data
;
SDL_Window
*
window
=
_GetBeApp
()
->
GetSDLWindow
(
bwin
->
GetID
());
BScreen
bscreen
;
BScreen
bscreen
;
if
(
!
bscreen
.
IsValid
())
{
if
(
!
bscreen
.
IsValid
())
{
return
-
1
;
return
-
1
;
}
}
if
(
bwin
->
ConnectionEnabled
()
&&
bwin
->
Connected
())
{
while
(
bwin
->
ConnectionEnabled
())
{
bwin
->
LockBuffer
();
if
(
bwin
->
Connected
()
&&
bwin
->
BufferExists
()
&&
bwin
->
BufferIsDirty
()
)
{
int32
windowPitch
=
window
->
surface
->
pitch
;
bwin
->
LockBuffer
();
int32
bufferPitch
=
bwin
->
GetRowBytes
();
int32
windowPitch
=
window
->
surface
->
pitch
;
uint8
*
windowpx
;
int32
bufferPitch
=
bwin
->
GetRowBytes
();
uint8
*
bufferpx
;
uint8
*
windowpx
;
uint8
*
bufferpx
;
int32
BPP
=
bwin
->
GetBytesPerPx
();
uint8
*
windowBaseAddress
=
(
uint8
*
)
window
->
surface
->
pixels
;
int32
BPP
=
bwin
->
GetBytesPerPx
();
int32
windowSub
=
bwin
->
GetFbX
()
*
BPP
+
uint8
*
windowBaseAddress
=
(
uint8
*
)
window
->
surface
->
pixels
;
int32
windowSub
=
bwin
->
GetFbX
()
*
BPP
+
bwin
->
GetFbY
()
*
windowPitch
;
bwin
->
GetFbY
()
*
windowPitch
;
clipping_rect
*
clips
=
bwin
->
GetClips
();
clipping_rect
*
clips
=
bwin
->
GetClips
();
int32
numClips
=
bwin
->
GetNumClips
();
int32
numClips
=
bwin
->
GetNumClips
();
int
i
,
y
;
int
i
,
y
;
/* Blit each clipping rectangle */
/* Blit each clipping rectangle */
bscreen
.
WaitForRetrace
();
bscreen
.
WaitForRetrace
();
for
(
i
=
0
;
i
<
numClips
;
++
i
)
{
for
(
i
=
0
;
i
<
numClips
;
++
i
)
{
clipping_rect
rc
=
clips
[
i
];
clipping_rect
rc
=
clips
[
i
];
/* Get addresses of the start of each clipping rectangle */
/* Get addresses of the start of each clipping rectangle */
int32
width
=
clips
[
i
].
right
-
clips
[
i
].
left
+
1
;
int32
width
=
clips
[
i
].
right
-
clips
[
i
].
left
+
1
;
int32
height
=
clips
[
i
].
bottom
-
clips
[
i
].
top
+
1
;
int32
height
=
clips
[
i
].
bottom
-
clips
[
i
].
top
+
1
;
bufferpx
=
bwin
->
GetBufferPx
()
+
bufferpx
=
bwin
->
GetBufferPx
()
+
clips
[
i
].
top
*
bufferPitch
+
clips
[
i
].
left
*
BPP
;
clips
[
i
].
top
*
bufferPitch
+
clips
[
i
].
left
*
BPP
;
windowpx
=
windowBaseAddress
+
windowpx
=
windowBaseAddress
+
clips
[
i
].
top
*
windowPitch
+
clips
[
i
].
left
*
BPP
-
windowSub
;
clips
[
i
].
top
*
windowPitch
+
clips
[
i
].
left
*
BPP
-
windowSub
;
/* Copy each row of pixels from the window buffer into the frame
/* Copy each row of pixels from the window buffer into the frame
buffer */
buffer */
for
(
y
=
0
;
y
<
height
;
++
y
)
for
(
y
=
0
;
y
<
height
;
++
y
)
{
{
memcpy
(
bufferpx
,
windowpx
,
width
*
BPP
);
memcpy
(
bufferpx
,
windowpx
,
width
*
BPP
);
bufferpx
+=
bufferPitch
;
bufferpx
+=
bufferPitch
;
windowpx
+=
windowPitch
;
windowpx
+=
windowPitch
;
}
}
}
bwin
->
SetBufferDirty
(
false
);
bwin
->
UnlockBuffer
();
}
else
{
snooze
(
1000
);
}
}
bwin
->
UnlockBuffer
();
}
}
return
0
;
return
B_OK
;
}
}
void
BE_DestroyWindowFramebuffer
(
_THIS
,
SDL_Window
*
window
)
{
void
BE_DestroyWindowFramebuffer
(
_THIS
,
SDL_Window
*
window
)
{
...
@@ -307,6 +329,7 @@ void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
...
@@ -307,6 +329,7 @@ void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
uint8
*
winBuffer
=
bwin
->
GetWindowFramebuffer
();
uint8
*
winBuffer
=
bwin
->
GetWindowFramebuffer
();
SDL_free
(
winBuffer
);
SDL_free
(
winBuffer
);
bwin
->
SetWindowFramebuffer
(
NULL
);
bwin
->
SetWindowFramebuffer
(
NULL
);
bwin
->
SetBufferExists
(
false
);
bwin
->
UnlockBuffer
();
bwin
->
UnlockBuffer
();
}
}
...
...
src/video/bwindow/SDL_bmodes.h
View file @
bf4cf189
...
@@ -42,6 +42,7 @@ extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
...
@@ -42,6 +42,7 @@ extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
extern
int
BE_UpdateWindowFramebuffer
(
_THIS
,
SDL_Window
*
window
,
extern
int
BE_UpdateWindowFramebuffer
(
_THIS
,
SDL_Window
*
window
,
SDL_Rect
*
rects
,
int
numrects
);
SDL_Rect
*
rects
,
int
numrects
);
extern
void
BE_DestroyWindowFramebuffer
(
_THIS
,
SDL_Window
*
window
);
extern
void
BE_DestroyWindowFramebuffer
(
_THIS
,
SDL_Window
*
window
);
extern
int32
BE_DrawThread
(
void
*
data
);
#ifdef __cplusplus
#ifdef __cplusplus
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment