Skip to content

Commit

Permalink
Merge pull request #267 from N-R-K/selection_cleanup
Browse files Browse the repository at this point in the history
scrotSelectionGetUserSel() cleanup
  • Loading branch information
N-R-K authored Apr 9, 2023
2 parents a961b88 + aa7e463 commit 75664ef
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 83 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ AC_SUBST([CPPFLAGS], ["$X11_CFLAGS $XCOMPOSITE_CFLAGS $XEXT_CFLAGS \
AC_CHECK_HEADERS([stdint.h sys/time.h unistd.h])

# Required: Checks for library functions.
AC_CHECK_FUNCS([getopt_long getsubopt gethostname select strdup strerror strndup strtol],,
AC_CHECK_FUNCS([getopt_long getsubopt gethostname strdup strerror strndup strtol],,
AC_MSG_ERROR([required functions are not present.]))

AC_CONFIG_FILES([Makefile src/Makefile])
Expand Down
141 changes: 59 additions & 82 deletions src/scrot_selection.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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>
Expand Down Expand Up @@ -239,20 +237,14 @@ void scrotSelectionSetDefaultColorLine(void)

bool scrotSelectionGetUserSel(struct SelectionRect *selectionRect)
{
static int xfd = 0;
static int fdSize = 0;
XEvent ev;
fd_set fdSet;
int count = 0, done = 0;
enum { WAIT, DONE, ABORT } done = WAIT;
int rx = 0, ry = 0, rw = 0, rh = 0, isButtonPressed = 0;
Window target = None;
Status ret;

scrotSelectionCreate();

xfd = ConnectionNumber(disp);
fdSize = xfd + 1;

ret = XGrabKeyboard(disp, root, False, GrabModeAsync, GrabModeAsync, CurrentTime);
if (ret == AlreadyGrabbed) {
int attempts = 20;
Expand All @@ -267,89 +259,74 @@ bool scrotSelectionGetUserSel(struct SelectionRect *selectionRect)
errx(EXIT_FAILURE, "failed to grab keyboard");
}

while (1) {
/* Handle events here */
while (!done && XPending(disp)) {
XNextEvent(disp, &ev);
switch (ev.type) {
case MotionNotify:
if (isButtonPressed)
scrotSelectionMotionDraw(rx, ry, ev.xbutton.x, ev.xbutton.y);
break;
case ButtonPress:
isButtonPressed = 1;
rx = ev.xbutton.x;
ry = ev.xbutton.y;
target = scrotGetWindow(disp, ev.xbutton.subwindow, ev.xbutton.x, ev.xbutton.y);
if (target == None)
target = root;
break;
case ButtonRelease:
done = 1;
while (done == WAIT) {
XNextEvent(disp, &ev);
switch (ev.type) {
case MotionNotify:
if (isButtonPressed)
scrotSelectionMotionDraw(rx, ry, ev.xbutton.x, ev.xbutton.y);
break;
case ButtonPress:
isButtonPressed = 1;
rx = ev.xbutton.x;
ry = ev.xbutton.y;
target = scrotGetWindow(disp, ev.xbutton.subwindow, ev.xbutton.x, ev.xbutton.y);
if (target == None)
target = root;
break;
case ButtonRelease:
done = DONE;
break;
case KeyPress:
{
KeySym *keysym = NULL;
int keycode; /*dummy*/

keysym = XGetKeyboardMapping(disp, ev.xkey.keycode, 1, &keycode);

if (!keysym)
break;
case KeyPress:
{
KeySym *keysym = NULL;
int keycode; /*dummy*/

keysym = XGetKeyboardMapping(disp, ev.xkey.keycode, 1, &keycode);

if (!keysym)
break;

if (!isButtonPressed) {
key_abort_shot:
if (!opt.ignoreKeyboard || *keysym == XK_Escape) {
warnx("Key was pressed, aborting shot");
done = 2;
}
XFree(keysym);
break;
}

switch (*keysym) {
case XK_Right:
if (++rx > scr->width)
rx = scr->width;
break;
case XK_Left:
if (--rx < 0)
rx = 0;
break;
case XK_Down:
if (++ry > scr->height)
ry = scr->height;
break;
case XK_Up:
if (--ry < 0)
ry = 0;
break;
default:
goto key_abort_shot;
if (!isButtonPressed) {
key_abort_shot:
if (!opt.ignoreKeyboard || *keysym == XK_Escape) {
warnx("Key was pressed, aborting shot");
done = ABORT;
}
XFree(keysym);
scrotSelectionMotionDraw(rx, ry, ev.xbutton.x, ev.xbutton.y);
break;
}
case KeyRelease:
/* ignore */

switch (*keysym) {
case XK_Right:
if (++rx > scr->width)
rx = scr->width;
break;
default:
case XK_Left:
if (--rx < 0)
rx = 0;
break;
case XK_Down:
if (++ry > scr->height)
ry = scr->height;
break;
case XK_Up:
if (--ry < 0)
ry = 0;
break;
default:
goto key_abort_shot;
}
XFree(keysym);
scrotSelectionMotionDraw(rx, ry, ev.xbutton.x, ev.xbutton.y);
break;
}
if (done)
case DestroyNotify:
errx(EXIT_FAILURE, "received DestroyNotify event");
break;
default:
/* ignore */
break;

/* now block some */
FD_ZERO(&fdSet);
FD_SET(xfd, &fdSet);
errno = 0;
count = select(fdSize, &fdSet, NULL, NULL, NULL);
if ((count < 0)
&& ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF))) {
scrotSelectionDestroy();
errx(EXIT_FAILURE, "Connection to X display lost");
}
}
scrotSelectionDraw();
Expand All @@ -360,7 +337,7 @@ bool scrotSelectionGetUserSel(struct SelectionRect *selectionRect)

scrotSelectionDestroy();

if (done == 2)
if (done == ABORT)
return false;

if (isAreaSelect) {
Expand Down

0 comments on commit 75664ef

Please sign in to comment.