Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

acons.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: acons.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains code for dealing with animated icons/cursors. 00007 * 00008 * History: 00009 * 10-02-91 DarrinM Created. 00010 * 07-30-92 DarrinM Unicodized. 00011 \***************************************************************************/ 00012 00013 #include "precomp.h" 00014 #pragma hdrstop 00015 00016 /***************************************************************************\ 00017 * _SetSystemCursor (API) 00018 * 00019 * Replace a system (aka 'public') cursor with a user provided one. The new 00020 * cursor is pulled from a file (.CUR, .ICO, or .ANI) specified in WIN.INI. 00021 * 00022 * History: 00023 * 12-26-91 DarrinM Created. 00024 * 08-04-92 DarrinM Recreated. 00025 * 10/14/1995 SanfordS Win95 support. 00026 \***************************************************************************/ 00027 00028 BOOL zzzSetSystemCursor( 00029 PCURSOR pcur, 00030 DWORD id) 00031 { 00032 int i; 00033 00034 if (!CheckWinstaWriteAttributesAccess()) { 00035 return FALSE; 00036 } 00037 00038 UserAssert(pcur); 00039 00040 /* 00041 * Check if this cursor is one of the replaceable ones. 00042 */ 00043 for (i = 0; i < COCR_CONFIGURABLE; i++) 00044 if (gasyscur[i].Id == (WORD)id) 00045 break; 00046 00047 /* 00048 * Not replaceable, bail out. 00049 */ 00050 if (i == COCR_CONFIGURABLE) { 00051 RIPMSG1(RIP_WARNING, "_SetSystemCursor: called with bad id %x.\n", id); 00052 return FALSE; 00053 } 00054 00055 return zzzSetSystemImage(pcur, gasyscur[i].spcur); 00056 } 00057 00058 00059 /***********************************************************************\ 00060 * SetSystemImage 00061 * 00062 * Places the contents of pcur into pcurSys and destroys pcur. 00063 * 00064 * Returns: fSuccess 00065 * 00066 * 10/14/1995 Created SanfordS 00067 \***********************************************************************/ 00068 00069 BOOL zzzSetSystemImage( 00070 PCURSOR pcur, 00071 PCURSOR pcurSys) 00072 { 00073 #define CBCOPY (max(sizeof(CURSOR), sizeof(ACON)) - FIELD_OFFSET(CURSOR, CI_COPYSTART)) 00074 #define pacon ((PACON)pcur) 00075 00076 char cbT[CBCOPY]; 00077 UINT CURSORF_flags; 00078 00079 UserAssert(pcurSys); 00080 00081 if (pcurSys == pcur) 00082 return(TRUE); 00083 00084 /* 00085 * All ssytem images being replaced should have ordinal names 00086 * and reference the USER module and be unowned. 00087 */ 00088 UserAssert(!IS_PTR(pcurSys->strName.Buffer)); 00089 UserAssert(pcurSys->atomModName == atomUSER32); 00090 00091 /* 00092 * if pcur was an acon, transfer frame ownerships to pcurSys. 00093 */ 00094 UserAssert(pcurSys->head.ppi == NULL); 00095 if (pcur->CURSORF_flags & CURSORF_ACON && 00096 pcur->head.ppi != NULL) { 00097 00098 int i; 00099 PHE phe = HMPheFromObject(pcurSys); 00100 PTHREADINFO ptiOwner = ((PPROCESSINFO)phe->pOwner)->ptiList; 00101 00102 for (i = 0; i < pacon->cpcur; i++) { 00103 HMChangeOwnerProcess(pacon->aspcur[i], ptiOwner); 00104 pacon->aspcur[i]->head.ppi = NULL; 00105 } 00106 } 00107 00108 /* 00109 * If this assert fails, the CURSOR and ACON structures were changed 00110 * incorrectly - read the comments in user.h and wingdi.w around 00111 * tagCURSOR, tagACON, and CURSINFO. 00112 */ 00113 UserAssert(FIELD_OFFSET(CURSOR, CI_FIRST) == FIELD_OFFSET(ACON, CI_FIRST)); 00114 00115 /* 00116 * swap everything starting from CI_COPYSTART. 00117 */ 00118 RtlCopyMemory(&cbT, &pcur->CI_COPYSTART, CBCOPY); 00119 RtlCopyMemory(&pcur->CI_COPYSTART, &pcurSys->CI_COPYSTART, CBCOPY); 00120 RtlCopyMemory(&pcurSys->CI_COPYSTART, &cbT, CBCOPY); 00121 /* 00122 * Swap the CURSORF_ACON flags since they go with the swapped data. 00123 */ 00124 CURSORF_flags = pcur->CURSORF_flags & CURSORF_ACON; 00125 pcur->CURSORF_flags = 00126 (pcur->CURSORF_flags & ~CURSORF_ACON) | 00127 (pcurSys->CURSORF_flags & CURSORF_ACON); 00128 pcurSys->CURSORF_flags = 00129 (pcurSys->CURSORF_flags & ~CURSORF_ACON) | CURSORF_flags; 00130 00131 /* 00132 * If we swapped acons into pcur, then we need to change the ownerhsip to 00133 * make sure they can get destroyed 00134 */ 00135 if (pcur->CURSORF_flags & CURSORF_ACON) { 00136 int i; 00137 PTHREADINFO ptiCurrent = PtiCurrent(); 00138 for (i = 0; i < pacon->cpcur; i++) { 00139 HMChangeOwnerProcess(pacon->aspcur[i], ptiCurrent); 00140 } 00141 } 00142 00143 /* 00144 * Use THREADCLEANUP so system cursors are not destroyed. 00145 */ 00146 _DestroyCursor(pcur, CURSOR_THREADCLEANUP); 00147 00148 00149 /* 00150 * If the current logical current is changing the force the current physical 00151 * cursor to change. 00152 */ 00153 if (gpcurLogCurrent == pcurSys) { 00154 gpcurLogCurrent = NULL; 00155 gpcurPhysCurrent = NULL; 00156 zzzUpdateCursorImage(); 00157 } 00158 00159 /* 00160 * Mark the cursor as a system cursor that can be shadowed by GDI. 00161 */ 00162 pcurSys->CURSORF_flags |= CURSORF_SYSTEM; 00163 00164 return TRUE; 00165 #undef pacon 00166 #undef CBCOPY 00167 } 00168 00169 00170 00171 /***************************************************************************\ 00172 * _GetCursorFrameInfo (API) 00173 * 00174 * Example usage: 00175 * 00176 * hcur = _GetCursorFrameInfo(hacon, NULL, 4, &ccur); 00177 * hcur = _GetCursorFrameInfo(NULL, IDC_NORMAL, 0, &ccur); // get device's arrow 00178 * 00179 * History: 00180 * 08-05-92 DarrinM Created. 00181 \***************************************************************************/ 00182 00183 PCURSOR _GetCursorFrameInfo( 00184 PCURSOR pcur, 00185 int iFrame, 00186 PJIF pjifRate, 00187 LPINT pccur) 00188 { 00189 /* 00190 * If this is only a single cursor (not an ACON) just return it and 00191 * a frame count of 1. 00192 */ 00193 if (!(pcur->CURSORF_flags & CURSORF_ACON)) { 00194 *pccur = 1; 00195 *pjifRate = 0; 00196 return pcur; 00197 } 00198 00199 /* 00200 * Return the useful cursor information for the specified frame 00201 * of the ACON. 00202 */ 00203 #define pacon ((PACON)pcur) 00204 if (iFrame < 0 || iFrame >= pacon->cicur) 00205 return NULL; 00206 00207 *pccur = pacon->cicur; 00208 *pjifRate = pacon->ajifRate[iFrame]; 00209 00210 return pacon->aspcur[pacon->aicur[iFrame]]; 00211 #undef pacon 00212 } 00213 00214 00215 /***************************************************************************\ 00216 * DestroyAniIcon 00217 * 00218 * Free all the individual cursors that make up the frames of an animated 00219 * icon. 00220 * 00221 * WARNING: DestroyAniIcon assumes that all fields that an ACON shares with 00222 * a cursor will be freed by some cursor code (probably the cursor function 00223 * that calls this one). 00224 * 00225 * History: 00226 * 08-04-92 DarrinM Created. 00227 \***************************************************************************/ 00228 00229 BOOL DestroyAniIcon( 00230 PACON pacon) 00231 { 00232 int i; 00233 PCURSOR pcur; 00234 00235 for (i = 0; i < pacon->cpcur; i++) { 00236 UserAssert(pacon->aspcur[i]->CURSORF_flags & CURSORF_ACONFRAME); 00237 /* 00238 * This should not be a public acon; if it is, unlock won't be able 00239 * to destroy it. If destroy a public icon, ownership must be called 00240 * before calling this function (see zzzSetSystemImage) 00241 */ 00242 UserAssert(GETPPI(pacon->aspcur[i]) != NULL); 00243 pcur = Unlock(&pacon->aspcur[i]); 00244 if (pcur != NULL) { 00245 _DestroyCursor(pcur, CURSOR_ALWAYSDESTROY); 00246 } 00247 } 00248 00249 UserFreePool(pacon->aspcur); 00250 00251 return TRUE; 00252 } 00253 00254 00255 /***********************************************************************\ 00256 * LinkCursor 00257 * 00258 * Links unlinked cursor into the apropriate icon cache IFF its the 00259 * type of cursor that needs to be in the cache. 00260 * 00261 * Note that changing ownership if cursor objects needs to keep this 00262 * cache linking in mind. The unlink routine in 00263 * DestroyEmptyCursorObject() will handle public cursor objects made 00264 * local but that is all. 00265 * 00266 * 10/18/1995 Created SanfordS 00267 \***********************************************************************/ 00268 00269 VOID LinkCursor( 00270 PCURSOR pcur) 00271 { 00272 /* 00273 * Should never try to link twice! 00274 */ 00275 UserAssert(!(pcur->CURSORF_flags & CURSORF_LINKED)); 00276 /* 00277 * We don't cache acon frames because they all belong to the 00278 * root acon object. 00279 * 00280 * We don't cache process owned objects that are not LRSHARED 00281 * either. 00282 */ 00283 if (!(pcur->CURSORF_flags & CURSORF_ACONFRAME)) { 00284 PPROCESSINFO ppi = pcur->head.ppi; 00285 if (ppi == NULL) { 00286 /* 00287 * Public cache object. 00288 */ 00289 pcur->pcurNext = gpcurFirst; 00290 gpcurFirst = pcur; 00291 pcur->CURSORF_flags |= CURSORF_LINKED; 00292 } else if (pcur->CURSORF_flags & CURSORF_LRSHARED) { 00293 /* 00294 * Private cache LR_SHARED object. 00295 */ 00296 pcur->pcurNext = ppi->pCursorCache; 00297 ppi->pCursorCache = pcur; 00298 pcur->CURSORF_flags |= CURSORF_LINKED; 00299 } 00300 } 00301 } 00302 00303 00304 00305 00306 /***************************************************************************\ 00307 * 00308 * Initializes empty cursor/icons. Note that the string buffers and 00309 * pcurData are not captured. If a fault occurs in this routine, 00310 * all allocated memory will be freed when the cursors are destroyed. 00311 * 00312 * Critical side effect: If this function fails, the bitmaps must NOT 00313 * have been made public. (See CreateIconIndirect()). 00314 * 00315 * History: 00316 * 12-01-94 JimA Created. 00317 \***************************************************************************/ 00318 00319 BOOL _SetCursorIconData( 00320 PCURSOR pcur, 00321 PUNICODE_STRING cczpstrModName, 00322 PUNICODE_STRING cczpstrName, 00323 PCURSORDATA pcurData, 00324 DWORD cbData) 00325 { 00326 #define pacon ((PACON)pcur) 00327 int i; 00328 #if DBG 00329 BOOL fSuccess; 00330 #endif 00331 00332 pcur->CURSORF_flags |= pcurData->CURSORF_flags; 00333 pcur->rt = pcurData->rt; 00334 00335 if (pcurData->CURSORF_flags & CURSORF_ACON) { 00336 UserAssert(pacon->aspcur == NULL); 00337 RtlCopyMemory(&pacon->cpcur, 00338 &pcurData->cpcur, 00339 sizeof(ACON) - FIELD_OFFSET(ACON, cpcur)); 00340 } else { 00341 RtlCopyMemory(&pcur->CI_COPYSTART, 00342 &pcurData->CI_COPYSTART, 00343 sizeof(CURSOR) - FIELD_OFFSET(CURSOR, CI_COPYSTART)); 00344 } 00345 00346 /* 00347 * Save name of the cursor resource 00348 */ 00349 if (cczpstrName->Length != 0){ 00350 /* 00351 * AllocateUnicodeString guards access to src Buffer with 00352 * a try block. 00353 */ 00354 00355 if (!AllocateUnicodeString(&pcur->strName, cczpstrName)) 00356 return FALSE; 00357 } else { 00358 pcur->strName = *cczpstrName; 00359 } 00360 00361 /* 00362 * Save the module name 00363 */ 00364 if (cczpstrModName->Buffer) { 00365 /* 00366 * UserAddAtom guards access to the string with a try block. 00367 */ 00368 pcur->atomModName = UserAddAtom(cczpstrModName->Buffer, FALSE); 00369 if (pcur->atomModName == 0) { 00370 return FALSE; 00371 } 00372 } 00373 00374 if (pcur->CURSORF_flags & CURSORF_ACON) { 00375 00376 /* 00377 * Stash away animated icon info. 00378 */ 00379 pacon = (PACON)pcur; 00380 pacon->aspcur = UserAllocPool(cbData, TAG_CURSOR); 00381 if (pacon->aspcur == NULL) 00382 return FALSE; 00383 00384 /* 00385 * Copy the handle array. Do this in a try/except so the 00386 * buffer will be freed if pcurData goes away. Even though 00387 * cursor destruction would free the array, a fault will 00388 * leave the contents in an undetermined state and cause 00389 * problems during cursor destruction. 00390 */ 00391 try { 00392 RtlCopyMemory(pacon->aspcur, pcurData->aspcur, cbData); 00393 pacon->aicur = (DWORD *)((PBYTE)pacon->aspcur + (ULONG_PTR)pcurData->aicur); 00394 pacon->ajifRate = (PJIF)((PBYTE)pacon->aspcur + (ULONG_PTR)pcurData->ajifRate); 00395 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 00396 UserFreePool(pacon->aspcur); 00397 pacon->aspcur = NULL; 00398 return FALSE; 00399 } 00400 00401 /* 00402 * Convert handles into pointers and lock them in. 00403 */ 00404 for (i = 0; i < pacon->cpcur; i++) { 00405 PCURSOR pcurT; 00406 00407 pcurT = (PCURSOR) HMValidateHandle(pacon->aspcur[i], TYPE_CURSOR); 00408 if (pcurT) { 00409 pacon->aspcur[i] = NULL; 00410 Lock(&pacon->aspcur[i], pcurT); 00411 } else { 00412 while (--i >= 0) { 00413 Unlock(&pacon->aspcur[i]); 00414 } 00415 00416 UserFreePool(pacon->aspcur); 00417 pacon->aspcur = NULL; 00418 RIPMSG0(RIP_WARNING, "SetCursorIconData: invalid cursor handle for animated cursor"); 00419 return FALSE; 00420 } 00421 } 00422 } else { 00423 00424 PW32PROCESS W32Process = W32GetCurrentProcess(); 00425 00426 /* 00427 * Make the cursor and its bitmaps public - LAST THING! 00428 */ 00429 UserAssert(pcur->hbmMask); 00430 UserAssert(pcur->cx); 00431 UserAssert(pcur->cy); 00432 00433 /* 00434 * Make the cursor public so that it can be shared across processes. 00435 * Charge the curson to this very process GDI quota even if it's public. 00436 */ 00437 #if DBG 00438 fSuccess = 00439 #endif 00440 GreSetBitmapOwner(pcur->hbmMask, OBJECT_OWNER_PUBLIC); 00441 UserAssert(fSuccess); 00442 GreIncQuotaCount(W32Process); 00443 if (pcur->hbmColor) { 00444 #if DBG 00445 fSuccess = 00446 #endif 00447 GreSetBitmapOwner(pcur->hbmColor, OBJECT_OWNER_PUBLIC); 00448 UserAssert(fSuccess); 00449 GreIncQuotaCount(W32Process); 00450 } 00451 } 00452 00453 LinkCursor(pcur); 00454 00455 return TRUE; 00456 #undef pacon 00457 }

Generated on Sat May 15 19:39:13 2004 for test by doxygen 1.3.7