scrot_selection.c (scrot-1.7.tar.bz2) | : | scrot_selection.c (scrot-1.8) | ||
---|---|---|---|---|
/* scrot_selection.c | /* scrot_selection.c | |||
Copyright 2020-2021 Daniel T. Borelli <danieltborelli@gmail.com> | Copyright 2020-2022 Daniel T. Borelli <danieltborelli@gmail.com> | |||
Copyright 2021 Martin C <martincation@protonmail.com> | Copyright 2021-2023 Guilherme Janczak <guilherme.janczak@yandex.com> | |||
Copyright 2021 Peter Wu <peterwu@hotmail.com> | Copyright 2021 Martin C <martincation@protonmail.com> | |||
Copyright 2021 Wilson Smith <01wsmith+gh@gmail.com> | Copyright 2021 Peter Wu <peterwu@hotmail.com> | |||
Copyright 2021 Wilson Smith <01wsmith+gh@gmail.com> | ||||
Copyright 2022 NRK <nrk@disroot.org> | ||||
Permission is hereby granted, free of charge, to any person obtaining a copy | Permission is hereby granted, free of charge, to any person obtaining a copy | |||
of this software and associated documentation files (the "Software"), to | of this software and associated documentation files (the "Software"), to | |||
deal in the Software without restriction, including without limitation the | deal in the Software without restriction, including without limitation the | |||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |||
sell copies of the Software, and to permit persons to whom the Software is | sell copies of the Software, and to permit persons to whom the Software is | |||
furnished to do so, subject to the following conditions: | furnished to do so, subject to the following conditions: | |||
The above copyright notice and this permission notice shall be included in | The above copyright notice and this permission notice shall be included in | |||
all copies of the Software and its documentation and acknowledgment shall be | all copies of the Software and its documentation and acknowledgment shall be | |||
skipping to change at line 31 | skipping to change at line 33 | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | */ | |||
/* | /* | |||
This file is part of the scrot project. | This file is part of the scrot project. | |||
Part of the code comes from the main.c file and maintains its authorship. | Part of the code comes from the scrot.c file and maintains its authorship. | |||
*/ | */ | |||
#include <sys/select.h> | ||||
#include <assert.h> | ||||
#include <err.h> | ||||
#include <errno.h> | ||||
#include <stdint.h> | ||||
#include <stdlib.h> | ||||
#include <string.h> | ||||
#include <time.h> | ||||
#include <Imlib2.h> | ||||
#include <X11/Xlib.h> | ||||
#include <X11/cursorfont.h> | ||||
#include <X11/keysym.h> | ||||
#include "imlib.h" | ||||
#include "options.h" | ||||
#include "scrot.h" | #include "scrot.h" | |||
#include "scrot_selection.h" | ||||
#include "selection_classic.h" | #include "selection_classic.h" | |||
#include "selection_edge.h" | #include "selection_edge.h" | |||
struct Selection** selectionGet(void) | struct Selection **selectionGet(void) | |||
{ | { | |||
static struct Selection* sel = NULL; | static struct Selection *sel = NULL; | |||
return &sel; | return &sel; | |||
} | } | |||
static void selectionAllocate(void) | static void selectionAllocate(void) | |||
{ | { | |||
struct Selection** sel = selectionGet(); | struct Selection **sel = selectionGet(); | |||
*sel = calloc(1, sizeof(**sel)); | *sel = calloc(1, sizeof(**sel)); | |||
} | } | |||
static void selectionDeallocate(void) | static void selectionDeallocate(void) | |||
{ | { | |||
struct Selection** sel = selectionGet(); | struct Selection **sel = selectionGet(); | |||
free(*sel); | free(*sel); | |||
*sel = NULL; | *sel = NULL; | |||
} | } | |||
static void createCursors(void) | static void createCursors(void) | |||
{ | { | |||
struct Selection* const sel = *selectionGet(); | struct Selection *const sel = *selectionGet(); | |||
assert(sel != NULL); | assert(sel != NULL); | |||
if (opt.selection.mode == SELECTION_MODE_CAPTURE) | if (opt.selection.mode == SELECTION_MODE_CAPTURE) | |||
sel->curCross = XCreateFontCursor(disp, XC_cross); | sel->curCross = XCreateFontCursor(disp, XC_cross); | |||
else if (opt.selection.mode == SELECTION_MODE_HIDE) | else if (opt.selection.mode == SELECTION_MODE_HIDE) | |||
sel->curCross = XCreateFontCursor(disp, XC_spraycan); | sel->curCross = XCreateFontCursor(disp, XC_spraycan); | |||
else if (opt.selection.mode == SELECTION_MODE_BLUR) | else if (opt.selection.mode == SELECTION_MODE_BLUR) | |||
sel->curCross = XCreateFontCursor(disp, XC_box_spiral); | sel->curCross = XCreateFontCursor(disp, XC_box_spiral); | |||
else // SELECTION_MODE_HOLE | else // SELECTION_MODE_HOLE | |||
sel->curCross = XCreateFontCursor(disp, XC_target); | sel->curCross = XCreateFontCursor(disp, XC_target); | |||
sel->curAngleNE = XCreateFontCursor(disp, XC_ur_angle); | sel->curAngleNE = XCreateFontCursor(disp, XC_ur_angle); | |||
sel->curAngleNW = XCreateFontCursor(disp, XC_ul_angle); | sel->curAngleNW = XCreateFontCursor(disp, XC_ul_angle); | |||
sel->curAngleSE = XCreateFontCursor(disp, XC_lr_angle); | sel->curAngleSE = XCreateFontCursor(disp, XC_lr_angle); | |||
sel->curAngleSW = XCreateFontCursor(disp, XC_ll_angle); | sel->curAngleSW = XCreateFontCursor(disp, XC_ll_angle); | |||
} | } | |||
static void freeCursors(void) | static void freeCursors(void) | |||
{ | { | |||
struct Selection* const sel = *selectionGet(); | struct Selection *const sel = *selectionGet(); | |||
assert(sel != NULL); | assert(sel != NULL); | |||
XFreeCursor(disp, sel->curCross); | XFreeCursor(disp, sel->curCross); | |||
XFreeCursor(disp, sel->curAngleNE); | XFreeCursor(disp, sel->curAngleNE); | |||
XFreeCursor(disp, sel->curAngleNW); | XFreeCursor(disp, sel->curAngleNW); | |||
XFreeCursor(disp, sel->curAngleSE); | XFreeCursor(disp, sel->curAngleSE); | |||
XFreeCursor(disp, sel->curAngleSW); | XFreeCursor(disp, sel->curAngleSW); | |||
} | } | |||
void selectionCalculateRect(int x0, int y0, int x1, int y1) | void selectionCalculateRect(int x0, int y0, int x1, int y1) | |||
{ | { | |||
struct SelectionRect* const rect = scrotSelectionGetRect(); | struct SelectionRect *const rect = scrotSelectionGetRect(); | |||
rect->x = x0; | rect->x = x0; | |||
rect->y = y0; | rect->y = y0; | |||
rect->w = x1 - x0; | rect->w = x1 - x0; | |||
rect->h = y1 - y0; | rect->h = y1 - y0; | |||
if (rect->w == 0) | if (rect->w == 0) | |||
rect->w++; | rect->w++; | |||
if (rect->h == 0) | if (rect->h == 0) | |||
skipping to change at line 120 | skipping to change at line 140 | |||
if (rect->h < 0) { | if (rect->h < 0) { | |||
rect->y += rect->h; | rect->y += rect->h; | |||
rect->h = 0 - rect->h; | rect->h = 0 - rect->h; | |||
} | } | |||
} | } | |||
void scrotSelectionCreate(void) | void scrotSelectionCreate(void) | |||
{ | { | |||
selectionAllocate(); | selectionAllocate(); | |||
struct Selection* const sel = *selectionGet(); | struct Selection *const sel = *selectionGet(); | |||
assert(sel != NULL); | assert(sel != NULL); | |||
createCursors(); | createCursors(); | |||
if (!strncmp(opt.lineMode, LINE_MODE_S_CLASSIC, LINE_MODE_L_CLASSIC)) { | if (!strncmp(opt.lineMode, LINE_MODE_S_CLASSIC, LINE_MODE_L_CLASSIC)) { | |||
sel->create = selectionClassicCreate; | sel->create = selectionClassicCreate; | |||
sel->draw = selectionClassicDraw; | sel->draw = selectionClassicDraw; | |||
sel->motionDraw = selectionClassicMotionDraw; | sel->motionDraw = selectionClassicMotionDraw; | |||
sel->destroy = selectionClassicDestroy; | sel->destroy = selectionClassicDestroy; | |||
skipping to change at line 155 | skipping to change at line 175 | |||
if ((XGrabPointer(disp, root, False, EVENT_MASK, GrabModeAsync, | if ((XGrabPointer(disp, root, False, EVENT_MASK, GrabModeAsync, | |||
GrabModeAsync, root, sel->curCross, CurrentTime) | GrabModeAsync, root, sel->curCross, CurrentTime) | |||
!= GrabSuccess)) { | != GrabSuccess)) { | |||
scrotSelectionDestroy(); | scrotSelectionDestroy(); | |||
errx(EXIT_FAILURE, "couldn't grab pointer"); | errx(EXIT_FAILURE, "couldn't grab pointer"); | |||
} | } | |||
} | } | |||
void scrotSelectionDestroy(void) | void scrotSelectionDestroy(void) | |||
{ | { | |||
struct Selection* const sel = *selectionGet(); | struct Selection *const sel = *selectionGet(); | |||
XUngrabPointer(disp, CurrentTime); | XUngrabPointer(disp, CurrentTime); | |||
freeCursors(); | freeCursors(); | |||
XSync(disp, True); | XSync(disp, True); | |||
sel->destroy(); | sel->destroy(); | |||
selectionDeallocate(); | selectionDeallocate(); | |||
} | } | |||
void scrotSelectionDraw(void) | void scrotSelectionDraw(void) | |||
{ | { | |||
struct Selection const* const sel = *selectionGet(); | const struct Selection *const sel = *selectionGet(); | |||
sel->draw(); | sel->draw(); | |||
} | } | |||
void scrotSelectionMotionDraw(int x0, int y0, int x1, int y1) | void scrotSelectionMotionDraw(int x0, int y0, int x1, int y1) | |||
{ | { | |||
struct Selection const* const sel = *selectionGet(); | const struct Selection *const sel = *selectionGet(); | |||
unsigned int const EVENT_MASK = ButtonMotionMask | ButtonReleaseMask; | const unsigned int EVENT_MASK = ButtonMotionMask | ButtonReleaseMask; | |||
Cursor cursor = None; | Cursor cursor = None; | |||
if (x1 > x0 && y1 > y0) | if (x1 > x0 && y1 > y0) | |||
cursor = sel->curAngleSE; | cursor = sel->curAngleSE; | |||
else if (x1 > x0) | else if (x1 > x0) | |||
cursor = sel->curAngleNE; | cursor = sel->curAngleNE; | |||
else if (y1 > y0) | else if (y1 > y0) | |||
cursor = sel->curAngleSW; | cursor = sel->curAngleSW; | |||
else | else | |||
cursor = sel->curAngleNW; | cursor = sel->curAngleNW; | |||
XChangeActivePointerGrab(disp, EVENT_MASK, cursor, CurrentTime); | XChangeActivePointerGrab(disp, EVENT_MASK, cursor, CurrentTime); | |||
sel->motionDraw(x0, y0, x1, y1); | sel->motionDraw(x0, y0, x1, y1); | |||
} | } | |||
struct SelectionRect* scrotSelectionGetRect(void) | struct SelectionRect *scrotSelectionGetRect(void) | |||
{ | { | |||
return &(*selectionGet())->rect; | return &(*selectionGet())->rect; | |||
} | } | |||
Status scrotSelectionCreateNamedColor(char const* nameColor, XColor* color) | Status scrotSelectionCreateNamedColor(const char *nameColor, XColor *color) | |||
{ | { | |||
assert(nameColor != NULL); | assert(nameColor != NULL); | |||
assert(color != NULL); | assert(color != NULL); | |||
return XAllocNamedColor(disp, XDefaultColormap(disp, DefaultScreen(disp)), | return XAllocNamedColor(disp, XDefaultColormap(disp, DefaultScreen(disp)), | |||
nameColor, color, &(XColor) {}); | nameColor, color, &(XColor){0}); | |||
} | } | |||
void scrotSelectionGetLineColor(XColor* color) | void scrotSelectionGetLineColor(XColor *color) | |||
{ | { | |||
scrotSelectionSetDefaultColorLine(); | scrotSelectionSetDefaultColorLine(); | |||
Status const ret = scrotSelectionCreateNamedColor(opt.lineColor, color); | const Status ret = scrotSelectionCreateNamedColor(opt.lineColor, color); | |||
if (!ret) { | if (!ret) { | |||
scrotSelectionDestroy(); | scrotSelectionDestroy(); | |||
errx(EXIT_FAILURE, "Error allocate color:%s", strerror(BadColor)); | errx(EXIT_FAILURE, "Error allocate color:%s", strerror(BadColor)); | |||
} | } | |||
} | } | |||
void scrotSelectionSetDefaultColorLine(void) | void scrotSelectionSetDefaultColorLine(void) | |||
{ | { | |||
if (!opt.lineColor) | if (!opt.lineColor) | |||
opt.lineColor = "gray"; | opt.lineColor = "gray"; | |||
} | } | |||
bool scrotSelectionGetUserSel(struct SelectionRect* selectionRect) | bool scrotSelectionGetUserSel(struct SelectionRect *selectionRect) | |||
{ | { | |||
static int xfd = 0; | static int xfd = 0; | |||
static int fdSize = 0; | static int fdSize = 0; | |||
XEvent ev; | XEvent ev; | |||
fd_set fdSet; | fd_set fdSet; | |||
int count = 0, done = 0; | int count = 0, done = 0; | |||
int rx = 0, ry = 0, rw = 0, rh = 0, isButtonPressed = 0; | int rx = 0, ry = 0, rw = 0, rh = 0, isButtonPressed = 0; | |||
Window target = None; | Window target = None; | |||
Status ret; | Status ret; | |||
skipping to change at line 271 | skipping to change at line 291 | |||
ry = ev.xbutton.y; | ry = ev.xbutton.y; | |||
target = scrotGetWindow(disp, ev.xbutton.subwindow, ev.xbutton.x , ev.xbutton.y); | target = scrotGetWindow(disp, ev.xbutton.subwindow, ev.xbutton.x , ev.xbutton.y); | |||
if (target == None) | if (target == None) | |||
target = root; | target = root; | |||
break; | break; | |||
case ButtonRelease: | case ButtonRelease: | |||
done = 1; | done = 1; | |||
break; | break; | |||
case KeyPress: | case KeyPress: | |||
{ | { | |||
KeySym* keysym = NULL; | KeySym *keysym = NULL; | |||
int keycode; /*dummy*/ | int keycode; /*dummy*/ | |||
keysym = XGetKeyboardMapping(disp, ev.xkey.keycode, 1, &keycode) ; | keysym = XGetKeyboardMapping(disp, ev.xkey.keycode, 1, &keycode) ; | |||
if (!keysym) | if (!keysym) | |||
break; | break; | |||
if (!isButtonPressed) { | if (!isButtonPressed) { | |||
key_abort_shot: | key_abort_shot: | |||
if (!opt.ignoreKeyboard || *keysym == XK_Escape) { | if (!opt.ignoreKeyboard || *keysym == XK_Escape) { | |||
skipping to change at line 338 | skipping to change at line 358 | |||
if ((count < 0) | if ((count < 0) | |||
&& ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF))) { | && ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF))) { | |||
scrotSelectionDestroy(); | scrotSelectionDestroy(); | |||
errx(EXIT_FAILURE, "Connection to X display lost"); | errx(EXIT_FAILURE, "Connection to X display lost"); | |||
} | } | |||
} | } | |||
scrotSelectionDraw(); | scrotSelectionDraw(); | |||
XUngrabKeyboard(disp, CurrentTime); | XUngrabKeyboard(disp, CurrentTime); | |||
bool const isAreaSelect = (scrotSelectionGetRect()->w > 5); | const bool isAreaSelect = (scrotSelectionGetRect()->w > 5); | |||
scrotSelectionDestroy(); | scrotSelectionDestroy(); | |||
if (done == 2) | if (done == 2) | |||
return false; | return false; | |||
if (isAreaSelect) { | if (isAreaSelect) { | |||
/* If a rect has been drawn, it's an area selection */ | /* If a rect has been drawn, it's an area selection */ | |||
rw = ev.xbutton.x - rx; | rw = ev.xbutton.x - rx; | |||
rh = ev.xbutton.y - ry; | rh = ev.xbutton.y - ry; | |||
skipping to change at line 374 | skipping to change at line 394 | |||
} | } | |||
// Not record pointer if there is a selection area because it is busy on that, | // Not record pointer if there is a selection area because it is busy on that, | |||
// unless the delay option is used. | // unless the delay option is used. | |||
if (opt.delay == 0) | if (opt.delay == 0) | |||
opt.pointer = 0; | opt.pointer = 0; | |||
} else { | } else { | |||
/* else it's a window click */ | /* else it's a window click */ | |||
if (!scrotGetGeometry(target, &rx, &ry, &rw, &rh)) | if (!scrotGetGeometry(target, &rx, &ry, &rw, &rh)) | |||
return false; | return false; | |||
clientWindow = target; | ||||
} | } | |||
scrotNiceClip(&rx, &ry, &rw, &rh); | scrotNiceClip(&rx, &ry, &rw, &rh); | |||
if (!opt.silent) | if (!opt.silent) | |||
XBell(disp, 0); | XBell(disp, 0); | |||
selectionRect->x = rx; | selectionRect->x = rx; | |||
selectionRect->y = ry; | selectionRect->y = ry; | |||
selectionRect->w = rw; | selectionRect->w = rw; | |||
selectionRect->h = rh; | selectionRect->h = rh; | |||
return true; | return true; | |||
} | } | |||
static void changeImageOpacity(Imlib_Image image, int const opacity) | static void changeImageOpacity(Imlib_Image image, const int opacity) | |||
{ | { | |||
#define PIXEL_ARGB(a, r, g, b) ((a) << 24) | ((r) << 16) | ((g) << 8) | (b) | ||||
#define PIXEL_A(argb) (((argb) >> 24) & 0xff) | ||||
#define PIXEL_R(argb) (((argb) >> 16) & 0xff) | ||||
#define PIXEL_G(argb) (((argb) >> 8) & 0xff) | ||||
#define PIXEL_B(argb) (((argb) ) & 0xff) | ||||
imlib_context_set_image(image); | imlib_context_set_image(image); | |||
int const w = imlib_image_get_width(); | const int w = imlib_image_get_width(); | |||
int const h = imlib_image_get_height(); | const int h = imlib_image_get_height(); | |||
DATA32* data = imlib_image_get_data(); | uint32_t *data = imlib_image_get_data(); | |||
DATA32* end = data + (h * w); | uint32_t *end = data + (h * w); | |||
for (DATA32* pixel = data; pixel != end; ++pixel) { | for (uint32_t *pixel = data; pixel != end; ++pixel) { | |||
DATA8 const a = PIXEL_A(*pixel) * opacity / 255; | const uint32_t a = (*pixel >> 24) * opacity / 255; | |||
DATA8 const r = PIXEL_R(*pixel); | *pixel = (a << 24) | (*pixel & 0x00FFFFFF); | |||
DATA8 const g = PIXEL_G(*pixel); | ||||
DATA8 const b = PIXEL_B(*pixel); | ||||
*pixel = (DATA32)PIXEL_ARGB(a, r, g, b); | ||||
} | } | |||
imlib_image_put_back_data(data); | imlib_image_put_back_data(data); | |||
} | } | |||
static Imlib_Image loadImage(char const* const fileName, int const opacity) | static Imlib_Image loadImage(const char *const fileName, const int opacity) | |||
{ | { | |||
Imlib_Image image = imlib_load_image(fileName); | Imlib_Image image = imlib_load_image(fileName); | |||
if (!image) { | if (!image) { | |||
errx(EXIT_FAILURE, "option --select: Failed to load image:%s", | errx(EXIT_FAILURE, "option --select: Failed to load image:%s", | |||
fileName); | fileName); | |||
} | } | |||
imlib_context_set_image(image); | imlib_context_set_image(image); | |||
skipping to change at line 444 | skipping to change at line 456 | |||
changeImageOpacity(image, opacity); | changeImageOpacity(image, opacity); | |||
return image; | return image; | |||
} | } | |||
Imlib_Image scrotSelectionSelectMode(void) | Imlib_Image scrotSelectionSelectMode(void) | |||
{ | { | |||
struct SelectionRect rect0, rect1; | struct SelectionRect rect0, rect1; | |||
unsigned int const oldMode = opt.selection.mode; | const unsigned int oldMode = opt.selection.mode; | |||
opt.selection.mode = SELECTION_MODE_CAPTURE; | opt.selection.mode = SELECTION_MODE_CAPTURE; | |||
if (!scrotSelectionGetUserSel(&rect0)) | if (!scrotSelectionGetUserSel(&rect0)) | |||
return NULL; | return NULL; | |||
opt.selection.mode = oldMode; | opt.selection.mode = oldMode; | |||
if (opt.selection.mode & SELECTION_MODE_NOT_CAPTURE) | if (opt.selection.mode & SELECTION_MODE_NOT_CAPTURE) | |||
if (!scrotSelectionGetUserSel(&rect1)) | if (!scrotSelectionGetUserSel(&rect1)) | |||
skipping to change at line 471 | skipping to change at line 483 | |||
if (opt.pointer) | if (opt.pointer) | |||
scrotGrabMousePointer(capture, rect0.x, rect0.y); | scrotGrabMousePointer(capture, rect0.x, rect0.y); | |||
if (opt.selection.mode == SELECTION_MODE_CAPTURE) | if (opt.selection.mode == SELECTION_MODE_CAPTURE) | |||
return capture; | return capture; | |||
XColor color; | XColor color; | |||
scrotSelectionGetLineColor(&color); | scrotSelectionGetLineColor(&color); | |||
int const x = rect1.x - rect0.x; | const int x = rect1.x - rect0.x; | |||
int const y = rect1.y - rect0.y; | const int y = rect1.y - rect0.y; | |||
int const opacity = optionsParseRequireRange(opt.lineOpacity, | const int opacity = opt.lineOpacity; | |||
SELECTION_OPACITY_MIN, SELECTION_OPACITY_MAX); | ||||
imlib_context_set_image(capture); | imlib_context_set_image(capture); | |||
switch(opt.selection.mode) { | switch(opt.selection.mode) { | |||
case SELECTION_MODE_HOLE: | case SELECTION_MODE_HOLE: | |||
if (opacity > 0) { | if (opacity > 0) { | |||
Imlib_Image hole = imlib_clone_image(); | Imlib_Image hole = imlib_clone_image(); | |||
imlib_context_set_color(color.red, color.green, color.blue, opacity) ; | imlib_context_set_color(color.red, color.green, color.blue, opacity) ; | |||
imlib_image_fill_rectangle(0, 0, rect0.w, rect0.h); | imlib_image_fill_rectangle(0, 0, rect0.w, rect0.h); | |||
imlib_blend_image_onto_image(hole, 0, x, y, rect1.w, rect1.h, x, y, rect1.w, rect1.h); | imlib_blend_image_onto_image(hole, 0, x, y, rect1.w, rect1.h, x, y, rect1.w, rect1.h); | |||
imlib_context_set_image(hole); | imlib_context_set_image(hole); | |||
imlib_free_image_and_decache(); | imlib_free_image_and_decache(); | |||
} | } | |||
break; | break; | |||
case SELECTION_MODE_HIDE: | case SELECTION_MODE_HIDE: | |||
{ | { | |||
char* const fileName = opt.selection.paramStr; | char *const fileName = opt.selection.paramStr; | |||
if (fileName) { | if (fileName) { | |||
if (opacity > 0) { | if (opacity > 0) { | |||
Imlib_Image hide = loadImage(fileName, opacity); | Imlib_Image hide = loadImage(fileName, opacity); | |||
imlib_context_set_image(hide); | imlib_context_set_image(hide); | |||
int const w = imlib_image_get_width(); | int const w = imlib_image_get_width(); | |||
int const h = imlib_image_get_height(); | int const h = imlib_image_get_height(); | |||
imlib_context_set_image(capture); | imlib_context_set_image(capture); | |||
imlib_blend_image_onto_image(hide, 0, 0, 0, w, h, x, y, rect1.w, rect1.h); | imlib_blend_image_onto_image(hide, 0, 0, 0, w, h, x, y, rect1.w, rect1.h); | |||
imlib_context_set_image(hide); | imlib_context_set_image(hide); | |||
skipping to change at line 513 | skipping to change at line 524 | |||
} | } | |||
free(fileName); | free(fileName); | |||
} else { | } else { | |||
imlib_context_set_color(color.red, color.green, color.blue, opacity) ; | imlib_context_set_color(color.red, color.green, color.blue, opacity) ; | |||
imlib_image_fill_rectangle(x, y, rect1.w, rect1.h); | imlib_image_fill_rectangle(x, y, rect1.w, rect1.h); | |||
} | } | |||
break; | break; | |||
} | } | |||
case SELECTION_MODE_BLUR: | case SELECTION_MODE_BLUR: | |||
{ | { | |||
int const amountBlur = opt.selection.paramNum; | const int amountBlur = opt.selection.paramNum; | |||
Imlib_Image blur = imlib_clone_image(); | Imlib_Image blur = imlib_clone_image(); | |||
imlib_context_set_image(blur); | imlib_context_set_image(blur); | |||
imlib_image_blur(amountBlur); | imlib_image_blur(amountBlur); | |||
imlib_context_set_image(capture); | imlib_context_set_image(capture); | |||
imlib_blend_image_onto_image(blur, 0, x, y, rect1.w, rect1.h, x, y, rect 1.w, rect1.h); | imlib_blend_image_onto_image(blur, 0, x, y, rect1.w, rect1.h, x, y, rect 1.w, rect1.h); | |||
imlib_context_set_image(blur); | imlib_context_set_image(blur); | |||
imlib_free_image_and_decache(); | imlib_free_image_and_decache(); | |||
break; | break; | |||
} | } | |||
default: | default: | |||
End of changes. 34 change blocks. | ||||
50 lines changed or deleted | 61 lines changed or added |