Blender  V3.3
screendump.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
9 #include <errno.h>
10 #include <string.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "BLI_blenlib.h"
15 #include "BLI_utildefines.h"
16 
17 #include "IMB_imbuf.h"
18 #include "IMB_imbuf_types.h"
19 
20 #include "DNA_scene_types.h"
21 #include "DNA_screen_types.h"
22 #include "DNA_space_types.h"
23 
24 #include "BKE_context.h"
25 #include "BKE_global.h"
26 #include "BKE_image.h"
27 #include "BKE_image_format.h"
28 #include "BKE_main.h"
29 #include "BKE_report.h"
30 #include "BKE_screen.h"
31 
32 #include "RNA_access.h"
33 #include "RNA_define.h"
34 #include "RNA_prototypes.h"
35 
36 #include "UI_interface.h"
37 
38 #include "WM_api.h"
39 #include "WM_types.h"
40 
41 #include "screen_intern.h"
42 
43 typedef struct ScreenshotData {
45  int dumpsx, dumpsy;
47  bool use_crop;
48 
51 
52 /* call from both exec and invoke */
54 {
55  int dumprect_size[2];
56 
58  wmWindow *win = CTX_wm_window(C);
59 
60  /* do redraw so we don't show popups/menus */
62 
63  uint *dumprect = WM_window_pixels_read(wm, win, dumprect_size);
64 
65  if (dumprect) {
66  ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot");
67 
68  scd->dumpsx = dumprect_size[0];
69  scd->dumpsy = dumprect_size[1];
70  scd->dumprect = dumprect;
71  if (area) {
72  scd->crop = area->totrct;
73  }
74 
75  BKE_image_format_init(&scd->im_format, false);
76 
77  op->customdata = scd;
78 
79  return true;
80  }
81  op->customdata = NULL;
82  return false;
83 }
84 
86 {
87  ScreenshotData *scd = op->customdata;
88 
89  if (scd) {
90  if (scd->dumprect) {
91  MEM_freeN(scd->dumprect);
92  }
93  MEM_freeN(scd);
94  op->customdata = NULL;
95  }
96 }
97 
99 {
100  const bool use_crop = STREQ(op->idname, "SCREEN_OT_screenshot_area");
101  ScreenshotData *scd = op->customdata;
102  bool ok = false;
103 
104  if (scd == NULL) {
105  /* when running exec directly */
106  screenshot_data_create(C, op, use_crop ? CTX_wm_area(C) : NULL);
107  scd = op->customdata;
108  }
109 
110  if (scd) {
111  if (scd->dumprect) {
112  ImBuf *ibuf;
113  char path[FILE_MAX];
114 
115  RNA_string_get(op->ptr, "filepath", path);
117 
118  /* operator ensures the extension */
119  ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0);
120  ibuf->rect = scd->dumprect;
121 
122  /* crop to show only single editor */
123  if (use_crop) {
124  IMB_rect_crop(ibuf, &scd->crop);
125  scd->dumprect = ibuf->rect;
126  }
127 
128  if (scd->im_format.planes == R_IMF_PLANES_BW) {
129  /* bw screenshot? - users will notice if it fails! */
130  IMB_color_to_bw(ibuf);
131  }
132  if (BKE_imbuf_write(ibuf, path, &scd->im_format)) {
133  ok = true;
134  }
135  else {
136  BKE_reportf(op->reports, RPT_ERROR, "Could not write image: %s", strerror(errno));
137  }
138 
139  IMB_freeImBuf(ibuf);
140  }
141  }
142 
144 
146 }
147 
148 static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *event)
149 {
150  const bool use_crop = STREQ(op->idname, "SCREEN_OT_screenshot_area");
151  ScrArea *area = NULL;
152  if (use_crop) {
153  area = CTX_wm_area(C);
154  bScreen *screen = CTX_wm_screen(C);
155  ScrArea *area_test = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->xy);
156  if (area_test != NULL) {
157  area = area_test;
158  }
159  }
160 
161  if (screenshot_data_create(C, op, area)) {
162  if (RNA_struct_property_is_set(op->ptr, "filepath")) {
163  return screenshot_exec(C, op);
164  }
165 
166  /* extension is added by 'screenshot_check' after */
167  char filepath[FILE_MAX] = "//screen";
168  const char *blendfile_path = BKE_main_blendfile_path_from_global();
169  if (blendfile_path[0] != '\0') {
170  BLI_strncpy(filepath, blendfile_path, sizeof(filepath));
171  BLI_path_extension_replace(filepath, sizeof(filepath), ""); /* strip '.blend' */
172  }
173  RNA_string_set(op->ptr, "filepath", filepath);
174 
176 
177  return OPERATOR_RUNNING_MODAL;
178  }
179  return OPERATOR_CANCELLED;
180 }
181 
183 {
184  ScreenshotData *scd = op->customdata;
186 }
187 
189 {
191 }
192 
194  PropertyRNA *prop,
195  void *UNUSED(user_data))
196 {
197  const char *prop_id = RNA_property_identifier(prop);
198 
199  return !(STREQ(prop_id, "filepath"));
200 }
201 
203 {
204  uiLayout *layout = op->layout;
205  ScreenshotData *scd = op->customdata;
206 
207  uiLayoutSetPropSep(layout, true);
208  uiLayoutSetPropDecorate(layout, false);
209 
210  /* image template */
211  PointerRNA ptr;
212  RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &scd->im_format, &ptr);
213  uiTemplateImageSettings(layout, &ptr, false);
214 
215  /* main draw call */
218 }
219 
221 {
222  if (G.background) {
223  return false;
224  }
225 
226  return WM_operator_winactive(C);
227 }
228 
230 {
235  ot->ui = screenshot_draw;
237 
240  FILE_SPECIAL,
241  FILE_SAVE,
245 }
246 
248 {
249  ot->name = "Save Screenshot";
250  ot->idname = "SCREEN_OT_screenshot";
251  ot->description = "Capture a picture of the whole Blender window";
252 
254 
255  ot->flag = 0;
256 }
257 
259 {
260  /* NOTE: the term "area" is a Blender internal name, "Editor" makes more sense for the UI. */
261  ot->name = "Save Screenshot (Editor)";
262  ot->idname = "SCREEN_OT_screenshot_area";
263  ot->description = "Capture a picture of an editor";
264 
266 
268 }
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:733
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, const struct ImageFormatData *imf)
void BKE_image_format_init(struct ImageFormatData *imf, const bool render)
Definition: image_format.cc:26
const char * BKE_main_blendfile_path_from_global(void)
Definition: main.c:562
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
struct ScrArea struct ScrArea * BKE_screen_find_area_xy(struct bScreen *screen, int spacetype, const int xy[2]) ATTR_NONNULL(1
#define FILE_MAX
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1393
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:897
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define STREQ(a, b)
#define R_IMF_PLANES_BW
@ FILE_SORT_DEFAULT
@ FILE_SPECIAL
@ FILE_TYPE_FOLDER
@ FILE_TYPE_IMAGE
@ FILE_DEFAULTDISPLAY
#define SPACE_TYPE_ANY
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void IMB_color_to_bw(struct ImBuf *ibuf)
Definition: divers.c:844
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:500
void IMB_rect_crop(struct ImBuf *ibuf, const struct rcti *crop)
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
void uiTemplateImageSettings(uiLayout *layout, struct PointerRNA *imfptr, bool color_management)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
@ UI_BUT_LABEL_ALIGN_NONE
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, bool(*check_prop)(struct PointerRNA *ptr, struct PropertyRNA *prop, void *user_data), void *user_data, struct PropertyRNA *prop_activate_init, eButLabelAlign label_align, bool compact)
@ WM_FILESEL_FILEPATH
Definition: WM_api.h:755
@ FILE_SAVE
Definition: WM_api.h:765
@ OPTYPE_DEPENDS_ON_CURSOR
Definition: WM_types.h:184
void * user_data
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:5155
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:5116
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:5301
struct ScreenshotData ScreenshotData
static bool screenshot_poll(bContext *C)
Definition: screendump.c:220
void SCREEN_OT_screenshot(wmOperatorType *ot)
Definition: screendump.c:247
static int screenshot_data_create(bContext *C, wmOperator *op, ScrArea *area)
Definition: screendump.c:53
static void screenshot_cancel(bContext *UNUSED(C), wmOperator *op)
Definition: screendump.c:188
static void screen_screenshot_impl(wmOperatorType *ot)
Definition: screendump.c:229
static void screenshot_draw(bContext *UNUSED(C), wmOperator *op)
Definition: screendump.c:202
void SCREEN_OT_screenshot_area(wmOperatorType *ot)
Definition: screendump.c:258
static int screenshot_exec(bContext *C, wmOperator *op)
Definition: screendump.c:98
static void screenshot_data_free(wmOperator *op)
Definition: screendump.c:85
static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screendump.c:148
static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
Definition: screendump.c:193
static bool screenshot_check(bContext *UNUSED(C), wmOperator *op)
Definition: screendump.c:182
unsigned int * rect
ImageFormatData im_format
Definition: screendump.c:49
uint * dumprect
Definition: screendump.c:44
int xy[2]
Definition: WM_types.h:682
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:927
const char * description
Definition: WM_types.h:893
void(* ui)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:954
bool(* check)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:911
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct ReportList * reports
struct uiLayout * layout
struct PointerRNA * ptr
void WM_redraw_windows(bContext *C)
Definition: wm_draw.c:1380
void WM_event_add_fileselect(bContext *C, wmOperator *op)
PointerRNA * ptr
Definition: wm_files.c:3480
wmOperatorType * ot
Definition: wm_files.c:3479
void WM_operator_properties_filesel(wmOperatorType *ot, const int filter, const short type, const eFileSel_Action action, const eFileSel_Flag flag, const short display, const short sort)
bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
bool WM_operator_winactive(bContext *C)
uint * WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2])
Definition: wm_window.c:1953