patch 8.1.1645: cannot use a popup window for a balloon

Problem:    Cannot use a popup window for a balloon.
Solution:   Add popup_beval().  Add the "mousemoved" property.  Add the
            screenpos() function.
diff --git a/src/testdir/dumps/Test_popupwin_beval_1.dump b/src/testdir/dumps/Test_popupwin_beval_1.dump
new file mode 100644
index 0000000..410ac5c
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_beval_1.dump
@@ -0,0 +1,10 @@
+|1+0&#ffffff0| @73
+>2| @73
+|3| @73
+|4| @12|t+0#0000001#ffd7ff255|e|x|t| +0#0000000#ffffff0@56
+|h|e|r|e| |i|s| |s|o|m|e| |t|e|x|t| |t|o| |h|o|v|e|r| |o|v|e|r| @43
+|6| @73
+|7| @73
+|8| @73
+|9| @73
+|:|c|a|l@1| |H|o|v|e|r|(|)| @43|2|,|1| @10|T|o|p| 
diff --git a/src/testdir/dumps/Test_popupwin_beval_2.dump b/src/testdir/dumps/Test_popupwin_beval_2.dump
new file mode 100644
index 0000000..34b222d
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_beval_2.dump
@@ -0,0 +1,10 @@
+|1+0&#ffffff0| @73
+>2| @73
+|3| @73
+|4| @12|t+0#0000001#ffd7ff255|e|x|t| +0#0000000#ffffff0@56
+|h|e|r|e| |i|s| |s|o|m|e| |t|e|x|t| |t|o| |h|o|v|e|r| |o|v|e|r| @43
+|6| @73
+|7| @73
+|8| @73
+|9| @73
+|:|c|a|l@1| |M|o|v|e|O|n|t|o|P|o|p|u|p|(|)| @35|2|,|1| @10|T|o|p| 
diff --git a/src/testdir/dumps/Test_popupwin_beval_3.dump b/src/testdir/dumps/Test_popupwin_beval_3.dump
new file mode 100644
index 0000000..2e8e419
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_beval_3.dump
@@ -0,0 +1,10 @@
+|1+0&#ffffff0| @73
+>2| @73
+|3| @73
+|4| @73
+|h|e|r|e| |i|s| |s|o|m|e| |t|e|x|t| |t|o| |h|o|v|e|r| |o|v|e|r| @43
+|6| @73
+|7| @73
+|8| @73
+|9| @73
+|:|c|a|l@1| |M|o|v|e|A|w|a|y|(|)| @40|2|,|1| @10|T|o|p| 
diff --git a/src/testdir/test_cursor_func.vim b/src/testdir/test_cursor_func.vim
index 1231957..0f638b3 100644
--- a/src/testdir/test_cursor_func.vim
+++ b/src/testdir/test_cursor_func.vim
@@ -72,3 +72,31 @@
   call assert_equal(6, winsaveview().curswant)
   quit!
 endfunc
+
+func Test_screenpos()
+  rightbelow new
+  rightbelow 20vsplit
+  call setline(1, ["\tsome text", "long wrapping line here", "next line"])
+  redraw
+  let winid = win_getid()
+  let [winrow, wincol] = win_screenpos(winid)
+  call assert_equal({'row': winrow,
+	\ 'col': wincol + 0,
+	\ 'curscol': wincol + 7,
+	\ 'endcol': wincol + 7}, screenpos(winid, 1, 1))
+  call assert_equal({'row': winrow,
+	\ 'col': wincol + 13,
+	\ 'curscol': wincol + 13,
+	\ 'endcol': wincol + 13}, screenpos(winid, 1, 7))
+  call assert_equal({'row': winrow + 2,
+	\ 'col': wincol + 1,
+	\ 'curscol': wincol + 1,
+	\ 'endcol': wincol + 1}, screenpos(winid, 2, 22))
+  setlocal number
+  call assert_equal({'row': winrow + 3,
+	\ 'col': wincol + 9,
+	\ 'curscol': wincol + 9,
+	\ 'endcol': wincol + 9}, screenpos(winid, 2, 22))
+  close
+  bwipe!
+endfunc
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index 00cc287..f952a42 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -1005,6 +1005,53 @@
   bwipe!
 endfunc
 
