--- SheepShaver/src/video.cpp 2004/04/10 23:15:20 1.6 +++ SheepShaver/src/video.cpp 2012/03/27 03:43:28 1.17 @@ -1,7 +1,7 @@ /* * video.cpp - Video/graphics emulation * - * SheepShaver (C) 1997-2004 Marc Hellwig and Christian Bauer + * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +21,6 @@ /* * TODO * - check for supported modes ??? - * - window mode "hardware" cursor hotspot */ #include @@ -74,15 +73,15 @@ static long save_conf_mode = APPLE_8_BIT // Function pointers of imported functions typedef int16 (*iocic_ptr)(void *, int16); static uint32 iocic_tvect = 0; -static inline int16 IOCommandIsComplete(void *arg1, int16 arg2) +static inline int16 IOCommandIsComplete(uintptr arg1, int16 arg2) { - return (int16)CallMacOS2(iocic_ptr, iocic_tvect, arg1, arg2); + return (int16)CallMacOS2(iocic_ptr, iocic_tvect, (void *)arg1, arg2); } typedef int16 (*vslnewis_ptr)(void *, uint32, uint32 *); static uint32 vslnewis_tvect = 0; -static inline int16 VSLNewInterruptService(void *arg1, uint32 arg2, uint32 *arg3) +static inline int16 VSLNewInterruptService(uintptr arg1, uint32 arg2, uintptr arg3) { - return (int16)CallMacOS3(vslnewis_ptr, vslnewis_tvect, arg1, arg2, arg3); + return (int16)CallMacOS3(vslnewis_ptr, vslnewis_tvect, (void *)arg1, arg2, (uint32 *)arg3); } typedef int16 (*vsldisposeis_ptr)(uint32); static uint32 vsldisposeis_tvect = 0; @@ -98,9 +97,9 @@ int16 VSLDoInterruptService(uint32 arg1) } typedef void (*nqdmisc_ptr)(uint32, void *); static uint32 nqdmisc_tvect = 0; -void NQDMisc(uint32 arg1, void *arg2) +void NQDMisc(uint32 arg1, uintptr arg2) { - CallMacOS2(nqdmisc_ptr, nqdmisc_tvect, arg1, arg2); + CallMacOS2(nqdmisc_ptr, nqdmisc_tvect, arg1, (void *)arg2); } @@ -143,6 +142,17 @@ bool VideoSnapshot(int xsize, int ysize, /* + * Determine whether we should use the hardware or software cursor, and return true for the former, false for the latter. + * Currently we use the hardware cursor if we can, but perhaps this can be made a preference someday. + */ + +static bool UseHardwareCursor(void) +{ + return video_can_change_cursor(); +} + + +/* * Video driver open routine */ @@ -156,20 +166,24 @@ static int16 VideoOpen(uint32 pb, VidLoc csSave->saveMode = VModes[cur_mode].viAppleMode; csSave->savePage = 0; csSave->saveVidParms = 0; // Add the right table - csSave->gammaTable = NULL; // No gamma table yet - csSave->maxGammaTableSize = 0; csSave->luminanceMapping = false; + csSave->cursorHardware = UseHardwareCursor(); csSave->cursorX = 0; csSave->cursorY = 0; csSave->cursorVisible = 0; csSave->cursorSet = 0; + csSave->cursorHotFlag = false; + csSave->cursorHotX = 0; + csSave->cursorHotY = 0; - // Activate default gamma table + // Find and set default gamma table + csSave->gammaTable = 0; + csSave->maxGammaTableSize = 0; set_gamma(csSave, 0); // Install and activate interrupt service SheepVar32 theServiceID = 0; - VSLNewInterruptService(csSave->regEntryID, FOURCC('v','b','l',' '), (uint32 *)theServiceID.addr()); + VSLNewInterruptService(csSave->regEntryID, FOURCC('v','b','l',' '), theServiceID.addr()); csSave->vslServiceID = theServiceID.value(); D(bug(" Interrupt ServiceID %08lx\n", csSave->vslServiceID)); csSave->interruptsEnabled = true; @@ -182,82 +196,66 @@ static int16 VideoOpen(uint32 pb, VidLoc * Video driver control routine */ -static int16 set_gamma(VidLocals *csSave, uint32 gamma) +static bool allocate_gamma_table(VidLocals *csSave, uint32 size) { - GammaTbl *clientGamma = (GammaTbl *)gamma; - GammaTbl *gammaTable = csSave->gammaTable; + if (size > csSave->maxGammaTableSize) { + if (csSave->gammaTable) { + Mac_sysfree(csSave->gammaTable); + csSave->gammaTable = 0; + csSave->maxGammaTableSize = 0; + } + if ((csSave->gammaTable = Mac_sysalloc(size)) == 0) + return false; + csSave->maxGammaTableSize = size; + } + return true; +} - if (clientGamma == NULL) { +static int16 set_gamma(VidLocals *csSave, uint32 gamma) +{ + if (gamma == 0) { // Build linear ramp, 256 entries - // No gamma table supplied, build linear ramp - uint32 linearRampSize = sizeof(GammaTbl) + 256 - 2; - uint8 *correctionData; - - // Allocate new gamma table if existing gamma table is smaller than required. - if (linearRampSize > csSave->maxGammaTableSize) { - delete[] csSave->gammaTable; - csSave->gammaTable = (GammaTbl *)new uint8[linearRampSize]; - csSave->maxGammaTableSize = linearRampSize; - gammaTable = csSave->gammaTable; - } - - gammaTable->gVersion = 0; // A version 0 style of the GammaTbl structure - gammaTable->gType = 0; // Frame buffer hardware invariant - gammaTable->gFormulaSize = 0; // No formula data, just correction data - gammaTable->gChanCnt = 1; // Apply same correction to Red, Green, & Blue - gammaTable->gDataCnt = 256; // gDataCnt == 2^^gDataWidth - gammaTable->gDataWidth = 8; // 8 bits of significant data per entry - - // Find the starting address of the correction data. This can be computed by starting at - // the address of gFormula[0] and adding the gFormulaSize. - correctionData = (uint8 *)((uint32)&gammaTable->gFormulaData[0] + gammaTable->gFormulaSize); + // Allocate new table, if necessary + if (!allocate_gamma_table(csSave, SIZEOF_GammaTbl + 256)) + return memFullErr; + + // Initialize header + WriteMacInt16(csSave->gammaTable + gVersion, 0); // A version 0 style of the GammaTbl structure + WriteMacInt16(csSave->gammaTable + gType, 0); // Frame buffer hardware invariant + WriteMacInt16(csSave->gammaTable + gFormulaSize, 0); // No formula data, just correction data + WriteMacInt16(csSave->gammaTable + gChanCnt, 1); // Apply same correction to Red, Green, & Blue + WriteMacInt16(csSave->gammaTable + gDataCnt, 256); // gDataCnt == 2^^gDataWidth + WriteMacInt16(csSave->gammaTable + gDataWidth, 8); // 8 bits of significant data per entry // Build the linear ramp - for (int i=0; igDataCnt; i++) - *correctionData++ = i; + uint32 p = csSave->gammaTable + gFormulaData; + for (int i=0; i<256; i++) + WriteMacInt8(p + i, i); - } else { + } else { // User-supplied gamma table - // User supplied a gamma table, so make sure it is a valid one - if (clientGamma->gVersion != 0) + // Validate header + if (ReadMacInt16(gamma + gVersion) != 0) return paramErr; - if (clientGamma->gType != 0) + if (ReadMacInt16(gamma + gType) != 0) return paramErr; - if ((clientGamma->gChanCnt != 1) && (clientGamma->gChanCnt != 3)) + int chan_cnt = ReadMacInt16(gamma + gChanCnt); + if (chan_cnt != 1 && chan_cnt != 3) return paramErr; - if (clientGamma->gDataWidth > 8) + int data_width = ReadMacInt16(gamma + gDataWidth); + if (data_width > 8) return paramErr; - if (clientGamma->gDataCnt != (1 << clientGamma->gDataWidth)) + int data_cnt = ReadMacInt16(gamma + gDataWidth); + if (data_cnt != (1 << data_width)) return paramErr; - uint32 tableSize = sizeof(GammaTbl) // fixed size header - + clientGamma->gFormulaSize // add formula size - + clientGamma->gChanCnt * clientGamma->gDataCnt // assume 1 byte/entry - - 2; // correct gFormulaData[0] counted twice - - // Allocate new gamma table if existing gamma table is smaller than required. - if (tableSize > csSave->maxGammaTableSize) { - delete[] csSave->gammaTable; - csSave->gammaTable = (GammaTbl *)new uint8[tableSize]; - csSave->maxGammaTableSize = tableSize; - gammaTable = csSave->gammaTable; - } - - // Copy gamma table header - *gammaTable = *clientGamma; - - // Copy the formula data (if any) - uint8 *newData = (uint8 *)&gammaTable->gFormulaData[0]; // Point to newGamma's formula data - uint8 *clientData = (uint8 *)&clientGamma->gFormulaData[0]; // Point to clientGamma's formula data - for (int i=0; igFormulaSize; i++) - *newData++ = *clientData++; - - // Copy the correction data. Convientiently, after copying the formula data, the 'newData' - // pointer and the 'clientData' pointer are pointing to the their respective starting points - // of their correction data. - for (int i=0; igChanCnt; i++) - for (int j=0; jgDataCnt; j++) - *newData++ = *clientData++; + // Allocate new table, if necessary + int size = SIZEOF_GammaTbl + ReadMacInt16(gamma + gFormulaSize) + chan_cnt * data_cnt; + if (!allocate_gamma_table(csSave, size)) + return memFullErr; + + // Copy table + Mac2Mac_memcpy(csSave->gammaTable, gamma, size); } return noErr; } @@ -298,16 +296,26 @@ static int16 VideoControl(uint32 pb, Vid uint8 *green_gamma = NULL; uint8 *blue_gamma = NULL; int gamma_data_width = 0; - if (display_type == DIS_SCREEN && csSave->gammaTable != NULL) { // Windows are gamma-corrected by BeOS - do_gamma = true; - GammaTbl *gamma = csSave->gammaTable; - gamma_data_width = gamma->gDataWidth; - red_gamma = (uint8 *)&gamma->gFormulaData + gamma->gFormulaSize; - if (gamma->gChanCnt == 1) { - green_gamma = blue_gamma = red_gamma; - } else { - green_gamma = red_gamma + gamma->gDataCnt; - blue_gamma = red_gamma + 2 * gamma->gDataCnt; + if (csSave->gammaTable) { +#ifdef __BEOS__ + // Windows are gamma-corrected by BeOS + const bool can_do_gamma = (display_type == DIS_SCREEN); +#else + const bool can_do_gamma = true; +#endif + if (can_do_gamma) { + uint32 gamma_table = csSave->gammaTable; + red_gamma = Mac2HostAddr(gamma_table + gFormulaData + ReadMacInt16(gamma_table + gFormulaSize)); + int chan_cnt = ReadMacInt16(gamma_table + gChanCnt); + if (chan_cnt == 1) + green_gamma = blue_gamma = red_gamma; + else { + int ofs = ReadMacInt16(gamma_table + gDataCnt); + green_gamma = red_gamma + ofs; + blue_gamma = green_gamma + ofs; + } + gamma_data_width = ReadMacInt16(gamma_table + gDataWidth); + do_gamma = true; } } @@ -355,9 +363,11 @@ static int16 VideoControl(uint32 pb, Vid return noErr; } - case cscSetGamma: // SetGamma - D(bug("SetGamma\n")); - return set_gamma(csSave, ReadMacInt32(param)); + case cscSetGamma: { // SetGamma + uint32 user_table = ReadMacInt32(param + csGTable); + D(bug("SetGamma %08x\n", user_table)); + return set_gamma(csSave, ReadMacInt32(user_table)); + } case cscGrayPage: { // GrayPage D(bug("GrayPage %d\n", ReadMacInt16(param + csPage))); @@ -418,51 +428,123 @@ static int16 VideoControl(uint32 pb, Vid case cscSetHardwareCursor: { // D(bug("SetHardwareCursor\n")); + + if (!csSave->cursorHardware) + return controlErr; + csSave->cursorSet = false; bool changed = false; - // Get cursor data even on a screen, to set the right cursor image when switching back to a window // Image uint32 cursor = ReadMacInt32(param); // Pointer to CursorImage uint32 pmhandle = ReadMacInt32(cursor + ciCursorPixMap); if (pmhandle == 0 || ReadMacInt32(pmhandle) == 0) return controlErr; uint32 pixmap = ReadMacInt32(pmhandle); - if (memcmp(MacCursor + 4, Mac2HostAddr(ReadMacInt32(pixmap)), 32)) { - memcpy(MacCursor + 4, Mac2HostAddr(ReadMacInt32(pixmap)), 32); - changed = true; - } + + // XXX: only certain image formats are handled properly at the moment + uint16 rowBytes = ReadMacInt16(pixmap + 4) & 0x7FFF; + if (rowBytes != 2) + return controlErr; // Mask uint32 bmhandle = ReadMacInt32(cursor + ciCursorBitMask); if (bmhandle == 0 || ReadMacInt32(bmhandle) == 0) return controlErr; uint32 bitmap = ReadMacInt32(bmhandle); + + // Get cursor data even on a screen, to set the right cursor image when switching back to a window. + // Hotspot is stale, but will be fixed by the next call to DrawHardwareCursor, which is likely to + // occur immediately hereafter. + + if (memcmp(MacCursor + 4, Mac2HostAddr(ReadMacInt32(pixmap)), 32)) { + memcpy(MacCursor + 4, Mac2HostAddr(ReadMacInt32(pixmap)), 32); + changed = true; + } if (memcmp(MacCursor + 4 + 32, Mac2HostAddr(ReadMacInt32(bitmap)), 32)) { memcpy(MacCursor + 4 + 32, Mac2HostAddr(ReadMacInt32(bitmap)), 32); changed = true; } - // Hotspot (!! this doesn't work) - MacCursor[2] = ReadMacInt8(0x885); - MacCursor[3] = ReadMacInt8(0x887); - // Set new cursor image - if (display_type == DIS_SCREEN) + if (!video_can_change_cursor()) return controlErr; if (changed) video_set_cursor(); csSave->cursorSet = true; + csSave->cursorHotFlag = true; return noErr; } - case cscDrawHardwareCursor: + case cscDrawHardwareCursor: { // D(bug("DrawHardwareCursor\n")); + + if (!csSave->cursorHardware) + return controlErr; + + int32 oldX = csSave->cursorX; + int32 oldY = csSave->cursorY; + uint32 oldVisible = csSave->cursorVisible; + csSave->cursorX = ReadMacInt32(param + csCursorX); csSave->cursorY = ReadMacInt32(param + csCursorY); csSave->cursorVisible = ReadMacInt32(param + csCursorVisible); + bool changed = (csSave->cursorVisible != oldVisible); + + // If this is the first DrawHardwareCursor call since the cursor was last set (via SetHardwareCursor), + // attempt to set an appropriate cursor hotspot. SetHardwareCursor itself does not know what the + // hotspot should be; it knows only the cursor image and mask. The hotspot is known only to the caller, + // and we have to try to infer it here. The usual sequence of calls when changing the cursor is: + // + // DrawHardwareCursor with (oldX, oldY, invisible) + // SetHardwareCursor with (cursor) + // DrawHardwareCursor with (newX, newY, visible) + // + // The key thing to note is that the sequence is intended not to change the current screen pixel location + // indicated by the hotspot. Thus, the difference between (newX, newY) and (oldX, oldY) reflects precisely + // the difference between the old cursor hotspot and the new one. For example, if you change from a + // cursor whose hotspot is (1, 1) to one whose hotspot is (7, 4), then you must adjust the cursor position + // by (-6, -3) in order for the same screen pixel to remain under the new hotspot. + // + // Alas, on rare occasions this heuristic can fail, and if you did nothing else you could even get stuck + // with the wrong hotspot from then on. To address that possibility, we force the hotspot to (1, 1) + // whenever the cursor being drawn is the standard arrow. Thus, while it is very unlikely that you will + // ever have the wrong hotspot, if you do, it is easy to recover. + + if (csSave->cursorHotFlag) { + csSave->cursorHotFlag = false; + D(bug("old hotspot (%d, %d)\n", csSave->cursorHotX, csSave->cursorHotY)); + + static uint8 arrow[] = { + 0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0x7C, 0x00, 0x7E, 0x00, 0x7F, 0x00, + 0x7F, 0x80, 0x7C, 0x00, 0x6C, 0x00, 0x46, 0x00, 0x06, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, + }; + if (memcmp(MacCursor + 4, arrow, 32) == 0) { + csSave->cursorHotX = 1; + csSave->cursorHotY = 1; + } else if (csSave->cursorX != oldX || csSave->cursorY != oldY) { + int32 hotX = csSave->cursorHotX + (oldX - csSave->cursorX); + int32 hotY = csSave->cursorHotY + (oldY - csSave->cursorY); + + if (0 <= hotX && hotX <= 15 && 0 <= hotY && hotY <= 15) { + csSave->cursorHotX = hotX; + csSave->cursorHotY = hotY; + } + } + if (MacCursor[2] != csSave->cursorHotX || MacCursor[3] != csSave->cursorHotY) { + MacCursor[2] = csSave->cursorHotX; + MacCursor[3] = csSave->cursorHotY; + changed = true; + } + D(bug("new hotspot (%d, %d)\n", csSave->cursorHotX, csSave->cursorHotY)); + } + + if (changed && video_can_change_cursor()) + video_set_cursor(); + return noErr; + } case 43: { // Driver Gestalt uint32 sel = ReadMacInt32(pb + csParam); @@ -519,6 +601,21 @@ static uint32 max_depth(uint32 id) return max; } +// Get X/Y size of specified resolution +static void get_size_of_resolution(int id, uint32 &x, uint32 &y) +{ + VideoInfo *p = VModes; + while (p->viType != DIS_INVALID) { + if (p->viAppleID == id) { + x = p->viXsize; + y = p->viYsize; + return; + } + p++; + } + x = y = 0; +} + static int16 VideoStatus(uint32 pb, VidLocals *csSave) { int16 code = ReadMacInt16(pb + csCode); @@ -600,7 +697,7 @@ static int16 VideoStatus(uint32 pb, VidL case cscGetGamma: // GetGamma D(bug("GetGamma\n")); WriteMacInt32(param, (uint32)csSave->gammaTable); - return statusErr; + return noErr; case cscGetDefaultMode: // GetDefaultMode D(bug("GetDefaultMode\n")); @@ -690,6 +787,11 @@ static int16 VideoStatus(uint32 pb, VidL WriteMacInt32(param + csVerticalLines, 768); WriteMacInt32(param + csRefreshRate, 75<<16); break; + case APPLE_1152x768: + WriteMacInt32(param + csHorizontalPixels, 1152); + WriteMacInt32(param + csVerticalLines, 768); + WriteMacInt32(param + csRefreshRate, 75<<16); + break; case APPLE_1152x900: WriteMacInt32(param + csHorizontalPixels, 1152); WriteMacInt32(param + csVerticalLines, 900); @@ -705,6 +807,14 @@ static int16 VideoStatus(uint32 pb, VidL WriteMacInt32(param + csVerticalLines, 1200); WriteMacInt32(param + csRefreshRate, 75<<16); break; + case APPLE_CUSTOM: { + uint32 x, y; + get_size_of_resolution(work_id, x, y); + WriteMacInt32(param + csHorizontalPixels, x); + WriteMacInt32(param + csVerticalLines, y); + WriteMacInt32(param + csRefreshRate, 75<<16); + break; + } } return noErr; } @@ -808,6 +918,9 @@ static int16 VideoStatus(uint32 pb, VidL case APPLE_1024x768: timing = timingVESA_1024x768_75hz; break; + case APPLE_1152x768: + timing = timingApple_1152x870_75hz; // FIXME + break; case APPLE_1152x900: timing = timingApple_1152x870_75hz; break; @@ -830,11 +943,15 @@ static int16 VideoStatus(uint32 pb, VidL case cscSupportsHardwareCursor: D(bug("SupportsHardwareCursor\n")); - WriteMacInt32(param, 1); + WriteMacInt32(param, csSave->cursorHardware); return noErr; case cscGetHardwareCursorDrawState: D(bug("GetHardwareCursorDrawState\n")); + + if (!csSave->cursorHardware) + return statusErr; + WriteMacInt32(param + csCursorX, csSave->cursorX); WriteMacInt32(param + csCursorY, csSave->cursorY); WriteMacInt32(param + csCursorVisible, csSave->cursorVisible); @@ -868,47 +985,51 @@ static int16 VideoClose(uint32 pb, VidLo * Native (PCI) driver entry */ -int16 VideoDoDriverIO(void *spaceID, void *commandID, void *commandContents, uint32 commandCode, uint32 commandKind) +int16 VideoDoDriverIO(uint32 spaceID, uint32 commandID, uint32 commandContents, uint32 commandCode, uint32 commandKind) { -// D(bug("VideoDoDriverIO space %p, command %p, contents %p, code %d, kind %d\n", spaceID, commandID, commandContents, commandCode, commandKind)); +// D(bug("VideoDoDriverIO space %08x, command %08x, contents %08x, code %d, kind %d\n", spaceID, commandID, commandContents, commandCode, commandKind)); int16 err = noErr; switch (commandCode) { case kInitializeCommand: case kReplaceCommand: - if (private_data != NULL) // Might be left over from a reboot - delete private_data->gammaTable; + if (private_data != NULL) { // Might be left over from a reboot + if (private_data->gammaTable) + Mac_sysfree(private_data->gammaTable); + if (private_data->regEntryID) + Mac_sysfree(private_data->regEntryID); + } delete private_data; - iocic_tvect = (uint32)FindLibSymbol("\021DriverServicesLib", "\023IOCommandIsComplete"); + iocic_tvect = FindLibSymbol("\021DriverServicesLib", "\023IOCommandIsComplete"); D(bug("IOCommandIsComplete TVECT at %08lx\n", iocic_tvect)); if (iocic_tvect == 0) { printf("FATAL: VideoDoDriverIO(): Can't find IOCommandIsComplete()\n"); err = -1; break; } - vslnewis_tvect = (uint32)FindLibSymbol("\020VideoServicesLib", "\026VSLNewInterruptService"); + vslnewis_tvect = FindLibSymbol("\020VideoServicesLib", "\026VSLNewInterruptService"); D(bug("VSLNewInterruptService TVECT at %08lx\n", vslnewis_tvect)); if (vslnewis_tvect == 0) { printf("FATAL: VideoDoDriverIO(): Can't find VSLNewInterruptService()\n"); err = -1; break; } - vsldisposeis_tvect = (uint32)FindLibSymbol("\020VideoServicesLib", "\032VSLDisposeInterruptService"); + vsldisposeis_tvect = FindLibSymbol("\020VideoServicesLib", "\032VSLDisposeInterruptService"); D(bug("VSLDisposeInterruptService TVECT at %08lx\n", vsldisposeis_tvect)); if (vsldisposeis_tvect == 0) { printf("FATAL: VideoDoDriverIO(): Can't find VSLDisposeInterruptService()\n"); err = -1; break; } - vsldois_tvect = (uint32)FindLibSymbol("\020VideoServicesLib", "\025VSLDoInterruptService"); + vsldois_tvect = FindLibSymbol("\020VideoServicesLib", "\025VSLDoInterruptService"); D(bug("VSLDoInterruptService TVECT at %08lx\n", vsldois_tvect)); if (vsldois_tvect == 0) { printf("FATAL: VideoDoDriverIO(): Can't find VSLDoInterruptService()\n"); err = -1; break; } - nqdmisc_tvect = (uint32)FindLibSymbol("\014InterfaceLib", "\007NQDMisc"); + nqdmisc_tvect = FindLibSymbol("\014InterfaceLib", "\007NQDMisc"); D(bug("NQDMisc TVECT at %08lx\n", nqdmisc_tvect)); if (nqdmisc_tvect == 0) { printf("FATAL: VideoDoDriverIO(): Can't find NQDMisc()\n"); @@ -917,33 +1038,43 @@ int16 VideoDoDriverIO(void *spaceID, voi } private_data = new VidLocals; - private_data->gammaTable = NULL; - memcpy(private_data->regEntryID, (uint8 *)commandContents + 2, 16); // DriverInitInfo.deviceEntry + private_data->gammaTable = 0; + private_data->regEntryID = Mac_sysalloc(sizeof(RegEntryID)); + if (private_data->regEntryID == 0) { + printf("FATAL: VideoDoDriverIO(): Can't allocate service owner\n"); + err = -1; + break; + } + Mac2Mac_memcpy(private_data->regEntryID, commandContents + 2, 16); // DriverInitInfo.deviceEntry private_data->interruptsEnabled = false; // Disable interrupts break; case kFinalizeCommand: case kSupersededCommand: - if (private_data != NULL) - delete private_data->gammaTable; + if (private_data != NULL) { + if (private_data->gammaTable) + Mac_sysfree(private_data->gammaTable); + if (private_data->regEntryID) + Mac_sysfree(private_data->regEntryID); + } delete private_data; private_data = NULL; break; case kOpenCommand: - err = VideoOpen((uint32)commandContents, private_data); + err = VideoOpen(commandContents, private_data); break; case kCloseCommand: - err = VideoClose((uint32)commandContents, private_data); + err = VideoClose(commandContents, private_data); break; case kControlCommand: - err = VideoControl((uint32)commandContents, private_data); + err = VideoControl(commandContents, private_data); break; case kStatusCommand: - err = VideoStatus((uint32)commandContents, private_data); + err = VideoStatus(commandContents, private_data); break; case kReadCommand: