Patch 8.0.1542
Problem: Terminal screen dump does not include cursor position.
Solution: Mark the cursor position in the cump.
Files: src/terminal.c,
src/testdir/dumps/Test_popup_position_01.dump,
src/testdir/dumps/Test_popup_position_02.dump,
src/testdir/dumps/Test_popup_position_03.dump,
src/testdir/dumps/Test_popup_position_04.dump,
src/testdir/dumps/Test_syntax_c_01.dump
*** ../vim-8.0.1541/src/terminal.c 2018-02-24 19:53:09.142750492 +0100
--- src/terminal.c 2018-02-25 21:28:19.925837681 +0100
***************
*** 2906,2911 ****
--- 2906,2913 ----
VTermPos pos;
VTermScreen *screen;
VTermScreenCell prev_cell;
+ VTermState *state;
+ VTermPos cursor_pos;
if (check_restricted() || check_secure())
return;
***************
*** 2948,2953 ****
--- 2950,2958 ----
vim_memset(&prev_cell, 0, sizeof(prev_cell));
screen = vterm_obtain_screen(term->tl_vterm);
+ state = vterm_obtain_state(term->tl_vterm);
+ vterm_state_get_cursorpos(state, &cursor_pos);
+
for (pos.row = 0; (max_height == 0 || pos.row < max_height)
&& pos.row < term->tl_rows; ++pos.row)
{
***************
*** 2960,2965 ****
--- 2965,2972 ----
int same_attr;
int same_chars = TRUE;
int i;
+ int is_cursor_pos = (pos.col == cursor_pos.col
+ && pos.row == cursor_pos.row);
if (vterm_screen_get_cell(screen, pos, &cell) == 0)
vim_memset(&cell, 0, sizeof(cell));
***************
*** 2975,2981 ****
== vtermAttr2hl(prev_cell.attrs)
&& same_color(&cell.fg, &prev_cell.fg)
&& same_color(&cell.bg, &prev_cell.bg);
! if (same_chars && cell.width == prev_cell.width && same_attr)
{
++repeat;
}
--- 2982,2989 ----
== vtermAttr2hl(prev_cell.attrs)
&& same_color(&cell.fg, &prev_cell.fg)
&& same_color(&cell.bg, &prev_cell.bg);
! if (same_chars && cell.width == prev_cell.width && same_attr
! && !is_cursor_pos)
{
++repeat;
}
***************
*** 2986,2992 ****
fprintf(fd, "@%d", repeat);
repeat = 0;
}
! fputs("|", fd);
if (cell.chars[0] == NUL)
fputs(" ", fd);
--- 2994,3000 ----
fprintf(fd, "@%d", repeat);
repeat = 0;
}
! fputs(is_cursor_pos ? ">" : "|", fd);
if (cell.chars[0] == NUL)
fputs(" ", fd);
***************
*** 3075,3081 ****
* Return the cell width of the longest line.
*/
static int
! read_dump_file(FILE *fd)
{
int c;
garray_T ga_text;
--- 3083,3089 ----
* Return the cell width of the longest line.
*/
static int
! read_dump_file(FILE *fd, VTermPos *cursor_pos)
{
int c;
garray_T ga_text;
***************
*** 3085,3094 ****
--- 3093,3105 ----
cellattr_T cell;
term_T *term = curbuf->b_term;
int max_cells = 0;
+ int start_row = term->tl_scrollback.ga_len;
ga_init2(&ga_text, 1, 90);
ga_init2(&ga_cell, sizeof(cellattr_T), 90);
vim_memset(&cell, 0, sizeof(cell));
+ cursor_pos->row = -1;
+ cursor_pos->col = -1;
c = fgetc(fd);
for (;;)
***************
*** 3123,3132 ****
c = fgetc(fd);
}
! else if (c == '|')
{
int prev_len = ga_text.ga_len;
/* normal character(s) followed by "+", "*", "|", "@" or NL */
c = fgetc(fd);
if (c != EOF)
--- 3134,3151 ----
c = fgetc(fd);
}
! else if (c == '|' || c == '>')
{
int prev_len = ga_text.ga_len;
+ if (c == '>')
+ {
+ if (cursor_pos->row != -1)
+ dump_is_corrupt(&ga_text); /* duplicate cursor */
+ cursor_pos->row = term->tl_scrollback.ga_len - start_row;
+ cursor_pos->col = ga_cell.ga_len;
+ }
+
/* normal character(s) followed by "+", "*", "|", "@" or NL */
c = fgetc(fd);
if (c != EOF)
***************
*** 3134,3140 ****
for (;;)
{
c = fgetc(fd);
! if (c == '+' || c == '*' || c == '|' || c == '@'
|| c == EOF || c == '\n')
break;
ga_append(&ga_text, c);
--- 3153,3159 ----
for (;;)
{
c = fgetc(fd);
! if (c == '+' || c == '*' || c == '|' || c == '>' || c == '@'
|| c == EOF || c == '\n')
break;
ga_append(&ga_text, c);
***************
*** 3146,3152 ****
prev_char = vim_strnsave(((char_u *)ga_text.ga_data) + prev_len,
ga_text.ga_len - prev_len);
! if (c == '@' || c == '|' || c == '\n')
{
/* use all attributes from previous cell */
}
--- 3165,3171 ----
prev_char = vim_strnsave(((char_u *)ga_text.ga_data) + prev_len,
ga_text.ga_len - prev_len);
! if (c == '@' || c == '|' || c == '>' || c == '\n')
{
/* use all attributes from previous cell */
}
***************
*** 3336,3346 ****
term_T *term = buf->b_term;
int width;
int width2;
rettv->vval.v_number = buf->b_fnum;
/* read the files, fill the buffer with the diff */
! width = read_dump_file(fd1);
/* Delete the empty line that was in the empty buffer. */
ml_delete(1, FALSE);
--- 3355,3374 ----
term_T *term = buf->b_term;
int width;
int width2;
+ VTermPos cursor_pos1;
+ VTermPos cursor_pos2;
rettv->vval.v_number = buf->b_fnum;
/* read the files, fill the buffer with the diff */
! width = read_dump_file(fd1, &cursor_pos1);
!
! /* position the cursor */
! if (cursor_pos1.row >= 0)
! {
! curwin->w_cursor.lnum = cursor_pos1.row + 1;
! coladvance(cursor_pos1.col);
! }
/* Delete the empty line that was in the empty buffer. */
ml_delete(1, FALSE);
***************
*** 3363,3369 ****
ml_append(curbuf->b_ml.ml_line_count, textline, 0, FALSE);
bot_lnum = curbuf->b_ml.ml_line_count;
! width2 = read_dump_file(fd2);
if (width2 > width)
{
vim_free(textline);
--- 3391,3397 ----
ml_append(curbuf->b_ml.ml_line_count, textline, 0, FALSE);
bot_lnum = curbuf->b_ml.ml_line_count;
! width2 = read_dump_file(fd2, &cursor_pos2);
if (width2 > width)
{
vim_free(textline);
***************
*** 3410,3416 ****
--- 3438,3457 ----
textline[col] = ' ';
if (len1 != len2 || STRNCMP(p1, p2, len1) != 0)
+ /* text differs */
textline[col] = 'X';
+ else if (lnum == cursor_pos1.row + 1
+ && col == cursor_pos1.col
+ && (cursor_pos1.row != cursor_pos2.row
+ || cursor_pos1.col != cursor_pos2.col))
+ /* cursor in first but not in second */
+ textline[col] = '>';
+ else if (lnum == cursor_pos2.row + 1
+ && col == cursor_pos2.col
+ && (cursor_pos1.row != cursor_pos2.row
+ || cursor_pos1.col != cursor_pos2.col))
+ /* cursor in second but not in first */
+ textline[col] = '<';
else if (cellattr1 != NULL && cellattr2 != NULL)
{
if ((cellattr1 + col)->width
*** ../vim-8.0.1541/src/testdir/dumps/Test_popup_position_01.dump
2018-02-24 19:53:09.142750492 +0100
--- src/testdir/dumps/Test_popup_position_01.dump 2018-02-25
21:28:32.069758455 +0100
***************
*** 1,7 ****
|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @5
|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| @5
@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5||+1&&|
+0&&@11|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
! |6|7|8|9|_|a| @30||+1&&|6+0&&|7|8|9|_|a| @30
|~+0#4040ff13&| @9|
+0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
| +0#4040ff13#ffffff0@30
|~| @9|
+0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b|
| +0#4040ff13#ffffff0@30
|~| @35||+1#0000000&|~+0#4040ff13&| @35
--- 1,7 ----
|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @5
|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| @5
@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5||+1&&|
+0&&@11|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
! |6|7|8|9|_|a> @30||+1&&|6+0&&|7|8|9|_|a| @30
|~+0#4040ff13&| @9|
+0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
| +0#4040ff13#ffffff0@30
|~| @9|
+0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b|
| +0#4040ff13#ffffff0@30
|~| @35||+1#0000000&|~+0#4040ff13&| @35
*** ../vim-8.0.1541/src/testdir/dumps/Test_popup_position_02.dump
2018-02-24 19:53:09.142750492 +0100
--- src/testdir/dumps/Test_popup_position_02.dump 2018-02-25
21:30:15.641085809 +0100
***************
*** 1,7 ****
|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @5
|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| @5
@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5||+1&&|
+0&&@11|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
! |6|7|8|9|_|a| @30||+1&&|6+0&&|7|8|9|_|a| @30
|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @9|
+0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @9|
+0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @35
--- 1,7 ----
|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @5
|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| @5
@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5||+1&&|
+0&&@11|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
! |6|7|8|9|_|a| @30||+1&&|6+0&&|7|8|9|_|a> @30
|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @9|
+0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @9|
+0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @35
*** ../vim-8.0.1541/src/testdir/dumps/Test_popup_position_03.dump
2018-02-24 19:53:09.146750467 +0100
--- src/testdir/dumps/Test_popup_position_03.dump 2018-02-25
21:34:33.199451766 +0100
***************
*** 1,7 ****
|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @5
|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| @5
@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5||+1&&|
+0&&@11|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
! |6|7|8|9|_|a| @30||+1&&|6+0&&|7|8|9|_|a| @30
|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @4|
+0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @4|
+0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @35
--- 1,7 ----
|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @5
|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b|
@5||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| @5
@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5||+1&&|
+0&&@11|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
! |6|7|8|9|_|a| @30||+1&&|6+0&&|7|8|9|_|a> @30
|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @4|
+0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @4|
+0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @35
*** ../vim-8.0.1541/src/testdir/dumps/Test_popup_position_04.dump
2018-02-24 21:25:25.202496627 +0100
--- src/testdir/dumps/Test_popup_position_04.dump 2018-02-25
21:35:08.899223940 +0100
***************
*** 3,9 ****
|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7
|8|9|_|b| @32||+1&&|8+0&&|9|_|b| @32
@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5||+1&&|
+0&&@11|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
! |6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
@20||+1&&|6+0&&|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @20
|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @9|
+0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @9|
+0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @35
--- 3,9 ----
|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7||+1&&|1+0&&|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7
|8|9|_|b| @32||+1&&|8+0&&|9|_|b| @32
@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5||+1&&|
+0&&@11|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
! |6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a|
@20||+1&&|6+0&&|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a> @20
|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @9|
+0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @9|
+0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5
|~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13&| @35
*** ../vim-8.0.1541/src/testdir/dumps/Test_syntax_c_01.dump 2018-02-24
16:51:26.783025245 +0100
--- src/testdir/dumps/Test_syntax_c_01.dump 2018-02-25 21:33:46.899746820
+0100
***************
*** 1,4 ****
! |/+0#0000e05#ffffff0|*| |c|o|m@1|e|n|t| |l|i|n|e| |a|t| |t|h|e| |t|o|p| |*|/|
+0#0000000&@45
| @1|i+0#00e0003&|n|t| +0#0000000&@69
|m|a|i|n|(|i+0#00e0003&|n|t| +0#0000000&|a|r|g|c|,| |c+0#00e0003&|h|a|r|
+0#0000000&|*@1|a|r|g|v|)|/+0#0000e05&@1| |a|n|o|t|h|e|r| |c|o|m@1|e|n|t|
+0#0000000&@29
|{| @73
--- 1,4 ----
! >/+0#0000e05#ffffff0|*| |c|o|m@1|e|n|t| |l|i|n|e| |a|t| |t|h|e| |t|o|p| |*|/|
+0#0000000&@45
| @1|i+0#00e0003&|n|t| +0#0000000&@69
|m|a|i|n|(|i+0#00e0003&|n|t| +0#0000000&|a|r|g|c|,| |c+0#00e0003&|h|a|r|
+0#0000000&|*@1|a|r|g|v|)|/+0#0000e05&@1| |a|n|o|t|h|e|r| |c|o|m@1|e|n|t|
+0#0000000&@29
|{| @73
*** ../vim-8.0.1541/src/version.c 2018-02-24 21:36:30.538119108 +0100
--- src/version.c 2018-02-25 21:37:44.998224923 +0100
***************
*** 780,781 ****
--- 780,783 ----
{ /* Add new patch number below this line */
+ /**/
+ 1542,
/**/
--
A parent can be arrested if his child cannot hold back a burp during a church
service.
[real standing law in Nebraska, United States of America]
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.