comparison gtk4/dw.c @ 2281:0e93b09ed0e1

GTK4: Cache the cairo context during the drawing area callback. This allows drawing to work for now. However drawing outside of the callback to widgets is currently broken, and not entirely sure it can be fixed with GTK4.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 03 Feb 2021 07:43:18 +0000
parents 7902be60c542
children b045bb67922d
comparison
equal deleted inserted replaced
2280:7902be60c542 2281:0e93b09ed0e1
543 return retval; 543 return retval;
544 } 544 }
545 545
546 static gint _dw_expose_event(GtkWidget *widget, cairo_t *cr, int width, int height, gpointer data) 546 static gint _dw_expose_event(GtkWidget *widget, cairo_t *cr, int width, int height, gpointer data)
547 { 547 {
548 SignalHandler work = _dw_get_signal_handler(data);
549 int retval = FALSE; 548 int retval = FALSE;
550 549
551 if(work.window) 550 if(widget && GTK_IS_DRAWING_AREA(widget))
552 { 551 {
553 DWExpose exp; 552 DWExpose exp;
554 int (*exposefunc)(HWND, DWExpose *, void *) = work.func; 553 int (*exposefunc)(HWND, DWExpose *, void *) = g_object_get_data(G_OBJECT(widget), "_dw_expose_func");
555 554
556 exp.x = exp.y = 0; 555 exp.x = exp.y = 0;
557 exp.width = width; 556 exp.width = width;
558 exp.height = height; 557 exp.height = height;
559 retval = exposefunc(work.window, &exp, work.data); 558 /* Save the cairo context for use in the drawing functions */
559 g_object_set_data(G_OBJECT(widget), "_dw_cr", (gpointer)cr);
560 retval = exposefunc((HWND)widget, &exp, data);
561 g_object_set_data(G_OBJECT(widget), "_dw_cr", NULL);
560 } 562 }
561 return retval; 563 return retval;
562 } 564 }
563 565
564 static gint _dw_combobox_select_event(GtkWidget *widget, gpointer data) 566 static gint _dw_combobox_select_event(GtkWidget *widget, gpointer data)
5472 */ 5474 */
5473 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) 5475 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
5474 { 5476 {
5475 cairo_t *cr = NULL; 5477 cairo_t *cr = NULL;
5476 GdkDrawContext *dc = NULL; 5478 GdkDrawContext *dc = NULL;
5479 int cached = FALSE;
5477 5480
5478 if(handle) 5481 if(handle)
5479 { 5482 {
5480 GtkNative *native = gtk_widget_get_native(handle); 5483 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
5481 GdkSurface *surface = gtk_native_get_surface(native); 5484 cached = TRUE;
5482
5483 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5484 {
5485 cairo_region_t *region = cairo_region_create();
5486 gdk_draw_context_begin_frame(dc, region);
5487 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5488 cairo_region_destroy(region);
5489 }
5490 else 5485 else
5491 return; 5486 {
5487 GtkNative *native = gtk_widget_get_native(handle);
5488 GdkSurface *surface = gtk_native_get_surface(native);
5489
5490 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5491 {
5492 cairo_region_t *region = cairo_region_create();
5493 gdk_draw_context_begin_frame(dc, region);
5494 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5495 cairo_region_destroy(region);
5496 }
5497 else
5498 return;
5499 }
5492 } 5500 }
5493 else if(pixmap) 5501 else if(pixmap)
5494 cr = cairo_create(pixmap->image); 5502 cr = cairo_create(pixmap->image);
5495 if(cr) 5503 if(cr)
5496 { 5504 {
5503 /* If we are using a drawing context... 5511 /* If we are using a drawing context...
5504 * we don't own the cairo context so don't destroy it. 5512 * we don't own the cairo context so don't destroy it.
5505 */ 5513 */
5506 if(dc) 5514 if(dc)
5507 gdk_draw_context_end_frame(dc); 5515 gdk_draw_context_end_frame(dc);
5508 else 5516 else if(!cached)
5509 cairo_destroy(cr); 5517 cairo_destroy(cr);
5510 } 5518 }
5511 } 5519 }
5512 5520
5513 /* Draw a line on a window (preferably a render window). 5521 /* Draw a line on a window (preferably a render window).
5521 */ 5529 */
5522 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2) 5530 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
5523 { 5531 {
5524 cairo_t *cr = NULL; 5532 cairo_t *cr = NULL;
5525 GdkDrawContext *dc = NULL; 5533 GdkDrawContext *dc = NULL;
5534 int cached = FALSE;
5526 5535
5527 if(handle) 5536 if(handle)
5528 { 5537 {
5529 GtkNative *native = gtk_widget_get_native(handle); 5538 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
5530 GdkSurface *surface = gtk_native_get_surface(native); 5539 cached = TRUE;
5531
5532 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5533 {
5534 cairo_region_t *region = cairo_region_create();
5535 gdk_draw_context_begin_frame(dc, region);
5536 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5537 cairo_region_destroy(region);
5538 }
5539 else 5540 else
5540 return; 5541 {
5542 GtkNative *native = gtk_widget_get_native(handle);
5543 GdkSurface *surface = gtk_native_get_surface(native);
5544
5545 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5546 {
5547 cairo_region_t *region = cairo_region_create();
5548 gdk_draw_context_begin_frame(dc, region);
5549 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5550 cairo_region_destroy(region);
5551 }
5552 else
5553 return;
5554 }
5541 } 5555 }
5542 else if(pixmap) 5556 else if(pixmap)
5543 cr = cairo_create(pixmap->image); 5557 cr = cairo_create(pixmap->image);
5544 if(cr) 5558 if(cr)
5545 { 5559 {
5553 /* If we are using a drawing context... 5567 /* If we are using a drawing context...
5554 * we don't own the cairo context so don't destroy it. 5568 * we don't own the cairo context so don't destroy it.
5555 */ 5569 */
5556 if(dc) 5570 if(dc)
5557 gdk_draw_context_end_frame(dc); 5571 gdk_draw_context_end_frame(dc);
5558 else 5572 else if(!cached)
5559 cairo_destroy(cr); 5573 cairo_destroy(cr);
5560 } 5574 }
5561 } 5575 }
5562 5576
5563 /* Draw a closed polygon on a window (preferably a render window). 5577 /* Draw a closed polygon on a window (preferably a render window).
5572 void dw_draw_polygon(HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y) 5586 void dw_draw_polygon(HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y)
5573 { 5587 {
5574 cairo_t *cr = NULL; 5588 cairo_t *cr = NULL;
5575 int z; 5589 int z;
5576 GdkDrawContext *dc = NULL; 5590 GdkDrawContext *dc = NULL;
5591 int cached = FALSE;
5577 5592
5578 if(handle) 5593 if(handle)
5579 { 5594 {
5580 GtkNative *native = gtk_widget_get_native(handle); 5595 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
5581 GdkSurface *surface = gtk_native_get_surface(native); 5596 cached = TRUE;
5582
5583 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5584 {
5585 cairo_region_t *region = cairo_region_create();
5586 gdk_draw_context_begin_frame(dc, region);
5587 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5588 cairo_region_destroy(region);
5589 }
5590 else 5597 else
5591 return; 5598 {
5599 GtkNative *native = gtk_widget_get_native(handle);
5600 GdkSurface *surface = gtk_native_get_surface(native);
5601
5602 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5603 {
5604 cairo_region_t *region = cairo_region_create();
5605 gdk_draw_context_begin_frame(dc, region);
5606 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5607 cairo_region_destroy(region);
5608 }
5609 else
5610 return;
5611 }
5592 } 5612 }
5593 else if(pixmap) 5613 else if(pixmap)
5594 cr = cairo_create(pixmap->image); 5614 cr = cairo_create(pixmap->image);
5595 if(cr) 5615 if(cr)
5596 { 5616 {
5612 /* If we are using a drawing context... 5632 /* If we are using a drawing context...
5613 * we don't own the cairo context so don't destroy it. 5633 * we don't own the cairo context so don't destroy it.
5614 */ 5634 */
5615 if(dc) 5635 if(dc)
5616 gdk_draw_context_end_frame(dc); 5636 gdk_draw_context_end_frame(dc);
5617 else 5637 else if(!cached)
5618 cairo_destroy(cr); 5638 cairo_destroy(cr);
5619 } 5639 }
5620 } 5640 }
5621 5641
5622 /* Draw a rectangle on a window (preferably a render window). 5642 /* Draw a rectangle on a window (preferably a render window).
5631 */ 5651 */
5632 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height) 5652 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height)
5633 { 5653 {
5634 cairo_t *cr = NULL; 5654 cairo_t *cr = NULL;
5635 GdkDrawContext *dc = NULL; 5655 GdkDrawContext *dc = NULL;
5656 int cached = FALSE;
5636 5657
5637 if(handle) 5658 if(handle)
5638 { 5659 {
5639 GtkNative *native = gtk_widget_get_native(handle); 5660 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
5640 GdkSurface *surface = gtk_native_get_surface(native); 5661 cached = TRUE;
5641
5642 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5643 {
5644 cairo_region_t *region = cairo_region_create();
5645 gdk_draw_context_begin_frame(dc, region);
5646 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5647 cairo_region_destroy(region);
5648 }
5649 else 5662 else
5650 return; 5663 {
5664 GtkNative *native = gtk_widget_get_native(handle);
5665 GdkSurface *surface = gtk_native_get_surface(native);
5666
5667 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5668 {
5669 cairo_region_t *region = cairo_region_create();
5670 gdk_draw_context_begin_frame(dc, region);
5671 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5672 cairo_region_destroy(region);
5673 }
5674 else
5675 return;
5676 }
5651 } 5677 }
5652 else if(pixmap) 5678 else if(pixmap)
5653 cr = cairo_create(pixmap->image); 5679 cr = cairo_create(pixmap->image);
5654 if(cr) 5680 if(cr)
5655 { 5681 {
5670 /* If we are using a drawing context... 5696 /* If we are using a drawing context...
5671 * we don't own the cairo context so don't destroy it. 5697 * we don't own the cairo context so don't destroy it.
5672 */ 5698 */
5673 if(dc) 5699 if(dc)
5674 gdk_draw_context_end_frame(dc); 5700 gdk_draw_context_end_frame(dc);
5675 else 5701 else if(!cached)
5676 cairo_destroy(cr); 5702 cairo_destroy(cr);
5677 } 5703 }
5678 } 5704 }
5679 5705
5680 /* Draw an arc on a window (preferably a render window). 5706 /* Draw an arc on a window (preferably a render window).
5692 */ 5718 */
5693 void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) 5719 void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2)
5694 { 5720 {
5695 cairo_t *cr = NULL; 5721 cairo_t *cr = NULL;
5696 GdkDrawContext *dc = NULL; 5722 GdkDrawContext *dc = NULL;
5723 int cached = FALSE;
5697 5724
5698 if(handle) 5725 if(handle)
5699 { 5726 {
5700 GtkNative *native = gtk_widget_get_native(handle); 5727 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
5701 GdkSurface *surface = gtk_native_get_surface(native); 5728 cached = TRUE;
5702
5703 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5704 {
5705 cairo_region_t *region = cairo_region_create();
5706 gdk_draw_context_begin_frame(dc, region);
5707 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5708 cairo_region_destroy(region);
5709 }
5710 else 5729 else
5711 return; 5730 {
5731 GtkNative *native = gtk_widget_get_native(handle);
5732 GdkSurface *surface = gtk_native_get_surface(native);
5733
5734 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5735 {
5736 cairo_region_t *region = cairo_region_create();
5737 gdk_draw_context_begin_frame(dc, region);
5738 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5739 cairo_region_destroy(region);
5740 }
5741 else
5742 return;
5743 }
5712 } 5744 }
5713 else if(pixmap) 5745 else if(pixmap)
5714 cr = cairo_create(pixmap->image); 5746 cr = cairo_create(pixmap->image);
5715 if(cr) 5747 if(cr)
5716 { 5748 {
5743 /* If we are using a drawing context... 5775 /* If we are using a drawing context...
5744 * we don't own the cairo context so don't destroy it. 5776 * we don't own the cairo context so don't destroy it.
5745 */ 5777 */
5746 if(dc) 5778 if(dc)
5747 gdk_draw_context_end_frame(dc); 5779 gdk_draw_context_end_frame(dc);
5748 else 5780 else if(!cached)
5749 cairo_destroy(cr); 5781 cairo_destroy(cr);
5750 } 5782 }
5751 } 5783 }
5752 5784
5753 /* Draw text on a window (preferably a render window). 5785 /* Draw text on a window (preferably a render window).
5762 { 5794 {
5763 cairo_t *cr = NULL; 5795 cairo_t *cr = NULL;
5764 PangoFontDescription *font; 5796 PangoFontDescription *font;
5765 char *tmpname, *fontname = "monospace 10"; 5797 char *tmpname, *fontname = "monospace 10";
5766 GdkDrawContext *dc = NULL; 5798 GdkDrawContext *dc = NULL;
5799 int cached = FALSE;
5767 5800
5768 if(!text) 5801 if(!text)
5769 return; 5802 return;
5770 5803
5771 if(handle) 5804 if(handle)
5772 { 5805 {
5773 GtkNative *native = gtk_widget_get_native(handle); 5806 if((cr = g_object_get_data(G_OBJECT(handle), "_dw_cr")))
5774 GdkSurface *surface = gtk_native_get_surface(native); 5807 cached = TRUE;
5775
5776 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5777 {
5778 cairo_region_t *region = cairo_region_create();
5779 gdk_draw_context_begin_frame(dc, region);
5780 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5781 cairo_region_destroy(region);
5782 }
5783 else 5808 else
5784 return; 5809 {
5810 GtkNative *native = gtk_widget_get_native(handle);
5811 GdkSurface *surface = gtk_native_get_surface(native);
5812
5813 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
5814 {
5815 cairo_region_t *region = cairo_region_create();
5816 gdk_draw_context_begin_frame(dc, region);
5817 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
5818 cairo_region_destroy(region);
5819 }
5820 else
5821 return;
5822 }
5785 if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname"))) 5823 if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname")))
5786 fontname = tmpname; 5824 fontname = tmpname;
5787 } 5825 }
5788 else if(pixmap) 5826 else if(pixmap)
5789 { 5827 {
5840 /* If we are using a drawing context... 5878 /* If we are using a drawing context...
5841 * we don't own the cairo context so don't destroy it. 5879 * we don't own the cairo context so don't destroy it.
5842 */ 5880 */
5843 if(dc) 5881 if(dc)
5844 gdk_draw_context_end_frame(dc); 5882 gdk_draw_context_end_frame(dc);
5845 else 5883 else if(!cached)
5846 cairo_destroy(cr); 5884 cairo_destroy(cr);
5847 } 5885 }
5848 } 5886 }
5849 5887
5850 /* Query the width and height of a text string. 5888 /* Query the width and height of a text string.
6159 int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight) 6197 int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight)
6160 { 6198 {
6161 cairo_t *cr = NULL; 6199 cairo_t *cr = NULL;
6162 int retval = DW_ERROR_GENERAL; 6200 int retval = DW_ERROR_GENERAL;
6163 GdkDrawContext *dc = NULL; 6201 GdkDrawContext *dc = NULL;
6202 int cached = FALSE;
6164 6203
6165 if((!dest && (!destp || !destp->image)) || (!src && (!srcp || !srcp->image))) 6204 if((!dest && (!destp || !destp->image)) || (!src && (!srcp || !srcp->image)))
6166 return retval; 6205 return retval;
6167 6206
6168 if(dest) 6207 if(dest)
6169 { 6208 {
6170 GtkNative *native = gtk_widget_get_native(dest); 6209 if((cr = g_object_get_data(G_OBJECT(dest), "_dw_cr")))
6171 GdkSurface *surface = gtk_native_get_surface(native); 6210 cached = TRUE;
6172
6173 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
6174 {
6175 cairo_region_t *region = cairo_region_create();
6176 gdk_draw_context_begin_frame(dc, region);
6177 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
6178 cairo_region_destroy(region);
6179 }
6180 else 6211 else
6181 return retval; 6212 {
6213 GtkNative *native = gtk_widget_get_native(dest);
6214 GdkSurface *surface = gtk_native_get_surface(native);
6215
6216 if((dc = GDK_DRAW_CONTEXT(gdk_surface_create_cairo_context(surface))))
6217 {
6218 cairo_region_t *region = cairo_region_create();
6219 gdk_draw_context_begin_frame(dc, region);
6220 cr = gdk_cairo_context_cairo_create(GDK_CAIRO_CONTEXT(dc));
6221 cairo_region_destroy(region);
6222 }
6223 else
6224 return retval;
6225 }
6182 } 6226 }
6183 else if(destp) 6227 else if(destp)
6184 cr = cairo_create(destp->image); 6228 cr = cairo_create(destp->image);
6185 6229
6186 if(cr) 6230 if(cr)
6207 /* If we are using a drawing context... 6251 /* If we are using a drawing context...
6208 * we don't own the cairo context so don't destroy it. 6252 * we don't own the cairo context so don't destroy it.
6209 */ 6253 */
6210 if(dc) 6254 if(dc)
6211 gdk_draw_context_end_frame(dc); 6255 gdk_draw_context_end_frame(dc);
6212 else 6256 else if(!cached)
6213 cairo_destroy(cr); 6257 cairo_destroy(cr);
6214 retval = DW_ERROR_NONE; 6258 retval = DW_ERROR_NONE;
6215 } 6259 }
6216 return retval; 6260 return retval;
6217 } 6261 }
9537 9581
9538 GObject *_dw_draw_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data) 9582 GObject *_dw_draw_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data)
9539 { 9583 {
9540 if(GTK_IS_DRAWING_AREA(object)) 9584 if(GTK_IS_DRAWING_AREA(object))
9541 { 9585 {
9542 /* TODO: Might need to use the disconnect paramater since this isn't a normal signal handler */ 9586 g_object_set_data(object, "_dw_expose_func", sigfunc);
9543 gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(object), signal->func, data, NULL); 9587 gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(object), signal->func, data, NULL);
9544 _dw_set_signal_handler(object, (HWND)object, sigfunc, data, signal->func, discfunc);
9545 return NULL; 9588 return NULL;
9546 } 9589 }
9547 return object; 9590 return object;
9548 } 9591 }
9549 9592