[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: MPS: scroll-bars
From: |
Eli Zaretskii |
Subject: |
Re: MPS: scroll-bars |
Date: |
Sat, 04 May 2024 11:47:43 +0300 |
> From: Gerd Möllmann <gerd.moellmann@gmail.com>
> Cc: Po Lu <luangruo@yahoo.com>, Eli Zaretskii <eliz@gnu.org>, Emacs Devel
> <emacs-devel@gnu.org>
> Date: Sat, 04 May 2024 09:09:00 +0200
>
> > #define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))
> >
> > Nice, nice :-)
>
> So, maybe this is also interesting on other platforms, who knows...
>
> struct window has members for scroll bars, e.g.
>
> Lisp_Object vertical_scroll_bar;
>
> These Lisp_Objects are either fixnums or Lisp_Misc_Ptrs (see function
> xmint_ptr in lisp.h).
That's not what I see on w32. Here's what I see:
static void
w32_set_vertical_scroll_bar (struct window *w,
int portion, int whole, int position)
{
Lisp_Object barobj;
struct scroll_bar *bar;
[...]
/* Does the scroll bar exist yet? */
if (NILP (w->vertical_scroll_bar))
{
[...]
bar = w32_scroll_bar_create (w, left, top, width, height, false);
}
[...]
XSETVECTOR (barobj, bar);
wset_vertical_scroll_bar (w, barobj);
And w32_scroll_bar_create does:
static struct scroll_bar *
w32_scroll_bar_create (struct window *w, int left, int top,
int width, int height, bool horizontal)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
[...]
struct scroll_bar *bar
= ALLOCATE_PSEUDOVECTOR (struct scroll_bar, w32_widget_high, PVEC_OTHER);
Lisp_Object barobj;
block_input ();
XSETWINDOW (bar->window, w);
bar->top = top;
bar->left = left;
bar->width = width;
bar->height = height;
bar->start = 0;
bar->end = 0;
bar->dragging = 0;
bar->horizontal = horizontal;
/* Requires geometry to be set before call to create the real window */
if (horizontal)
hwnd = my_create_hscrollbar (f, bar);
else
hwnd = my_create_vscrollbar (f, bar);
[...]
/* Add bar to its frame's list of scroll bars. */
bar->next = FRAME_SCROLL_BARS (f);
bar->prev = Qnil;
XSETVECTOR (barobj, bar);
fset_scroll_bars (f, barobj);
if (! NILP (bar->next))
XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
My conclusions:
. scroll-bar Lisp object is a pseudovector
. w->vertical_scroll_bar is set to the window's scroll-bar object
. scroll-bar objects of a frame are stored in a doubly-linked list
via the ->prev and ->next C pointers of 'struct scroll_bar'
. frame's f->scroll_bars points to the last scroll-bar object
created for the frame's windows, and thus effectively to the
linked list of the frame's scroll bars
. similarly, a frame has f->condemned_scroll_bars, which is a
doubly-linked list of condemned scroll bars, the ones that could
be deleted as result of redisplay (e.g., because their window were
deleted)
Moreover (and this is w32-specific, I think), the Lisp thread sends a
GUI message to the UI thread with the pointer to 'struct scroll_bar',
via the call to my_create_hscrollbar:
case WM_EMACS_CREATEVSCROLLBAR:
return (LRESULT) w32_createvscrollbar ((struct frame *) wParam,
(struct scroll_bar *) lParam);
static HWND
my_create_vscrollbar (struct frame * f, struct scroll_bar * bar)
{
return (HWND) SendMessage (FRAME_W32_WINDOW (f),
WM_EMACS_CREATEVSCROLLBAR, (WPARAM) f,
(LPARAM) bar); <<<<<<<<<<<<<<<<<<<<<<<<
}
the UI thread then uses the members of 'bar' like this:
static HWND
w32_createvscrollbar (struct frame *f, struct scroll_bar * bar)
{
HWND hwnd = CreateWindow ("SCROLLBAR", "",
/* Clip siblings so we don't draw over child
frames. Apparently this is not always
sufficient so we also try to make bar windows
bottommost. */
SBS_VERT | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
/* Position and size of scroll bar. */
bar->left, bar->top, bar->width, bar->height,
FRAME_W32_WINDOW (f), NULL, hinst, NULL);
So, what does this mean in the MPS build? I guess we need to make
sure scroll bars don't move, for the reference across threads to work?
I see that allocate_pseudovector does:
struct Lisp_Vector *
igc_alloc_pseudovector (size_t nwords_mem, size_t nwords_lisp,
size_t nwords_zero, enum pvec_type tag)
{
struct Lisp_Vector *v
= alloc (header_size + nwords_mem * word_size, IGC_OBJ_VECTOR, tag);
XSETPVECTYPESIZE (v, tag, nwords_lisp, nwords_mem - nwords_lisp);
maybe_finalize (v, tag);
return v;
}
But still for the life of me I don't really understand what that means
for us in this case. What does it mean for the references to its C
'struct scroll_bar' when the scroll-bar object is moved? If any of
these references are on some thread's stack, does it mean the object
will not move? And what about those prev and next pointers in frame's
scroll_bars lists -- do we need to do anything with them? Likewise
with the window's vertical_scroll_bar pointers.
- MPS: scroll-bars (was: MPS image cache), (continued)
- Re: MPS: scroll-bars, Po Lu, 2024/05/04
- Re: MPS: scroll-bars, Helmut Eller, 2024/05/04
- Re: MPS: scroll-bars, Gerd Möllmann, 2024/05/04
- Re: MPS: scroll-bars, Helmut Eller, 2024/05/04
- Re: MPS: scroll-bars, Gerd Möllmann, 2024/05/04
- Re: MPS: scroll-bars, Gerd Möllmann, 2024/05/04
- Re: MPS: scroll-bars, Gerd Möllmann, 2024/05/04
- Re: MPS: scroll-bars,
Eli Zaretskii <=
- Re: MPS: scroll-bars, Gerd Möllmann, 2024/05/04
- Re: MPS: scroll-bars, Eli Zaretskii, 2024/05/04
- Re: MPS: scroll-bars, Gerd Möllmann, 2024/05/04
- Re: MPS: w32 threads, Eli Zaretskii, 2024/05/04
- Re: MPS: w32 threads, Gerd Möllmann, 2024/05/04
- Re: MPS: w32 threads, Eli Zaretskii, 2024/05/05
- Re: MPS: w32 threads, Gerd Möllmann, 2024/05/05
- Re: MPS: w32 threads, Eli Zaretskii, 2024/05/05
- Re: MPS: w32 threads, Gerd Möllmann, 2024/05/05
- Re: MPS: w32 threads, Gerd Möllmann, 2024/05/05