Commit 422ff52b authored by Dmitry Antipov's avatar Dmitry Antipov

* window.h (struct window): Convert base_line_number, base_line_pos

and column_number_displayed members from Lisp_Object to ptrdiff_t.
Convert region_showing member from Lisp_Object to bitfield.
Remove sequence_number member.  Adjust comments.
* window.c (sequence_number): Remove.
(make_window): Initialize column_number_displayed.
* print.c (print_object): Follow the printed representation of
frames and print window pointer to distinguish between windows.
(adjust_window_count): Invalidate base_line_pos.  Adjust comment.
* xdisp.c (wset_base_line_number, wset_base_line_pos)
(wset_column_number_displayed, wset_region_showing): Remove.
(window_buffer_changed, mode_line_update_needed, redisplay_internal)
(try_scrolling, try_cursor_movement, redisplay_window)
(try_window_reusing_current_matrix, try_window_id, display_line)
(display_mode_lines, decode_mode_spec): Adjust users.
* .gdbinit (pwinx): Do not print sequence_number.
parent 8654f9d7
...@@ -358,7 +358,6 @@ end ...@@ -358,7 +358,6 @@ end
define pwinx define pwinx
set $w = $arg0 set $w = $arg0
xgetint $w->sequence_number
if ($w->mini_p != Qnil) if ($w->mini_p != Qnil)
printf "Mini " printf "Mini "
end end
......
2013-02-01 Dmitry Antipov <dmantipov@yandex.ru>
* window.h (struct window): Convert base_line_number, base_line_pos
and column_number_displayed members from Lisp_Object to ptrdiff_t.
Convert region_showing member from Lisp_Object to bitfield.
Remove sequence_number member. Adjust comments.
* window.c (sequence_number): Remove.
(make_window): Initialize column_number_displayed.
* print.c (print_object): Follow the printed representation of
frames and print window pointer to distinguish between windows.
(adjust_window_count): Invalidate base_line_pos. Adjust comment.
* xdisp.c (wset_base_line_number, wset_base_line_pos)
(wset_column_number_displayed, wset_region_showing): Remove.
(window_buffer_changed, mode_line_update_needed, redisplay_internal)
(try_scrolling, try_cursor_movement, redisplay_window)
(try_window_reusing_current_matrix, try_window_id, display_line)
(display_mode_lines, decode_mode_spec): Adjust users.
* .gdbinit (pwinx): Do not print sequence_number.
2013-02-01 Paul Eggert <eggert@cs.ucla.edu> 2013-02-01 Paul Eggert <eggert@cs.ucla.edu>
Use fdopendir, fstatat and readlinkat, for efficiency (Bug#13539). Use fdopendir, fstatat and readlinkat, for efficiency (Bug#13539).
......
...@@ -1766,7 +1766,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag ...@@ -1766,7 +1766,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
{ {
int len; int len;
strout ("#<window ", -1, -1, printcharfun); strout ("#<window ", -1, -1, printcharfun);
len = sprintf (buf, "%d", XWINDOW (obj)->sequence_number); len = sprintf (buf, "%p", XWINDOW (obj));
strout (buf, len, len, printcharfun); strout (buf, len, len, printcharfun);
if (!NILP (XWINDOW (obj)->buffer)) if (!NILP (XWINDOW (obj)->buffer))
{ {
......
...@@ -116,9 +116,6 @@ Lisp_Object minibuf_selected_window; ...@@ -116,9 +116,6 @@ Lisp_Object minibuf_selected_window;
/* Hook run at end of temp_output_buffer_show. */ /* Hook run at end of temp_output_buffer_show. */
static Lisp_Object Qtemp_buffer_show_hook; static Lisp_Object Qtemp_buffer_show_hook;
/* Incremented for each window created. */
static int sequence_number;
/* Nonzero after init_window_once has finished. */ /* Nonzero after init_window_once has finished. */
static int window_initialized; static int window_initialized;
...@@ -286,8 +283,9 @@ adjust_window_count (struct window *w, int arg) ...@@ -286,8 +283,9 @@ adjust_window_count (struct window *w, int arg)
b = b->base_buffer; b = b->base_buffer;
b->window_count += arg; b->window_count += arg;
eassert (b->window_count >= 0); eassert (b->window_count >= 0);
/* Catch redisplay's attention. */ /* These should be recalculated by redisplay code. */
w->window_end_valid = 0; w->window_end_valid = 0;
w->base_line_pos = 0;
} }
} }
...@@ -3429,8 +3427,6 @@ make_parent_window (Lisp_Object window, int horflag) ...@@ -3429,8 +3427,6 @@ make_parent_window (Lisp_Object window, int horflag)
adjust_window_count (p, 1); adjust_window_count (p, 1);
XSETWINDOW (parent, p); XSETWINDOW (parent, p);
p->sequence_number = ++sequence_number;
replace_window (window, parent, 1); replace_window (window, parent, 1);
wset_next (o, Qnil); wset_next (o, Qnil);
...@@ -3479,7 +3475,7 @@ make_window (void) ...@@ -3479,7 +3475,7 @@ make_window (void)
w->nrows_scale_factor = w->ncols_scale_factor = 1; w->nrows_scale_factor = w->ncols_scale_factor = 1;
w->phys_cursor_type = -1; w->phys_cursor_type = -1;
w->phys_cursor_width = -1; w->phys_cursor_width = -1;
w->sequence_number = ++sequence_number; w->column_number_displayed = -1;
/* Reset window_list. */ /* Reset window_list. */
Vwindow_list = Qnil; Vwindow_list = Qnil;
......
...@@ -192,23 +192,6 @@ struct window ...@@ -192,23 +192,6 @@ struct window
and Qt, so bitfield can't be used here. */ and Qt, so bitfield can't be used here. */
Lisp_Object dedicated; Lisp_Object dedicated;
/* Line number and position of a line somewhere above the top of the
screen. If this field is nil, it means we don't have a base
line. */
Lisp_Object base_line_number;
/* If this field is nil, it means we don't have a base line.
If it is a buffer, it means don't display the line number
as long as the window shows that buffer. */
Lisp_Object base_line_pos;
/* If we have highlighted the region (or any part of it),
this is the mark position that we used, as an integer. */
Lisp_Object region_showing;
/* The column number currently displayed in this window's mode line,
or nil if column numbers are not being displayed. */
Lisp_Object column_number_displayed;
/* If redisplay in this window goes beyond this buffer position, /* If redisplay in this window goes beyond this buffer position,
must run the redisplay-end-trigger-hook. */ must run the redisplay-end-trigger-hook. */
Lisp_Object redisplay_end_trigger; Lisp_Object redisplay_end_trigger;
...@@ -238,9 +221,6 @@ struct window ...@@ -238,9 +221,6 @@ struct window
/* Number saying how recently window was selected. */ /* Number saying how recently window was selected. */
int use_time; int use_time;
/* Unique number of window assigned when it was created. */
int sequence_number;
/* Number of columns display within the window is scrolled to the left. */ /* Number of columns display within the window is scrolled to the left. */
ptrdiff_t hscroll; ptrdiff_t hscroll;
...@@ -260,6 +240,19 @@ struct window ...@@ -260,6 +240,19 @@ struct window
it should be positive. */ it should be positive. */
ptrdiff_t last_point; ptrdiff_t last_point;
/* Line number and position of a line somewhere above the top of the
screen. If this field is zero, it means we don't have a base line. */
ptrdiff_t base_line_number;
/* If this field is zero, it means we don't have a base line.
If it is -1, it means don't display the line number as long
as the window shows its buffer. */
ptrdiff_t base_line_pos;
/* The column number currently displayed in this window's mode
line, or -1 if column numbers are not being displayed. */
ptrdiff_t column_number_displayed;
/* Scaling factor for the glyph_matrix size calculation in this window. /* Scaling factor for the glyph_matrix size calculation in this window.
Used if window contains many small images or uses proportional fonts, Used if window contains many small images or uses proportional fonts,
as the normal may yield a matrix which is too small. */ as the normal may yield a matrix which is too small. */
...@@ -340,6 +333,9 @@ struct window ...@@ -340,6 +333,9 @@ struct window
the frame image that window_end_pos did not get onto the frame. */ the frame image that window_end_pos did not get onto the frame. */
unsigned window_end_valid : 1; unsigned window_end_valid : 1;
/* Nonzero if we have highlighted the region (or any part of it). */
unsigned region_showing : 1;
/* Amount by which lines of this window are scrolled in /* Amount by which lines of this window are scrolled in
y-direction (smooth scrolling). */ y-direction (smooth scrolling). */
int vscroll; int vscroll;
......
...@@ -367,28 +367,6 @@ Lisp_Object Qcenter; ...@@ -367,28 +367,6 @@ Lisp_Object Qcenter;
static Lisp_Object Qmargin, Qpointer; static Lisp_Object Qmargin, Qpointer;
static Lisp_Object Qline_height; static Lisp_Object Qline_height;
/* These setters are used only in this file, so they can be private. */
static void
wset_base_line_number (struct window *w, Lisp_Object val)
{
w->base_line_number = val;
}
static void
wset_base_line_pos (struct window *w, Lisp_Object val)
{
w->base_line_pos = val;
}
static void
wset_column_number_displayed (struct window *w, Lisp_Object val)
{
w->column_number_displayed = val;
}
static void
wset_region_showing (struct window *w, Lisp_Object val)
{
w->region_showing = val;
}
#ifdef HAVE_WINDOW_SYSTEM #ifdef HAVE_WINDOW_SYSTEM
/* Test if overflow newline into fringe. Called with iterator IT /* Test if overflow newline into fringe. Called with iterator IT
...@@ -10775,7 +10753,7 @@ window_buffer_changed (struct window *w) ...@@ -10775,7 +10753,7 @@ window_buffer_changed (struct window *w)
return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star) return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
|| ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active))) || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
!= !NILP (w->region_showing))); != w->region_showing));
} }
/* Nonzero if W has %c in its mode line and mode line should be updated. */ /* Nonzero if W has %c in its mode line and mode line should be updated. */
...@@ -10783,9 +10761,9 @@ window_buffer_changed (struct window *w) ...@@ -10783,9 +10761,9 @@ window_buffer_changed (struct window *w)
static int static int
mode_line_update_needed (struct window *w) mode_line_update_needed (struct window *w)
{ {
return (!NILP (w->column_number_displayed) return (w->column_number_displayed != -1
&& !(PT == w->last_point && !window_outdated (w)) && !(PT == w->last_point && !window_outdated (w))
&& (XFASTINT (w->column_number_displayed) != current_column ())); && (w->column_number_displayed != current_column ()));
} }
/*********************************************************************** /***********************************************************************
...@@ -13038,18 +13016,6 @@ redisplay_internal (void) ...@@ -13038,18 +13016,6 @@ redisplay_internal (void)
clear_garbaged_frames (); clear_garbaged_frames ();
} }
/* If showing the region, and mark has changed, we must redisplay
the whole window. The assignment to this_line_start_pos prevents
the optimization directly below this if-statement. */
if (((!NILP (Vtransient_mark_mode)
&& !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
!= !NILP (w->region_showing))
|| (!NILP (w->region_showing)
&& !EQ (w->region_showing,
Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
CHARPOS (this_line_start_pos) = 0;
/* Optimize the case that only the line containing the cursor in the /* Optimize the case that only the line containing the cursor in the
selected window has changed. Variables starting with this_ are selected window has changed. Variables starting with this_ are
set in display_line and record information about the line set in display_line and record information about the line
...@@ -13213,7 +13179,7 @@ redisplay_internal (void) ...@@ -13213,7 +13179,7 @@ redisplay_internal (void)
&& (EQ (selected_window, && (EQ (selected_window,
BVAR (current_buffer, last_selected_window)) BVAR (current_buffer, last_selected_window))
|| highlight_nonselected_windows) || highlight_nonselected_windows)
&& NILP (w->region_showing) && !w->region_showing
&& NILP (Vshow_trailing_whitespace) && NILP (Vshow_trailing_whitespace)
&& !cursor_in_echo_area) && !cursor_in_echo_area)
{ {
...@@ -14710,7 +14676,7 @@ try_scrolling (Lisp_Object window, int just_this_one_p, ...@@ -14710,7 +14676,7 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
if (!just_this_one_p if (!just_this_one_p
|| current_buffer->clip_changed || current_buffer->clip_changed
|| BEG_UNCHANGED < CHARPOS (startp)) || BEG_UNCHANGED < CHARPOS (startp))
wset_base_line_number (w, Qnil); w->base_line_number = 0;
/* If cursor ends up on a partially visible line, /* If cursor ends up on a partially visible line,
treat that as being off the bottom of the screen. */ treat that as being off the bottom of the screen. */
...@@ -14859,7 +14825,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste ...@@ -14859,7 +14825,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
region exists, cursor movement has to do more than just region exists, cursor movement has to do more than just
set the cursor. */ set the cursor. */
&& markpos_of_region () < 0 && markpos_of_region () < 0
&& NILP (w->region_showing) && !w->region_showing
&& NILP (Vshow_trailing_whitespace) && NILP (Vshow_trailing_whitespace)
/* This code is not used for mini-buffer for the sake of the case /* This code is not used for mini-buffer for the sake of the case
of redisplaying to replace an echo area message; since in of redisplaying to replace an echo area message; since in
...@@ -15425,7 +15391,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) ...@@ -15425,7 +15391,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
/* Forget any recorded base line for line number display. */ /* Forget any recorded base line for line number display. */
if (!buffer_unchanged_p) if (!buffer_unchanged_p)
wset_base_line_number (w, Qnil); w->base_line_number = 0;
/* Redisplay the mode line. Select the buffer properly for that. /* Redisplay the mode line. Select the buffer properly for that.
Also, run the hook window-scroll-functions Also, run the hook window-scroll-functions
...@@ -15665,7 +15631,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) ...@@ -15665,7 +15631,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
|| current_buffer->clip_changed || current_buffer->clip_changed
|| BEG_UNCHANGED < CHARPOS (startp)) || BEG_UNCHANGED < CHARPOS (startp))
/* Forget any recorded base line for line number display. */ /* Forget any recorded base line for line number display. */
wset_base_line_number (w, Qnil); w->base_line_number = 0;
if (!cursor_row_fully_visible_p (w, 1, 0)) if (!cursor_row_fully_visible_p (w, 1, 0))
{ {
...@@ -15732,11 +15698,9 @@ redisplay_window (Lisp_Object window, int just_this_one_p) ...@@ -15732,11 +15698,9 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
debug_method_add (w, "recenter"); debug_method_add (w, "recenter");
#endif #endif
/* w->vscroll = 0; */
/* Forget any previously recorded base line for line number display. */ /* Forget any previously recorded base line for line number display. */
if (!buffer_unchanged_p) if (!buffer_unchanged_p)
wset_base_line_number (w, Qnil); w->base_line_number = 0;
/* Determine the window start relative to point. */ /* Determine the window start relative to point. */
init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
...@@ -15956,10 +15920,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p) ...@@ -15956,10 +15920,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
&& !FRAME_WINDOW_P (f) && !FRAME_WINDOW_P (f)
&& !WINDOW_FULL_WIDTH_P (w)) && !WINDOW_FULL_WIDTH_P (w))
/* Line number to display. */ /* Line number to display. */
|| INTEGERP (w->base_line_pos) || w->base_line_pos > 0
/* Column number is displayed and different from the one displayed. */ /* Column number is displayed and different from the one displayed. */
|| (!NILP (w->column_number_displayed) || (w->column_number_displayed != -1
&& (XFASTINT (w->column_number_displayed) != current_column ()))) && (w->column_number_displayed != current_column ())))
/* This means that the window has a mode line. */ /* This means that the window has a mode line. */
&& (WINDOW_WANTS_MODELINE_P (w) && (WINDOW_WANTS_MODELINE_P (w)
|| WINDOW_WANTS_HEADER_LINE_P (w))) || WINDOW_WANTS_HEADER_LINE_P (w)))
...@@ -15990,11 +15954,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p) ...@@ -15990,11 +15954,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
goto need_larger_matrices; goto need_larger_matrices;
} }
if (!line_number_displayed if (!line_number_displayed && w->base_line_pos != -1)
&& !BUFFERP (w->base_line_pos))
{ {
wset_base_line_pos (w, Qnil); w->base_line_pos = 0;
wset_base_line_number (w, Qnil); w->base_line_number = 0;
} }
finish_menu_bars: finish_menu_bars:
...@@ -16231,7 +16194,7 @@ try_window_reusing_current_matrix (struct window *w) ...@@ -16231,7 +16194,7 @@ try_window_reusing_current_matrix (struct window *w)
/* Can't do this if region may have changed. */ /* Can't do this if region may have changed. */
if (0 <= markpos_of_region () if (0 <= markpos_of_region ()
|| !NILP (w->region_showing) || w->region_showing
|| !NILP (Vshow_trailing_whitespace)) || !NILP (Vshow_trailing_whitespace))
return 0; return 0;
...@@ -17070,7 +17033,7 @@ try_window_id (struct window *w) ...@@ -17070,7 +17033,7 @@ try_window_id (struct window *w)
GIVE_UP (11); GIVE_UP (11);
/* Likewise if showing a region. */ /* Likewise if showing a region. */
if (!NILP (w->region_showing)) if (w->region_showing)
GIVE_UP (10); GIVE_UP (10);
/* Can't use this if overlay arrow position and/or string have /* Can't use this if overlay arrow position and/or string have
...@@ -19157,7 +19120,7 @@ display_line (struct it *it) ...@@ -19157,7 +19120,7 @@ display_line (struct it *it)
} }
/* Is IT->w showing the region? */ /* Is IT->w showing the region? */
wset_region_showing (it->w, it->region_beg_charpos > 0 ? Qt : Qnil); it->w->region_showing = it->region_beg_charpos > 0;
/* Clear the result glyph row and enable it. */ /* Clear the result glyph row and enable it. */
prepare_desired_row (row); prepare_desired_row (row);
...@@ -20161,7 +20124,7 @@ display_mode_lines (struct window *w) ...@@ -20161,7 +20124,7 @@ display_mode_lines (struct window *w)
/* These will be set while the mode line specs are processed. */ /* These will be set while the mode line specs are processed. */
line_number_displayed = 0; line_number_displayed = 0;
wset_column_number_displayed (w, Qnil); w->column_number_displayed = -1;
if (WINDOW_WANTS_MODELINE_P (w)) if (WINDOW_WANTS_MODELINE_P (w))
{ {
...@@ -21184,8 +21147,7 @@ decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_ ...@@ -21184,8 +21147,7 @@ decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_
returned with spaces to that value. Return a Lisp string in returned with spaces to that value. Return a Lisp string in
*STRING if the resulting string is taken from that Lisp string. *STRING if the resulting string is taken from that Lisp string.
Note we operate on the current buffer for most purposes, Note we operate on the current buffer for most purposes. */
the exception being w->base_line_pos. */
static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------"; static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
...@@ -21296,7 +21258,7 @@ decode_mode_spec (struct window *w, register int c, int field_width, ...@@ -21296,7 +21258,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
else else
{ {
ptrdiff_t col = current_column (); ptrdiff_t col = current_column ();
wset_column_number_displayed (w, make_number (col)); w->column_number_displayed = col;
pint2str (decode_mode_spec_buf, width, col); pint2str (decode_mode_spec_buf, width, col);
return decode_mode_spec_buf; return decode_mode_spec_buf;
} }
...@@ -21355,27 +21317,24 @@ decode_mode_spec (struct window *w, register int c, int field_width, ...@@ -21355,27 +21317,24 @@ decode_mode_spec (struct window *w, register int c, int field_width,
/* If we decided that this buffer isn't suitable for line numbers, /* If we decided that this buffer isn't suitable for line numbers,
don't forget that too fast. */ don't forget that too fast. */
if (EQ (w->base_line_pos, w->buffer)) if (w->base_line_pos == -1)
goto no_value; goto no_value;
/* But do forget it, if the window shows a different buffer now. */
else if (BUFFERP (w->base_line_pos))
wset_base_line_pos (w, Qnil);
/* If the buffer is very big, don't waste time. */ /* If the buffer is very big, don't waste time. */
if (INTEGERP (Vline_number_display_limit) if (INTEGERP (Vline_number_display_limit)
&& BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit)) && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
{ {
wset_base_line_pos (w, Qnil); w->base_line_pos = 0;
wset_base_line_number (w, Qnil); w->base_line_number = 0;
goto no_value; goto no_value;
} }
if (INTEGERP (w->base_line_number) if (w->base_line_number > 0
&& INTEGERP (w->base_line_pos) && w->base_line_pos > 0
&& XFASTINT (w->base_line_pos) <= startpos) && w->base_line_pos <= startpos)
{ {
line = XFASTINT (w->base_line_number); line = w->base_line_number;
linepos = XFASTINT (w->base_line_pos); linepos = w->base_line_pos;
linepos_byte = buf_charpos_to_bytepos (b, linepos); linepos_byte = buf_charpos_to_bytepos (b, linepos);
} }
else else
...@@ -21398,8 +21357,8 @@ decode_mode_spec (struct window *w, register int c, int field_width, ...@@ -21398,8 +21357,8 @@ decode_mode_spec (struct window *w, register int c, int field_width,
go back past it. */ go back past it. */
if (startpos == BUF_BEGV (b)) if (startpos == BUF_BEGV (b))
{ {
wset_base_line_number (w, make_number (topline)); w->base_line_number = topline;
wset_base_line_pos (w, make_number (BUF_BEGV (b))); w->base_line_pos = BUF_BEGV (b);
} }
else if (nlines < height + 25 || nlines > height * 3 + 50 else if (nlines < height + 25 || nlines > height * 3 + 50
|| linepos == BUF_BEGV (b)) || linepos == BUF_BEGV (b))
...@@ -21425,13 +21384,13 @@ decode_mode_spec (struct window *w, register int c, int field_width, ...@@ -21425,13 +21384,13 @@ decode_mode_spec (struct window *w, register int c, int field_width,
give up on line numbers for this window. */ give up on line numbers for this window. */
if (position == limit_byte && limit == startpos - distance) if (position == limit_byte && limit == startpos - distance)
{ {
wset_base_line_pos (w, w->buffer); w->base_line_pos = -1;
wset_base_line_number (w, Qnil); w->base_line_number = 0;
goto no_value; goto no_value;
} }
wset_base_line_number (w, make_number (topline - nlines)); w->base_line_number = topline - nlines;
wset_base_line_pos (w, make_number (BYTE_TO_CHAR (position))); w->base_line_pos = BYTE_TO_CHAR (position);
} }
/* Now count lines from the start pos to point. */ /* Now count lines from the start pos to point. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment