summaryrefslogtreecommitdiff
path: root/src/w32xfns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32xfns.c')
-rw-r--r--src/w32xfns.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/src/w32xfns.c b/src/w32xfns.c
index 39a69d14db9..22d39ae0037 100644
--- a/src/w32xfns.c
+++ b/src/w32xfns.c
@@ -1,5 +1,5 @@
/* Functions taken directly from X sources for use with the Microsoft Windows API.
- Copyright (C) 1989, 1992-1995, 1999, 2001-2017 Free Software
+ Copyright (C) 1989, 1992-1995, 1999, 2001-2022 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
@@ -136,13 +136,13 @@ select_palette (struct frame *f, HDC hdc)
f->output_data.w32->old_palette = NULL;
if (RealizePalette (hdc) != GDI_ERROR)
- {
- Lisp_Object frame, framelist;
- FOR_EACH_FRAME (framelist, frame)
{
- SET_FRAME_GARBAGED (XFRAME (frame));
+ Lisp_Object frame, framelist;
+ FOR_EACH_FRAME (framelist, frame)
+ {
+ SET_FRAME_GARBAGED (XFRAME (frame));
+ }
}
- }
}
void
@@ -157,19 +157,70 @@ deselect_palette (struct frame *f, HDC hdc)
HDC
get_frame_dc (struct frame *f)
{
- HDC hdc;
+ HDC hdc, paint_dc;
+ HBITMAP back_buffer;
+ HGDIOBJ obj;
+ struct w32_output *output;
if (f->output_method != output_w32)
emacs_abort ();
enter_crit ();
+ output = FRAME_OUTPUT_DATA (f);
+
+ if (output->paint_dc)
+ {
+ if (output->paint_buffer_width != FRAME_PIXEL_WIDTH (f)
+ || output->paint_buffer_height != FRAME_PIXEL_HEIGHT (f)
+ || w32_disable_double_buffering)
+ w32_release_paint_buffer (f);
+ else
+ {
+ output->paint_buffer_dirty = 1;
+ return output->paint_dc;
+ }
+ }
- hdc = GetDC (f->output_data.w32->window_desc);
+ hdc = GetDC (output->window_desc);
/* If this gets called during startup before the frame is valid,
there is a chance of corrupting random data or crashing. */
if (hdc)
- select_palette (f, hdc);
+ {
+ select_palette (f, hdc);
+
+ if (!w32_disable_double_buffering
+ && FRAME_OUTPUT_DATA (f)->want_paint_buffer)
+ {
+ back_buffer
+ = CreateCompatibleBitmap (hdc, FRAME_PIXEL_WIDTH (f),
+ FRAME_PIXEL_HEIGHT (f));
+
+ if (back_buffer)
+ {
+ paint_dc = CreateCompatibleDC (hdc);
+
+ if (!paint_dc)
+ DeleteObject (back_buffer);
+ else
+ {
+ obj = SelectObject (paint_dc, back_buffer);
+
+ output->paint_dc_object = obj;
+ output->paint_dc = paint_dc;
+ output->paint_buffer_handle = hdc;
+ output->paint_buffer = back_buffer;
+ output->paint_buffer_width = FRAME_PIXEL_WIDTH (f);
+ output->paint_buffer_height = FRAME_PIXEL_HEIGHT (f);
+ output->paint_buffer_dirty = 1;
+
+ SET_FRAME_GARBAGED (f);
+
+ return paint_dc;
+ }
+ }
+ }
+ }
return hdc;
}
@@ -179,8 +230,15 @@ release_frame_dc (struct frame *f, HDC hdc)
{
int ret;
- deselect_palette (f, hdc);
- ret = ReleaseDC (f->output_data.w32->window_desc, hdc);
+ /* Avoid releasing the double-buffered DC here, since it'll be
+ released upon the next buffer flip instead. */
+ if (hdc != FRAME_OUTPUT_DATA (f)->paint_dc)
+ {
+ deselect_palette (f, hdc);
+ ret = ReleaseDC (f->output_data.w32->window_desc, hdc);
+ }
+ else
+ ret = 0;
leave_crit ();