+func Test_popup_beval()
+  if !CanRunVimInTerminal()
+    throw 'Skipped: cannot make screendumps'
+  endif
+
+  let lines =<< trim END
+	call setline(1, range(1, 20))
+	call setline(5, 'here is some text to hover over')
+	set balloonevalterm
+	set balloonexpr=BalloonExpr()
+	set balloondelay=100
+	func BalloonExpr()
+	  let s:winid = popup_beval([v:beval_text], {})
+	  return ''
+	endfunc
+	func Hover()
+	  call test_setmouse(5, 15)
+	  call feedkeys("\<MouseMove>\<Ignore>", "xt")
+	  sleep 100m
+	endfunc
+	func MoveOntoPopup()
+	  call test_setmouse(4, 17)
+	  call feedkeys("\<F4>\<MouseMove>\<Ignore>", "xt")
+	endfunc
+	func MoveAway()
+	  call test_setmouse(5, 13)
+	  call feedkeys("\<F5>\<MouseMove>\<Ignore>", "xt")
+	endfunc
+  END
+  call writefile(lines, 'XtestPopupBeval')
+  let buf = RunVimInTerminal('-S XtestPopupBeval', {'rows': 10})
+  call term_wait(buf, 100)
+  call term_sendkeys(buf, 'j')
+  call term_sendkeys(buf, ":call Hover()\<CR>")
+  call VerifyScreenDump(buf, 'Test_popupwin_beval_1', {})
+
+  call term_sendkeys(buf, ":call MoveOntoPopup()\<CR>")
+  call VerifyScreenDump(buf, 'Test_popupwin_beval_2', {})
+
+  call term_sendkeys(buf, ":call MoveAway()\<CR>")
+  call VerifyScreenDump(buf, 'Test_popupwin_beval_3', {})
+
+  " clean up
+  call StopVimInTerminal(buf)
+  call delete('XtestPopupBeval')
+endfunc
+
 func Test_popup_filter()
   new
   call setline(1, 'some text')
@@ -1413,7 +1460,7 @@
   let winid = popup_atcursor('text', {'moved': 'any'})
   redraw
   call assert_equal(1, popup_getpos(winid).visible)
-  call assert_equal([4, 4], popup_getoptions(winid).moved)
+  call assert_equal([1, 4, 4], popup_getoptions(winid).moved)
   " trigger the check for last_cursormoved by going into insert mode
   call feedkeys("li\<Esc>", 'xt')
   call assert_equal({}, popup_getpos(winid))
@@ -1423,7 +1470,7 @@
   let winid = popup_atcursor('text', {'moved': 'word'})
   redraw
   call assert_equal(1, popup_getpos(winid).visible)
-  call assert_equal([4, 7], popup_getoptions(winid).moved)
+  call assert_equal([1, 4, 7], popup_getoptions(winid).moved)
   call feedkeys("hi\<Esc>", 'xt')
   call assert_equal({}, popup_getpos(winid))
   call popup_clear()
@@ -1432,7 +1479,7 @@
   let winid = popup_atcursor('text', {'moved': 'word'})
   redraw
   call assert_equal(1, popup_getpos(winid).visible)
-  call assert_equal([4, 7], popup_getoptions(winid).moved)
+  call assert_equal([1, 4, 7], popup_getoptions(winid).moved)
   call feedkeys("li\<Esc>", 'xt')
   call assert_equal(1, popup_getpos(winid).visible)
   call feedkeys("ei\<Esc>", 'xt')
@@ -1446,7 +1493,7 @@
   let winid = popup_atcursor('text', {})
   redraw
   call assert_equal(1, popup_getpos(winid).visible)
-  call assert_equal([2, 15], popup_getoptions(winid).moved)
+  call assert_equal([2, 2, 15], popup_getoptions(winid).moved)
   call feedkeys("eli\<Esc>", 'xt')
   call assert_equal(1, popup_getpos(winid).visible)
   call feedkeys("wi\<Esc>", 'xt')