2 * Server-side cursors / icons
4 * Copyright 2007 Henri Verbeet
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define WIN32_NO_STATUS
34 unsigned short height
;
35 unsigned short and_width_bytes
;
36 unsigned short xor_width_bytes
;
39 /* bits contains both the AND and XOR bitmap data, in that order */
44 struct process
*process
;
45 unsigned int num_frames
;
47 cursor_frame_t
*frames
;
50 void destroy_cursor( cursor_t
*cursor
)
54 for (i
= 0; i
< cursor
->num_frames
; ++i
)
56 free( cursor
->frames
[i
].bits
);
59 free( cursor
->frames
);
63 /* destroy all cursors belonging to a given process */
64 void destroy_process_cursors( struct process
*process
)
66 user_handle_t handle
= 0;
69 while ((cursor
= next_user_handle( &handle
, USER_CURSOR
)))
71 if (cursor
->process
!= process
) continue;
73 destroy_cursor( cursor
);
74 free_user_handle( handle
);
79 DECL_HANDLER(create_cursor
)
81 cursor_t
*cursor
= mem_alloc( sizeof(cursor_t
) );
82 cursor
->process
= current
->process
;
83 cursor
->num_frames
= req
->num_frames
;
84 cursor
->delay
= req
->delay
;
85 cursor
->frames
= mem_alloc( req
->num_frames
* sizeof(cursor_frame_t
) );
86 memset( cursor
->frames
, 0, req
->num_frames
* sizeof(cursor_frame_t
) );
88 reply
->handle
= alloc_user_handle( cursor
, USER_CURSOR
);
91 /* Destroy a cursor */
92 DECL_HANDLER(destroy_cursor
)
94 cursor_t
*cursor
= free_user_handle( req
->handle
);
96 if (cursor
) destroy_cursor( cursor
);
100 DECL_HANDLER(get_cursor_info
)
102 cursor_t
*cursor
= get_user_object( req
->handle
, USER_CURSOR
);
106 reply
->num_frames
= cursor
->num_frames
;
107 reply
->delay
= cursor
->delay
;
110 /* Get frame info & bitmap bits */
111 DECL_HANDLER(get_cursor_frame
)
113 unsigned int data_size
;
114 unsigned int frame_idx
= req
->frame_idx
;
115 cursor_t
*cursor
= get_user_object( req
->handle
, USER_CURSOR
);
116 cursor_frame_t
*frame
;
118 if (!cursor
|| cursor
->num_frames
< frame_idx
)
124 frame
= &cursor
->frames
[frame_idx
];
126 reply
->xhot
= frame
->xhot
;
127 reply
->yhot
= frame
->yhot
;
128 reply
->width
= frame
->width
;
129 reply
->height
= frame
->height
;
130 reply
->and_width_bytes
= frame
->and_width_bytes
;
131 reply
->xor_width_bytes
= frame
->xor_width_bytes
;
132 reply
->planes
= frame
->planes
;
133 reply
->bpp
= frame
->bpp
;
135 data_size
= (frame
->and_width_bytes
+ frame
->xor_width_bytes
) * frame
->height
;
136 if (data_size
> get_reply_max_size())
138 set_error( STATUS_BUFFER_OVERFLOW
);
142 set_reply_data( frame
->bits
, data_size
);
145 /* Set frame info & bitmap bits */
146 DECL_HANDLER(set_cursor_frame
)
148 size_t data_size
= get_req_data_size();
149 unsigned int frame_idx
= req
->frame_idx
;
150 cursor_t
*cursor
= get_user_object( req
->handle
, USER_CURSOR
);
151 cursor_frame_t
*frame
;
153 if (!cursor
|| cursor
->num_frames
< frame_idx
|| !data_size
) return;
155 frame
= &cursor
->frames
[frame_idx
];
157 frame
->xhot
= req
->xhot
;
158 frame
->yhot
= req
->yhot
;
159 frame
->width
= req
->width
;
160 frame
->height
= req
->height
;
161 frame
->and_width_bytes
= req
->and_width_bytes
;
162 frame
->xor_width_bytes
= req
->xor_width_bytes
;
163 frame
->planes
= req
->planes
;
164 frame
->bpp
= req
->bpp
;
167 frame
->bits
= memdup( get_req_data(), data_size
);