168353368SRudolf Cornelissen /*
268353368SRudolf Cornelissen Copyright 1999, Be Incorporated. All Rights Reserved.
368353368SRudolf Cornelissen This file may be used under the terms of the Be Sample Code License.
468353368SRudolf Cornelissen
568353368SRudolf Cornelissen Other authors:
668353368SRudolf Cornelissen Mark Watson,
768353368SRudolf Cornelissen Rudolf Cornelissen 4/2003-5/2004
868353368SRudolf Cornelissen */
968353368SRudolf Cornelissen
1068353368SRudolf Cornelissen #define MODULE_BIT 0x20000000
1168353368SRudolf Cornelissen
1268353368SRudolf Cornelissen #include "acc_std.h"
1368353368SRudolf Cornelissen
SET_CURSOR_SHAPE(uint16 width,uint16 height,uint16 hot_x,uint16 hot_y,uint8 * andMask,uint8 * xorMask)1468353368SRudolf Cornelissen status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask)
1568353368SRudolf Cornelissen {
1668353368SRudolf Cornelissen LOG(4,("SET_CURSOR_SHAPE: width %d, height %d, hot_x %d, hot_y %d\n",
1768353368SRudolf Cornelissen width, height, hot_x, hot_y));
1868353368SRudolf Cornelissen
1968353368SRudolf Cornelissen if ((width != 16) || (height != 16))
2068353368SRudolf Cornelissen {
2168353368SRudolf Cornelissen return B_ERROR;
2268353368SRudolf Cornelissen }
2368353368SRudolf Cornelissen else if ((hot_x >= width) || (hot_y >= height))
2468353368SRudolf Cornelissen {
2568353368SRudolf Cornelissen return B_ERROR;
2668353368SRudolf Cornelissen }
2768353368SRudolf Cornelissen else
2868353368SRudolf Cornelissen {
2968353368SRudolf Cornelissen head1_cursor_define(andMask,xorMask);
3068353368SRudolf Cornelissen if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_OFF)
3168353368SRudolf Cornelissen head2_cursor_define(andMask,xorMask);
3268353368SRudolf Cornelissen
3368353368SRudolf Cornelissen /* Update cursor variables appropriately. */
3468353368SRudolf Cornelissen si->cursor.width = width;
3568353368SRudolf Cornelissen si->cursor.height = height;
3668353368SRudolf Cornelissen si->cursor.hot_x = hot_x;
3768353368SRudolf Cornelissen si->cursor.hot_y = hot_y;
3868353368SRudolf Cornelissen }
3968353368SRudolf Cornelissen
4068353368SRudolf Cornelissen return B_OK;
4168353368SRudolf Cornelissen }
4268353368SRudolf Cornelissen
4368353368SRudolf Cornelissen /* Move the cursor to the specified position on the desktop, taking account of virtual/dual issues */
MOVE_CURSOR(uint16 x,uint16 y)4468353368SRudolf Cornelissen void MOVE_CURSOR(uint16 x, uint16 y)
4568353368SRudolf Cornelissen {
4668353368SRudolf Cornelissen uint16 hds = si->dm.h_display_start; /* the current horizontal starting pixel */
4768353368SRudolf Cornelissen uint16 vds = si->dm.v_display_start; /* the current vertical starting line */
4868353368SRudolf Cornelissen uint16 h_adjust;
4968353368SRudolf Cornelissen
5068353368SRudolf Cornelissen /* clamp cursor to display */
5168353368SRudolf Cornelissen if (x >= si->dm.virtual_width) x = si->dm.virtual_width - 1;
5268353368SRudolf Cornelissen if (y >= si->dm.virtual_height) y = si->dm.virtual_height - 1;
5368353368SRudolf Cornelissen
5468353368SRudolf Cornelissen /* store, for our info */
5568353368SRudolf Cornelissen si->cursor.x = x;
5668353368SRudolf Cornelissen si->cursor.y = y;
5768353368SRudolf Cornelissen
5868353368SRudolf Cornelissen /* setting up minimum amount to scroll not needed:
5968353368SRudolf Cornelissen * Nvidia cards can always do pixelprecise panning on both heads */
6068353368SRudolf Cornelissen h_adjust = 0x00;
6168353368SRudolf Cornelissen
6268353368SRudolf Cornelissen /* adjust h/v_display_start to move cursor onto screen */
6368353368SRudolf Cornelissen switch (si->dm.flags & DUALHEAD_BITS)
6468353368SRudolf Cornelissen {
6568353368SRudolf Cornelissen case DUALHEAD_ON:
6668353368SRudolf Cornelissen case DUALHEAD_SWITCH:
6768353368SRudolf Cornelissen if (x >= ((si->dm.timing.h_display * 2) + hds))
6868353368SRudolf Cornelissen {
6968353368SRudolf Cornelissen hds = ((x - (si->dm.timing.h_display * 2)) + 1 + h_adjust) & ~h_adjust;
7068353368SRudolf Cornelissen /* make sure we stay within the display! */
7168353368SRudolf Cornelissen if ((hds + (si->dm.timing.h_display * 2)) > si->dm.virtual_width)
7268353368SRudolf Cornelissen hds -= (h_adjust + 1);
7368353368SRudolf Cornelissen }
7468353368SRudolf Cornelissen else if (x < hds)
7568353368SRudolf Cornelissen hds = x & ~h_adjust;
7668353368SRudolf Cornelissen break;
7768353368SRudolf Cornelissen default:
7868353368SRudolf Cornelissen if (x >= (si->dm.timing.h_display + hds))
7968353368SRudolf Cornelissen {
8068353368SRudolf Cornelissen hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust;
8168353368SRudolf Cornelissen /* make sure we stay within the display! */
8268353368SRudolf Cornelissen if ((hds + si->dm.timing.h_display) > si->dm.virtual_width)
8368353368SRudolf Cornelissen hds -= (h_adjust + 1);
8468353368SRudolf Cornelissen }
8568353368SRudolf Cornelissen else if (x < hds)
8668353368SRudolf Cornelissen hds = x & ~h_adjust;
8768353368SRudolf Cornelissen break;
8868353368SRudolf Cornelissen }
8968353368SRudolf Cornelissen
9068353368SRudolf Cornelissen if (y >= (si->dm.timing.v_display + vds))
9168353368SRudolf Cornelissen vds = y - si->dm.timing.v_display + 1;
9268353368SRudolf Cornelissen else if (y < vds)
9368353368SRudolf Cornelissen vds = y;
9468353368SRudolf Cornelissen
9568353368SRudolf Cornelissen /* reposition the desktop _and_ the overlay on the display if required */
9668353368SRudolf Cornelissen if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start))
9768353368SRudolf Cornelissen {
9868353368SRudolf Cornelissen MOVE_DISPLAY(hds,vds);
99*886dbf81SRudolf Cornelissen eng_bes_move_overlay();
10068353368SRudolf Cornelissen }
10168353368SRudolf Cornelissen
10268353368SRudolf Cornelissen /* put cursor in correct physical position, so stay onscreen (rel. to CRTC) */
10368353368SRudolf Cornelissen if (x > (hds + si->cursor.hot_x)) x -= (hds + si->cursor.hot_x);
10468353368SRudolf Cornelissen else x = 0;
10568353368SRudolf Cornelissen if (y > (vds + si->cursor.hot_y)) y -= (vds + si->cursor.hot_y);
10668353368SRudolf Cornelissen else y = 0;
10768353368SRudolf Cornelissen
10868353368SRudolf Cornelissen /* position the cursor on the display */
10968353368SRudolf Cornelissen switch (si->dm.flags & DUALHEAD_BITS)
11068353368SRudolf Cornelissen {
11168353368SRudolf Cornelissen case DUALHEAD_CLONE:
11268353368SRudolf Cornelissen head1_cursor_position(x,y);
11368353368SRudolf Cornelissen head2_cursor_position(x,y);
11468353368SRudolf Cornelissen break;
11568353368SRudolf Cornelissen case DUALHEAD_ON:
11668353368SRudolf Cornelissen case DUALHEAD_SWITCH:
11768353368SRudolf Cornelissen if (x < si->dm.timing.h_display)
11868353368SRudolf Cornelissen {
11968353368SRudolf Cornelissen if (si->cursor.dh_right)
12068353368SRudolf Cornelissen {
12168353368SRudolf Cornelissen LOG(4,("MOVE_CURSOR: now on left side\n"));
12268353368SRudolf Cornelissen head2_cursor_hide();
12368353368SRudolf Cornelissen head1_cursor_show();
12468353368SRudolf Cornelissen si->cursor.dh_right = false;
12568353368SRudolf Cornelissen }
12668353368SRudolf Cornelissen head1_cursor_position(x, y);
12768353368SRudolf Cornelissen }
12868353368SRudolf Cornelissen else
12968353368SRudolf Cornelissen {
13068353368SRudolf Cornelissen if (!si->cursor.dh_right)
13168353368SRudolf Cornelissen {
13268353368SRudolf Cornelissen LOG(4,("MOVE_CURSOR: now on right side\n"));
13368353368SRudolf Cornelissen head1_cursor_hide();
13468353368SRudolf Cornelissen head2_cursor_show();
13568353368SRudolf Cornelissen si->cursor.dh_right = true;
13668353368SRudolf Cornelissen }
13768353368SRudolf Cornelissen head2_cursor_position((x - si->dm.timing.h_display), y);
13868353368SRudolf Cornelissen }
13968353368SRudolf Cornelissen break;
14068353368SRudolf Cornelissen default: /* singlehead mode */
14168353368SRudolf Cornelissen head1_cursor_position(x,y);
14268353368SRudolf Cornelissen break;
14368353368SRudolf Cornelissen }
14468353368SRudolf Cornelissen }
14568353368SRudolf Cornelissen
SHOW_CURSOR(bool is_visible)14668353368SRudolf Cornelissen void SHOW_CURSOR(bool is_visible)
14768353368SRudolf Cornelissen {
14868353368SRudolf Cornelissen /* record for our info */
14968353368SRudolf Cornelissen si->cursor.is_visible = is_visible;
15068353368SRudolf Cornelissen
15168353368SRudolf Cornelissen switch (si->dm.flags & DUALHEAD_BITS)
15268353368SRudolf Cornelissen {
15368353368SRudolf Cornelissen case DUALHEAD_CLONE:
15468353368SRudolf Cornelissen if (is_visible)
15568353368SRudolf Cornelissen {
15668353368SRudolf Cornelissen head1_cursor_show();
15768353368SRudolf Cornelissen head2_cursor_show();
15868353368SRudolf Cornelissen }
15968353368SRudolf Cornelissen else
16068353368SRudolf Cornelissen {
16168353368SRudolf Cornelissen head1_cursor_hide();
16268353368SRudolf Cornelissen head2_cursor_hide();
16368353368SRudolf Cornelissen }
16468353368SRudolf Cornelissen break;
16568353368SRudolf Cornelissen case DUALHEAD_ON:
16668353368SRudolf Cornelissen case DUALHEAD_SWITCH:
16768353368SRudolf Cornelissen if (is_visible)
16868353368SRudolf Cornelissen {
16968353368SRudolf Cornelissen if (!si->cursor.dh_right)
17068353368SRudolf Cornelissen {
17168353368SRudolf Cornelissen head1_cursor_show();
17268353368SRudolf Cornelissen }
17368353368SRudolf Cornelissen else
17468353368SRudolf Cornelissen {
17568353368SRudolf Cornelissen head2_cursor_show();
17668353368SRudolf Cornelissen }
17768353368SRudolf Cornelissen }
17868353368SRudolf Cornelissen else
17968353368SRudolf Cornelissen {
18068353368SRudolf Cornelissen head1_cursor_hide();
18168353368SRudolf Cornelissen head2_cursor_hide();
18268353368SRudolf Cornelissen }
18368353368SRudolf Cornelissen break;
18468353368SRudolf Cornelissen default: /* singlehead mode */
18568353368SRudolf Cornelissen if (is_visible)
18668353368SRudolf Cornelissen {
18768353368SRudolf Cornelissen head1_cursor_show();
18868353368SRudolf Cornelissen }
18968353368SRudolf Cornelissen else
19068353368SRudolf Cornelissen {
19168353368SRudolf Cornelissen head1_cursor_hide();
19268353368SRudolf Cornelissen }
19368353368SRudolf Cornelissen break;
19468353368SRudolf Cornelissen }
19568353368SRudolf Cornelissen }
196